diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5832378bff..5041f4b625 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @cliu123 @cwperks @DarshitChanpura @davidlago @peternied @RyanL1997 @scrawfor99 @reta +* @cliu123 @cwperks @DarshitChanpura @davidlago @peternied @RyanL1997 @scrawfor99 @reta @willyborankin diff --git a/.github/actions/create-bwc-build/action.yaml b/.github/actions/create-bwc-build/action.yaml index b6ee3d5478..fcfa612a7d 100644 --- a/.github/actions/create-bwc-build/action.yaml +++ b/.github/actions/create-bwc-build/action.yaml @@ -5,7 +5,7 @@ inputs: plugin-branch: description: 'The branch of the plugin that should be built, e.g "2.2", "1.x"' required: true - + outputs: built-version: description: 'The version of OpenSearch that was associated with this branch' diff --git a/.github/actions/start-opensearch-with-one-plugin/action.yml b/.github/actions/start-opensearch-with-one-plugin/action.yml index b562851b0c..fa5681c422 100644 --- a/.github/actions/start-opensearch-with-one-plugin/action.yml +++ b/.github/actions/start-opensearch-with-one-plugin/action.yml @@ -70,7 +70,7 @@ runs: # Run any configuration scripts - name: Run Setup Script for Linux if: ${{ runner.os == 'Linux' && inputs.setup-script-name != '' }} - run: | + run: | echo "running linux setup" chmod +x ./${{ inputs.setup-script-name }}.sh ./${{ inputs.setup-script-name }}.sh diff --git a/.github/workflows/delete_backport_branch.yml b/.github/workflows/delete_backport_branch.yml index 35417b46b3..9964fe1ec8 100644 --- a/.github/workflows/delete_backport_branch.yml +++ b/.github/workflows/delete_backport_branch.yml @@ -1,9 +1,9 @@ name: Delete merged branch of the backport PRs -on: +on: pull_request: types: - closed - + jobs: delete-branch: runs-on: ubuntu-latest diff --git a/.github/workflows/plugin_install.yml b/.github/workflows/plugin_install.yml index 75289d560a..301c193e11 100644 --- a/.github/workflows/plugin_install.yml +++ b/.github/workflows/plugin_install.yml @@ -38,7 +38,7 @@ jobs: if: ${{ runner.os == 'Linux' }} run: | cat > setup.sh <<'EOF' - chmod +x ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/plugins/${{ env.PLUGIN_NAME }}/tools/install_demo_configuration.sh + chmod +x ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/plugins/${{ env.PLUGIN_NAME }}/tools/install_demo_configuration.sh /bin/bash -c "yes | ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/plugins/${{ env.PLUGIN_NAME }}/tools/install_demo_configuration.sh" EOF diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a7e7d89e9a..371de48a2e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,7 +5,7 @@ OpenSearch is a community project that is built and maintained by people just like **you**. [This document](https://github.com/opensearch-project/.github/blob/main/CONTRIBUTING.md) explains how you can contribute to this and related projects. -Visit the following link(s) for more information on specific practices: +Visit the following link(s) for more information on specific practices: - [Triaging](./TRIAGING.md) diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index 5168d01a46..358b2eac14 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -48,9 +48,9 @@ The `curl localhost:9200` call should succeed again. Kill the server with `Ctrl+ >Worth noting:\ > The version of OpenSearch and the security plugin must match as there is an explicit version check at startup. This can be a bit confusing as, for example, at the time of writing this guide, the `main` branch of this security plugin builds version `3.0.0.0-SNAPSHOT` compatible with OpenSearch `3.0.0`. Check the expected compatible version in `build.gradle` file [here](https://github.com/opensearch-project/security/blob/main/build.gradle) and make sure you get the correct branch from OpenSearch when building that project. -> +> > The line to look for: `opensearch_version = System.getProperty("opensearch.version", "x")` -> +> > Alternatively, you can find the compatible version of OpenSearch by running in project root folder > ``` > ./gradlew properties -q | grep -E '^version:' | awk '{print $2}' @@ -164,7 +164,7 @@ Checkstyle enforces several rules within this codebase. Sometimes it will be nec *Execute Checkstyle* ``` -./gradlew checkstyleMain checkstyleTest +./gradlew checkstyleMain checkstyleTest ``` *Example violation* diff --git a/DEVELOPING_WITH_DOCKER.md b/DEVELOPING_WITH_DOCKER.md index a0ba045846..6616e11313 100644 --- a/DEVELOPING_WITH_DOCKER.md +++ b/DEVELOPING_WITH_DOCKER.md @@ -1,40 +1,40 @@ # Developing with Docker -Docker is a powerful tool that can be used to quickly spin up an OpenSearch cluster. When you follow the steps to run [OpenSearch with Docker](https://opensearch.org/docs/latest/install-and-configure/install-opensearch/docker/), you will find the Security Plugin already included in the basic distribution. +Docker is a powerful tool that can be used to quickly spin up an OpenSearch cluster. When you follow the steps to run [OpenSearch with Docker](https://opensearch.org/docs/latest/install-and-configure/install-opensearch/docker/), you will find the Security Plugin already included in the basic distribution. - [Developing with Docker](#developing-with-docker) - [Configuring Security](#configuring-security) - [Mounting Local Volumes](#mounting-local-volumes) - [Example docker-compose](#example-docker-compose) - -## Configuring Security -By default, the Docker installation of OpenSearch does not enable the Security plugin. In order to enable Security development, you will need set `DISABLE_SECURITY_PLUGIN=false`, as well as change `DISABLE_INSTALL_DEMO_CONFIG` and `DISABLE_SECURITY_DASHBOARDS_PLUGIN`. This will install the demo certificates, and allow you to develop with realistic Security configurations. An example of a completely configured docker-compose file is shown below. +## Configuring Security + +By default, the Docker installation of OpenSearch does not enable the Security plugin. In order to enable Security development, you will need set `DISABLE_SECURITY_PLUGIN=false`, as well as change `DISABLE_INSTALL_DEMO_CONFIG` and `DISABLE_SECURITY_DASHBOARDS_PLUGIN`. This will install the demo certificates, and allow you to develop with realistic Security configurations. An example of a completely configured docker-compose file is shown below. > Warning: You should never use the demo certificates for a production environment. Instead, you will need to follow the steps on [configuring security](https://opensearch.org/docs/latest/security/configuration/index/) before using the cluster for production. -### Mounting Local Volumes +### Mounting Local Volumes -In order to test development changes with an OpenSearch Docker-installation, you will need to mount the volumes in your docker-compose file. +In order to test development changes with an OpenSearch Docker-installation, you will need to mount the volumes in your docker-compose file. -To update your cluster to have local changes, follow these steps: +To update your cluster to have local changes, follow these steps: 1. First you will need to make changes in your local `opensearch-project/security` repository. For this example, assume your fork is cloned into a directory called `security`. -2. After you make changes to your cloned repository, you will need to run `./gradlew assemble`. This will create a `.jar` file you can mount into the Docker container. The file will be located at `./security/build/distributions/opensearch-security-.0-SNAPSHOT.jar`, where the `` field is simply the OpenSearch distribution. -3. You will then need to navigate to your `docker-compose.yml` file where you are running you OpenSearch cluster from. For this example, let us assume this is in another directory called `opensearch-docker`. -4. Modify the compose file, so that in the `volumes:` section of each node configuration (the default configuration will have `opensearch-node1` and `opensearch-node2`), you have a new line which reads `~/security/build/distributions/opensearch-security-.0-SNAPSHOT.jar:/usr/share/opensearch/plugins/opensearch-security/opensearch-security-.0.jar`. This line should be added to the volumes section of all nodes in the compose file. You will not need to add it to the `opensearch-dashboards` section. -5. You can now restart the Docker container by running `docker-compose down -v` and `docker-compose up`. Your changes will now be live in the OpenSearch cluster instance. +2. After you make changes to your cloned repository, you will need to run `./gradlew assemble`. This will create a `.jar` file you can mount into the Docker container. The file will be located at `./security/build/distributions/opensearch-security-.0-SNAPSHOT.jar`, where the `` field is simply the OpenSearch distribution. +3. You will then need to navigate to your `docker-compose.yml` file where you are running you OpenSearch cluster from. For this example, let us assume this is in another directory called `opensearch-docker`. +4. Modify the compose file, so that in the `volumes:` section of each node configuration (the default configuration will have `opensearch-node1` and `opensearch-node2`), you have a new line which reads `~/security/build/distributions/opensearch-security-.0-SNAPSHOT.jar:/usr/share/opensearch/plugins/opensearch-security/opensearch-security-.0.jar`. This line should be added to the volumes section of all nodes in the compose file. You will not need to add it to the `opensearch-dashboards` section. +5. You can now restart the Docker container by running `docker-compose down -v` and `docker-compose up`. Your changes will now be live in the OpenSearch cluster instance. -### Example docker-compose +### Example docker-compose -This is an example of a completely configured docker-compose file for a local installation of the 2.5.0 version of OpenSearch. +This is an example of a completely configured docker-compose file for a local installation of the 2.5.0 version of OpenSearch. ``` version: '3' services: opensearch-node1: - image: opensearchstaging/opensearch:2.5.0 # This is a image of the 2.5.0 distribution + image: opensearchstaging/opensearch:2.5.0 # This is a image of the 2.5.0 distribution environment: - cluster.name=opensearch-cluster - node.name=opensearch-node1 @@ -58,7 +58,7 @@ services: # - ./config/opensearch.yml:/usr/share/opensearch/config/opensearch.yml # These paths are relative to the location of the docker-compose file # - ./config/esnode.pem:/usr/share/opensearch/config/esnode.pem # - ./config/esnode-key.pem:/usr/share/opensearch/config/esnode-key.pem - # - ./config/root-ca.pem:/usr/share/opensearch/config/root-ca.pem + # - ./config/root-ca.pem:/usr/share/opensearch/config/root-ca.pem # - ./config/opensearch-security/audit.yml:/usr/share/opensearch/config/opensearch-security/audit.yml # - ./config/opensearch-security/tenants.yml:/usr/share/opensearch/config/opensearch-security/tenants.yml # - /OpenSearch-Snapshots:/mnt/snapshots # This is where your snapshots would be stored @@ -86,8 +86,8 @@ services: # - ./config/root-ca.pem:/usr/share/opensearch/config/root-ca.pem # - ./config/opensearch-security/audit.yml:/usr/share/opensearch/config/opensearch-security/audit.yml # - ./config/opensearch-security/tenants.yml:/usr/share/opensearch/config/opensearch-security/tenants.yml - # - /OpenSearch-Snapshots:/mnt/snapshots - # - /security/build/distributions/opensearch-security-2.5.0.0-SNAPSHOT.jar:/usr/share/opensearch/plugins/opensearch-security/opensearch-security-2.5.0.0.jar + # - /OpenSearch-Snapshots:/mnt/snapshots + # - /security/build/distributions/opensearch-security-2.5.0.0-SNAPSHOT.jar:/usr/share/opensearch/plugins/opensearch-security/opensearch-security-2.5.0.0.jar networks: - opensearch-net opensearch-dashboards: diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 4605135a16..f27e192923 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -22,6 +22,7 @@ This document contains a list of maintainers in this repo. See [opensearch-proje | Ryan Liang | [RyanL1997](https://github.com/RyanL1997) | Amazon | | Stephen Crawford | [scrawfor99](https://github.com/scrawfor99) | Amazon | | Andriy Redko | [reta](https://github.com/reta) | Aiven | +| Andrey Pleskach | [willyborankin](https://github.com/willyborankin) | Aiven | ## Practices diff --git a/README.md b/README.md index b9ca3b80da..5c89f5d72d 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -[![CI](https://github.com/opensearch-project/security/workflows/CI/badge.svg?branch=main)](https://github.com/opensearch-project/security/actions) [![](https://img.shields.io/github/issues/opensearch-project/security/untriaged?labelColor=red)](https://github.com/opensearch-project/security/issues?q=is%3Aissue+is%3Aopen+label%3A"untriaged") [![](https://img.shields.io/github/issues/opensearch-project/security/security%20vulnerability?labelColor=red)](https://github.com/opensearch-project/security/issues?q=is%3Aissue+is%3Aopen+label%3A"security%20vulnerability") [![](https://img.shields.io/github/issues/opensearch-project/security)](https://github.com/opensearch-project/security/issues) [![](https://img.shields.io/github/issues-pr/opensearch-project/security)](https://github.com/opensearch-project/security/pulls) +[![CI](https://github.com/opensearch-project/security/workflows/CI/badge.svg?branch=main)](https://github.com/opensearch-project/security/actions) [![](https://img.shields.io/github/issues/opensearch-project/security/untriaged?labelColor=red)](https://github.com/opensearch-project/security/issues?q=is%3Aissue+is%3Aopen+label%3A"untriaged") [![](https://img.shields.io/github/issues/opensearch-project/security/security%20vulnerability?labelColor=red)](https://github.com/opensearch-project/security/issues?q=is%3Aissue+is%3Aopen+label%3A"security%20vulnerability") [![](https://img.shields.io/github/issues/opensearch-project/security)](https://github.com/opensearch-project/security/issues) [![](https://img.shields.io/github/issues-pr/opensearch-project/security)](https://github.com/opensearch-project/security/pulls) [![](https://img.shields.io/codecov/c/gh/opensearch-project/security)](https://app.codecov.io/gh/opensearch-project/security) [![](https://img.shields.io/github/issues/opensearch-project/security/v2.4.0)](https://github.com/opensearch-project/security/issues?q=is%3Aissue+is%3Aopen+label%3A"v2.4.0") [![](https://img.shields.io/github/issues/opensearch-project/security/v3.0.0)](https://github.com/opensearch-project/security/issues?q=is%3Aissue+is%3Aopen+label%3A"v3.0.0") [![Slack](https://img.shields.io/badge/Slack-4A154B?&logo=slack&logoColor=white)](https://opensearch.slack.com/archives/C051Y637FKK) -## Announcement: The Slack workspace is live! Please join the [conversation](https://opensearch.slack.com/archives/C051Y637FKK). +## Announcement: The Slack workspace is live! Please join the [conversation](https://opensearch.slack.com/archives/C051Y637FKK). @@ -37,7 +37,7 @@ OpenSearch Security is a plugin for OpenSearch that offers encryption, authentic * Full data in transit encryption * Node-to-node encryption * Certificate revocation lists -* Hot Certificate renewal +* Hot Certificate renewal ### Authentication * Internal user database @@ -60,7 +60,7 @@ OpenSearch Security is a plugin for OpenSearch that offers encryption, authentic * REST management API ### Audit/Compliance logging -* Audit logging +* Audit logging * Compliance logging for GDPR, HIPAA, PCI, SOX and ISO compliance ### OpenSearch Dashboards multi-tenancy @@ -126,7 +126,7 @@ sequenceDiagram participant OpenSearch participant SecurityPlugin participant Cluster as Plugin - + Client->>OpenSearch: Request OpenSearch->>SecurityPlugin: Request SecurityPlugin->>SecurityPlugin: Add Auth information to request context @@ -188,7 +188,7 @@ If you discover a potential security issue in this project we ask that you notif ## License -This code is licensed under the Apache 2.0 License. +This code is licensed under the Apache 2.0 License. ## Copyright diff --git a/TRIAGING.md b/TRIAGING.md index 2c4ea32fdf..bb61779a7c 100644 --- a/TRIAGING.md +++ b/TRIAGING.md @@ -20,7 +20,7 @@ If you have an issue you'd like to bring forth please consider getting a link to ### Is there an agenda for each week? -Meetings are lightly structured as follows: +Meetings are lightly structured as follows: 1. Announcements: If there are any announcements to be made they will happen at the start of the meeting. 2. Review of new issues: The meetings always start with reviewing all untriaged [issues](https://github.com/search?q=label%3Auntriaged+is%3Aopen++repo%3Aopensearch-project%2Fsecurity+repo%3Aopensearch-project%2Fsecurity-dashboards-plugin&type=issues&ref=advsearch&s=created&o=desc) for the security and security-dashboards repositories. @@ -53,7 +53,7 @@ There you can find answers to many common questions as well as speak with implem ### What if my issue is critical to OpenSearch operations, do I have to wait for the weekly meeting for it to be addressed? -All new issues for the [security](https://github.com/opensearch-project/security/issues?q=is%3Aissue+is%3Aopen+label%3Auntriaged) repo and [security-dashboards](https://github.com/opensearch-project/security-dashboards-plugin/issues?q=is%3Aissue+is%3Aopen+-label%3Atriaged) repo are reviewed daily to check for critical issues which require immediate triaging. If an issue relates to a severe concern for OpenSearch operation, it will be triaged by a maintainer mid-week. You can still come to discuss an issue at the following meeting even if it has already been triaged during the week. +All new issues for the [security](https://github.com/opensearch-project/security/issues?q=is%3Aissue+is%3Aopen+label%3Auntriaged) repo and [security-dashboards](https://github.com/opensearch-project/security-dashboards-plugin/issues?q=is%3Aissue+is%3Aopen+-label%3Atriaged) repo are reviewed daily to check for critical issues which require immediate triaging. If an issue relates to a severe concern for OpenSearch operation, it will be triaged by a maintainer mid-week. You can still come to discuss an issue at the following meeting even if it has already been triaged during the week. ### Is this where I should bring up potential security vulnerabilities? diff --git a/build.gradle b/build.gradle index ef187e290f..863a4ae234 100644 --- a/build.gradle +++ b/build.gradle @@ -52,7 +52,7 @@ plugins { id 'idea' id 'jacoco' id 'maven-publish' - id 'com.diffplug.spotless' version '6.18.0' + id 'com.diffplug.spotless' version '6.19.0' id 'checkstyle' id 'com.netflix.nebula.ospackage' version "11.1.0" id "org.gradle.test-retry" version "1.5.2" @@ -70,15 +70,53 @@ apply plugin: 'opensearch.opensearchplugin' apply plugin: 'opensearch.pluginzip' apply plugin: 'opensearch.rest-test' apply plugin: 'opensearch.testclusters' - -licenseFile = rootProject.file('LICENSE.txt') -noticeFile = rootProject.file('NOTICE.txt') +// apply from: 'gradle/formatting.gradle' spotless { java { + // Normally this isn't necessary, but we have Java sources in + // non-standard places + target '**/com/amazon/dlic/**/*.java' + target '**/com/amazon/security/**/*.java' + target '**/test/java/org/opensearch/security/**/*.java' + + removeUnusedImports() + eclipse().configFile rootProject.file('formatter/formatterConfig.xml') + trimTrailingWhitespace() + endWithNewline(); + // note: you can use an empty string for all the imports you didn't specify explicitly, and '\\#` prefix for static imports importOrder('java', 'javax', '', 'com.amazon', 'org.opensearch', '\\#') - targetExclude('src/integrationTest/**') + + custom 'Refuse wildcard imports', { + // Wildcard imports can't be resolved; fail the build + if (it =~ /\s+import .*\*;/) { + throw new AssertionError("Do not use wildcard imports. 'spotlessApply' cannot resolve this issue.") + } + } + + // See DEVELOPER_GUIDE.md for details of when to enable this. + if (System.getProperty('spotless.paddedcell') != null) { + paddedCell() + } + } + format 'misc', { + target '*.md', '*.gradle', '**/*.json', '**/*.yaml', '**/*.yml', '**/*.svg' + + trimTrailingWhitespace() + endWithNewline() + } + format('javaFoo', JavaExtension) { + + importOrder('java', 'javax', '', 'com.amazon', 'org.opensearch', '\\#') + target '**/*.java' + targetExclude '**/com/amazon/dlic/**/*.java' + targetExclude '**/com/amazon/security/**/*.java' + targetExclude '**/test/java/org/opensearch/security/**/*.java' + targetExclude 'src/integrationTest/**' + + trimTrailingWhitespace() + endWithNewline(); } format("integrationTest", JavaExtension) { target('src/integrationTest/java/**/*.java') @@ -87,6 +125,9 @@ spotless { } } +licenseFile = rootProject.file('LICENSE.txt') +noticeFile = rootProject.file('NOTICE.txt') + spotbugs { includeFilter = file('spotbugs-include.xml') } @@ -301,6 +342,7 @@ configurations { force "io.netty:netty-transport:${versions.netty}" force "io.netty:netty-transport-native-unix-common:${versions.netty}" force "org.apache.bcel:bcel:6.6.0" // This line should be removed once Spotbugs is upgraded to 4.7.4 + force "com.github.luben:zstd-jni:${versions.zstd}" } } @@ -346,7 +388,6 @@ task integrationTest(type: Test) { check.dependsOn integrationTest dependencies { - implementation 'jakarta.annotation:jakarta.annotation-api:1.3.5' 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}" @@ -424,7 +465,7 @@ dependencies { runtimeOnly 'com.fasterxml.woodstox:woodstox-core:6.4.0' runtimeOnly 'org.apache.ws.xmlschema:xmlschema-core:2.2.5' runtimeOnly 'org.apache.santuario:xmlsec:2.2.3' - runtimeOnly 'com.github.luben:zstd-jni:1.5.2-1' + runtimeOnly "com.github.luben:zstd-jni:${versions.zstd}" runtimeOnly 'org.checkerframework:checker-qual:3.5.0' runtimeOnly "org.bouncycastle:bcpkix-jdk15on:${versions.bouncycastle}" diff --git a/bwc-test/src/test/java/SecurityBackwardsCompatibilityIT.java b/bwc-test/src/test/java/SecurityBackwardsCompatibilityIT.java index 1afc1b88d5..d3c3658245 100644 --- a/bwc-test/src/test/java/SecurityBackwardsCompatibilityIT.java +++ b/bwc-test/src/test/java/SecurityBackwardsCompatibilityIT.java @@ -12,17 +12,17 @@ import java.util.Set; import java.util.stream.Collectors; -import org.junit.Assume; +import com.google.common.collect.ImmutableMap; import org.junit.Assert; +import org.junit.Assume; import org.junit.Before; + +import org.opensearch.Version; import org.opensearch.client.Response; import org.opensearch.common.settings.Settings; import org.opensearch.rest.RestStatus; import org.opensearch.test.rest.OpenSearchRestTestCase; -import org.opensearch.Version; -import com.google.common.collect.ImmutableMap; - import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasItem; diff --git a/config/roles.yml b/config/roles.yml index e4eb3ac535..d03b47ab28 100644 --- a/config/roles.yml +++ b/config/roles.yml @@ -205,6 +205,8 @@ index_management_full_access: - "cluster:admin/opendistro/ism/*" - "cluster:admin/opendistro/rollup/*" - "cluster:admin/opendistro/transform/*" + - "cluster:admin/opensearch/controlcenter/lron/*" + - "cluster:admin/opensearch/notifications/channels/get" - "cluster:admin/opensearch/notifications/feature/publish" index_permissions: - index_patterns: diff --git a/formatter/formatterConfig.xml b/formatter/formatterConfig.xml new file mode 100644 index 0000000000..713e55274d --- /dev/null +++ b/formatter/formatterConfig.xml @@ -0,0 +1,362 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gradle/formatting.gradle b/gradle/formatting.gradle new file mode 100644 index 0000000000..1851438039 --- /dev/null +++ b/gradle/formatting.gradle @@ -0,0 +1,36 @@ +allprojects { + project.apply plugin: "com.diffplug.spotless" + spotless { + java { + // Normally this isn't necessary, but we have Java sources in + // non-standard places + target '*/com/amazon/dlic/auth/**/*.java' + + removeUnusedImports() + eclipse().configFile rootProject.file('formatter/formatterConfig.xml') + trimTrailingWhitespace() + endWithNewline(); + + // note: you can use an empty string for all the imports you didn't specify explicitly, and '\\#` prefix for static imports + importOrder('java', 'javax', '', 'com.amazon', 'org.opensearch', '\\#') + + custom 'Refuse wildcard imports', { + // Wildcard imports can't be resolved; fail the build + if (it =~ /\s+import .*\*;/) { + throw new AssertionError("Do not use wildcard imports. 'spotlessApply' cannot resolve this issue.") + } + } + + // See DEVELOPER_GUIDE.md for details of when to enable this. + if (System.getProperty('spotless.paddedcell') != null) { + paddedCell() + } + } + format 'misc', { + target '*.md', '*.gradle', '**/*.json', '**/*.yaml', '**/*.yml', '**/*.svg' + + trimTrailingWhitespace() + endWithNewline() + } + } +} diff --git a/legacy/securityconfig_v6/action_groups.yml b/legacy/securityconfig_v6/action_groups.yml index 14c1b3082f..3faa4c5e31 100644 --- a/legacy/securityconfig_v6/action_groups.yml +++ b/legacy/securityconfig_v6/action_groups.yml @@ -128,7 +128,7 @@ CLUSTER_COMPOSITE_OPS: - "indices:admin/aliases*" - "indices:data/write/reindex" - CLUSTER_COMPOSITE_OPS_RO - + MANAGE_SNAPSHOTS: readonly: true permissions: diff --git a/legacy/securityconfig_v6/config.yml b/legacy/securityconfig_v6/config.yml index 15d5ee9973..d867a72200 100644 --- a/legacy/securityconfig_v6/config.yml +++ b/legacy/securityconfig_v6/config.yml @@ -1,14 +1,14 @@ # This is the main OpenSearch Security configuration file where authentication # and authorization is defined. -# +# # You need to configure at least one authentication domain in the authc of this file. -# An authentication domain is responsible for extracting the user credentials from -# the request and for validating them against an authentication backend like Active Directory for example. +# An authentication domain is responsible for extracting the user credentials from +# the request and for validating them against an authentication backend like Active Directory for example. # -# If more than one authentication domain is configured the first one which succeeds wins. +# If more than one authentication domain is configured the first one which succeeds wins. # If all authentication domains fail then the request is unauthenticated. # In this case an exception is thrown and/or the HTTP status is set to 401. -# +# # After authentication authorization (authz) will be applied. There can be zero or more authorizers which collect # the roles from a given backend for the authenticated user. # @@ -21,18 +21,18 @@ # For HTTP it is possible to allow anonymous authentication. If that is the case then the HTTP authenticators try to # find user credentials in the HTTP request. If credentials are found then the user gets regularly authenticated. # If none can be found the user will be authenticated as an "anonymous" user. This user has always the username "opendistro_security_anonymous" -# and one role named "opendistro_security_anonymous_backendrole". +# and one role named "opendistro_security_anonymous_backendrole". # If you enable anonymous authentication all HTTP authenticators will not challenge. -# +# # # Note: If you define more than one HTTP authenticators make sure to put non-challenging authenticators like "proxy" or "clientcert" -# first and the challenging one last. +# first and the challenging one last. # Because it's not possible to challenge a client with two different authentication methods (for example # Kerberos and Basic) only one can have the challenge flag set to true. You can cope with this situation # by using pre-authentication, e.g. sending a HTTP Basic authentication header in the request. # # Default value of the challenge flag is true. -# +# # # HTTP # basic (challenging) @@ -78,7 +78,7 @@ opendistro_security: ###### and here https://tools.ietf.org/html/rfc7239 ###### and https://tomcat.apache.org/tomcat-8.0-doc/config/valve.html#Remote_IP_Valve authc: - kerberos_auth_domain: + kerberos_auth_domain: http_enabled: false transport_enabled: false order: 6 @@ -92,7 +92,7 @@ opendistro_security: strip_realm_from_principal: true authentication_backend: type: noop - basic_internal_auth_domain: + basic_internal_auth_domain: http_enabled: true transport_enabled: true order: 4 @@ -164,11 +164,11 @@ opendistro_security: password: null userbase: 'ou=people,dc=example,dc=com' # Filter to search for users (currently in the whole subtree beneath userbase) - # {0} is substituted with the username + # {0} is substituted with the username usersearch: '(sAMAccountName={0})' # Use this attribute from the user as username (if not set then DN is used) username_attribute: null - authz: + authz: roles_from_myldap: http_enabled: false transport_enabled: false @@ -191,8 +191,8 @@ opendistro_security: rolebase: 'ou=groups,dc=example,dc=com' # Filter to search for roles (currently in the whole subtree beneath rolebase) # {0} is substituted with the DN of the user - # {1} is substituted with the username - # {2} is substituted with an attribute value from user's directory entry, of the authenticated user. Use userroleattribute to specify the name of the attribute + # {1} is substituted with the username + # {2} is substituted with an attribute value from user's directory entry, of the authenticated user. Use userroleattribute to specify the name of the attribute rolesearch: '(member={0})' # Specify the name of the attribute which value should be substituted with {2} above userroleattribute: null @@ -206,12 +206,12 @@ opendistro_security: resolve_nested_roles: true userbase: 'ou=people,dc=example,dc=com' # Filter to search for users (currently in the whole subtree beneath userbase) - # {0} is substituted with the username + # {0} is substituted with the username usersearch: '(uid={0})' # Skip users matching a user name, a wildcard or a regex pattern - #skip_users: + #skip_users: # - 'cn=Michael Jackson,ou*people,o=TEST' - # - '/\S*/' + # - '/\S*/' roles_from_another_ldap: http_enabled: false transport_enabled: false diff --git a/legacy/securityconfig_v6/internal_users.yml b/legacy/securityconfig_v6/internal_users.yml index 19c5eff661..c7d177787d 100644 --- a/legacy/securityconfig_v6/internal_users.yml +++ b/legacy/securityconfig_v6/internal_users.yml @@ -19,13 +19,13 @@ logstash: roles: - logstash -#password is: kibanaserver +#password is: kibanaserver kibanaserver: readonly: true hash: $2a$12$4AcgAt3xwOWadA5s5blL6ev39OXDNhmOesEoo33eZtrq2N0YrU3H. #password is: kibanaro -kibanaro: +kibanaro: hash: $2a$12$JJSXNfTowz7Uu5ttXfeYpeYE0arACvcwlPBStB1F.MI7f0U9Z4DGC roles: - kibanauser diff --git a/legacy/securityconfig_v6/roles.yml b/legacy/securityconfig_v6/roles.yml index 68a5bd6f98..c546b85393 100644 --- a/legacy/securityconfig_v6/roles.yml +++ b/legacy/securityconfig_v6/roles.yml @@ -3,7 +3,7 @@ # - '' # indices: # '': -# '': +# '': # - '' # _dls_: '' # _fls_: @@ -15,9 +15,9 @@ # and a type. If a request is executed against all indices (or all types) then the asterix ('*') is needed. # Every role a user has will be examined if it allows the action against an index (or type). At least one role must match # for the request to be successful. If no role match then the request will be denied. Currently a match must happen within -# one single role - that means that permissions can not span multiple roles. +# one single role - that means that permissions can not span multiple roles. -# For , and simple wildcards and regular expressions are possible. +# For , and simple wildcards and regular expressions are possible. # A asterix (*) will match any character sequence (or an empty sequence) # A question mark (?) will match any single character (but NOT empty character) # Example: '*my*index' will match 'my_first_index' as well as 'myindex' but not 'myindex1' @@ -27,7 +27,7 @@ # '//' # Example: '/\S*/' will match any non whitespace characters -# Important: +# Important: # Index, alias or type names can not contain dots (.) in the or expression. # Reason is that we currently parse the config file into a OpenSearch settings object which cannot cope with dots in keys. # Workaround: Just configure something like '?kibana' instead of '.kibana' or 'my?index' instead of 'my.index' @@ -59,7 +59,7 @@ opendistro_security_readall: '*': - READ -# Read all and monitor, but no write permissions +# Read all and monitor, but no write permissions opendistro_security_readall_and_monitor: cluster: - CLUSTER_MONITOR @@ -99,7 +99,7 @@ opendistro_security_kibana_user: - INDICES_ALL '?management-beats': '*': - - INDICES_ALL + - INDICES_ALL '*': '*': - indices:data/read/field_caps* @@ -135,7 +135,7 @@ opendistro_security_kibana_server: - "indices:admin/aliases*" # For logstash and beats -opendistro_security_logstash: +opendistro_security_logstash: cluster: - CLUSTER_MONITOR - CLUSTER_COMPOSITE_OPS diff --git a/legacy/securityconfig_v6/roles_mapping.yml b/legacy/securityconfig_v6/roles_mapping.yml index b3263eb234..588ba13f6e 100644 --- a/legacy/securityconfig_v6/roles_mapping.yml +++ b/legacy/securityconfig_v6/roles_mapping.yml @@ -9,12 +9,12 @@ opendistro_security_all_access: opendistro_security_logstash: backendroles: - logstash - + opendistro_security_kibana_server: readonly: true users: - kibanaserver - + opendistro_security_kibana_user: backendroles: - kibanauser diff --git a/release-notes/opensearch-security.release-notes-2.8.0.0.md b/release-notes/opensearch-security.release-notes-2.8.0.0.md new file mode 100644 index 0000000000..32d33d83f7 --- /dev/null +++ b/release-notes/opensearch-security.release-notes-2.8.0.0.md @@ -0,0 +1,30 @@ +## 2023-06-06 Version 2.8.0.0 + +Compatible with OpenSearch 2.8.0 + +### Features + +* Identify extension Transport requests and permit handshake and extension registration actions ([#2599](https://github.com/opensearch-project/security/pull/2599)) +* Use ExtensionsManager.lookupExtensionSettingsById when verifying extension unique id ([#2749](https://github.com/opensearch-project/security/pull/2749)) +* Generate auth tokens for service accounts ([#2716](https://github.com/opensearch-project/security/pull/2716)) +* Security User Refactor ([#2594](https://github.com/opensearch-project/security/pull/2594)) +* Add score based password verification ([#2557](https://github.com/opensearch-project/security/pull/2557)) +* Usage of JWKS with JWT (w/o OpenID connect) ([#2808](https://github.com/opensearch-project/security/pull/2808)) + +### Bug Fixes + +* `deserializeSafeFromHeader` uses `context.getHeader(headerName)` instead of `context.getHeaders()` ([#2768](https://github.com/opensearch-project/security/pull/2768)) +* Fix multitency config update ([#2758](https://github.com/opensearch-project/security/pull/2758)) + +### Enhancements + +* Add default roles for SQL plugin: PPL and cross-cluster search ([#2729](https://github.com/opensearch-project/security/pull/2729)) +* Update security-analytics roles to add correlation engine apis ([#2732](https://github.com/opensearch-project/security/pull/2732)) +* Changes in role.yml for long-running operation notification feature in Index-Management repo ([#2789](https://github.com/opensearch-project/security/pull/2789)) +* Rest admin permissions ([#2411](https://github.com/opensearch-project/security/pull/2411)) +* Separate config option to enable restapi: permissions ([#2605](https://github.com/opensearch-project/security/pull/2605)) + +### Maintenance + +* Update to Gradle 8.1.1 ([#2738](https://github.com/opensearch-project/security/pull/2738)) +* Upgrade spring-core from 5.3.26 to 5.3.27 ([#2717](https://github.com/opensearch-project/security/pull/2717)) diff --git a/src/integrationTest/java/org/opensearch/security/http/JwtAuthenticationTests.java b/src/integrationTest/java/org/opensearch/security/http/JwtAuthenticationTests.java index 5875a120a4..65a4e32d7e 100644 --- a/src/integrationTest/java/org/opensearch/security/http/JwtAuthenticationTests.java +++ b/src/integrationTest/java/org/opensearch/security/http/JwtAuthenticationTests.java @@ -141,7 +141,7 @@ public void shouldAuthenticateWithJwtToken_positive() { response.assertStatusCode(200); String username = response.getTextFromJsonBody(POINTER_USERNAME); - assertThat(username, equalTo(username)); + assertThat(username, equalTo(USER_SUPERHERO)); } } 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 9978186f96..bef819effd 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 @@ -55,6 +55,8 @@ public abstract class AbstractHTTPJwtAuthenticator implements HTTPAuthenticator private final String jwtUrlParameter; private final String subjectKey; private final String rolesKey; + private final String requiredAudience; + private final String requiredIssuer; public static final int DEFAULT_CLOCK_SKEW_TOLERANCE_SECONDS = 30; private final int clockSkewToleranceSeconds ; @@ -66,10 +68,12 @@ public AbstractHTTPJwtAuthenticator(Settings settings, Path configPath) { rolesKey = settings.get("roles_key"); subjectKey = settings.get("subject_key"); clockSkewToleranceSeconds = settings.getAsInt("jwt_clock_skew_tolerance_seconds", DEFAULT_CLOCK_SKEW_TOLERANCE_SECONDS); + requiredAudience = settings.get("required_audience"); + requiredIssuer = settings.get("required_issuer"); try { this.keyProvider = this.initKeyProvider(settings, configPath); - jwtVerifier = new JwtVerifier(keyProvider, clockSkewToleranceSeconds ); + jwtVerifier = new JwtVerifier(keyProvider, clockSkewToleranceSeconds, requiredIssuer, requiredAudience); } catch (Exception e) { log.error("Error creating JWT authenticator. JWT authentication will not work", e); @@ -233,4 +237,12 @@ public boolean reRequestAuthentication(RestChannel channel, AuthCredentials auth return true; } + public String getRequiredAudience() { + return requiredAudience; + } + + public String getRequiredIssuer() { + return requiredIssuer; + } + } diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticator.java b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticator.java index 0cede73911..b6738b725b 100644 --- a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticator.java +++ b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticator.java @@ -32,9 +32,15 @@ protected KeyProvider initKeyProvider(Settings settings, Path configPath) throws int refreshRateLimitTimeWindowMs = settings.getAsInt("refresh_rate_limit_time_window_ms", 10000); int refreshRateLimitCount = settings.getAsInt("refresh_rate_limit_count", 10); - - KeySetRetriever keySetRetriever = new KeySetRetriever(settings.get("openid_connect_url"), - getSSLConfig(settings, configPath), settings.getAsBoolean("cache_jwks_endpoint", false)); + String jwksUri = settings.get("jwks_uri"); + + KeySetRetriever keySetRetriever; + if(jwksUri != null && !jwksUri.isBlank()) { + keySetRetriever = + new KeySetRetriever(getSSLConfig(settings, configPath), settings.getAsBoolean("cache_jwks_endpoint", false), jwksUri); + } else { + keySetRetriever = new KeySetRetriever(settings.get("openid_connect_url"), getSSLConfig(settings, configPath), settings.getAsBoolean("cache_jwks_endpoint", false)); + } keySetRetriever.setRequestTimeoutMs(idpRequestTimeoutMs); diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/JwtVerifier.java b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/JwtVerifier.java index 99074ab233..3666607a04 100644 --- a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/JwtVerifier.java +++ b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/JwtVerifier.java @@ -33,10 +33,14 @@ public class JwtVerifier { private final KeyProvider keyProvider; private final int clockSkewToleranceSeconds; + private final String requiredIssuer; + private final String requiredAudience; - public JwtVerifier(KeyProvider keyProvider, int clockSkewToleranceSeconds ) { + public JwtVerifier(KeyProvider keyProvider, int clockSkewToleranceSeconds, String requiredIssuer, String requiredAudience) { this.keyProvider = keyProvider; this.clockSkewToleranceSeconds = clockSkewToleranceSeconds; + this.requiredIssuer = requiredIssuer; + this.requiredAudience = requiredAudience; } public JwtToken getVerifiedJwtToken(String encodedJwt) throws BadCredentialsException { @@ -50,13 +54,13 @@ public JwtToken getVerifiedJwtToken(String encodedJwt) throws BadCredentialsExce kid = StringEscapeUtils.unescapeJava(escapedKid); } JsonWebKey key = keyProvider.getKey(kid); - + // Algorithm is not mandatory for the key material, so we set it to the same as the JWT if (key.getAlgorithm() == null && key.getPublicKeyUse() == PublicKeyUse.SIGN && key.getKeyType() == KeyType.RSA) { key.setAlgorithm(jwt.getJwsHeaders().getAlgorithm()); } - + JwsSignatureVerifier signatureVerifier = getInitializedSignatureVerifier(key, jwt); @@ -106,12 +110,26 @@ private JwsSignatureVerifier getInitializedSignatureVerifier(JsonWebKey key, Jwt } } - private void validateClaims(JwtToken jwt) throws BadCredentialsException, JwtException { + private void validateClaims(JwtToken jwt) throws JwtException { JwtClaims claims = jwt.getClaims(); if (claims != null) { JwtUtils.validateJwtExpiry(claims, clockSkewToleranceSeconds, false); JwtUtils.validateJwtNotBefore(claims, clockSkewToleranceSeconds, false); + validateRequiredAudienceAndIssuer(claims); + } + } + + private void validateRequiredAudienceAndIssuer(JwtClaims claims) { + String audience = claims.getAudience(); + String issuer = claims.getIssuer(); + + if (!Strings.isNullOrEmpty(requiredAudience) && !requiredAudience.equals(audience)) { + throw new JwtException("Invalid audience"); + } + + if (!Strings.isNullOrEmpty(requiredIssuer) && !requiredIssuer.equals(issuer)) { + throw new JwtException("Invalid issuer"); } } } 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 50be122aec..f56c0dd90c 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 @@ -14,6 +14,7 @@ import java.io.IOException; import java.util.concurrent.TimeUnit; +import joptsimple.internal.Strings; import org.apache.cxf.rs.security.jose.jwk.JsonWebKeys; import org.apache.cxf.rs.security.jose.jwk.JwkUtils; import org.apache.hc.client5.http.cache.HttpCacheContext; @@ -54,15 +55,20 @@ public class KeySetRetriever implements KeySetProvider { private int oidcCacheModuleResponses = 0; private long oidcRequests = 0; private long lastCacheStatusLog = 0; + private String jwksUri; KeySetRetriever(String openIdConnectEndpoint, SSLConfig sslConfig, boolean useCacheForOidConnectEndpoint) { this.openIdConnectEndpoint = openIdConnectEndpoint; this.sslConfig = sslConfig; - if (useCacheForOidConnectEndpoint) { - cacheConfig = CacheConfig.custom().setMaxCacheEntries(10).setMaxObjectSize(1024L * 1024L).build(); - oidcHttpCacheStorage = new BasicHttpCacheStorage(cacheConfig); - } + configureCache(useCacheForOidConnectEndpoint); + } + + KeySetRetriever(SSLConfig sslConfig, boolean useCacheForOidConnectEndpoint, String jwksUri) { + this.jwksUri = jwksUri; + this.sslConfig = sslConfig; + + configureCache(useCacheForOidConnectEndpoint); } public JsonWebKeys get() throws AuthenticatorUnavailableException { @@ -101,6 +107,14 @@ public JsonWebKeys get() throws AuthenticatorUnavailableException { String getJwksUri() throws AuthenticatorUnavailableException { + if (!Strings.isNullOrEmpty(jwksUri)) { + return jwksUri; + } + + if (Strings.isNullOrEmpty(openIdConnectEndpoint)) { + throw new AuthenticatorUnavailableException("Either openid_connect_url or jwks_uri must be configured for OIDC Authentication backend"); + } + try (CloseableHttpClient httpClient = createHttpClient(oidcHttpCacheStorage)) { HttpGet httpGet = new HttpGet(openIdConnectEndpoint); @@ -204,6 +218,13 @@ private CloseableHttpClient createHttpClient(HttpCacheStorage httpCacheStorage) return builder.build(); } + private void configureCache(boolean useCacheForOidConnectEndpoint) { + if (useCacheForOidConnectEndpoint) { + cacheConfig = CacheConfig.custom().setMaxCacheEntries(10).setMaxObjectSize(1024L * 1024L).build(); + oidcHttpCacheStorage = new BasicHttpCacheStorage(cacheConfig); + } + } + public int getOidcCacheHits() { return oidcCacheHits; } 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 ab26a94402..12c5032d04 100755 --- a/src/main/java/com/amazon/dlic/auth/ldap/LdapUser.java +++ b/src/main/java/com/amazon/dlic/auth/ldap/LdapUser.java @@ -41,7 +41,7 @@ public LdapUser(final String name, String originalUsername, final LdapEntry user /** * May return null because ldapEntry is transient - * + * * @return ldapEntry or null if object was deserialized */ public LdapEntry getUserEntry() { @@ -55,7 +55,7 @@ public String getDn() { public String getOriginalUsername() { return originalUsername; } - + public static Map extractLdapAttributes(String originalUsername, final LdapEntry userEntry, int customAttrMaxValueLen, WildcardMatcher allowlistedCustomLdapAttrMatcher) { Map attributes = new HashMap<>(); 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 1ce545e8da..ef53ca97dc 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 @@ -168,13 +168,13 @@ public boolean exists(final User user) { ldapConnection = LDAPAuthorizationBackend.getConnection(settings, configPath); LdapEntry userEntry = exists(userName, ldapConnection, settings, userBaseSettings, this.returnAttributes, this.shouldFollowReferrals); boolean exists = userEntry != null; - + if(exists) { user.addAttributes(LdapUser.extractLdapAttributes(userName, userEntry, customAttrMaxValueLen, allowlistedCustomLdapAttrMatcher)); } - + return exists; - + } catch (final Exception e) { log.warn("User {} does not exist due to ", userName, e); return false; 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 68a8a3fba6..a2be4027ef 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 @@ -398,7 +398,7 @@ public Response reopen() throws LdapException { @Override public Response open(BindRequest request) throws LdapException { - + try { if(isDebugEnabled && delegate != null && delegate.isOpen()) { log.debug("Opened a connection, total count is now {}", CONNECTION_COUNTER.incrementAndGet()); @@ -406,13 +406,13 @@ public Response open(BindRequest request) throws LdapException { } catch (Throwable e) { //ignore } - + return delegate.open(request); } @Override public Response open() throws LdapException { - + try { if(isDebugEnabled && delegate != null && delegate.isOpen()) { log.debug("Opened a connection, total count is now {}", CONNECTION_COUNTER.incrementAndGet()); @@ -420,7 +420,7 @@ public Response open() throws LdapException { } catch (Throwable e) { //ignore } - + return delegate.open(); } @@ -441,7 +441,7 @@ public ConnectionConfig getConnectionConfig() { @Override public void close(RequestControl[] controls) { - + try { if(isDebugEnabled && delegate != null && delegate.isOpen()) { log.debug("Closed a connection, total count is now {}", CONNECTION_COUNTER.decrementAndGet()); @@ -449,7 +449,7 @@ public void close(RequestControl[] controls) { } catch (Throwable e) { //ignore } - + try { delegate.close(controls); } finally { @@ -459,7 +459,7 @@ public void close(RequestControl[] controls) { @Override public void close() { - + try { if(isDebugEnabled && delegate != null && delegate.isOpen()) { log.debug("Closed a connection, total count is now {}", CONNECTION_COUNTER.decrementAndGet()); @@ -467,7 +467,7 @@ public void close() { } catch (Throwable e) { //ignore } - + try { delegate.close(); } finally { 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 f64f3fc0b4..c142201b18 100755 --- a/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthenticationBackend2.java +++ b/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthenticationBackend2.java @@ -217,13 +217,13 @@ private boolean exists0(final User user) { ldapConnection = this.connectionFactory.getConnection(); ldapConnection.open(); LdapEntry userEntry = this.userSearcher.exists(ldapConnection, userName, this.returnAttributes, this.shouldFollowReferrals); - + boolean exists = userEntry != null; - + if(exists) { user.addAttributes(LdapUser.extractLdapAttributes(userName, userEntry, customAttrMaxValueLen, whitelistedCustomLdapAttrMatcher)); } - + return exists; } catch (final Exception e) { log.warn("User {} does not exist due to exception", userName, e); diff --git a/src/main/java/com/amazon/dlic/auth/ldap2/LDAPConnectionFactoryFactory.java b/src/main/java/com/amazon/dlic/auth/ldap2/LDAPConnectionFactoryFactory.java index f711e41982..eca9a1e65e 100644 --- a/src/main/java/com/amazon/dlic/auth/ldap2/LDAPConnectionFactoryFactory.java +++ b/src/main/java/com/amazon/dlic/auth/ldap2/LDAPConnectionFactoryFactory.java @@ -132,7 +132,7 @@ public ConnectionPool createConnectionPool() { checkForDeprecatedSetting(settings, ConfigConstants.LDAP_LEGACY_POOL_PRUNING_PERIOD, ConfigConstants.LDAP_POOL_PRUNING_PERIOD); checkForDeprecatedSetting(settings, ConfigConstants.LDAP_LEGACY_POOL_IDLE_TIME, ConfigConstants.LDAP_POOL_IDLE_TIME); - + result.setPruneStrategy(new IdlePruneStrategy( Duration.ofMinutes(this.settings.getAsLong(ConfigConstants.LDAP_POOL_PRUNING_PERIOD, this.settings.getAsLong(ConfigConstants.LDAP_LEGACY_POOL_PRUNING_PERIOD, 5l))), Duration.ofMinutes(this.settings.getAsLong(ConfigConstants.LDAP_POOL_IDLE_TIME, this.settings.getAsLong(ConfigConstants.LDAP_LEGACY_POOL_IDLE_TIME, 10l)))) diff --git a/src/main/java/org/opensearch/security/DefaultObjectMapper.java b/src/main/java/org/opensearch/security/DefaultObjectMapper.java index 7c3168c68a..774af04bfa 100644 --- a/src/main/java/org/opensearch/security/DefaultObjectMapper.java +++ b/src/main/java/org/opensearch/security/DefaultObjectMapper.java @@ -54,7 +54,7 @@ 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); //objectMapper.enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS); @@ -116,7 +116,7 @@ public T run() throws Exception { throw (IOException) e.getCause(); } } - + @SuppressWarnings("removal") public static T readValue(String string, Class clazz) throws IOException { @@ -137,7 +137,7 @@ public T run() throws Exception { throw (IOException) e.getCause(); } } - + @SuppressWarnings("removal") public static JsonNode readTree(String string) throws IOException { diff --git a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java index 9bf13957da..85b6798410 100644 --- a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java +++ b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java @@ -838,7 +838,7 @@ public Collection createComponents(Client localClient, ClusterService cl securityRestHandler = new SecurityRestFilter(backendRegistry, auditLog, threadPool, principalExtractor, settings, configPath, compatConfig); - + HTTPOnBehalfOfJwtAuthenticator acInstance = new HTTPOnBehalfOfJwtAuthenticator(); final DynamicConfigFactory dcf = new DynamicConfigFactory(cr, settings, configPath, localClient, threadPool, cih); diff --git a/src/main/java/org/opensearch/security/action/configupdate/ConfigUpdateNodeResponse.java b/src/main/java/org/opensearch/security/action/configupdate/ConfigUpdateNodeResponse.java index 29c5b6c9a1..0e6944e9c4 100644 --- a/src/main/java/org/opensearch/security/action/configupdate/ConfigUpdateNodeResponse.java +++ b/src/main/java/org/opensearch/security/action/configupdate/ConfigUpdateNodeResponse.java @@ -37,10 +37,10 @@ import org.opensearch.core.xcontent.XContentBuilder; public class ConfigUpdateNodeResponse extends BaseNodeResponse implements ToXContentObject { - + private String[] updatedConfigTypes; private String message; - + public ConfigUpdateNodeResponse(StreamInput in) throws IOException { super(in); this.updatedConfigTypes = in.readStringArray(); @@ -52,11 +52,11 @@ public ConfigUpdateNodeResponse(final DiscoveryNode node, String[] updatedConfig this.updatedConfigTypes = updatedConfigTypes; this.message = message; } - + public static ConfigUpdateNodeResponse readNodeResponse(StreamInput in) throws IOException { return new ConfigUpdateNodeResponse(in); } - + public String[] getUpdatedConfigTypes() { return updatedConfigTypes==null?null:Arrays.copyOf(updatedConfigTypes, updatedConfigTypes.length); } @@ -64,7 +64,7 @@ public String[] getUpdatedConfigTypes() { public String getMessage() { return message; } - + @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); diff --git a/src/main/java/org/opensearch/security/action/configupdate/TransportConfigUpdateAction.java b/src/main/java/org/opensearch/security/action/configupdate/TransportConfigUpdateAction.java index 42879a8b6c..c5c60cf8a6 100644 --- a/src/main/java/org/opensearch/security/action/configupdate/TransportConfigUpdateAction.java +++ b/src/main/java/org/opensearch/security/action/configupdate/TransportConfigUpdateAction.java @@ -57,12 +57,12 @@ public class TransportConfigUpdateAction private final Provider backendRegistry; private final ConfigurationRepository configurationRepository; private DynamicConfigFactory dynamicConfigFactory; - + @Inject public TransportConfigUpdateAction(final Settings settings, final ThreadPool threadPool, final ClusterService clusterService, final TransportService transportService, final ConfigurationRepository configurationRepository, final ActionFilters actionFilters, - Provider backendRegistry, DynamicConfigFactory dynamicConfigFactory) { + Provider backendRegistry, DynamicConfigFactory dynamicConfigFactory) { super(ConfigUpdateAction.NAME, threadPool, clusterService, transportService, actionFilters, ConfigUpdateRequest::new, TransportConfigUpdateAction.NodeConfigUpdateRequest::new, ThreadPool.Names.MANAGEMENT, ConfigUpdateNodeResponse.class); @@ -96,14 +96,14 @@ public void writeTo(final StreamOutput out) throws IOException { protected ConfigUpdateNodeResponse newNodeResponse(StreamInput in) throws IOException { return new ConfigUpdateNodeResponse(in); } - + @Override protected ConfigUpdateResponse newResponse(ConfigUpdateRequest request, List responses, List failures) { return new ConfigUpdateResponse(this.clusterService.getClusterName(), responses, failures); } - + @Override protected ConfigUpdateNodeResponse nodeOperation(final NodeConfigUpdateRequest request) { configurationRepository.reloadConfiguration(CType.fromStringValues((request.request.getConfigTypes()))); 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 897843ca92..901800f0a2 100644 --- a/src/main/java/org/opensearch/security/action/whoami/TransportWhoAmIAction.java +++ b/src/main/java/org/opensearch/security/action/whoami/TransportWhoAmIAction.java @@ -65,10 +65,10 @@ protected void doExecute(Task task, WhoAmIRequest request, ActionListener { +ActionRequestBuilder { public WhoAmIRequestBuilder(final ClusterAdminClient client) throws IOException { this(client, WhoAmIAction.INSTANCE); } diff --git a/src/main/java/org/opensearch/security/action/whoami/WhoAmIResponse.java b/src/main/java/org/opensearch/security/action/whoami/WhoAmIResponse.java index 876079dced..2b25344f76 100644 --- a/src/main/java/org/opensearch/security/action/whoami/WhoAmIResponse.java +++ b/src/main/java/org/opensearch/security/action/whoami/WhoAmIResponse.java @@ -37,12 +37,12 @@ import org.opensearch.core.xcontent.XContentBuilder; public class WhoAmIResponse extends ActionResponse implements ToXContent { - + private String dn; private boolean isAdmin; private boolean isAuthenticated; private boolean isNodeCertificateRequest; - + public WhoAmIResponse(String dn, boolean isAdmin, boolean isAuthenticated, boolean isNodeCertificateRequest) { this.dn = dn; this.isAdmin = isAdmin; @@ -93,8 +93,8 @@ public boolean isNodeCertificateRequest() { @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - - builder.startObject("whoami"); + + builder.startObject("whoami"); builder.field("dn", dn); builder.field("is_admin", isAdmin); builder.field("is_authenticated", isAuthenticated); diff --git a/src/main/java/org/opensearch/security/auditlog/AuditLog.java b/src/main/java/org/opensearch/security/auditlog/AuditLog.java index a35bfaa209..128944e387 100644 --- a/src/main/java/org/opensearch/security/auditlog/AuditLog.java +++ b/src/main/java/org/opensearch/security/auditlog/AuditLog.java @@ -74,7 +74,7 @@ public interface AuditLog extends Closeable { // set config void setConfig(AuditConfig auditConfig); - + public enum Origin { REST, TRANSPORT, LOCAL } 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 5fb11102a8..1152abe89e 100644 --- a/src/main/java/org/opensearch/security/auditlog/config/AuditConfig.java +++ b/src/main/java/org/opensearch/security/auditlog/config/AuditConfig.java @@ -275,7 +275,7 @@ static Set fromSettingStringSet(final Settings settings, FilterEntries f final boolean foundDefault = stringSetOfKey.stream().anyMatch(defaultDetectorValue::equals); if (!foundDefault) { - return stringSetOfKey; + return stringSetOfKey; } // Fallback to the legacy keyname diff --git a/src/main/java/org/opensearch/security/auth/AuthFailureListener.java b/src/main/java/org/opensearch/security/auth/AuthFailureListener.java index 6495c8e2c9..b835078aa3 100644 --- a/src/main/java/org/opensearch/security/auth/AuthFailureListener.java +++ b/src/main/java/org/opensearch/security/auth/AuthFailureListener.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.auth; diff --git a/src/main/java/org/opensearch/security/auth/AuthenticationBackend.java b/src/main/java/org/opensearch/security/auth/AuthenticationBackend.java index 5762cd371a..0296f56a4a 100644 --- a/src/main/java/org/opensearch/security/auth/AuthenticationBackend.java +++ b/src/main/java/org/opensearch/security/auth/AuthenticationBackend.java @@ -43,13 +43,13 @@ * Instead catch all exceptions and log a appropriate error message. A logger can be instantiated like: *

* {@code private final Logger log = LogManager.getLogger(this.getClass());} - * + * *

*/ public interface AuthenticationBackend { /** - * The type (name) of the authenticator. Only for logging. + * The type (name) of the authenticator. Only for logging. * @return the type */ String getType(); @@ -58,20 +58,20 @@ public interface AuthenticationBackend { * Validate credentials and return an authenticated user (or throw an OpenSearchSecurityException) *

* Results of this method are normally cached so that we not need to query the backend for every authentication attempt. - *

+ *

* @param The credentials to be validated, never null * @return the authenticated User, never null * @throws OpenSearchSecurityException in case an authentication failure * (when credentials are incorrect, the user does not exist or the backend is not reachable) */ User authenticate(AuthCredentials credentials) throws OpenSearchSecurityException; - + /** - * + * * Lookup for a specific user in the authentication backend - * + * * @param user The user for which the authentication backend should be queried. If the authentication backend supports - * user attributes in combination with impersonation the attributes needs to be added to user by calling {@code user.addAttributes()} + * user attributes in combination with impersonation the attributes needs to be added to user by calling {@code user.addAttributes()} * @return true if the user exists in the authentication backend, false otherwise. Before return call {@code user.addAttributes()} as explained above. */ boolean exists(User user); diff --git a/src/main/java/org/opensearch/security/auth/AuthorizationBackend.java b/src/main/java/org/opensearch/security/auth/AuthorizationBackend.java index 83bf131a62..3aea412e69 100644 --- a/src/main/java/org/opensearch/security/auth/AuthorizationBackend.java +++ b/src/main/java/org/opensearch/security/auth/AuthorizationBackend.java @@ -49,7 +49,7 @@ public interface AuthorizationBackend { /** - * The type (name) of the authorizer. Only for logging. + * The type (name) of the authorizer. Only for logging. * @return the type */ String getType(); @@ -61,7 +61,7 @@ public interface AuthorizationBackend { *

* @param user The authenticated user to populate with backend roles, never null * @param credentials Credentials to authenticate to the authorization backend, maybe null. - * This parameter is for future usage, currently always empty credentials are passed! + * This parameter is for future usage, currently always empty credentials are passed! * @throws OpenSearchSecurityException in case when the authorization backend cannot be reached * or the {@code credentials} are insufficient to authenticate to the authorization backend. */ diff --git a/src/main/java/org/opensearch/security/auth/BackendRegistry.java b/src/main/java/org/opensearch/security/auth/BackendRegistry.java index a36aced5e1..9e8154230a 100644 --- a/src/main/java/org/opensearch/security/auth/BackendRegistry.java +++ b/src/main/java/org/opensearch/security/auth/BackendRegistry.java @@ -181,7 +181,7 @@ public boolean authenticate(final RestRequest request, final RestChannel channel if (isDebugEnabled) { log.debug("Rejecting REST request because of blocked address: {}", request.getHttpChannel().getRemoteAddress()); } - + channel.sendResponse(new BytesRestResponse(RestStatus.UNAUTHORIZED, "Authentication finally failed")); return false; @@ -200,14 +200,14 @@ public boolean authenticate(final RestRequest request, final RestChannel channel // ThreadContext injected user return true; } - + if (!isInitialized()) { log.error("Not yet initialized (you may need to run securityadmin)"); channel.sendResponse(new BytesRestResponse(RestStatus.SERVICE_UNAVAILABLE, "OpenSearch Security not initialized.")); return false; } - + final TransportAddress remoteAddress = xffResolver.resolve(request); final boolean isTraceEnabled = log.isTraceEnabled(); if (isTraceEnabled) { @@ -293,7 +293,7 @@ public boolean authenticate(final RestRequest request, final RestChannel channel } } - //http completed + //http completed authenticatedUser = authcz(userCache, restRoleCache, ac, authDomain.getBackend(), restAuthorizers); if(authenticatedUser == null) { @@ -481,7 +481,7 @@ private User authcz(final Cache cache, Cache * A HTTP authenticator extracts {@link AuthCredentials} from a {@link RestRequest} *

- * + * * Implementation classes must provide a public constructor *

* {@code public MyHTTPAuthenticator(org.opensearch.common.settings.Settings settings, java.nio.file.Path configPath)} @@ -51,14 +51,14 @@ public interface HTTPAuthenticator { /** - * The type (name) of the authenticator. Only for logging. + * The type (name) of the authenticator. Only for logging. * @return the type */ String getType(); - + /** * Extract {@link AuthCredentials} from {@link RestRequest} - * + * * @param request The rest request * @param context The current thread context * @return The authentication credentials (complete or incomplete) or null when no credentials are found in the request @@ -68,17 +68,17 @@ public interface HTTPAuthenticator { * @throws OpenSearchSecurityException */ AuthCredentials extractCredentials(RestRequest request, ThreadContext context) throws OpenSearchSecurityException; - + /** * If the {@code extractCredentials()} call was not successful or the authentication flow needs another roundtrip this method * will be called. If the custom HTTP authenticator does not support this method is a no-op and false should be returned. - * + * * If the custom HTTP authenticator does support re-request authentication or supports authentication flows with multiple roundtrips * then the response should be sent (through the channel) and true must be returned. - * + * * @param channel The rest channel to sent back the response via {@code channel.sendResponse()} * @param credentials The credentials from the prior authentication attempt - * @return false if re-request is not supported/necessary, true otherwise. + * @return false if re-request is not supported/necessary, true otherwise. * If true is returned {@code channel.sendResponse()} must be called so that the request completes. */ boolean reRequestAuthentication(final RestChannel channel, AuthCredentials credentials); diff --git a/src/main/java/org/opensearch/security/auth/blocking/ClientBlockRegistry.java b/src/main/java/org/opensearch/security/auth/blocking/ClientBlockRegistry.java index a5eba40353..e74c3ad70a 100644 --- a/src/main/java/org/opensearch/security/auth/blocking/ClientBlockRegistry.java +++ b/src/main/java/org/opensearch/security/auth/blocking/ClientBlockRegistry.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.auth.blocking; diff --git a/src/main/java/org/opensearch/security/auth/blocking/HeapBasedClientBlockRegistry.java b/src/main/java/org/opensearch/security/auth/blocking/HeapBasedClientBlockRegistry.java index 363645cd90..450dda54db 100644 --- a/src/main/java/org/opensearch/security/auth/blocking/HeapBasedClientBlockRegistry.java +++ b/src/main/java/org/opensearch/security/auth/blocking/HeapBasedClientBlockRegistry.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.auth.blocking; 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 3f603437a0..a4d596b61d 100644 --- a/src/main/java/org/opensearch/security/auth/limiting/AbstractRateLimiter.java +++ b/src/main/java/org/opensearch/security/auth/limiting/AbstractRateLimiter.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.auth.limiting; 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 42f1d1f165..35a6571f8f 100644 --- a/src/main/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiter.java +++ b/src/main/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiter.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.auth.limiting; 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 7fe5ac05d6..3fd0c12246 100644 --- a/src/main/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiter.java +++ b/src/main/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiter.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.auth.limiting; diff --git a/src/main/java/org/opensearch/security/configuration/AdminDNs.java b/src/main/java/org/opensearch/security/configuration/AdminDNs.java index ced262d543..72a4485e9f 100644 --- a/src/main/java/org/opensearch/security/configuration/AdminDNs.java +++ b/src/main/java/org/opensearch/security/configuration/AdminDNs.java @@ -62,7 +62,7 @@ public AdminDNs(final Settings settings) { 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); @@ -73,13 +73,13 @@ public AdminDNs(final Settings settings) { 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); + adminUsernames.add(dn); } else { - log.error("Unable to parse admin dn {}",dn, e); + 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+"."); @@ -95,7 +95,7 @@ public AdminDNs(final Settings settings) { ); log.debug("Loaded {} impersonation DN's {}", allowedDnsImpersonations.size(), allowedDnsImpersonations); - + final Settings impersonationUsersRest = settings.getByPrefix(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS+"."); allowedRestImpersonations = impersonationUsersRest.keySet().stream() @@ -103,9 +103,9 @@ public AdminDNs(final Settings settings) { 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); } @@ -129,11 +129,11 @@ public boolean isAdmin(User user) { } return false; } - + public boolean isAdminDN(String dn) { - + if(dn == null) return false; - + try { return isAdminDN(new LdapName(dn)); } catch (InvalidNameException e) { @@ -143,16 +143,16 @@ public boolean isAdminDN(String dn) { 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/ClusterInfoHolder.java b/src/main/java/org/opensearch/security/configuration/ClusterInfoHolder.java index 61877f2bf2..1c42321986 100644 --- a/src/main/java/org/opensearch/security/configuration/ClusterInfoHolder.java +++ b/src/main/java/org/opensearch/security/configuration/ClusterInfoHolder.java @@ -40,7 +40,7 @@ public class ClusterInfoHolder implements ClusterStateListener { private volatile DiscoveryNodes nodes = null; private volatile Boolean isLocalNodeElectedClusterManager = null; private volatile boolean initialized; - + @Override public void clusterChanged(ClusterChangedEvent event) { if(nodes == null || event.nodesChanged()) { @@ -50,7 +50,7 @@ public void clusterChanged(ClusterChangedEvent event) { } initialized = true; } - + isLocalNodeElectedClusterManager = event.localNodeClusterManager()?Boolean.TRUE:Boolean.FALSE; } @@ -69,7 +69,7 @@ public Boolean hasNode(DiscoveryNode node) { } return null; } - + return nodes.nodeExists(node)?Boolean.TRUE:Boolean.FALSE; } } diff --git a/src/main/java/org/opensearch/security/configuration/CompatConfig.java b/src/main/java/org/opensearch/security/configuration/CompatConfig.java index 6912cb4fbb..48f91b10be 100644 --- a/src/main/java/org/opensearch/security/configuration/CompatConfig.java +++ b/src/main/java/org/opensearch/security/configuration/CompatConfig.java @@ -50,13 +50,13 @@ public CompatConfig(final Environment environment, final OpensearchDynamicSettin this.staticSettings = environment.settings(); this.transportPassiveAuthSetting = transportPassiveAuthSetting; } - + @Subscribe public void onDynamicConfigModelChanged(DynamicConfigModel dcm) { this.dcm = dcm; log.debug("dynamicSecurityConfig updated?: {}", (dcm != null)); } - + //true is default public boolean restAuthEnabled() { final boolean restInitiallyDisabled = staticSettings.getAsBoolean(ConfigConstants.SECURITY_UNSUPPORTED_DISABLE_REST_AUTH_INITIALLY, false); @@ -79,7 +79,7 @@ public boolean restAuthEnabled() { } } - + //true is default public boolean transportInterClusterAuthEnabled() { final boolean interClusterAuthInitiallyDisabled = staticSettings.getAsBoolean(ConfigConstants.SECURITY_UNSUPPORTED_DISABLE_INTERTRANSPORT_AUTH_INITIALLY, false); diff --git a/src/main/java/org/opensearch/security/configuration/ConfigCallback.java b/src/main/java/org/opensearch/security/configuration/ConfigCallback.java index d7d1ed0cee..cb8fc1eedf 100644 --- a/src/main/java/org/opensearch/security/configuration/ConfigCallback.java +++ b/src/main/java/org/opensearch/security/configuration/ConfigCallback.java @@ -30,7 +30,7 @@ import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; public interface ConfigCallback { - + void success(SecurityDynamicConfiguration dConf); void noData(String id); void singleFailure(Failure failure); diff --git a/src/main/java/org/opensearch/security/configuration/ConfigUpdateAlreadyInProgressException.java b/src/main/java/org/opensearch/security/configuration/ConfigUpdateAlreadyInProgressException.java index ea7799e014..c628a3156e 100644 --- a/src/main/java/org/opensearch/security/configuration/ConfigUpdateAlreadyInProgressException.java +++ b/src/main/java/org/opensearch/security/configuration/ConfigUpdateAlreadyInProgressException.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.configuration; diff --git a/src/main/java/org/opensearch/security/configuration/DlsFlsRequestValve.java b/src/main/java/org/opensearch/security/configuration/DlsFlsRequestValve.java index 4aa9fadcae..f5751efcae 100644 --- a/src/main/java/org/opensearch/security/configuration/DlsFlsRequestValve.java +++ b/src/main/java/org/opensearch/security/configuration/DlsFlsRequestValve.java @@ -36,7 +36,7 @@ import org.opensearch.threadpool.ThreadPool; public interface DlsFlsRequestValve { - + boolean invoke(String action, ActionRequest request, ActionListener listener, EvaluatedDlsFlsConfig evaluatedDlsFlsConfig, Resolved resolved); void handleSearchContext(SearchContext context, ThreadPool threadPool, NamedXContentRegistry namedXContentRegistry); @@ -61,5 +61,5 @@ public void onQueryPhase(QuerySearchResult queryResult) { } } - + } diff --git a/src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java b/src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java index 532f820210..947557d342 100644 --- a/src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java +++ b/src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java @@ -266,7 +266,7 @@ public boolean invoke(String action, ActionRequest request, final ActionListener RestStatus.FORBIDDEN)); return false; } - + if (evaluatedDlsFlsConfig.hasDls()) { if (request instanceof SearchRequest) { @@ -317,7 +317,7 @@ public void handleSearchContext(SearchContext context, ThreadPool threadPool, Na assert context.parsedQuery() != null; final Set unparsedDlsQueries = queries.get(dlsEval); - + if (unparsedDlsQueries != null && !unparsedDlsQueries.isEmpty()) { BooleanQuery.Builder queryBuilder = dlsQueryParser.parse(unparsedDlsQueries, context.getQueryShardContext(), (q) -> new ConstantScoreQuery(q)); @@ -390,7 +390,7 @@ private void setDlsHeaders(EvaluatedDlsFlsConfig dlsFls, ActionRequest request) } else { if (threadContext.getHeader(ConfigConstants.OPENDISTRO_SECURITY_DLS_QUERY_HEADER) != null) { Object deserializedDlsQueries = Base64Helper.deserializeObject(threadContext.getHeader(ConfigConstants.OPENDISTRO_SECURITY_DLS_QUERY_HEADER)); - if (!dlsQueries.equals(deserializedDlsQueries)) { + if (!dlsQueries.equals(deserializedDlsQueries)) { throw new OpenSearchSecurityException(ConfigConstants.OPENDISTRO_SECURITY_DLS_QUERY_HEADER + " does not match (SG 900D)"); } } else { diff --git a/src/main/java/org/opensearch/security/configuration/DlsQueryParser.java b/src/main/java/org/opensearch/security/configuration/DlsQueryParser.java index fd3b3aee98..a5f07541c8 100644 --- a/src/main/java/org/opensearch/security/configuration/DlsQueryParser.java +++ b/src/main/java/org/opensearch/security/configuration/DlsQueryParser.java @@ -99,7 +99,7 @@ public BooleanQuery.Builder parse(Set unparsedDlsQueries, QueryShardCont return dlsQueryBuilder; } - + private static void handleNested(final QueryShardContext queryShardContext, final BooleanQuery.Builder dlsQueryBuilder, final Query parentQuery) { final BitSetProducer parentDocumentsFilter = queryShardContext.bitsetFilter(NON_NESTED_QUERY); @@ -131,7 +131,7 @@ boolean containsTermLookupQuery(Set unparsedQueries) { if (log.isDebugEnabled()) { log.debug("containsTermLookupQuery() returns true due to " + query + "\nqueries: " + unparsedQueries); } - + return true; } } @@ -139,7 +139,7 @@ boolean containsTermLookupQuery(Set unparsedQueries) { if (log.isDebugEnabled()) { log.debug("containsTermLookupQuery() returns false\nqueries: " + unparsedQueries); } - + return false; } @@ -156,5 +156,5 @@ boolean containsTermLookupQuery(String query) { } } - + } diff --git a/src/main/java/org/opensearch/security/configuration/EmptyFilterLeafReader.java b/src/main/java/org/opensearch/security/configuration/EmptyFilterLeafReader.java index 4b603fa804..79069ef53e 100644 --- a/src/main/java/org/opensearch/security/configuration/EmptyFilterLeafReader.java +++ b/src/main/java/org/opensearch/security/configuration/EmptyFilterLeafReader.java @@ -102,7 +102,7 @@ public EmptyDirectoryReader(final DirectoryReader in) throws IOException { protected DirectoryReader doWrapDirectoryReader(final DirectoryReader in) throws IOException { return new EmptyDirectoryReader(in); } - + @Override public CacheHelper getReaderCacheHelper() { return in.getReaderCacheHelper(); diff --git a/src/main/java/org/opensearch/security/configuration/InvalidConfigException.java b/src/main/java/org/opensearch/security/configuration/InvalidConfigException.java index 5e96af6449..ba6a29b08a 100644 --- a/src/main/java/org/opensearch/security/configuration/InvalidConfigException.java +++ b/src/main/java/org/opensearch/security/configuration/InvalidConfigException.java @@ -29,7 +29,7 @@ public class InvalidConfigException extends Exception { /** - * + * */ private static final long serialVersionUID = 1L; diff --git a/src/main/java/org/opensearch/security/configuration/StaticResourceException.java b/src/main/java/org/opensearch/security/configuration/StaticResourceException.java index b4d787aa0f..8574a170bb 100644 --- a/src/main/java/org/opensearch/security/configuration/StaticResourceException.java +++ b/src/main/java/org/opensearch/security/configuration/StaticResourceException.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.configuration; diff --git a/src/main/java/org/opensearch/security/filter/SecurityFilter.java b/src/main/java/org/opensearch/security/filter/SecurityFilter.java index 7bdd5946d5..4dd629c010 100644 --- a/src/main/java/org/opensearch/security/filter/SecurityFilter.java +++ b/src/main/java/org/opensearch/security/filter/SecurityFilter.java @@ -192,7 +192,7 @@ private void ap if (user != null) { org.apache.logging.log4j.ThreadContext.put("user", user.getName()); } - + if (isActionTraceEnabled()) { String count = ""; @@ -232,12 +232,12 @@ private void ap chain.proceed(task, action, request, listener); return; } - - + + if(immutableIndicesMatcher != WildcardMatcher.NONE) { - + boolean isImmutable = false; - + if(request instanceof BulkShardRequest) { for(BulkItemRequest bsr: ((BulkShardRequest) request).items()) { isImmutable = checkImmutableIndices(bsr.request(), listener); @@ -248,7 +248,7 @@ private void ap } else { isImmutable = checkImmutableIndices(request, listener); } - + if(isImmutable) { return; } @@ -301,7 +301,7 @@ private void ap } final PrivilegesEvaluatorResponse pres = eval.evaluate(user, action, request, task, injectedRoles); - + if (log.isDebugEnabled()) { log.debug(pres.toString()); } @@ -384,7 +384,7 @@ private static boolean isUserAdmin(User user, final AdminDNs adminDns) { } private void attachSourceFieldContext(ActionRequest request) { - + if(request instanceof SearchRequest && SourceFieldsContext.isNeeded((SearchRequest) request)) { if(threadContext.getHeader("_opendistro_security_source_field_context") == null) { final String serializedSourceFieldContext = Base64Helper.serializeObject(new SourceFieldsContext((SearchRequest) request)); @@ -397,7 +397,7 @@ private void attachSourceFieldContext(ActionRequest request) { } } } - + @SuppressWarnings("rawtypes") private boolean checkImmutableIndices(Object request, ActionListener listener) { final boolean isModifyIndexRequest = request instanceof DeleteRequest @@ -413,11 +413,11 @@ private boolean checkImmutableIndices(Object request, ActionListener listener) { listener.onFailure(new OpenSearchSecurityException("Index is immutable", RestStatus.FORBIDDEN)); return true; } - + if ((request instanceof IndexRequest) && isRequestIndexImmutable(request)) { ((IndexRequest) request).opType(OpType.CREATE); } - + return false; } diff --git a/src/main/java/org/opensearch/security/filter/SecurityRestFilter.java b/src/main/java/org/opensearch/security/filter/SecurityRestFilter.java index ebd2e8d633..25926dab32 100644 --- a/src/main/java/org/opensearch/security/filter/SecurityRestFilter.java +++ b/src/main/java/org/opensearch/security/filter/SecurityRestFilter.java @@ -117,7 +117,7 @@ public SecurityRestFilter(final BackendRegistry registry, final AuditLog auditLo */ public RestHandler wrap(RestHandler original, AdminDNs adminDNs) { return new RestHandler() { - + @Override public void handleRequest(RestRequest request, RestChannel channel, NodeClient client) throws Exception { org.apache.logging.log4j.ThreadContext.clearAll(); @@ -143,7 +143,7 @@ private boolean checkAndAuthenticateRequest(RestRequest request, RestChannel cha NodeClient client) throws Exception { threadContext.putTransient(ConfigConstants.OPENDISTRO_SECURITY_ORIGIN, Origin.REST.toString()); - + if(HTTPHelper.containsBadHeader(request)) { final OpenSearchException exception = ExceptionUtils.createBadHeaderException(); log.error(exception.toString()); @@ -151,7 +151,7 @@ private boolean checkAndAuthenticateRequest(RestRequest request, RestChannel cha channel.sendResponse(new BytesRestResponse(channel, RestStatus.FORBIDDEN, exception)); return true; } - + if(SSLRequestHelper.containsBadHeader(threadContext, ConfigConstants.OPENDISTRO_SECURITY_CONFIG_PREFIX)) { final OpenSearchException exception = ExceptionUtils.createBadHeaderException(); log.error(exception.toString()); @@ -166,7 +166,7 @@ private boolean checkAndAuthenticateRequest(RestRequest request, RestChannel cha if(sslInfo.getPrincipal() != null) { threadContext.putTransient("_opendistro_security_ssl_principal", sslInfo.getPrincipal()); } - + if(sslInfo.getX509Certs() != null) { threadContext.putTransient("_opendistro_security_ssl_peer_certificates", sslInfo.getX509Certs()); } @@ -179,7 +179,7 @@ private boolean checkAndAuthenticateRequest(RestRequest request, RestChannel cha channel.sendResponse(new BytesRestResponse(channel, RestStatus.FORBIDDEN, e)); return true; } - + if(!compatConfig.restAuthEnabled()) { return false; } @@ -198,7 +198,7 @@ private boolean checkAndAuthenticateRequest(RestRequest request, RestChannel cha org.apache.logging.log4j.ThreadContext.put("user", ((User)threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER)).getName()); } } - + return false; } diff --git a/src/main/java/org/opensearch/security/http/HTTPBasicAuthenticator.java b/src/main/java/org/opensearch/security/http/HTTPBasicAuthenticator.java index 35278d261f..30e6134381 100644 --- a/src/main/java/org/opensearch/security/http/HTTPBasicAuthenticator.java +++ b/src/main/java/org/opensearch/security/http/HTTPBasicAuthenticator.java @@ -47,20 +47,20 @@ public class HTTPBasicAuthenticator implements HTTPAuthenticator { protected final Logger log = LogManager.getLogger(this.getClass()); public HTTPBasicAuthenticator(final Settings settings, final Path configPath) { - + } @Override public AuthCredentials extractCredentials(final RestRequest request, ThreadContext threadContext) { final boolean forceLogin = request.paramAsBoolean("force_login", false); - + if(forceLogin) { return null; } - + final String authorizationHeader = request.header("Authorization"); - + return HTTPHelper.extractCredentials(authorizationHeader, log); } diff --git a/src/main/java/org/opensearch/security/http/HTTPClientCertAuthenticator.java b/src/main/java/org/opensearch/security/http/HTTPClientCertAuthenticator.java index 51ff6304b1..373919669d 100644 --- a/src/main/java/org/opensearch/security/http/HTTPClientCertAuthenticator.java +++ b/src/main/java/org/opensearch/security/http/HTTPClientCertAuthenticator.java @@ -48,7 +48,7 @@ import org.opensearch.security.user.AuthCredentials; public class HTTPClientCertAuthenticator implements HTTPAuthenticator { - + protected final Logger log = LogManager.getLogger(this.getClass()); protected final Settings settings; @@ -62,29 +62,29 @@ public AuthCredentials extractCredentials(final RestRequest request, final Threa final String principal = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_PRINCIPAL); if (!Strings.isNullOrEmpty(principal)) { - + final String usernameAttribute = settings.get("username_attribute"); final String rolesAttribute = settings.get("roles_attribute"); - + try { final LdapName rfc2253dn = new LdapName(principal); String username = principal.trim(); String[] backendRoles = null; - + if(usernameAttribute != null && usernameAttribute.length() > 0) { final List usernames = getDnAttribute(rfc2253dn, usernameAttribute); if(usernames.isEmpty() == false) { username = usernames.get(0); } } - + if(rolesAttribute != null && rolesAttribute.length() > 0) { final List roles = getDnAttribute(rfc2253dn, rolesAttribute); if(roles.isEmpty() == false) { backendRoles = roles.toArray(new String[0]); } } - + return new AuthCredentials(username, backendRoles).markComplete(); } catch (InvalidNameException e) { log.error("Client cert had no properly formed DN (was: {})", principal); @@ -106,8 +106,8 @@ public boolean reRequestAuthentication(final RestChannel channel, AuthCredential public String getType() { return "clientcert"; } - - private List getDnAttribute(LdapName rfc2253dn, String attribute) { + + private List getDnAttribute(LdapName rfc2253dn, String attribute) { final List attrValues = new ArrayList<>(rfc2253dn.size()); final List reverseRdn = new ArrayList<>(rfc2253dn.getRdns()); Collections.reverse(reverseRdn); @@ -117,7 +117,7 @@ private List getDnAttribute(LdapName rfc2253dn, String attribute) { attrValues.add(rdn.getValue().toString()); } } - + return Collections.unmodifiableList(attrValues); } } diff --git a/src/main/java/org/opensearch/security/http/HTTPProxyAuthenticator.java b/src/main/java/org/opensearch/security/http/HTTPProxyAuthenticator.java index 28fb80e0db..348811b694 100644 --- a/src/main/java/org/opensearch/security/http/HTTPProxyAuthenticator.java +++ b/src/main/java/org/opensearch/security/http/HTTPProxyAuthenticator.java @@ -57,14 +57,14 @@ public HTTPProxyAuthenticator(Settings settings, final Path configPath) { @Override public AuthCredentials extractCredentials(final RestRequest request, ThreadContext context) { - + if(context.getTransient(ConfigConstants.OPENDISTRO_SECURITY_XFF_DONE) != Boolean.TRUE) { throw new OpenSearchSecurityException("xff not done"); } - + final String userHeader = settings.get("user_header"); final String rolesHeader = settings.get("roles_header"); - + if (log.isDebugEnabled()) { log.debug("Headers {}", request.getHeaders()); log.debug("UserHeader {}, value {}", userHeader, userHeader == null ? null : request.header(userHeader)); diff --git a/src/main/java/org/opensearch/security/http/RemoteIpDetector.java b/src/main/java/org/opensearch/security/http/RemoteIpDetector.java index 404fd2dcc2..5d9e933c8f 100644 --- a/src/main/java/org/opensearch/security/http/RemoteIpDetector.java +++ b/src/main/java/org/opensearch/security/http/RemoteIpDetector.java @@ -120,23 +120,23 @@ String detect(RestRequest request, ThreadContext threadContext){ if (isTraceEnabled) { log.trace("originalRemoteAddr {}", originalRemoteAddr); } - + //X-Forwarded-For: client1, proxy1, proxy2 // ^^^^^^ originalRemoteAddr - + //originalRemoteAddr need to be in the list of internalProxies if (internalProxies !=null && internalProxies.matcher(originalRemoteAddr).matches()) { String remoteIp = null; final StringBuilder concatRemoteIpHeaderValue = new StringBuilder(); - + //client1, proxy1, proxy2 final List remoteIpHeaders = request.getHeaders().get(remoteIpHeader); //X-Forwarded-For if(remoteIpHeaders == null || remoteIpHeaders.isEmpty()) { return originalRemoteAddr; } - + for (String rh:remoteIpHeaders) { if (concatRemoteIpHeaderValue.length() > 0) { concatRemoteIpHeaderValue.append(", "); @@ -144,7 +144,7 @@ String detect(RestRequest request, ThreadContext threadContext){ concatRemoteIpHeaderValue.append(rh); } - + if (isTraceEnabled) { log.trace("concatRemoteIpHeaderValue {}", concatRemoteIpHeaderValue.toString()); } @@ -162,14 +162,14 @@ String detect(RestRequest request, ThreadContext threadContext){ break; } } - + // continue to loop on remoteIpHeaderValue to build the new value of the remoteIpHeader final LinkedList newRemoteIpHeaderValue = new LinkedList<>(); for (; idx >= 0; idx--) { String currentRemoteIp = remoteIpHeaderValue[idx]; newRemoteIpHeaderValue.addFirst(currentRemoteIp); } - + if (remoteIp != null) { if (isTraceEnabled) { final String originalRemoteHost = ((InetSocketAddress)request.getHttpChannel().getRemoteAddress()).getAddress().getHostName(); @@ -178,17 +178,17 @@ String detect(RestRequest request, ThreadContext threadContext){ threadContext.putTransient(ConfigConstants.OPENDISTRO_SECURITY_XFF_DONE, Boolean.TRUE); return remoteIp; - + } else { log.warn("Remote ip could not be detected, this should normally not happen"); } - + } else { if (isTraceEnabled) { log.trace("Skip RemoteIpDetector for request {} with originalRemoteAddr '{}' cause no internal proxy matches", request.uri(), request.getHttpChannel().getRemoteAddress()); } } - + return originalRemoteAddr; } diff --git a/src/main/java/org/opensearch/security/http/SecurityHttpServerTransport.java b/src/main/java/org/opensearch/security/http/SecurityHttpServerTransport.java index 3d977dcc7e..6f2f57053f 100644 --- a/src/main/java/org/opensearch/security/http/SecurityHttpServerTransport.java +++ b/src/main/java/org/opensearch/security/http/SecurityHttpServerTransport.java @@ -39,7 +39,7 @@ import org.opensearch.transport.SharedGroupFactory; public class SecurityHttpServerTransport extends SecuritySSLNettyHttpServerTransport { - + public SecurityHttpServerTransport(final Settings settings, final NetworkService networkService, final BigArrays bigArrays, final ThreadPool threadPool, final SecurityKeyStore odsks, final SslExceptionHandler sslExceptionHandler, final NamedXContentRegistry namedXContentRegistry, final ValidatingDispatcher dispatcher, final ClusterSettings clusterSettings, SharedGroupFactory sharedGroupFactory) { diff --git a/src/main/java/org/opensearch/security/http/SecurityNonSslHttpServerTransport.java b/src/main/java/org/opensearch/security/http/SecurityNonSslHttpServerTransport.java index b05153db4c..3c1dedc55e 100644 --- a/src/main/java/org/opensearch/security/http/SecurityNonSslHttpServerTransport.java +++ b/src/main/java/org/opensearch/security/http/SecurityNonSslHttpServerTransport.java @@ -54,7 +54,7 @@ public ChannelHandler configureServerChannelHandler() { } protected class NonSslHttpChannelHandler extends Netty4HttpServerTransport.HttpChannelHandler { - + protected NonSslHttpChannelHandler(Netty4HttpServerTransport transport, final HttpHandlingSettings handlingSettings) { super(transport, handlingSettings); } diff --git a/src/main/java/org/opensearch/security/http/XFFResolver.java b/src/main/java/org/opensearch/security/http/XFFResolver.java index 23de8e3676..c44e98537d 100644 --- a/src/main/java/org/opensearch/security/http/XFFResolver.java +++ b/src/main/java/org/opensearch/security/http/XFFResolver.java @@ -47,7 +47,7 @@ public class XFFResolver { private volatile boolean enabled; private volatile RemoteIpDetector detector; private final ThreadContext threadContext; - + public XFFResolver(final ThreadPool threadPool) { super(); this.threadContext = threadPool.getThreadContext(); @@ -58,16 +58,16 @@ public TransportAddress resolve(final RestRequest request) throws OpenSearchSecu if (isTraceEnabled) { log.trace("resolve {}", request.getHttpChannel().getRemoteAddress()); } - + if(enabled && request.getHttpChannel().getRemoteAddress() instanceof InetSocketAddress && request.getHttpChannel() instanceof Netty4HttpChannel) { final InetSocketAddress isa = new InetSocketAddress(detector.detect(request, threadContext), ((InetSocketAddress)request.getHttpChannel().getRemoteAddress()).getPort()); - - if(isa.isUnresolved()) { + + if(isa.isUnresolved()) { throw new OpenSearchSecurityException("Cannot resolve address "+isa.getHostString()); } - - + + if (isTraceEnabled) { if(threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_XFF_DONE) == Boolean.TRUE) { log.trace("xff resolved {} to {}", request.getHttpChannel().getRemoteAddress(), isa); @@ -77,7 +77,7 @@ public TransportAddress resolve(final RestRequest request) throws OpenSearchSecu } return new TransportAddress(isa); } else if(request.getHttpChannel().getRemoteAddress() instanceof InetSocketAddress){ - + if (isTraceEnabled) { log.trace("no xff done (enabled or no netty request) {},{},{},{}",enabled, request.getClass()); 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 d792158fea..e98f26d85a 100644 --- a/src/main/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticator.java +++ b/src/main/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticator.java @@ -60,7 +60,7 @@ public AuthCredentials extractCredentials(final RestRequest request, ThreadConte if(credentials == null) { return null; } - + String attrHeaderPrefix = settings.get("attr_header_prefix"); if(Strings.isNullOrEmpty(attrHeaderPrefix)) { log.debug("attr_header_prefix is null. Skipping additional attribute extraction"); @@ -68,7 +68,7 @@ public AuthCredentials extractCredentials(final RestRequest request, ThreadConte } else if(log.isDebugEnabled()) { log.debug("attrHeaderPrefix {}", attrHeaderPrefix); } - + credentials.addAttribute(ATTR_PROXY_USERNAME, credentials.getUsername()); attrHeaderPrefix = attrHeaderPrefix.toLowerCase(); for (Entry> entry : request.getHeaders().entrySet()) { diff --git a/src/main/java/org/opensearch/security/httpclient/HttpClient.java b/src/main/java/org/opensearch/security/httpclient/HttpClient.java index d032ca3544..ad507ea47c 100644 --- a/src/main/java/org/opensearch/security/httpclient/HttpClient.java +++ b/src/main/java/org/opensearch/security/httpclient/HttpClient.java @@ -195,7 +195,7 @@ public boolean index(final String content, final String index, final String type try { final IndexRequest ir = new IndexRequest(index); - + final IndexResponse response = rclient.index(ir .setRefreshPolicy(refresh?RefreshPolicy.IMMEDIATE:RefreshPolicy.NONE) .source(content, XContentType.JSON), RequestOptions.DEFAULT); diff --git a/src/main/java/org/opensearch/security/privileges/DocumentAllowList.java b/src/main/java/org/opensearch/security/privileges/DocumentAllowList.java index 8bfbb7c0db..129233a007 100644 --- a/src/main/java/org/opensearch/security/privileges/DocumentAllowList.java +++ b/src/main/java/org/opensearch/security/privileges/DocumentAllowList.java @@ -193,7 +193,7 @@ public static class Entry { if (index.indexOf('/') != -1 || index.indexOf('|') != -1) { throw new IllegalArgumentException("Invalid index name: " + index); } - + this.index = index; this.id = id; } diff --git a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java index 36d53b2a9e..278dc86b7c 100644 --- a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java +++ b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java @@ -134,7 +134,7 @@ public class PrivilegesEvaluator { private final boolean dfmEmptyOverwritesAll; private DynamicConfigModel dcm; private final NamedXContentRegistry namedXContentRegistry; - + public PrivilegesEvaluator(final ClusterService clusterService, final ThreadPool threadPool, final ConfigurationRepository configurationRepository, final IndexNameExpressionResolver resolver, AuditLog auditLog, final Settings settings, final PrivilegesInterceptor privilegesInterceptor, final ClusterInfoHolder clusterInfoHolder, @@ -309,7 +309,7 @@ public PrivilegesEvaluatorResponse evaluate(final User user, String action0, fin } presponse.evaluatedDlsFlsConfig = getSecurityRoles(mappedRoles).getDlsFls(user, dfmEmptyOverwritesAll, resolver, clusterService, namedXContentRegistry); - + if (isClusterPerm(action0)) { if(!securityRoles.impliesClusterPermissionPermission(action0)) { @@ -384,7 +384,7 @@ public PrivilegesEvaluatorResponse evaluate(final User user, String action0, fin presponse.allowed = true; return presponse; } - + // term aggregations if (termsAggregationEvaluator.evaluate(requestedResolved, request, clusterService, user, securityRoles, resolver, presponse) .isComplete()) { return presponse; @@ -728,7 +728,7 @@ private boolean checkDocAllowListHeader(User user, String action, ActionRequest if (log.isDebugEnabled()) { log.debug("Request " + request + " is allowed by " + documentAllowList); } - + return true; } else { return false; @@ -739,7 +739,7 @@ private boolean checkDocAllowListHeader(User user, String action, ActionRequest return false; } } - + private List toString(List aliases) { if(aliases == null || aliases.size() == 0) { return Collections.emptyList(); diff --git a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluatorResponse.java b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluatorResponse.java index 8b3e51f045..31ce7095d2 100644 --- a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluatorResponse.java +++ b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluatorResponse.java @@ -42,11 +42,11 @@ public class PrivilegesEvaluatorResponse { PrivilegesEvaluatorResponseState state = PrivilegesEvaluatorResponseState.PENDING; Resolved resolved; CreateIndexRequestBuilder createIndexRequestBuilder; - + public Resolved getResolved() { return resolved; } - + public boolean isAllowed() { return allowed; } @@ -61,11 +61,11 @@ public Set getMissingPrivileges() { public EvaluatedDlsFlsConfig getEvaluatedDlsFlsConfig() { return evaluatedDlsFlsConfig; } - + public CreateIndexRequestBuilder getCreateIndexRequestBuilder() { return createIndexRequestBuilder; } - + public PrivilegesEvaluatorResponse markComplete() { this.state = PrivilegesEvaluatorResponseState.COMPLETE; return this; @@ -89,10 +89,10 @@ public String toString() { return "PrivEvalResponse [allowed=" + allowed + ", missingPrivileges=" + missingPrivileges + ", evaluatedDlsFlsConfig=" + evaluatedDlsFlsConfig + "]"; } - + public static enum PrivilegesEvaluatorResponseState { PENDING, COMPLETE; } - + } diff --git a/src/main/java/org/opensearch/security/privileges/PrivilegesInterceptor.java b/src/main/java/org/opensearch/security/privileges/PrivilegesInterceptor.java index c76910474f..dd569b05fb 100644 --- a/src/main/java/org/opensearch/security/privileges/PrivilegesInterceptor.java +++ b/src/main/java/org/opensearch/security/privileges/PrivilegesInterceptor.java @@ -65,7 +65,7 @@ protected static ReplaceResult newAccessGrantedReplaceResult(CreateIndexRequestB protected final Client client; protected final ThreadPool threadPool; - public PrivilegesInterceptor(final IndexNameExpressionResolver resolver, final ClusterService clusterService, + public PrivilegesInterceptor(final IndexNameExpressionResolver resolver, final ClusterService clusterService, final Client client, ThreadPool threadPool) { this.resolver = resolver; this.clusterService = clusterService; @@ -77,7 +77,7 @@ public ReplaceResult replaceDashboardsIndex(final ActionRequest request, final S final Resolved requestedResolved, final Map tenants) { throw new RuntimeException("not implemented"); } - + protected final ThreadContext getThreadContext() { return threadPool.getThreadContext(); } diff --git a/src/main/java/org/opensearch/security/privileges/SecurityIndexAccessEvaluator.java b/src/main/java/org/opensearch/security/privileges/SecurityIndexAccessEvaluator.java index 60456a4eb3..a74ea17ccd 100644 --- a/src/main/java/org/opensearch/security/privileges/SecurityIndexAccessEvaluator.java +++ b/src/main/java/org/opensearch/security/privileges/SecurityIndexAccessEvaluator.java @@ -47,9 +47,9 @@ import org.opensearch.tasks.Task; public class SecurityIndexAccessEvaluator { - + Logger log = LogManager.getLogger(this.getClass()); - + private final String securityIndex; private final AuditLog auditLog; private final WildcardMatcher securityDeniedActionMatcher; @@ -86,7 +86,7 @@ public SecurityIndexAccessEvaluator(final Settings settings, AuditLog auditLog, securityDeniedActionMatcher = WildcardMatcher.from(restoreSecurityIndexEnabled ? securityIndexDeniedActionPatternsList : securityIndexDeniedActionPatternsListNoSnapshot); } - + public PrivilegesEvaluatorResponse evaluate(final ActionRequest request, final Task task, final String action, final Resolved requestedResolved, final PrivilegesEvaluatorResponse presponse) { final boolean isDebugEnabled = log.isDebugEnabled(); diff --git a/src/main/java/org/opensearch/security/privileges/SnapshotRestoreEvaluator.java b/src/main/java/org/opensearch/security/privileges/SnapshotRestoreEvaluator.java index c457b42624..c536ae2d2e 100644 --- a/src/main/java/org/opensearch/security/privileges/SnapshotRestoreEvaluator.java +++ b/src/main/java/org/opensearch/security/privileges/SnapshotRestoreEvaluator.java @@ -47,7 +47,7 @@ public class SnapshotRestoreEvaluator { private final String securityIndex; private final AuditLog auditLog; private final boolean restoreSecurityIndexEnabled; - + public SnapshotRestoreEvaluator(final Settings settings, AuditLog auditLog) { this.enableSnapshotRestorePrivilege = settings.getAsBoolean(ConfigConstants.SECURITY_ENABLE_SNAPSHOT_RESTORE_PRIVILEGE, ConfigConstants.SECURITY_DEFAULT_ENABLE_SNAPSHOT_RESTORE_PRIVILEGE); @@ -63,27 +63,27 @@ public PrivilegesEvaluatorResponse evaluate(final ActionRequest request, final T if (!(request instanceof RestoreSnapshotRequest)) { return presponse; } - + // snapshot restore for regular users not enabled if (!enableSnapshotRestorePrivilege) { log.warn("{} is not allowed for a regular user", action); presponse.allowed = false; - return presponse.markComplete(); + return presponse.markComplete(); } // if this feature is enabled, users can also snapshot and restore // the Security index and the global state if (restoreSecurityIndexEnabled) { presponse.allowed = true; - return presponse; + return presponse; } - + if (clusterInfoHolder.isLocalNodeElectedClusterManager() == Boolean.FALSE) { presponse.allowed = true; - return presponse.markComplete(); + return presponse.markComplete(); } - + final RestoreSnapshotRequest restoreRequest = (RestoreSnapshotRequest) request; // Do not allow restore of global state @@ -91,7 +91,7 @@ public PrivilegesEvaluatorResponse evaluate(final ActionRequest request, final T auditLog.logSecurityIndexAttempt(request, action, task); log.warn("{} with 'include_global_state' enabled is not allowed", action); presponse.allowed = false; - return presponse.markComplete(); + return presponse.markComplete(); } final List rs = SnapshotRestoreHelper.resolveOriginalIndices(restoreRequest); @@ -100,7 +100,7 @@ public PrivilegesEvaluatorResponse evaluate(final ActionRequest request, final T auditLog.logSecurityIndexAttempt(request, action, task); log.warn("{} for '{}' as source index is not allowed", action, securityIndex); presponse.allowed = false; - return presponse.markComplete(); + return presponse.markComplete(); } return presponse; } diff --git a/src/main/java/org/opensearch/security/privileges/TermsAggregationEvaluator.java b/src/main/java/org/opensearch/security/privileges/TermsAggregationEvaluator.java index 1d1d048350..53709458fd 100644 --- a/src/main/java/org/opensearch/security/privileges/TermsAggregationEvaluator.java +++ b/src/main/java/org/opensearch/security/privileges/TermsAggregationEvaluator.java @@ -56,12 +56,12 @@ public class TermsAggregationEvaluator { "indices:data/read/field_caps*" //"indices:admin/mappings/fields/get*" }; - + private static final QueryBuilder NONE_QUERY = new MatchNoneQueryBuilder(); - + public TermsAggregationEvaluator() { } - + public PrivilegesEvaluatorResponse evaluate(final Resolved resolved, final ActionRequest request, ClusterService clusterService, User user, SecurityRoles securityRoles, IndexNameExpressionResolver resolver, PrivilegesEvaluatorResponse presponse) { try { if(request instanceof SearchRequest) { @@ -81,14 +81,14 @@ public PrivilegesEvaluatorResponse evaluate(final Resolved resolved, final Actio && ab.getPipelineAggregations().isEmpty() && ab.getSubAggregations().isEmpty()) { - + final Set allPermittedIndices = securityRoles.getAllPermittedIndicesForDashboards(resolved, user, READ_ACTIONS, resolver, clusterService); if(allPermittedIndices == null || allPermittedIndices.isEmpty()) { sr.source().query(NONE_QUERY); } else { sr.source().query(new TermsQueryBuilder("_index", allPermittedIndices)); - } - + } + presponse.allowed = true; return presponse.markComplete(); } @@ -99,7 +99,7 @@ public PrivilegesEvaluatorResponse evaluate(final Resolved resolved, final Actio log.warn("Unable to evaluate terms aggregation",e); return presponse; } - + return presponse; } } diff --git a/src/main/java/org/opensearch/security/resolver/IndexResolverReplacer.java b/src/main/java/org/opensearch/security/resolver/IndexResolverReplacer.java index d2d0685860..5892a91a30 100644 --- a/src/main/java/org/opensearch/security/resolver/IndexResolverReplacer.java +++ b/src/main/java/org/opensearch/security/resolver/IndexResolverReplacer.java @@ -369,7 +369,7 @@ public final static class Resolved { private final Set remoteIndices; private final boolean isLocalAll; private final IndicesOptions indicesOptions; - + public Resolved(final ImmutableSet aliases, final ImmutableSet allIndices, final ImmutableSet originalRequested, @@ -394,15 +394,15 @@ public Set getAliases() { public Set getAllIndices() { return allIndices; } - + public Set getAllIndicesResolved(ClusterService clusterService, IndexNameExpressionResolver resolver) { - if (isLocalAll) { + if (isLocalAll) { return new HashSet<>(Arrays.asList(resolver.concreteIndexNames(clusterService.state(), indicesOptions, "*"))); - } else { + } else { return allIndices; } } - + public boolean isAllIndicesEmpty() { return allIndices.isEmpty(); } @@ -711,7 +711,7 @@ private boolean getOrReplaceAllIndices(final Object request, final IndicesProvid } private IndicesOptions indicesOptionsFrom(Object localRequest) { - + if(!respectRequestIndicesOptions) { return IndicesOptions.fromOptions(false, true, true, false, true); } diff --git a/src/main/java/org/opensearch/security/rest/DashboardsInfoAction.java b/src/main/java/org/opensearch/security/rest/DashboardsInfoAction.java index 0fd88e7565..a7620f6bdc 100644 --- a/src/main/java/org/opensearch/security/rest/DashboardsInfoAction.java +++ b/src/main/java/org/opensearch/security/rest/DashboardsInfoAction.java @@ -92,9 +92,9 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli public void accept(RestChannel channel) throws Exception { XContentBuilder builder = channel.newBuilder(); //NOSONAR BytesRestResponse response = null; - + try { - + final User user = (User)threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER); builder.startObject(); @@ -131,6 +131,6 @@ public void accept(RestChannel channel) throws Exception { public String getName() { return "Kibana Info Action"; } - - + + } diff --git a/src/main/java/org/opensearch/security/rest/SecurityHealthAction.java b/src/main/java/org/opensearch/security/rest/SecurityHealthAction.java index b88d2700c9..17d5ee122f 100644 --- a/src/main/java/org/opensearch/security/rest/SecurityHealthAction.java +++ b/src/main/java/org/opensearch/security/rest/SecurityHealthAction.java @@ -67,7 +67,7 @@ public List routes() { @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { return new RestChannelConsumer() { - + final String mode = request.param("mode","strict"); @Override @@ -76,8 +76,8 @@ public void accept(RestChannel channel) throws Exception { RestStatus restStatus = RestStatus.OK; BytesRestResponse response = null; try { - - + + String status = "UP"; String message = null; @@ -98,12 +98,12 @@ public void accept(RestChannel channel) throws Exception { } finally { builder.close(); } - - + + channel.sendResponse(response); } - - + + }; } diff --git a/src/main/java/org/opensearch/security/rest/SecurityInfoAction.java b/src/main/java/org/opensearch/security/rest/SecurityInfoAction.java index f8e03da5d2..7867e8790d 100644 --- a/src/main/java/org/opensearch/security/rest/SecurityInfoAction.java +++ b/src/main/java/org/opensearch/security/rest/SecurityInfoAction.java @@ -88,12 +88,12 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli public void accept(RestChannel channel) throws Exception { XContentBuilder builder = channel.newBuilder(); //NOSONAR BytesRestResponse response = null; - + try { - + final boolean verbose = request.paramAsBoolean("verbose", false); - + final X509Certificate[] certs = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_PEER_CERTIFICATES); final User user = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER); final TransportAddress remoteAddress = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS); @@ -112,7 +112,7 @@ public void accept(RestChannel channel) throws Exception { builder.field("principal", (String)threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_PRINCIPAL)); builder.field("peer_certificates", certs != null && certs.length > 0 ? certs.length + "" : "0"); builder.field("sso_logout_url", (String)threadContext.getTransient(ConfigConstants.SSO_LOGOUT_URL)); - + if(user != null && verbose) { try { builder.field("size_of_user", RamUsageEstimator.humanReadableUnits(Base64Helper.serializeObject(user).length())); @@ -122,8 +122,8 @@ public void accept(RestChannel channel) throws Exception { //ignore } } - - + + builder.endObject(); response = new BytesRestResponse(RestStatus.OK, builder); @@ -144,7 +144,7 @@ public void accept(RestChannel channel) throws Exception { } }; } - + @Override public String getName() { return "OpenSearch Security Info Action"; diff --git a/src/main/java/org/opensearch/security/rest/TenantInfoAction.java b/src/main/java/org/opensearch/security/rest/TenantInfoAction.java index 266d2edf49..f7b2a606c6 100644 --- a/src/main/java/org/opensearch/security/rest/TenantInfoAction.java +++ b/src/main/java/org/opensearch/security/rest/TenantInfoAction.java @@ -78,7 +78,7 @@ public class TenantInfoAction extends BaseRestHandler { private final AdminDNs adminDns; private final ConfigurationRepository configurationRepository; - public TenantInfoAction(final Settings settings, final RestController controller, + public TenantInfoAction(final Settings settings, final RestController controller, final PrivilegesEvaluator evaluator, final ThreadPool threadPool, final ClusterService clusterService, final AdminDNs adminDns, final ConfigurationRepository configurationRepository) { super(); @@ -102,18 +102,18 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli public void accept(RestChannel channel) throws Exception { XContentBuilder builder = channel.newBuilder(); //NOSONAR BytesRestResponse response = null; - + try { final User user = (User)threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER); - + //only allowed for admins or the kibanaserveruser if(!isAuthorized()) { response = new BytesRestResponse(RestStatus.FORBIDDEN,""); } else { builder.startObject(); - + final SortedMap lookup = clusterService.state().metadata().getIndicesLookup(); for(final String indexOrAlias: lookup.keySet()) { final String tenant = tenantNameForIndex(indexOrAlias); @@ -123,7 +123,7 @@ public void accept(RestChannel channel) throws Exception { } builder.endObject(); - + response = new BytesRestResponse(RestStatus.OK, builder); } } catch (final Exception e1) { @@ -179,21 +179,21 @@ private final SecurityDynamicConfiguration load(final CType config, boolean l private String tenantNameForIndex(String index) { String[] indexParts; - if(index == null + if(index == null || (indexParts = index.split("_")).length != 3 ) { return null; } - - + + if(!indexParts[0].equals(evaluator.dashboardsIndex())) { return null; } - + try { final int expectedHash = Integer.parseInt(indexParts[1]); final String sanitizedName = indexParts[2]; - + for(String tenant: evaluator.getAllConfiguredTenantNames()) { if(tenant.hashCode() == expectedHash && sanitizedName.equals(tenant.toLowerCase().replaceAll("[^a-z0-9]+",""))) { return tenant; @@ -211,6 +211,6 @@ private String tenantNameForIndex(String index) { public String getName() { return "Tenant Info Action"; } - - + + } diff --git a/src/main/java/org/opensearch/security/securityconf/ConfigModelV6.java b/src/main/java/org/opensearch/security/securityconf/ConfigModelV6.java index 987b8fac64..7a978034f1 100644 --- a/src/main/java/org/opensearch/security/securityconf/ConfigModelV6.java +++ b/src/main/java/org/opensearch/security/securityconf/ConfigModelV6.java @@ -83,9 +83,9 @@ public ConfigModelV6( SecurityDynamicConfiguration rolesmapping, DynamicConfigModel dcm, Settings opensearchSettings) { - + this.roles = roles; - + try { rolesMappingResolution = ConfigConstants.RolesMappingResolution.valueOf( opensearchSettings.get(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, ConfigConstants.RolesMappingResolution.MAPPING_ONLY.toString()) @@ -94,13 +94,13 @@ public ConfigModelV6( log.error("Cannot apply roles mapping resolution", e); rolesMappingResolution = ConfigConstants.RolesMappingResolution.MAPPING_ONLY; } - + agr = reloadActionGroups(actiongroups); securityRoles = reload(roles); tenantHolder = new TenantHolder(roles); roleMappingHolder = new RoleMappingHolder(rolesmapping, dcm.getHostsResolverMode()); } - + public Set getAllConfiguredTenantNames() { final Set configuredTenants = new HashSet<>(); for (Entry securityRole : roles.getCEntries().entrySet()) { @@ -114,18 +114,18 @@ public Set getAllConfiguredTenantNames() { return Collections.unmodifiableSet(configuredTenants); } - + public SecurityRoles getSecurityRoles() { return securityRoles; } - + private static interface ActionGroupResolver { Set resolvedActions(final List actions); } - + private ActionGroupResolver reloadActionGroups(SecurityDynamicConfiguration actionGroups) { return new ActionGroupResolver() { - + private Set getGroupMembers(final String groupname) { if (actionGroups == null) { @@ -134,27 +134,27 @@ private Set getGroupMembers(final String groupname) { return Collections.unmodifiableSet(resolve(actionGroups, groupname)); } - + private Set resolve(final SecurityDynamicConfiguration actionGroups, final String entry) { - + // SG5 format, plain array //List en = actionGroups.getAsList(DotPath.of(entry)); //if (en.isEmpty()) { // try SG6 format including readonly and permissions key // en = actionGroups.getAsList(DotPath.of(entry + "." + ConfigConstants.CONFIGKEY_ACTION_GROUPS_PERMISSIONS)); //} - + if(!actionGroups.getCEntries().containsKey(entry)) { return Collections.emptySet(); } - + final Set ret = new HashSet(); - + final Object actionGroupAsObject = actionGroups.getCEntries().get(entry); - + if(actionGroupAsObject != null && actionGroupAsObject instanceof List) { - + for (final String perm: ((List) actionGroupAsObject)) { if (actionGroups.getCEntries().keySet().contains(perm)) { ret.addAll(resolve(actionGroups,perm)); @@ -162,8 +162,8 @@ private Set resolve(final SecurityDynamicConfiguration actionGroups, ret.add(perm); } } - - + + } else if(actionGroupAsObject != null && actionGroupAsObject instanceof ActionGroupsV6) { for (final String perm: ((ActionGroupsV6) actionGroupAsObject).getPermissions()) { if (actionGroups.getCEntries().keySet().contains(perm)) { @@ -175,10 +175,10 @@ private Set resolve(final SecurityDynamicConfiguration actionGroups, } else { throw new RuntimeException("Unable to handle "+actionGroupAsObject); } - + return Collections.unmodifiableSet(ret); } - + @Override public Set resolvedActions(final List actions) { final Set resolvedActions = new HashSet(); @@ -208,7 +208,7 @@ private SecurityRoles reload(SecurityDynamicConfiguration settings) { @Override public SecurityRole call() throws Exception { SecurityRole _securityRole = new SecurityRole(securityRole.getKey()); - + if(securityRole.getValue() == null) { return null; } @@ -261,8 +261,8 @@ public SecurityRole call() throws Exception { _securityRole.addIndexPattern(_indexPattern); } - - + + return _securityRole; } }); @@ -352,7 +352,7 @@ public Set getRoles() { public Set getRoleNames() { return getRoles().stream().map(r -> r.getName()).collect(Collectors.toSet()); } - + public SecurityRoles filter(Set keep) { final SecurityRoles retVal = new SecurityRoles(roles.size()); for (SecurityRole sr : roles) { @@ -371,7 +371,7 @@ public EvaluatedDlsFlsConfig getDlsFls(User user, boolean dfmEmptyOverwritesAll, final Map> dlsQueries = new HashMap>(); final Map> flsFields = new HashMap>(); final Map> maskedFieldsMap = new HashMap>(); - + for (SecurityRole sr : roles) { for (IndexPattern ip : sr.getIpatterns()) { final Set fls = ip.getFls(); @@ -423,7 +423,7 @@ public EvaluatedDlsFlsConfig getDlsFls(User user, boolean dfmEmptyOverwritesAll, } } } - + if (maskedFields != null && maskedFields.size() > 0) { if (maskedFieldsMap.containsKey(indexPattern)) { @@ -444,7 +444,7 @@ public EvaluatedDlsFlsConfig getDlsFls(User user, boolean dfmEmptyOverwritesAll, } } } - + return new EvaluatedDlsFlsConfig(dlsQueries, flsFields, maskedFieldsMap); } @@ -1010,10 +1010,10 @@ private static boolean impliesTypePerm(Set ipatterns, Resolved res ); } - - + + //####### - + private class TenantHolder { private SetMultimap> tenantsMM = null; @@ -1024,7 +1024,7 @@ public TenantHolder(SecurityDynamicConfiguration roles) { final ExecutorService execs = Executors.newFixedThreadPool(10); for(Entry securityRole: roles.getCEntries().entrySet()) { - + if(securityRole.getValue() == null) { continue; } @@ -1036,7 +1036,7 @@ public Tuple>> call() throws Exception { final Map tenants = securityRole.getValue().getTenants(); if (tenants != null) { - + for (String tenant : tenants.keySet()) { if ("RW".equalsIgnoreCase(tenants.get(tenant))) { @@ -1125,7 +1125,7 @@ private class RoleMappingHolder { private RoleMappingHolder(final SecurityDynamicConfiguration rolesMapping, final String hostResolverMode) { this.hostResolverMode = hostResolverMode; - + if (rolesMapping != null) { users = ArrayListMultimap.create(); @@ -1228,10 +1228,10 @@ private Set map(final User user, final TransportAddress caller) { } } - - - - + + + + public Map mapTenants(User user, Set roles) { return tenantHolder.mapTenants(user, roles); diff --git a/src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java b/src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java index 1e2adee1db..560cfb8a6d 100644 --- a/src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java +++ b/src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java @@ -92,7 +92,7 @@ public ConfigModelV7( this.roles = roles; this.tenants = tenants; - + try { rolesMappingResolution = ConfigConstants.RolesMappingResolution.valueOf( opensearchSettings.get(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, ConfigConstants.RolesMappingResolution.MAPPING_ONLY.toString()) @@ -111,18 +111,18 @@ public ConfigModelV7( public Set getAllConfiguredTenantNames() { return Collections.unmodifiableSet(tenants.getCEntries().keySet()); } - + public SecurityRoles getSecurityRoles() { return securityRoles; } - + private static interface ActionGroupResolver { Set resolvedActions(final List actions); } private ActionGroupResolver reloadActionGroups(SecurityDynamicConfiguration actionGroups) { return new ActionGroupResolver() { - + private Set getGroupMembers(final String groupname) { if (actionGroups == null) { @@ -131,27 +131,27 @@ private Set getGroupMembers(final String groupname) { return Collections.unmodifiableSet(resolve(actionGroups, groupname)); } - + private Set resolve(final SecurityDynamicConfiguration actionGroups, final String entry) { - + // SG5 format, plain array //List en = actionGroups.getAsList(DotPath.of(entry)); //if (en.isEmpty()) { // try SG6 format including readonly and permissions key // en = actionGroups.getAsList(DotPath.of(entry + "." + ConfigConstants.CONFIGKEY_ACTION_GROUPS_PERMISSIONS)); //} - + if(!actionGroups.getCEntries().containsKey(entry)) { return Collections.emptySet(); } - + final Set ret = new HashSet(); - + final Object actionGroupAsObject = actionGroups.getCEntries().get(entry); - + if(actionGroupAsObject != null && actionGroupAsObject instanceof List) { - + for (final String perm: ((List) actionGroupAsObject)) { if (actionGroups.getCEntries().keySet().contains(perm)) { ret.addAll(resolve(actionGroups,perm)); @@ -159,8 +159,8 @@ private Set resolve(final SecurityDynamicConfiguration actionGroups, ret.add(perm); } } - - + + } else if(actionGroupAsObject != null && actionGroupAsObject instanceof ActionGroupsV7) { for (final String perm: ((ActionGroupsV7) actionGroupAsObject).getAllowed_actions()) { if (actionGroups.getCEntries().keySet().contains(perm)) { @@ -172,10 +172,10 @@ private Set resolve(final SecurityDynamicConfiguration actionGroups, } else { throw new RuntimeException("Unable to handle "+actionGroupAsObject); } - + return Collections.unmodifiableSet(ret); } - + @Override public Set resolvedActions(final List actions) { final Set resolvedActions = new HashSet(); @@ -205,7 +205,7 @@ private SecurityRoles reload(SecurityDynamicConfiguration settings) { @Override public SecurityRole call() throws Exception { SecurityRole.Builder _securityRole = new SecurityRole.Builder(securityRole.getKey()); - + if(securityRole.getValue() == null) { return null; } @@ -238,21 +238,21 @@ public SecurityRole call() throws Exception { _indexPattern.addFlsFields(fls); _indexPattern.addMaskedFields(maskedFields); _indexPattern.addPerm(agr.resolvedActions(permittedAliasesIndex.getAllowed_actions())); - + /*for(Entry> type: permittedAliasesIndex.getValue().getTypes(-).entrySet()) { TypePerm typePerm = new TypePerm(type.getKey()); final List perms = type.getValue(); typePerm.addPerms(agr.resolvedActions(perms)); _indexPattern.addTypePerms(typePerm); }*/ - + _securityRole.addIndexPattern(_indexPattern); - + } } - - + + return _securityRole.build(); } }); @@ -339,7 +339,7 @@ public String toString() { public Set getRoles() { return Collections.unmodifiableSet(roles); } - + public Set getRoleNames() { return getRoles().stream().map(r -> r.getName()).collect(Collectors.toSet()); } @@ -367,8 +367,8 @@ public EvaluatedDlsFlsConfig getDlsFls(User user, boolean dfmEmptyOverwritesAll, return EvaluatedDlsFlsConfig.EMPTY; } - - Map> dlsQueriesByIndex = new HashMap>(); + + Map> dlsQueriesByIndex = new HashMap>(); Map> flsFields = new HashMap>(); Map> maskedFieldsMap = new HashMap>(); @@ -379,7 +379,7 @@ public EvaluatedDlsFlsConfig getDlsFls(User user, boolean dfmEmptyOverwritesAll, Set noDlsConcreteIndices = new HashSet<>(); Set noFlsConcreteIndices = new HashSet<>(); Set noMaskedFieldConcreteIndices = new HashSet<>(); - + for (SecurityRole role : roles) { for (IndexPattern ip : role.getIpatterns()) { final Set concreteIndices = ip.concreteIndexNames(user, resolver, cs); @@ -409,12 +409,12 @@ public EvaluatedDlsFlsConfig getDlsFls(User user, boolean dfmEmptyOverwritesAll, } else if (dfmEmptyOverwritesAll) { noFlsConcreteIndices.addAll(concreteIndices); } - + Set maskedFields = ip.getMaskedFields(); if (maskedFields != null && maskedFields.size() > 0) { - for (String concreteIndex : concreteIndices) { + for (String concreteIndex : concreteIndices) { if (maskedFieldsMap.containsKey(concreteIndex)) { maskedFieldsMap.get(concreteIndex).addAll(Sets.newHashSet(maskedFields)); } else { @@ -498,7 +498,7 @@ public boolean impliesTypePermGlobal(Resolved resolved, User user, String[] acti roles.stream().forEach(p -> ipatterns.addAll(p.getIpatterns())); return ConfigModelV7.impliesTypePerm(ipatterns, resolved, user, actions, resolver, cs); } - + private boolean containsDlsFlsConfig() { for (SecurityRole role : roles) { for (IndexPattern ip : role.getIpatterns()) { @@ -562,7 +562,7 @@ private Set getAllResolvedPermittedIndices(Resolved resolved, User user, for (IndexPattern p : ipatterns) { //what if we cannot resolve one (for create purposes) final boolean patternMatch = p.getPerms().matchAll(actions); - + // final Set tperms = p.getTypePerms(); // for (TypePerm tp : tperms) { // if (WildcardMatcher.matchAny(tp.typePattern, resolved.getTypes(-).toArray(new String[0]))) { @@ -810,7 +810,7 @@ public String getDlsQuery(User user) { public boolean hasDlsQuery() { return dlsQuery != null && !dlsQuery.isEmpty(); } - + public Set getFls() { return Collections.unmodifiableSet(fls); } @@ -818,7 +818,7 @@ public Set getFls() { public boolean hasFlsFields() { return fls != null && !fls.isEmpty(); } - + public Set getMaskedFields() { return Collections.unmodifiableSet(maskedFields); } @@ -826,12 +826,12 @@ public Set getMaskedFields() { public boolean hasMaskedFields() { return maskedFields != null && !maskedFields.isEmpty(); } - + public WildcardMatcher getPerms() { return WildcardMatcher.from(perms); } - + } /*public static class TypePerm { @@ -1033,7 +1033,7 @@ private static boolean impliesTypePerm(Set ipatterns, Resolved res ) ); } - + private class TenantHolder { private SetMultimap> tenantsMM = null; @@ -1055,7 +1055,7 @@ public Tuple>> call() throws Exception { final Set> tuples = new HashSet<>(); final List tenants = securityRole.getValue().getTenant_permissions(); if (tenants != null) { - + for (RoleV7.Tenant tenant : tenants) { // find Wildcarded tenant patterns @@ -1166,7 +1166,7 @@ private class RoleMappingHolder { private RoleMappingHolder(final SecurityDynamicConfiguration rolemappings, final String hostResolverMode) { this.hostResolverMode = hostResolverMode; - + if (roles != null) { users = ArrayListMultimap.create(); @@ -1267,10 +1267,10 @@ private Set map(final User user, final TransportAddress caller) { } } - - - - + + + + public Map mapTenants(User user, Set roles) { return tenantHolder.mapTenants(user, roles); diff --git a/src/main/java/org/opensearch/security/securityconf/DynamicConfigFactory.java b/src/main/java/org/opensearch/security/securityconf/DynamicConfigFactory.java index 262eb37cf8..9d8c36576c 100644 --- a/src/main/java/org/opensearch/security/securityconf/DynamicConfigFactory.java +++ b/src/main/java/org/opensearch/security/securityconf/DynamicConfigFactory.java @@ -117,7 +117,7 @@ public final static SecurityDynamicConfiguration addStatics(SecurityDynamicCo return original; } - + protected final Logger log = LogManager.getLogger(this.getClass()); private final ConfigurationRepository cr; private final AtomicBoolean initialized = new AtomicBoolean(); @@ -127,7 +127,7 @@ public final static SecurityDynamicConfiguration addStatics(SecurityDynamicCo private final InternalAuthenticationBackend iab = new InternalAuthenticationBackend(); SecurityDynamicConfiguration config; - + public DynamicConfigFactory(ConfigurationRepository cr, final Settings opensearchSettings, final Path configPath, Client client, ThreadPool threadPool, ClusterInfoHolder cih) { super(); @@ -144,11 +144,11 @@ public DynamicConfigFactory(ConfigurationRepository cr, final Settings opensearc } else { log.info("Static resources will not be loaded."); } - + registerDCFListener(this.iab); this.cr.subscribeOnChange(this); } - + @Override public void onChange(Map> typeToConfig) { @@ -187,7 +187,7 @@ public void onChange(Map> typeToConfig) { if(config.getImplementingClass() == ConfigV7.class) { //statics - + if(roles.containsAny(staticRoles)) { throw new StaticResourceException("Cannot override static roles"); } @@ -205,24 +205,24 @@ public void onChange(Map> typeToConfig) { if(!actionGroups.add(staticActionGroups) && !staticActionGroups.getCEntries().isEmpty()) { throw new StaticResourceException("Unable to load static action groups"); } - + log.debug("Static action groups loaded ({})", staticActionGroups.getCEntries().size()); - + if(tenants.containsAny(staticTenants)) { throw new StaticResourceException("Cannot override static tenants"); } if(!tenants.add(staticTenants) && !staticTenants.getCEntries().isEmpty()) { throw new StaticResourceException("Unable to load static tenants"); } - + log.debug("Static tenants loaded ({})", staticTenants.getCEntries().size()); log.debug("Static configuration loaded (total roles: {}/total action groups: {}/total tenants: {})", roles.getCEntries().size(), actionGroups.getCEntries().size(), tenants.getCEntries().size()); - + //rebuild v7 Models dcm = new DynamicConfigModelV7(getConfigV7(config), opensearchSettings, configPath, iab); @@ -252,26 +252,26 @@ public void onChange(Map> typeToConfig) { } initialized.set(true); - + } - + private static ConfigV6 getConfigV6(SecurityDynamicConfiguration sdc) { @SuppressWarnings("unchecked") SecurityDynamicConfiguration c = (SecurityDynamicConfiguration) sdc; return c.getCEntry("opendistro_security"); } - + private static ConfigV7 getConfigV7(SecurityDynamicConfiguration sdc) { @SuppressWarnings("unchecked") SecurityDynamicConfiguration c = (SecurityDynamicConfiguration) sdc; return c.getCEntry("config"); } - + @Override public final boolean isInitialized() { return initialized.get(); } - + public void registerDCFListener(Object listener) { eventBus.register(listener); } @@ -279,15 +279,15 @@ public void registerDCFListener(Object listener) { public void unregisterDCFListener(Object listener) { eventBus.unregister(listener); } - + private static class InternalUsersModelV7 extends InternalUsersModel { - + private final SecurityDynamicConfiguration internalUserV7SecurityDynamicConfiguration; private final SecurityDynamicConfiguration rolesV7SecurityDynamicConfiguration; private final SecurityDynamicConfiguration rolesMappingsV7SecurityDynamicConfiguration; - + public InternalUsersModelV7(SecurityDynamicConfiguration internalUserV7SecurityDynamicConfiguration, SecurityDynamicConfiguration rolesV7SecurityDynamicConfiguration, SecurityDynamicConfiguration rolesMappingsV7SecurityDynamicConfiguration) { @@ -325,7 +325,7 @@ public String getHash(String user) { InternalUserV7 tmp = internalUserV7SecurityDynamicConfiguration.getCEntry(user); return tmp==null?null:tmp.getHash(); } - + public List getSecurityRoles(String user) { InternalUserV7 tmp = internalUserV7SecurityDynamicConfiguration.getCEntry(user); @@ -341,11 +341,11 @@ private boolean isRolesMappingHidden(String rolename) { return roleMapping!=null && roleMapping.isHidden(); } } - + private static class InternalUsersModelV6 extends InternalUsersModel { - + SecurityDynamicConfiguration configuration; - + public InternalUsersModelV6(SecurityDynamicConfiguration configuration) { super(); @@ -379,7 +379,7 @@ public String getHash(String user) { InternalUserV6 tmp = configuration.getCEntry(user); return tmp==null?null:tmp.getHash(); } - + public List getSecurityRoles(String user) { return Collections.emptyList(); } diff --git a/src/main/java/org/opensearch/security/securityconf/DynamicConfigModel.java b/src/main/java/org/opensearch/security/securityconf/DynamicConfigModel.java index 8b273be122..8668d77d19 100644 --- a/src/main/java/org/opensearch/security/securityconf/DynamicConfigModel.java +++ b/src/main/java/org/opensearch/security/securityconf/DynamicConfigModel.java @@ -54,7 +54,7 @@ import org.opensearch.security.http.proxy.HTTPExtendedProxyAuthenticator; public abstract class DynamicConfigModel { - + protected final Logger log = LogManager.getLogger(this.getClass()); public abstract SortedSet getRestAuthDomains(); public abstract Set getRestAuthorizers(); @@ -76,7 +76,7 @@ public abstract class DynamicConfigModel { public abstract String getFilteredAliasMode(); public abstract String getHostsResolverMode(); public abstract boolean isDnfofForEmptyResultsEnabled(); - + public abstract List getIpAuthFailureListeners(); public abstract Multimap getAuthBackendFailureListeners(); public abstract List> getIpClientBlockRegistries(); @@ -86,7 +86,7 @@ public abstract class DynamicConfigModel { public DynamicConfigModel() { super(); - + authImplMap.put("intern_c", InternalAuthenticationBackend.class.getName()); authImplMap.put("intern_z", NoOpAuthorizationBackend.class.getName()); @@ -98,7 +98,7 @@ public DynamicConfigModel() { authImplMap.put("ldap_c", "com.amazon.dlic.auth.ldap.backend.LDAPAuthenticationBackend"); authImplMap.put("ldap_z", "com.amazon.dlic.auth.ldap.backend.LDAPAuthorizationBackend"); - + authImplMap.put("ldap2_c", "com.amazon.dlic.auth.ldap2.LDAPAuthenticationBackend2"); authImplMap.put("ldap2_z", "com.amazon.dlic.auth.ldap2.LDAPAuthorizationBackend2"); @@ -110,11 +110,11 @@ public DynamicConfigModel() { authImplMap.put("jwt_h", "com.amazon.dlic.auth.http.jwt.HTTPJwtAuthenticator"); authImplMap.put("openid_h", "com.amazon.dlic.auth.http.jwt.keybyoidc.HTTPJwtKeyByOpenIdConnectAuthenticator"); authImplMap.put("saml_h", "com.amazon.dlic.auth.http.saml.HTTPSamlAuthenticator"); - + authImplMap.put("ip_authFailureListener", AddressBasedRateLimiter.class.getName()); authImplMap.put("username_authFailureListener", UserNameBasedRateLimiter.class.getName()); } - - - + + + } diff --git a/src/main/java/org/opensearch/security/securityconf/DynamicConfigModelV6.java b/src/main/java/org/opensearch/security/securityconf/DynamicConfigModelV6.java index 1e6467ae6f..3255bb4de4 100644 --- a/src/main/java/org/opensearch/security/securityconf/DynamicConfigModelV6.java +++ b/src/main/java/org/opensearch/security/securityconf/DynamicConfigModelV6.java @@ -62,7 +62,7 @@ import org.opensearch.security.support.ReflectionHelper; public class DynamicConfigModelV6 extends DynamicConfigModel { - + private final ConfigV6 config; private final Settings opensearchSettings; private final Path configPath; @@ -72,12 +72,12 @@ public class DynamicConfigModelV6 extends DynamicConfigModel { private Set transportAuthorizers; private List destroyableComponents; private final InternalAuthenticationBackend iab; - + private List ipAuthFailureListeners; private Multimap authBackendFailureListeners; private List> ipClientBlockRegistries; private Multimap> authBackendClientBlockRegistries; - + public DynamicConfigModelV6(ConfigV6 config, Settings opensearchSettings, Path configPath, InternalAuthenticationBackend iab) { super(); this.config = config; @@ -158,7 +158,7 @@ public boolean isMultiRolespanEnabled() { public String getFilteredAliasMode() { return config.dynamic.filtered_alias_mode; } - + @Override public boolean isDnfofForEmptyResultsEnabled() { return config.dynamic.do_not_fail_on_forbidden_empty; @@ -168,22 +168,22 @@ public boolean isDnfofForEmptyResultsEnabled() { public String getHostsResolverMode() { return config.dynamic.hosts_resolver_mode; } - + @Override public List getIpAuthFailureListeners() { return Collections.unmodifiableList(ipAuthFailureListeners); } - + @Override public Multimap getAuthBackendFailureListeners() { return Multimaps.unmodifiableMultimap(authBackendFailureListeners); } - + @Override public List> getIpClientBlockRegistries() { return Collections.unmodifiableList(ipClientBlockRegistries); } - + @Override public Multimap> getAuthBackendClientBlockRegistries() { return Multimaps.unmodifiableMultimap(authBackendClientBlockRegistries); @@ -195,7 +195,7 @@ public Settings getDynamicOnBehalfOfSettings() { } private void buildAAA() { - + final SortedSet restAuthDomains0 = new TreeSet<>(); final Set restAuthorizers0 = new HashSet<>(); final SortedSet transportAuthDomains0 = new TreeSet<>(); @@ -219,7 +219,7 @@ private void buildAAA() { final String authzBackendClazz = ad.getValue().authorization_backend.type; final AuthorizationBackend authorizationBackend; - + if(authzBackendClazz.equals(InternalAuthenticationBackend.class.getName()) //NOSONAR || authzBackendClazz.equals("internal") || authzBackendClazz.equals("intern")) { @@ -234,7 +234,7 @@ private void buildAAA() { .put(Settings.builder().loadFromSource(ad.getValue().authorization_backend.configAsJson(), XContentType.JSON).build()).build() , configPath); } - + if (httpEnabled) { restAuthorizers0.add(authorizationBackend); } @@ -242,7 +242,7 @@ private void buildAAA() { if (transportEnabled) { transportAuthorizers0.add(authorizationBackend); } - + if (authorizationBackend instanceof Destroyable) { destroyableComponents0.add((Destroyable) authorizationBackend); } @@ -281,7 +281,7 @@ private void buildAAA() { String httpAuthenticatorType = ad.getValue().http_authenticator.type; //no default HTTPAuthenticator httpAuthenticator = httpAuthenticatorType==null?null: (HTTPAuthenticator) newInstance(httpAuthenticatorType,"h", Settings.builder().put(opensearchSettings) - //.putProperties(ads.getAsStringMap(DotPath.of("http_authenticator.config")), DynamicConfiguration.checkKeyFunction()).build(), + //.putProperties(ads.getAsStringMap(DotPath.of("http_authenticator.config")), DynamicConfiguration.checkKeyFunction()).build(), .put(Settings.builder().loadFromSource(ad.getValue().http_authenticator.configAsJson(), XContentType.JSON).build()).build() , configPath); @@ -296,15 +296,15 @@ private void buildAAA() { if (transportEnabled) { transportAuthDomains0.add(_ad); } - + if (httpAuthenticator instanceof Destroyable) { destroyableComponents0.add((Destroyable) httpAuthenticator); } - + if (authenticationBackend instanceof Destroyable) { destroyableComponents0.add((Destroyable) authenticationBackend); } - + } catch (final Exception e) { log.error("Unable to initialize auth domain {} due to {}", ad, e.toString(), e); } @@ -313,30 +313,30 @@ private void buildAAA() { } List originalDestroyableComponents = destroyableComponents; - + restAuthDomains = Collections.unmodifiableSortedSet(restAuthDomains0); transportAuthDomains = Collections.unmodifiableSortedSet(transportAuthDomains0); restAuthorizers = Collections.unmodifiableSet(restAuthorizers0); transportAuthorizers = Collections.unmodifiableSet(transportAuthorizers0); - + destroyableComponents = Collections.unmodifiableList(destroyableComponents0); - + if(originalDestroyableComponents != null) { destroyDestroyables(originalDestroyableComponents); } - + originalDestroyableComponents = null; - + createAuthFailureListeners(ipAuthFailureListeners0, authBackendFailureListeners0, ipClientBlockRegistries0, authBackendClientBlockRegistries0, destroyableComponents0); - + ipAuthFailureListeners = Collections.unmodifiableList(ipAuthFailureListeners0); ipClientBlockRegistries = Collections.unmodifiableList(ipClientBlockRegistries0); authBackendClientBlockRegistries = Multimaps.unmodifiableMultimap(authBackendClientBlockRegistries0); authBackendFailureListeners = Multimaps.unmodifiableMultimap(authBackendFailureListeners0); } - + private void destroyDestroyables(List destroyableComponents) { for (Destroyable destroyable : destroyableComponents) { try { @@ -346,7 +346,7 @@ private void destroyDestroyables(List destroyableComponents) { } } } - + private T newInstance(final String clazzOrShortcut, String type, final Settings settings, final Path configPath) { String clazz = clazzOrShortcut; @@ -357,7 +357,7 @@ private T newInstance(final String clazzOrShortcut, String type, final Setti return ReflectionHelper.instantiateAAA(clazz, settings, configPath); } - + private String translateShortcutToClassName(final String clazzOrShortcut, final String type) { if (authImplMap.containsKey(clazzOrShortcut + "_" + type)) { @@ -366,17 +366,17 @@ private String translateShortcutToClassName(final String clazzOrShortcut, final return clazzOrShortcut; } } - + private void createAuthFailureListeners(List ipAuthFailureListeners, Multimap authBackendFailureListeners, List> ipClientBlockRegistries, Multimap> authBackendUserClientBlockRegistries, List destroyableComponents0) { for (Entry entry : config.dynamic.auth_failure_listeners.getListeners().entrySet()) { - + Settings entrySettings = Settings.builder() .put(opensearchSettings) .put(Settings.builder().loadFromSource(entry.getValue().asJson(), XContentType.JSON).build()).build(); - + String type = entry.getValue().type; String authenticationBackend = entry.getValue().authentication_backend; diff --git a/src/main/java/org/opensearch/security/securityconf/DynamicConfigModelV7.java b/src/main/java/org/opensearch/security/securityconf/DynamicConfigModelV7.java index c3e3792c5c..0b66d9a306 100644 --- a/src/main/java/org/opensearch/security/securityconf/DynamicConfigModelV7.java +++ b/src/main/java/org/opensearch/security/securityconf/DynamicConfigModelV7.java @@ -62,7 +62,7 @@ import org.opensearch.security.support.ReflectionHelper; public class DynamicConfigModelV7 extends DynamicConfigModel { - + private final ConfigV7 config; private final Settings opensearchSettings; private final Path configPath; @@ -77,7 +77,7 @@ public class DynamicConfigModelV7 extends DynamicConfigModel { private Multimap authBackendFailureListeners; private List> ipClientBlockRegistries; private Multimap> authBackendClientBlockRegistries; - + public DynamicConfigModelV7(ConfigV7 config, Settings opensearchSettings, Path configPath, InternalAuthenticationBackend iab) { super(); this.config = config; @@ -163,27 +163,27 @@ public String getFilteredAliasMode() { public String getHostsResolverMode() { return config.dynamic.hosts_resolver_mode; } - + @Override public boolean isDnfofForEmptyResultsEnabled() { return config.dynamic.do_not_fail_on_forbidden_empty; } - + @Override public List getIpAuthFailureListeners() { return Collections.unmodifiableList(ipAuthFailureListeners); } - + @Override public Multimap getAuthBackendFailureListeners() { return Multimaps.unmodifiableMultimap(authBackendFailureListeners); } - + @Override public List> getIpClientBlockRegistries() { return Collections.unmodifiableList(ipClientBlockRegistries); } - + @Override public Multimap> getAuthBackendClientBlockRegistries() { return Multimaps.unmodifiableMultimap(authBackendClientBlockRegistries); @@ -195,9 +195,9 @@ public Settings getDynamicOnBehalfOfSettings() { .put(Settings.builder().loadFromSource(config.dynamic.on_behalf_of.configAsJson(), XContentType.JSON).build()) .build(); } - + private void buildAAA() { - + final SortedSet restAuthDomains0 = new TreeSet<>(); final Set restAuthorizers0 = new HashSet<>(); final SortedSet transportAuthDomains0 = new TreeSet<>(); @@ -220,7 +220,7 @@ private void buildAAA() { final String authzBackendClazz = ad.getValue().authorization_backend.type; final AuthorizationBackend authorizationBackend; - + if(authzBackendClazz.equals(InternalAuthenticationBackend.class.getName()) //NOSONAR || authzBackendClazz.equals("internal") || authzBackendClazz.equals("intern")) { @@ -235,7 +235,7 @@ private void buildAAA() { .put(Settings.builder().loadFromSource(ad.getValue().authorization_backend.configAsJson(), XContentType.JSON).build()).build() , configPath); } - + if (httpEnabled) { restAuthorizers0.add(authorizationBackend); } @@ -243,7 +243,7 @@ private void buildAAA() { if (transportEnabled) { transportAuthorizers0.add(authorizationBackend); } - + if (authorizationBackend instanceof Destroyable) { destroyableComponents0.add((Destroyable) authorizationBackend); } @@ -281,7 +281,7 @@ private void buildAAA() { String httpAuthenticatorType = ad.getValue().http_authenticator.type; //no default HTTPAuthenticator httpAuthenticator = httpAuthenticatorType==null?null: (HTTPAuthenticator) newInstance(httpAuthenticatorType,"h", Settings.builder().put(opensearchSettings) - //.putProperties(ads.getAsStringMap(DotPath.of("http_authenticator.config")), DynamicConfiguration.checkKeyFunction()).build(), + //.putProperties(ads.getAsStringMap(DotPath.of("http_authenticator.config")), DynamicConfiguration.checkKeyFunction()).build(), .put(Settings.builder().loadFromSource(ad.getValue().http_authenticator.configAsJson(), XContentType.JSON).build()).build() , configPath); @@ -296,15 +296,15 @@ private void buildAAA() { if (transportEnabled) { transportAuthDomains0.add(_ad); } - + if (httpAuthenticator instanceof Destroyable) { destroyableComponents0.add((Destroyable) httpAuthenticator); } - + if (authenticationBackend instanceof Destroyable) { destroyableComponents0.add((Destroyable) authenticationBackend); } - + } catch (final Exception e) { log.error("Unable to initialize auth domain {} due to {}", ad, e.toString(), e); } @@ -313,23 +313,23 @@ private void buildAAA() { } List originalDestroyableComponents = destroyableComponents; - + restAuthDomains = Collections.unmodifiableSortedSet(restAuthDomains0); transportAuthDomains = Collections.unmodifiableSortedSet(transportAuthDomains0); restAuthorizers = Collections.unmodifiableSet(restAuthorizers0); transportAuthorizers = Collections.unmodifiableSet(transportAuthorizers0); - + destroyableComponents = Collections.unmodifiableList(destroyableComponents0); - + if(originalDestroyableComponents != null) { destroyDestroyables(originalDestroyableComponents); } - + originalDestroyableComponents = null; createAuthFailureListeners(ipAuthFailureListeners0, authBackendFailureListeners0, ipClientBlockRegistries0, authBackendClientBlockRegistries0, destroyableComponents0); - + ipAuthFailureListeners = Collections.unmodifiableList(ipAuthFailureListeners0); ipClientBlockRegistries = Collections.unmodifiableList(ipClientBlockRegistries0); authBackendClientBlockRegistries = Multimaps.unmodifiableMultimap(authBackendClientBlockRegistries0); @@ -346,7 +346,7 @@ private void destroyDestroyables(List destroyableComponents) { } } } - + private T newInstance(final String clazzOrShortcut, String type, final Settings settings, final Path configPath) { String clazz = clazzOrShortcut; @@ -357,7 +357,7 @@ private T newInstance(final String clazzOrShortcut, String type, final Setti return ReflectionHelper.instantiateAAA(clazz, settings, configPath); } - + private String translateShortcutToClassName(final String clazzOrShortcut, final String type) { if (authImplMap.containsKey(clazzOrShortcut + "_" + type)) { @@ -366,17 +366,17 @@ private String translateShortcutToClassName(final String clazzOrShortcut, final return clazzOrShortcut; } } - + private void createAuthFailureListeners(List ipAuthFailureListeners, Multimap authBackendFailureListeners, List> ipClientBlockRegistries, Multimap> authBackendUserClientBlockRegistries, List destroyableComponents0) { for (Entry entry : config.dynamic.auth_failure_listeners.getListeners().entrySet()) { - + Settings entrySettings = Settings.builder() .put(opensearchSettings) .put(Settings.builder().loadFromSource(entry.getValue().asJson(), XContentType.JSON).build()).build(); - + String type = entry.getValue().type; String authenticationBackend = entry.getValue().authentication_backend; diff --git a/src/main/java/org/opensearch/security/securityconf/EvaluatedDlsFlsConfig.java b/src/main/java/org/opensearch/security/securityconf/EvaluatedDlsFlsConfig.java index 9100e7dd02..8870cb3aad 100644 --- a/src/main/java/org/opensearch/security/securityconf/EvaluatedDlsFlsConfig.java +++ b/src/main/java/org/opensearch/security/securityconf/EvaluatedDlsFlsConfig.java @@ -87,7 +87,7 @@ public EvaluatedDlsFlsConfig filter(Resolved indices) { return this; } else { Set allIndices = indices.getAllIndices(); - + return new EvaluatedDlsFlsConfig(filter(dlsQueriesByIndex, allIndices), filter(flsByIndex, allIndices), filter(fieldMaskingByIndex, allIndices)); } @@ -108,7 +108,7 @@ private Map> filter(Map> map, Set> result = new HashMap<>(map.size()); - for (Map.Entry> entry : map.entrySet()) { + for (Map.Entry> entry : map.entrySet()) { if (WildcardMatcher.from(entry.getKey(), false).matchAny(allIndices)) { result.put(entry.getKey(), entry.getValue()); } diff --git a/src/main/java/org/opensearch/security/securityconf/Hideable.java b/src/main/java/org/opensearch/security/securityconf/Hideable.java index 9b1df8f157..8744575d64 100644 --- a/src/main/java/org/opensearch/security/securityconf/Hideable.java +++ b/src/main/java/org/opensearch/security/securityconf/Hideable.java @@ -28,7 +28,7 @@ package org.opensearch.security.securityconf; public interface Hideable { - + boolean isHidden(); boolean isReserved(); diff --git a/src/main/java/org/opensearch/security/securityconf/Initializable.java b/src/main/java/org/opensearch/security/securityconf/Initializable.java index fafc717866..ab1a1ebd4a 100644 --- a/src/main/java/org/opensearch/security/securityconf/Initializable.java +++ b/src/main/java/org/opensearch/security/securityconf/Initializable.java @@ -28,7 +28,7 @@ package org.opensearch.security.securityconf; public interface Initializable { - + boolean isInitialized(); } diff --git a/src/main/java/org/opensearch/security/securityconf/InternalUsersModel.java b/src/main/java/org/opensearch/security/securityconf/InternalUsersModel.java index 3ff1554a94..41c3116874 100644 --- a/src/main/java/org/opensearch/security/securityconf/InternalUsersModel.java +++ b/src/main/java/org/opensearch/security/securityconf/InternalUsersModel.java @@ -31,7 +31,7 @@ import java.util.Map; public abstract class InternalUsersModel { - + public abstract boolean exists(String user); public abstract List getBackenRoles(String user); public abstract Map getAttributes(String user); diff --git a/src/main/java/org/opensearch/security/securityconf/Migration.java b/src/main/java/org/opensearch/security/securityconf/Migration.java index 3cb111f11c..ec6a5525b9 100644 --- a/src/main/java/org/opensearch/security/securityconf/Migration.java +++ b/src/main/java/org/opensearch/security/securityconf/Migration.java @@ -55,15 +55,15 @@ public class Migration { - + public static Tuple,SecurityDynamicConfiguration> migrateRoles(SecurityDynamicConfiguration r6cs, SecurityDynamicConfiguration rms6) throws MigrationException { - + final SecurityDynamicConfiguration r7 = SecurityDynamicConfiguration.empty(); r7.setCType(r6cs.getCType()); r7.set_meta(new Meta()); r7.get_meta().setConfig_version(2); r7.get_meta().setType("roles"); - + final SecurityDynamicConfiguration t7 = SecurityDynamicConfiguration.empty(); t7.setCType(CType.TENANTS); t7.set_meta(new Meta()); @@ -71,11 +71,11 @@ public static Tuple,SecurityDynamicConfigur t7.get_meta().setType("tenants"); Set dedupTenants = new HashSet<>(); - + for(final Entry r6e: r6cs.getCEntries().entrySet()) { final String roleName = r6e.getKey(); final RoleV6 r6 = r6e.getValue(); - + if(r6 == null) { RoleV7 noPermRole = new RoleV7(); noPermRole.setDescription("Migrated from v6, was empty"); @@ -84,52 +84,52 @@ public static Tuple,SecurityDynamicConfigur } r7.putCEntry(roleName, new RoleV7(r6)); - + for(Entry tenant: r6.getTenants().entrySet()) { dedupTenants.add(tenant.getKey()); } } - + if(rms6 != null) { for(final Entry r6m: rms6.getCEntries().entrySet()) { final String roleName = r6m.getKey(); //final RoleMappingsV6 r6 = r6m.getValue(); - + if(!r7.exists(roleName)) { //rolemapping but role does not exists RoleV7 noPermRole = new RoleV7(); noPermRole.setDescription("Migrated from v6, was in rolemappings but no role existed"); r7.putCEntry(roleName, noPermRole); } - + } } - + for(String tenantName: dedupTenants) { TenantV7 entry = new TenantV7(); entry.setDescription("Migrated from v6"); t7.putCEntry(tenantName, entry); } - + return new Tuple, SecurityDynamicConfiguration>(r7, t7); - + } - + public static SecurityDynamicConfiguration migrateConfig(SecurityDynamicConfiguration r6cs) throws MigrationException { final SecurityDynamicConfiguration c7 = SecurityDynamicConfiguration.empty(); c7.setCType(r6cs.getCType()); c7.set_meta(new Meta()); c7.get_meta().setConfig_version(2); c7.get_meta().setType("config"); - + if(r6cs.getCEntries().size() != 1) { throw new MigrationException("Unable to migrate config because expected size was 1 but actual size is "+r6cs.getCEntries().size()); } - + if(r6cs.getCEntries().get("opendistro_security") == null) { throw new MigrationException("Unable to migrate config because 'opendistro_security' key not found"); } - + for(final Entry r6c: r6cs.getCEntries().entrySet()) { c7.putCEntry("config", new ConfigV7(r6c.getValue())); } @@ -181,23 +181,23 @@ public static SecurityDynamicConfiguration migrateInternalUsers i7.set_meta(new Meta()); i7.get_meta().setConfig_version(2); i7.get_meta().setType("internalusers"); - + for(final Entry r6i: r6is.getCEntries().entrySet()) { final String username = !Strings.isNullOrEmpty(r6i.getValue().getUsername())?r6i.getValue().getUsername():r6i.getKey(); i7.putCEntry(username, new InternalUserV7(r6i.getValue())); } - + return i7; } - + public static SecurityDynamicConfiguration migrateActionGroups(SecurityDynamicConfiguration r6as) throws MigrationException { - + final SecurityDynamicConfiguration a7 = SecurityDynamicConfiguration.empty(); a7.setCType(r6as.getCType()); a7.set_meta(new Meta()); a7.get_meta().setConfig_version(2); a7.get_meta().setType("actiongroups"); - + if(r6as.getImplementingClass().isAssignableFrom(List.class)) { for(final Entry r6a: r6as.getCEntries().entrySet()) { a7.putCEntry(r6a.getKey(), new ActionGroupsV7(r6a.getKey(), (List) r6a.getValue())); @@ -210,18 +210,18 @@ public static SecurityDynamicConfiguration migrateActionGroups( return a7; } - + public static SecurityDynamicConfiguration migrateRoleMappings(SecurityDynamicConfiguration r6rms) throws MigrationException { final SecurityDynamicConfiguration rms7 = SecurityDynamicConfiguration.empty(); rms7.setCType(r6rms.getCType()); rms7.set_meta(new Meta()); rms7.get_meta().setConfig_version(2); rms7.get_meta().setType("rolesmapping"); - + for(final Entry r6m: r6rms.getCEntries().entrySet()) { rms7.putCEntry(r6m.getKey(), new RoleMappingsV7(r6m.getValue())); } - + return rms7; } diff --git a/src/main/java/org/opensearch/security/securityconf/StaticDefinable.java b/src/main/java/org/opensearch/security/securityconf/StaticDefinable.java index d6ffb106cf..06b92100fa 100644 --- a/src/main/java/org/opensearch/security/securityconf/StaticDefinable.java +++ b/src/main/java/org/opensearch/security/securityconf/StaticDefinable.java @@ -28,7 +28,7 @@ package org.opensearch.security.securityconf; public interface StaticDefinable { - + boolean isStatic(); } diff --git a/src/main/java/org/opensearch/security/securityconf/impl/Meta.java b/src/main/java/org/opensearch/security/securityconf/impl/Meta.java index 42912c1dda..1e9060efa1 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/Meta.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/Meta.java @@ -30,17 +30,17 @@ import com.fasterxml.jackson.annotation.JsonIgnore; public class Meta { - - + + private String type; private int config_version; - + private CType cType; - + public String getType() { return type; } - + public void setType(String type) { this.type = type; cType = CType.fromString(type); @@ -51,7 +51,7 @@ public int getConfig_version() { public void setConfig_version(int config_version) { this.config_version = config_version; } - + @JsonIgnore public CType getCType() { return cType; @@ -61,6 +61,6 @@ public CType getCType() { public String toString() { return "Meta [type=" + type + ", config_version=" + config_version + ", cType=" + cType + "]"; } - - + + } 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 09eeee41e3..c282f439e8 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/SecurityDynamicConfiguration.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/SecurityDynamicConfiguration.java @@ -52,7 +52,7 @@ import org.opensearch.security.securityconf.StaticDefinable; public class SecurityDynamicConfiguration implements ToXContent { - + private static final TypeReference> typeRefMSO = new TypeReference>() {}; @JsonIgnore @@ -61,7 +61,7 @@ public class SecurityDynamicConfiguration implements ToXContent { private long primaryTerm= -1; private CType ctype; private int version = -1; - + public static SecurityDynamicConfiguration empty() { return new SecurityDynamicConfiguration(); } @@ -83,11 +83,11 @@ public static SecurityDynamicConfiguration fromJson(String json, CType ct sdc = DefaultObjectMapper.readValue(json, DefaultObjectMapper.getTypeFactory().constructParametricType(SecurityDynamicConfiguration.class, implementationClass)); } validate(sdc, version, ctype); - + } else { sdc = new SecurityDynamicConfiguration(); } - + sdc.ctype = ctype; sdc.seqNo = seqNo; sdc.primaryTerm = primaryTerm; @@ -95,35 +95,35 @@ public static SecurityDynamicConfiguration fromJson(String json, CType ct return sdc; } - + public static void validate(SecurityDynamicConfiguration sdc, int version, CType ctype) throws IOException { if(version < 2 && sdc.get_meta() != null) { throw new IOException("A version of "+version+" can not have a _meta key for "+ctype); } - + if(version >= 2 && sdc.get_meta() == null) { throw new IOException("A version of "+version+" must have a _meta key for "+ctype); } - + if(version < 2 && ctype == CType.CONFIG && (sdc.getCEntries().size() != 1 || !sdc.getCEntries().keySet().contains("opendistro_security"))) { throw new IOException("A version of "+version+" must have a single toplevel key named 'opendistro_security' for "+ctype); } - + if(version >= 2 && ctype == CType.CONFIG && (sdc.getCEntries().size() != 1 || !sdc.getCEntries().keySet().contains("config"))) { throw new IOException("A version of "+version+" must have a single toplevel key named 'config' for "+ctype); } - + } public static SecurityDynamicConfiguration fromNode(JsonNode json, CType ctype, int version, long seqNo, long primaryTerm) throws IOException { return fromJson(DefaultObjectMapper.writeValueAsString(json, false), ctype, version, seqNo, primaryTerm); } - + //for Jackson private SecurityDynamicConfiguration() { super(); } - + private Meta _meta; public Meta get_meta() { @@ -134,17 +134,17 @@ public void set_meta(Meta _meta) { this._meta = _meta; } - + @JsonAnySetter void setCEntries(String key, T value) { putCEntry(key, value); } - + @JsonAnyGetter public Map getCEntries() { return centries; } - + @JsonIgnore public void removeHidden() { for(Entry entry: new HashMap(centries).entrySet()) { @@ -153,7 +153,7 @@ public void removeHidden() { } } } - + @JsonIgnore public void removeStatic() { for(Entry entry: new HashMap(centries).entrySet()) { @@ -162,38 +162,38 @@ public void removeStatic() { } } } - + @JsonIgnore public void clearHashes() { for(Entry entry: centries.entrySet()) { if(entry.getValue() instanceof Hashed) { - ((Hashed) entry.getValue()).clearHash(); + ((Hashed) entry.getValue()).clearHash(); } } } - + public void removeOthers(String key) { T tmp = this.centries.get(key); this.centries.clear(); this.centries.put(key, tmp); } - + @JsonIgnore public T putCEntry(String key, T value) { return centries.put(key, value); } - + @JsonIgnore public void putCObject(String key, Object value) { centries.put(key, (T) value); } - + @JsonIgnore public T getCEntry(String key) { return centries.get(key); } - + @JsonIgnore public boolean exists(String key) { return centries.containsKey(key); @@ -216,7 +216,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws final boolean omitDefaults = params != null && params.paramAsBoolean("omit_defaults", false); return builder.map(DefaultObjectMapper.readValue(DefaultObjectMapper.writeValueAsString(this, omitDefaults), typeRefMSO)); } - + @Override @JsonIgnore public boolean isFragment() { @@ -237,7 +237,7 @@ public long getPrimaryTerm() { public CType getCType() { return ctype; } - + @JsonIgnore public void setCType(CType ctype) { this.ctype = ctype; @@ -247,7 +247,7 @@ public void setCType(CType ctype) { public int getVersion() { return version; } - + @JsonIgnore public Class getImplementingClass() { return ctype==null?null:ctype.getImplementationClass().get(getVersion()); @@ -265,7 +265,7 @@ public SecurityDynamicConfiguration deepClone() { @JsonIgnore public void remove(String key) { centries.remove(key); - + } @SuppressWarnings({ "rawtypes", "unchecked" }) @@ -273,19 +273,19 @@ public boolean add(SecurityDynamicConfiguration other) { if(other.ctype == null || !other.ctype.equals(this.ctype)) { return false; } - + if(other.getImplementingClass() == null || !other.getImplementingClass().equals(this.getImplementingClass())) { return false; } - + if(other.version != this.version) { return false; } - + this.centries.putAll(other.centries); return true; } - + @JsonIgnore @SuppressWarnings({ "rawtypes" }) public boolean containsAny(SecurityDynamicConfiguration other) { diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v6/ActionGroupsV6.java b/src/main/java/org/opensearch/security/securityconf/impl/v6/ActionGroupsV6.java index b64becf0a4..99bef31505 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v6/ActionGroupsV6.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v6/ActionGroupsV6.java @@ -35,7 +35,7 @@ public class ActionGroupsV6 implements Hideable { - + private boolean readonly; private boolean hidden; private List permissions = Collections.emptyList(); @@ -43,7 +43,7 @@ public class ActionGroupsV6 implements Hideable { public ActionGroupsV6() { super(); } - + @JsonIgnore public boolean isReserved() { return readonly; @@ -70,6 +70,6 @@ public void setPermissions(List permissions) { public String toString() { return "ActionGroups [readonly=" + readonly + ", hidden=" + hidden + ", permissions=" + permissions + "]"; } - - + + } diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v6/ConfigV6.java b/src/main/java/org/opensearch/security/securityconf/impl/v6/ConfigV6.java index 301cb68219..2f3c941cfe 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v6/ConfigV6.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v6/ConfigV6.java @@ -47,8 +47,8 @@ public class ConfigV6 { public Dynamic dynamic; - - + + @Override public String toString() { return "Config [dynamic=" + dynamic + "]"; @@ -73,7 +73,7 @@ public static class Dynamic { public String transport_userrname_attribute; public boolean do_not_fail_on_forbidden_empty; public OnBehalfOf on_behalf_of = new OnBehalfOf() { - + }; @Override @@ -100,9 +100,9 @@ public String toString() { return "Kibana [multitenancy_enabled=" + multitenancy_enabled + ", server_username=" + server_username + ", opendistro_role=" + opendistro_role + ", index=" + index + ", do_not_fail_on_forbidden=" + do_not_fail_on_forbidden + "]"; } - - - + + + } public static class Http { @@ -112,8 +112,8 @@ public static class Http { public String toString() { return "Http [anonymous_auth_enabled=" + anonymous_auth_enabled + ", xff=" + xff + "]"; } - - + + } public static class AuthFailureListeners { @@ -130,7 +130,7 @@ public Map getListeners() { return listeners; } - + } public static class AuthFailureListener { @@ -141,11 +141,11 @@ public static class AuthFailureListener { public int block_expiry_seconds = 60 * 10; public int max_blocked_clients = 100_000; public int max_tracked_clients = 100_000; - + public AuthFailureListener() { super(); } - + @JsonIgnore public String asJson() { try { @@ -175,12 +175,12 @@ public String toString() { return "Xff [enabled=" + enabled + ", internalProxies=" + internalProxies + ", remoteIpHeader=" + remoteIpHeader + ", proxiesHeader=" + proxiesHeader + ", trustedProxies=" + trustedProxies + "]"; } - - + + } public static class Authc { - + @JsonIgnore private final Map domains = new HashMap<>(); @@ -198,8 +198,8 @@ public Map getDomains() { public String toString() { return "Authc [domains=" + domains + "]"; } - - + + } public static class AuthcDomain { @@ -217,8 +217,8 @@ public String toString() { return "AuthcDomain [http_enabled=" + http_enabled + ", transport_enabled=" + transport_enabled + ", enabled=" + enabled + ", order=" + order + ", http_authenticator=" + http_authenticator + ", authentication_backend=" + authentication_backend + "]"; } - - + + } public static class HttpAuthenticator { @@ -226,7 +226,7 @@ public static class HttpAuthenticator { public boolean challenge = true; public String type; public Map config = Collections.emptyMap(); - + @JsonIgnore public String configAsJson() { try { @@ -240,14 +240,14 @@ public String configAsJson() { public String toString() { return "HttpAuthenticator [challenge=" + challenge + ", type=" + type + ", config=" + config + "]"; } - - + + } public static class AuthzBackend { public String type = "noop"; public Map config = Collections.emptyMap(); - + @JsonIgnore public String configAsJson() { try { @@ -261,14 +261,14 @@ public String configAsJson() { public String toString() { return "AuthzBackend [type=" + type + ", config=" + config + "]"; } - - + + } public static class AuthcBackend { public String type = InternalAuthenticationBackend.class.getName(); public Map config = Collections.emptyMap(); - + @JsonIgnore public String configAsJson() { try { @@ -282,8 +282,8 @@ public String configAsJson() { public String toString() { return "AuthcBackend [type=" + type + ", config=" + config + "]"; } - - + + } public static class Authz { @@ -304,8 +304,8 @@ public Map getDomains() { public String toString() { return "Authz [domains=" + domains + "]"; } - - + + } public static class AuthzDomain { @@ -320,8 +320,8 @@ public static class AuthzDomain { public String toString() { return "AuthzDomain [http_enabled=" + http_enabled + ", transport_enabled=" + transport_enabled + ", enabled=" + enabled + ", authorization_backend=" + authorization_backend + "]"; } - - + + } public static class OnBehalfOf { diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v6/InternalUserV6.java b/src/main/java/org/opensearch/security/securityconf/impl/v6/InternalUserV6.java index 827e573a3a..f650101b64 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v6/InternalUserV6.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v6/InternalUserV6.java @@ -37,7 +37,7 @@ import org.opensearch.security.securityconf.Hideable; public class InternalUserV6 implements Hideable, Hashed { - + private String hash; private boolean readonly; private boolean hidden; @@ -45,7 +45,7 @@ public class InternalUserV6 implements Hideable, Hashed { private Map attributes = Collections.emptyMap(); private String username; - + public InternalUserV6(String hash, boolean readonly, boolean hidden, List roles, Map attributes, String username) { super(); @@ -69,7 +69,7 @@ public InternalUserV6() { super(); //default constructor } - + public String getHash() { return hash; } @@ -80,7 +80,7 @@ public void setHash(String hash) { public void setPassword(String password){ // no-op setter. Due to a bug in 6.x, empty "password" may be saved to the internalusers doc. Ignore it. } - + public boolean isReadonly() { return readonly; } @@ -111,7 +111,7 @@ public String toString() { return "SgInternalUser [hash=" + hash + ", readonly=" + readonly + ", hidden=" + hidden + ", roles=" + roles + ", attributes=" + attributes + "]"; } - + @JsonIgnore public boolean isReserved() { return readonly; @@ -122,7 +122,7 @@ public boolean isReserved() { public void clearHash() { hash = ""; } - - + + } diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v6/RoleMappingsV6.java b/src/main/java/org/opensearch/security/securityconf/impl/v6/RoleMappingsV6.java index 1c28f99113..bb10fd8812 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v6/RoleMappingsV6.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v6/RoleMappingsV6.java @@ -82,7 +82,7 @@ public String toString() { return "RoleMappings [readonly=" + readonly + ", hidden=" + hidden + ", backendroles=" + backendroles + ", hosts=" + getHosts() + ", users=" + getUsers() + ", andBackendroles=" + andBackendroles + "]"; } - + @JsonIgnore public boolean isReserved() { return readonly; diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v6/RoleV6.java b/src/main/java/org/opensearch/security/securityconf/impl/v6/RoleV6.java index f0377f797b..e8254d4530 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v6/RoleV6.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v6/RoleV6.java @@ -60,13 +60,13 @@ void setTypes0(String key, List value) { public Map> getTypes() { return types; } - + private String _dls_; private List _fls_; private List _masked_fields_; - - + + public String get_dls_() { return _dls_; } @@ -84,7 +84,7 @@ public String toString() { return "Index [types=" + types + ", _dls_=" + _dls_ + ", _fls_=" + _fls_ + ", _masked_fields_=" + _masked_fields_ + "]"; } - + } @@ -132,7 +132,7 @@ public void setIndices(Map indices) { public String toString() { return "Role [readonly=" + readonly + ", hidden=" + hidden + ", cluster=" + cluster + ", tenants=" + tenants + ", indices=" + indices + "]"; } - + @JsonIgnore public boolean isReserved() { return readonly; diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v7/ActionGroupsV7.java b/src/main/java/org/opensearch/security/securityconf/impl/v7/ActionGroupsV7.java index d728dfb8cf..f38978eec2 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v7/ActionGroupsV7.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v7/ActionGroupsV7.java @@ -38,8 +38,8 @@ public class ActionGroupsV7 implements Hideable, StaticDefinable { - - + + private boolean reserved; private boolean hidden; @JsonProperty(value = "static") @@ -47,7 +47,7 @@ public class ActionGroupsV7 implements Hideable, StaticDefinable { private List allowed_actions = Collections.emptyList(); private String type; private String description; - + public ActionGroupsV7() { super(); } @@ -76,8 +76,8 @@ public String getDescription() { public void setDescription(String description) { this.description = description; } - - + + public boolean isReserved() { return reserved; } @@ -109,8 +109,8 @@ public String toString() { return "ActionGroupsV7 [reserved=" + reserved + ", hidden=" + hidden + ", _static=" + _static + ", allowed_actions=" + allowed_actions + ", type=" + type + ", description=" + description + "]"; } - - - - + + + + } 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 9a39979909..c413c1355d 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 @@ -54,7 +54,7 @@ public ConfigV7() { public ConfigV7(ConfigV6 c6) { dynamic = new Dynamic(); - + dynamic.filtered_alias_mode = c6.dynamic.filtered_alias_mode; dynamic.disable_rest_auth = c6.dynamic.disable_rest_auth; dynamic.disable_intertransport_auth = c6.dynamic.disable_intertransport_auth; @@ -65,40 +65,40 @@ public ConfigV7(ConfigV6 c6) { dynamic.multi_rolespan_enabled = c6.dynamic.multi_rolespan_enabled; dynamic.hosts_resolver_mode = c6.dynamic.hosts_resolver_mode; dynamic.transport_userrname_attribute = c6.dynamic.transport_userrname_attribute; - + dynamic.kibana = new Kibana(); - + dynamic.kibana.index = c6.dynamic.kibana.index; dynamic.kibana.multitenancy_enabled = c6.dynamic.kibana.multitenancy_enabled; dynamic.kibana.private_tenant_enabled = true; dynamic.kibana.default_tenant = ""; dynamic.kibana.server_username = c6.dynamic.kibana.server_username; - + dynamic.http = new Http(); - + dynamic.http.anonymous_auth_enabled = c6.dynamic.http.anonymous_auth_enabled; - + dynamic.http.xff = new Xff(); - + dynamic.http.xff.enabled = c6.dynamic.http.xff.enabled; dynamic.http.xff.internalProxies = c6.dynamic.http.xff.internalProxies; dynamic.http.xff.remoteIpHeader = c6.dynamic.http.xff.remoteIpHeader; - + dynamic.authc = new Authc(); - + dynamic.authc.domains.putAll(c6.dynamic.authc.getDomains().entrySet().stream().collect(Collectors.toMap( - entry -> entry.getKey(), + entry -> entry.getKey(), entry -> new AuthcDomain(entry.getValue())))); - + dynamic.authz = new Authz(); - + dynamic.authz.domains.putAll(c6.dynamic.authz.getDomains().entrySet().stream().collect(Collectors.toMap( - entry -> entry.getKey(), + entry -> entry.getKey(), entry -> new AuthzDomain(entry.getValue())))); - + dynamic.auth_failure_listeners = new AuthFailureListeners(); dynamic.auth_failure_listeners.listeners.putAll(c6.dynamic.auth_failure_listeners.getListeners().entrySet().stream().collect(Collectors.toMap( - entry -> entry.getKey(), + entry -> entry.getKey(), entry -> new AuthFailureListener(entry.getValue())))); } @@ -127,7 +127,7 @@ public static class Dynamic { public String transport_userrname_attribute; public boolean do_not_fail_on_forbidden_empty; public OnBehalfOf on_behalf_of = new OnBehalfOf(); - + @Override public String toString() { return "Dynamic [filtered_alias_mode=" + filtered_alias_mode + ", kibana=" + kibana + ", http=" + http + ", authc=" + authc + ", authz=" @@ -153,9 +153,9 @@ public String toString() { server_username + ", opendistro_role=" + opendistro_role + ", index=" + index + "]"; } - - - + + + } public static class Http { @@ -165,8 +165,8 @@ public static class Http { public String toString() { return "Http [anonymous_auth_enabled=" + anonymous_auth_enabled + ", xff=" + xff + "]"; } - - + + } public static class AuthFailureListeners { @@ -183,7 +183,7 @@ public Map getListeners() { return listeners; } - + } public static class AuthFailureListener { @@ -194,9 +194,9 @@ public static class AuthFailureListener { public int block_expiry_seconds = 60 * 10; public int max_blocked_clients = 100_000; public int max_tracked_clients = 100_000; - - - + + + public AuthFailureListener() { super(); } @@ -211,7 +211,7 @@ public AuthFailureListener(ConfigV6.AuthFailureListener v6) { this.max_blocked_clients = v6.max_blocked_clients; this.max_tracked_clients = v6.max_tracked_clients; } - + @JsonIgnore public String asJson() { try { @@ -237,12 +237,12 @@ public static class Xff { public String toString() { return "Xff [enabled=" + enabled + ", internalProxies=" + internalProxies + ", remoteIpHeader=" + remoteIpHeader+"]"; } - - + + } public static class Authc { - + @JsonIgnore private final Map domains = new HashMap<>(); @@ -260,9 +260,9 @@ public Map getDomains() { public String toString() { return "Authc [domains=" + domains + "]"; } - - - + + + } public static class AuthcDomain { @@ -276,11 +276,11 @@ public static class AuthcDomain { public HttpAuthenticator http_authenticator = new HttpAuthenticator(); public AuthcBackend authentication_backend = new AuthcBackend(); public String description; - + public AuthcDomain() { super(); } - + public AuthcDomain(ConfigV6.AuthcDomain v6) { super(); http_enabled = v6.http_enabled && v6.enabled; @@ -301,8 +301,8 @@ public String toString() { + ", http_authenticator=" + http_authenticator + ", authentication_backend=" + authentication_backend + ", description=" + description + "]"; } - - + + } public static class HttpAuthenticator { @@ -310,7 +310,7 @@ public static class HttpAuthenticator { public boolean challenge = true; public String type; public Map config = Collections.emptyMap(); - + public HttpAuthenticator() { super(); } @@ -337,16 +337,16 @@ public String configAsJson() { public String toString() { return "HttpAuthenticator [challenge=" + challenge + ", type=" + type + ", config=" + config + "]"; } - - + + } public static class AuthzBackend { public String type = "noop"; public Map config = Collections.emptyMap(); - - - + + + public AuthzBackend() { super(); } @@ -375,16 +375,16 @@ public String configAsJson() { public String toString() { return "AuthzBackend [type=" + type + ", config=" + config + "]"; } - - + + } public static class AuthcBackend { public String type = InternalAuthenticationBackend.class.getName(); public Map config = Collections.emptyMap(); - - - + + + public AuthcBackend() { super(); } @@ -413,8 +413,8 @@ public String configAsJson() { public String toString() { return "AuthcBackend [type=" + type + ", config=" + config + "]"; } - - + + } public static class Authz { @@ -435,8 +435,8 @@ public Map getDomains() { public String toString() { return "Authz [domains=" + domains + "]"; } - - + + } public static class AuthzDomain { @@ -446,11 +446,11 @@ public static class AuthzDomain { public boolean transport_enabled = true; public AuthzBackend authorization_backend = new AuthzBackend(); public String description; - + public AuthzDomain() { super(); } - + public AuthzDomain(ConfigV6.AuthzDomain v6) { http_enabled = v6.http_enabled && v6.enabled; transport_enabled = v6.transport_enabled && v6.enabled; diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v7/InternalUserV7.java b/src/main/java/org/opensearch/security/securityconf/impl/v7/InternalUserV7.java index b697a9485b..a7aed05cc1 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v7/InternalUserV7.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v7/InternalUserV7.java @@ -40,7 +40,7 @@ import org.opensearch.security.securityconf.impl.v6.InternalUserV6; public class InternalUserV7 implements Hideable, Hashed, StaticDefinable { - + private String hash; private boolean reserved; private boolean hidden; @@ -79,7 +79,7 @@ public InternalUserV7() { super(); //default constructor } - + public InternalUserV7(InternalUserV6 u6) { hash = u6.getHash(); reserved = u6.isReserved(); @@ -95,15 +95,15 @@ public String getHash() { public void setHash(String hash) { this.hash = hash; } - - + + public boolean isHidden() { return hidden; } public void setHidden(boolean hidden) { this.hidden = hidden; } - + public List getBackend_roles() { return backend_roles; @@ -171,7 +171,7 @@ public boolean isReserved() { public void setReserved(boolean reserved) { this.reserved = reserved; } - + @JsonProperty(value = "static") public boolean isStatic() { return _static; @@ -180,6 +180,6 @@ public boolean isStatic() { public void setStatic(boolean _static) { this._static = _static; } - - + + } diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v7/RoleMappingsV7.java b/src/main/java/org/opensearch/security/securityconf/impl/v7/RoleMappingsV7.java index c97ad2f92f..364d524497 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v7/RoleMappingsV7.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v7/RoleMappingsV7.java @@ -124,6 +124,6 @@ public String toString() { } - + } diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v7/RoleV7.java b/src/main/java/org/opensearch/security/securityconf/impl/v7/RoleV7.java index 262f8ed21d..dce4652d63 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v7/RoleV7.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v7/RoleV7.java @@ -51,11 +51,11 @@ public class RoleV7 implements Hideable, StaticDefinable { private List cluster_permissions = Collections.emptyList(); private List index_permissions = Collections.emptyList(); private List tenant_permissions = Collections.emptyList(); - + public RoleV7() { - + } - + public RoleV7(RoleV6 roleV6) { this.reserved = roleV6.isReserved(); this.hidden = roleV6.isHidden(); @@ -63,24 +63,24 @@ public RoleV7(RoleV6 roleV6) { this.cluster_permissions = roleV6.getCluster(); index_permissions = new ArrayList<>(); tenant_permissions = new ArrayList<>(); - + for(Entry v6i: roleV6.getIndices().entrySet()) { index_permissions.add(new Index(v6i.getKey(), v6i.getValue())); } - + //rw tenants List rwTenants = roleV6.getTenants().entrySet().stream().filter(e-> "rw".equalsIgnoreCase(e.getValue())).map(e->e.getKey()).collect(Collectors.toList()); - + if(rwTenants != null && !rwTenants.isEmpty()) { Tenant t = new Tenant(); t.setAllowed_actions(Collections.singletonList("kibana_all_write")); t.setTenant_patterns(rwTenants); tenant_permissions.add(t); } - - + + List roTenants = roleV6.getTenants().entrySet().stream().filter(e-> "ro".equalsIgnoreCase(e.getValue())).map(e->e.getKey()).collect(Collectors.toList()); - + if(roTenants != null && !roTenants.isEmpty()) { Tenant t = new Tenant(); t.setAllowed_actions(Collections.singletonList("kibana_all_read")); @@ -97,25 +97,25 @@ public static class Index { private List fls = Collections.emptyList(); private List masked_fields = Collections.emptyList(); private List allowed_actions = Collections.emptyList(); - + public Index(String pattern, RoleV6.Index v6Index) { super(); index_patterns = Collections.singletonList(pattern); dls = v6Index.get_dls_(); fls = v6Index.get_fls_(); masked_fields = v6Index.get_masked_fields_(); - Set tmpActions = new HashSet<>(); + Set tmpActions = new HashSet<>(); for(Entry> type: v6Index.getTypes().entrySet()) { tmpActions.addAll(type.getValue()); } allowed_actions = new ArrayList<>(tmpActions); } - - + + public Index() { super(); } - + public List getIndex_patterns() { return index_patterns; } @@ -152,27 +152,27 @@ public String toString() { + ", allowed_actions=" + allowed_actions + "]"; } } - - + + public static class Tenant { private List tenant_patterns = Collections.emptyList(); private List allowed_actions = Collections.emptyList(); - + /*public Index(String pattern, RoleV6.Index v6Index) { super(); index_patterns = Collections.singletonList(pattern); dls = v6Index.get_dls_(); fls = v6Index.get_fls_(); masked_fields = v6Index.get_masked_fields_(); - Set tmpActions = new HashSet<>(); + Set tmpActions = new HashSet<>(); for(Entry> type: v6Index.getTypes().entrySet()) { tmpActions.addAll(type.getValue()); } allowed_actions = new ArrayList<>(tmpActions); }*/ - - + + public Tenant() { super(); } @@ -197,10 +197,10 @@ public void setAllowed_actions(List allowed_actions) { public String toString() { return "Tenant [tenant_patterns=" + tenant_patterns + ", allowed_actions=" + allowed_actions + "]"; } - - + + } - + public boolean isHidden() { return hidden; @@ -226,7 +226,7 @@ public void setCluster_permissions(List cluster_permissions) { this.cluster_permissions = cluster_permissions; } - + public List getIndex_permissions() { return index_permissions; @@ -267,9 +267,9 @@ public String toString() { + ", cluster_permissions=" + cluster_permissions + ", index_permissions=" + index_permissions + ", tenant_permissions=" + tenant_permissions + "]"; } - - - + + + } diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v7/TenantV7.java b/src/main/java/org/opensearch/security/securityconf/impl/v7/TenantV7.java index 210fada185..1c55d0cd95 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v7/TenantV7.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v7/TenantV7.java @@ -39,7 +39,7 @@ public class TenantV7 implements Hideable, StaticDefinable { @JsonProperty(value = "static") private boolean _static; private String description; - + public boolean isHidden() { return hidden; } @@ -58,8 +58,8 @@ public boolean isReserved() { public void setReserved(boolean reserved) { this.reserved = reserved; } - - + + @JsonProperty(value = "static") public boolean isStatic() { return _static; @@ -72,6 +72,6 @@ public void setStatic(boolean _static) { public String toString() { return "TenantV7 [reserved=" + reserved + ", hidden=" + hidden + ", _static=" + _static + ", description=" + description + "]"; } - - + + } diff --git a/src/main/java/org/opensearch/security/ssl/ExternalSecurityKeyStore.java b/src/main/java/org/opensearch/security/ssl/ExternalSecurityKeyStore.java index 3fbbab69d6..87713a1d3a 100644 --- a/src/main/java/org/opensearch/security/ssl/ExternalSecurityKeyStore.java +++ b/src/main/java/org/opensearch/security/ssl/ExternalSecurityKeyStore.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl; @@ -45,13 +45,13 @@ public ExternalSecurityKeyStore(final Settings settings) { this.settings = Objects.requireNonNull(settings); final String externalContextId = settings .get(SSLConfigConstants.SECURITY_SSL_CLIENT_EXTERNAL_CONTEXT_ID, null); - + if(externalContextId == null || externalContextId.length() == 0) { throw new OpenSearchException("no external ssl context id was set"); } - + externalSslContext = contextMap.get(externalContextId); - + if(externalSslContext == null) { throw new OpenSearchException("no external ssl context for id "+externalContextId); } @@ -70,7 +70,7 @@ public SSLEngine createServerTransportSSLEngine() throws SSLException { @Override public SSLEngine createClientTransportSSLEngine(final String peerHost, final int peerPort) throws SSLException { if (peerHost != null) { - final SSLEngine engine = externalSslContext.createSSLEngine(peerHost, peerPort); + final SSLEngine engine = externalSslContext.createSSLEngine(peerHost, peerPort); final SSLParameters sslParams = new SSLParameters(); sslParams.setEndpointIdentificationAlgorithm("HTTPS"); engine.setSSLParameters(sslParams); @@ -135,31 +135,31 @@ public String getSubjectAlternativeNames(X509Certificate cert) { public static void registerExternalSslContext(String id, SSLContext externalSsslContext) { contextMap.put(Objects.requireNonNull(id), Objects.requireNonNull(externalSsslContext)); } - + public static boolean hasExternalSslContext(Settings settings) { - + final String externalContextId = settings .get(SSLConfigConstants.SECURITY_SSL_CLIENT_EXTERNAL_CONTEXT_ID, null); - + if(externalContextId == null || externalContextId.length() == 0) { return false; } - + return contextMap.containsKey(externalContextId); } - + public static boolean hasExternalSslContext(String id) { return contextMap.containsKey(id); } - + public static void removeExternalSslContext(String id) { contextMap.remove(id); } - + public static void removeAllExternalSslContexts() { contextMap.clear(); } - + private String[] evalSecure(String[] engineEnabled, String[] secure) { List tmp = new ArrayList<>(Arrays.asList(engineEnabled)); tmp.retainAll(Arrays.asList(secure)); diff --git a/src/main/java/org/opensearch/security/ssl/OpenSearchSecuritySSLPlugin.java b/src/main/java/org/opensearch/security/ssl/OpenSearchSecuritySSLPlugin.java index 755a2b188f..ab96c7bb3e 100644 --- a/src/main/java/org/opensearch/security/ssl/OpenSearchSecuritySSLPlugin.java +++ b/src/main/java/org/opensearch/security/ssl/OpenSearchSecuritySSLPlugin.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl; @@ -122,7 +122,7 @@ protected OpenSearchSecuritySSLPlugin(final Settings settings, final Path config this.sks = null; this.configPath = null; SSLConfig = new SSLConfig(false, false); - + AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { @@ -130,36 +130,36 @@ public Object run() { return null; } }); - - + + return; } SSLConfig = new SSLConfig(settings); this.configPath = configPath; - + if(this.configPath != null) { log.info("OpenSearch Config path is {}", this.configPath.toAbsolutePath()); } else { log.info("OpenSearch Config path is not set"); } - + final boolean allowClientInitiatedRenegotiation = settings.getAsBoolean(SSLConfigConstants.SECURITY_SSL_ALLOW_CLIENT_INITIATED_RENEGOTIATION, false); final boolean rejectClientInitiatedRenegotiation = Boolean.parseBoolean(System.getProperty(SSLConfigConstants.JDK_TLS_REJECT_CLIENT_INITIATED_RENEGOTIATION)); - + if(allowClientInitiatedRenegotiation && !rejectClientInitiatedRenegotiation) { final String renegoMsg = "Client side initiated TLS renegotiation enabled. This can open a vulnerablity for DoS attacks through client side initiated TLS renegotiation."; log.warn(renegoMsg); System.out.println(renegoMsg); System.err.println(renegoMsg); - } else { + } else { if(!rejectClientInitiatedRenegotiation) { - + final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new SpecialPermission()); } - + AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { @@ -198,7 +198,7 @@ public Object run() { NonValidatingObjectMapper.inject(injectableValues); client = !"node".equals(this.settings.get(OpenSearchSecuritySSLPlugin.CLIENT_TYPE)); - + httpSSLEnabled = settings.getAsBoolean(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_DEFAULT); transportSSLEnabled = settings.getAsBoolean(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, @@ -211,7 +211,7 @@ public Object run() { System.out.println("SSL not activated for http and/or transport."); System.err.println("SSL not activated for http and/or transport."); } - + if(ExternalSecurityKeyStore.hasExternalSslContext(settings)) { this.sks = new ExternalSecurityKeyStore(settings); } else { @@ -223,9 +223,9 @@ public Object run() { public Map> getHttpTransports(Settings settings, ThreadPool threadPool, BigArrays bigArrays, PageCacheRecycler pageCacheRecycler, CircuitBreakerService circuitBreakerService, NamedXContentRegistry xContentRegistry, NetworkService networkService, Dispatcher dispatcher, ClusterSettings clusterSettings) { - + if (!client && httpSSLEnabled) { - + final ValidatingDispatcher validatingDispatcher = new ValidatingDispatcher(threadPool.getThreadContext(), dispatcher, settings, configPath, NOOP_SSL_EXCEPTION_HANDLER); final SecuritySSLNettyHttpServerTransport sgsnht = new SecuritySSLNettyHttpServerTransport(settings, networkService, bigArrays, threadPool, @@ -233,7 +233,7 @@ public Map> getHttpTransports(Settings set sharedGroupFactory); return Collections.singletonMap("org.opensearch.security.ssl.http.netty.SecuritySSLNettyHttpServerTransport", () -> sgsnht); - + } return Collections.emptyMap(); @@ -243,35 +243,35 @@ public Map> getHttpTransports(Settings set public List getRestHandlers(Settings settings, RestController restController, ClusterSettings clusterSettings, IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter, IndexNameExpressionResolver indexNameExpressionResolver, Supplier nodesInCluster) { - + final List handlers = new ArrayList(1); - + if (!client) { handlers.add(new SecuritySSLInfoAction(settings, configPath, restController, sks, Objects.requireNonNull(principalExtractor))); } - + return handlers; } - - - + + + @Override public List getTransportInterceptors(NamedWriteableRegistry namedWriteableRegistry, ThreadContext threadContext) { List interceptors = new ArrayList(1); - + if(transportSSLEnabled && !client) { interceptors.add(new SecuritySSLTransportInterceptor(settings, null, null, SSLConfig, NOOP_SSL_EXCEPTION_HANDLER)); } - + return interceptors; } - - + + @Override public Map> getTransports(Settings settings, ThreadPool threadPool, PageCacheRecycler pageCacheRecycler, CircuitBreakerService circuitBreakerService, NamedWriteableRegistry namedWriteableRegistry, NetworkService networkService) { - + Map> transports = new HashMap>(); if (transportSSLEnabled) { transports.put("org.opensearch.security.ssl.http.netty.SecuritySSLNettyTransport", @@ -290,11 +290,11 @@ public Collection createComponents(Client localClient, ClusterService cl IndexNameExpressionResolver indexNameExpressionResolver, Supplier repositoriesServiceSupplier) { final List components = new ArrayList<>(1); - + if(client) { return components; } - + final String principalExtractorClass = settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PRINCIPAL_EXTRACTOR_CLASS, null); if(principalExtractorClass == null) { @@ -309,9 +309,9 @@ public Collection createComponents(Client localClient, ClusterService cl throw new OpenSearchException(e); } } - + components.add(principalExtractor); - + return components; } @@ -389,24 +389,24 @@ public List> getSettings() { @Override public Settings additionalSettings() { final Settings.Builder builder = Settings.builder(); - + if(!client && httpSSLEnabled) { - + if(settings.get("http.compression") == null) { builder.put("http.compression", false); log.info("Disabled https compression by default to mitigate BREACH attacks. You can enable it by setting 'http.compression: true' in opensearch.yml"); } - + builder.put(NetworkModule.HTTP_TYPE_KEY, "org.opensearch.security.ssl.http.netty.SecuritySSLNettyHttpServerTransport"); } - + if (transportSSLEnabled) { builder.put(NetworkModule.TRANSPORT_TYPE_KEY, "org.opensearch.security.ssl.http.netty.SecuritySSLNettyTransport"); } - + return builder.build(); } - + @Override public List getSettingsFilter() { List settingsFilter = new ArrayList<>(); diff --git a/src/main/java/org/opensearch/security/ssl/SecurityKeyStore.java b/src/main/java/org/opensearch/security/ssl/SecurityKeyStore.java index a14e8e7df1..107c48f0f5 100644 --- a/src/main/java/org/opensearch/security/ssl/SecurityKeyStore.java +++ b/src/main/java/org/opensearch/security/ssl/SecurityKeyStore.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl; @@ -33,7 +33,7 @@ public interface SecurityKeyStore { public String getHTTPProviderName(); public String getTransportServerProviderName(); public String getTransportClientProviderName(); - public String getSubjectAlternativeNames(X509Certificate cert); + public String getSubjectAlternativeNames(X509Certificate cert); public void initHttpSSLConfig(); public void initTransportSSLConfig(); diff --git a/src/main/java/org/opensearch/security/ssl/SslExceptionHandler.java b/src/main/java/org/opensearch/security/ssl/SslExceptionHandler.java index 531711dc54..427debfdba 100644 --- a/src/main/java/org/opensearch/security/ssl/SslExceptionHandler.java +++ b/src/main/java/org/opensearch/security/ssl/SslExceptionHandler.java @@ -1,10 +1,10 @@ /* * Copyright 2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl; @@ -22,15 +22,15 @@ import org.opensearch.transport.TransportRequest; public interface SslExceptionHandler { - + default void logError(Throwable t, RestRequest request, int type) { //no-op } - + default void logError(Throwable t, boolean isRest) { //no-op } - + default void logError(Throwable t, final TransportRequest request, String action, Task task, int type) { //no-op } diff --git a/src/main/java/org/opensearch/security/ssl/http/netty/SecuritySSLNettyHttpServerTransport.java b/src/main/java/org/opensearch/security/ssl/http/netty/SecuritySSLNettyHttpServerTransport.java index 7c53b6268a..b6012f036e 100644 --- a/src/main/java/org/opensearch/security/ssl/http/netty/SecuritySSLNettyHttpServerTransport.java +++ b/src/main/java/org/opensearch/security/ssl/http/netty/SecuritySSLNettyHttpServerTransport.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl.http.netty; @@ -45,7 +45,7 @@ public class SecuritySSLNettyHttpServerTransport extends Netty4HttpServerTranspo private static final Logger logger = LogManager.getLogger(SecuritySSLNettyHttpServerTransport.class); private final SecurityKeyStore sks; private final SslExceptionHandler errorHandler; - + public SecuritySSLNettyHttpServerTransport(final Settings settings, final NetworkService networkService, final BigArrays bigArrays, final ThreadPool threadPool, final SecurityKeyStore sks, final NamedXContentRegistry namedXContentRegistry, final ValidatingDispatcher dispatcher, final SslExceptionHandler errorHandler, ClusterSettings clusterSettings, SharedGroupFactory sharedGroupFactory) { @@ -94,7 +94,7 @@ protected void configurePipeline(ChannelHandlerContext ctx, String protocol) thr throw new IllegalStateException("Unknown application protocol: " + protocol); } } - + @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { super.exceptionCaught(ctx, cause); @@ -119,7 +119,7 @@ protected void initChannel(Channel ch) throws Exception { final SslHandler sslHandler = new SslHandler(SecuritySSLNettyHttpServerTransport.this.sks.createHTTPSSLEngine()); ch.pipeline().addFirst("ssl_http", sslHandler); } - + @Override protected void configurePipeline(Channel ch) { ch.pipeline().addLast(new Http2OrHttpHandler()); diff --git a/src/main/java/org/opensearch/security/ssl/http/netty/ValidatingDispatcher.java b/src/main/java/org/opensearch/security/ssl/http/netty/ValidatingDispatcher.java index 66976a930b..32a1f73568 100644 --- a/src/main/java/org/opensearch/security/ssl/http/netty/ValidatingDispatcher.java +++ b/src/main/java/org/opensearch/security/ssl/http/netty/ValidatingDispatcher.java @@ -1,10 +1,10 @@ /* * Copyright 2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl.http.netty; @@ -47,7 +47,7 @@ public class ValidatingDispatcher implements Dispatcher { private final Settings settings; private final Path configPath; - public ValidatingDispatcher(final ThreadContext threadContext, final Dispatcher originalDispatcher, + public ValidatingDispatcher(final ThreadContext threadContext, final Dispatcher originalDispatcher, final Settings settings, final Path configPath, final SslExceptionHandler errorHandler) { super(); this.threadContext = threadContext; @@ -68,15 +68,15 @@ public void dispatchBadRequest(RestChannel channel, ThreadContext threadContext, checkRequest(channel.request(), channel); originalDispatcher.dispatchBadRequest(channel, threadContext, cause); } - + protected void checkRequest(final RestRequest request, final RestChannel channel) { - + if(SSLRequestHelper.containsBadHeader(threadContext, "_opendistro_security_ssl_")) { final OpenSearchException exception = ExceptionUtils.createBadHeaderException(); errorHandler.logError(exception, request, 1); throw exception; } - + try { if(SSLRequestHelper.getSSLInfo(settings, configPath, request, null) == null) { logger.error("Not an SSL request"); diff --git a/src/main/java/org/opensearch/security/ssl/rest/SecuritySSLInfoAction.java b/src/main/java/org/opensearch/security/ssl/rest/SecuritySSLInfoAction.java index f5050d3242..5b1fae01e5 100644 --- a/src/main/java/org/opensearch/security/ssl/rest/SecuritySSLInfoAction.java +++ b/src/main/java/org/opensearch/security/ssl/rest/SecuritySSLInfoAction.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl.rest; @@ -68,11 +68,11 @@ public SecuritySSLInfoAction(final Settings settings, final Path configPath, fin public List routes() { return routes; } - + @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { return new RestChannelConsumer() { - + final Boolean showDn = request.paramAsBoolean("show_dn", Boolean.FALSE); @Override @@ -81,7 +81,7 @@ public void accept(RestChannel channel) throws Exception { BytesRestResponse response = null; try { - + SSLInfo sslInfo = SSLRequestHelper.getSSLInfo(settings, configPath, request, principalExtractor); X509Certificate[] certs = sslInfo == null?null:sslInfo.getX509Certs(); X509Certificate[] localCerts = sslInfo == null?null:sslInfo.getLocalCertificates(); @@ -123,7 +123,7 @@ public void accept(RestChannel channel) throws Exception { builder.close(); } } - + channel.sendResponse(response); } }; diff --git a/src/main/java/org/opensearch/security/ssl/transport/DefaultPrincipalExtractor.java b/src/main/java/org/opensearch/security/ssl/transport/DefaultPrincipalExtractor.java index d717df2da6..001059eefa 100644 --- a/src/main/java/org/opensearch/security/ssl/transport/DefaultPrincipalExtractor.java +++ b/src/main/java/org/opensearch/security/ssl/transport/DefaultPrincipalExtractor.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl.transport; @@ -38,7 +38,7 @@ public class DefaultPrincipalExtractor implements PrincipalExtractor { protected final Logger log = LogManager.getLogger(this.getClass()); - + @Override @SuppressWarnings("removal") public String extractPrincipal(final X509Certificate x509Certificate, final Type type) { @@ -54,7 +54,7 @@ public String extractPrincipal(final X509Certificate x509Certificate, final Type String dnString = AccessController.doPrivileged(new PrivilegedAction() { @Override - public String run() { + public String run() { final X500Principal principal = x509Certificate.getSubjectX500Principal(); return principal.toString(); } @@ -69,12 +69,12 @@ public String run() { } catch (InvalidNameException e) { log.error("Unable to parse: {}",dnString, e); } - - + + if(log.isTraceEnabled()) { log.trace("principal: {}", dnString); } - + return dnString; } diff --git a/src/main/java/org/opensearch/security/ssl/transport/PrincipalExtractor.java b/src/main/java/org/opensearch/security/ssl/transport/PrincipalExtractor.java index 06213af642..cccca06e0c 100644 --- a/src/main/java/org/opensearch/security/ssl/transport/PrincipalExtractor.java +++ b/src/main/java/org/opensearch/security/ssl/transport/PrincipalExtractor.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl.transport; @@ -20,7 +20,7 @@ import java.security.cert.X509Certificate; public interface PrincipalExtractor { - + public enum Type { HTTP, TRANSPORT @@ -28,13 +28,13 @@ public enum Type { /** * Extract the principal name - * + * * Please note that this method gets called for principal extraction of other nodes * as well as transport clients. It's up to the implementer to distinguish between them * and handle them appropriately. - * + * * Implementations must be public classes with a default public default constructor. - * + * * @param x509Certificate The first X509 certificate in the peer certificate chain * This can be null, in this case the method must also return null. * @return The principal as string. This may be null in case where x509Certificate is null diff --git a/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLNettyTransport.java b/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLNettyTransport.java index 58da4cb55e..5a38909f81 100644 --- a/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLNettyTransport.java +++ b/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLNettyTransport.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ /* @@ -101,7 +101,7 @@ public void onException(TcpChannel channel, Exception e) { protected ChannelHandler getServerChannelInitializer(String name) { return new SSLServerChannelInitializer(name); } - + @Override protected ChannelHandler getClientChannelInitializer(DiscoveryNode node) { return new SSLClientChannelInitializer(node); @@ -127,7 +127,7 @@ protected void initChannel(Channel ch) throws Exception { ch.pipeline().addFirst("ssl_server", sslHandler); } } - + @Override public final void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { if (cause instanceof DecoderException && cause != null) { @@ -147,7 +147,7 @@ protected static class ClientSSLHandler extends ChannelOutboundHandlerAdapter { private final boolean hostnameVerificationEnabled; private final boolean hostnameVerificationResovleHostName; private final SslExceptionHandler errorHandler; - + private ClientSSLHandler(final SecurityKeyStore sks, final boolean hostnameVerificationEnabled, final boolean hostnameVerificationResovleHostName, final SslExceptionHandler errorHandler) { @@ -156,14 +156,14 @@ private ClientSSLHandler(final SecurityKeyStore sks, final boolean hostnameVerif this.hostnameVerificationResovleHostName = hostnameVerificationResovleHostName; this.errorHandler = errorHandler; } - + @Override public final void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { if (cause instanceof DecoderException && cause != null) { cause = cause.getCause(); } - + errorHandler.logError(cause, false); logger.error("Exception during establishing a SSL connection: " + cause, cause); @@ -186,7 +186,7 @@ public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, Sock if(log.isDebugEnabled()) { log.debug("Hostname of peer is {} ({}/{}) with hostnameVerificationResovleHostName: {}", hostname, inetSocketAddress.getHostName(), inetSocketAddress.getHostString(), hostnameVerificationResovleHostName); } - + engine = sks.createClientTransportSSLEngine(hostname, inetSocketAddress.getPort()); } else { engine = sks.createClientTransportSSLEngine(null, -1); @@ -239,7 +239,7 @@ protected void initChannel(Channel ch) throws Exception { logger.debug("Connection to {} needs to be non ssl", node.getHostName()); } } - + @Override public final void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { if (cause instanceof DecoderException && cause != null) { @@ -249,7 +249,7 @@ public final void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) th errorHandler.logError(cause, false); logger.error("Exception during establishing a SSL connection: " + cause, cause); - + super.exceptionCaught(ctx, cause); } } 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 925f5cf0e9..53877df0f0 100644 --- a/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLRequestHandler.java +++ b/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLRequestHandler.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl.transport; @@ -47,7 +47,7 @@ public class SecuritySSLRequestHandler implements TransportRequestHandler { - + private final String action; private final TransportRequestHandler actualHandler; private final ThreadPool threadPool; @@ -68,7 +68,7 @@ public SecuritySSLRequestHandler(String action, TransportRequestHandler actua this.SSLConfig = SSLConfig; this.errorHandler = errorHandler; } - + protected ThreadContext getThreadContext() { if(threadPool == null) { return null; @@ -80,7 +80,7 @@ protected ThreadContext getThreadContext() { @Override public final void messageReceived(T request, TransportChannel channel, Task task) throws Exception { ThreadContext threadContext = getThreadContext() ; - + if(SSLRequestHelper.containsBadHeader(threadContext, "_opendistro_security_ssl_")) { final Exception exception = ExceptionUtils.createBadHeaderException(); channel.sendResponse(exception); @@ -91,12 +91,12 @@ public final void messageReceived(T request, TransportChannel channel, Task task if (!channelType.equals("direct") && !channelType.equals("transport")) { channel = getInnerChannel(channel); } - + if (!"transport".equals(channel.getChannelType())) { //netty4 messageReceivedDecorate(request, actualHandler, channel, task); return; } - + try { Netty4TcpChannel nettyChannel = null; @@ -111,7 +111,7 @@ public final void messageReceived(T request, TransportChannel channel, Task task } else { throw new Exception("Invalid channel of type "+channel.getClass()+ " ("+channel.getChannelType()+")"); } - + final SslHandler sslhandler = (SslHandler) nettyChannel.getNettyChannel().pipeline().get("ssl_server"); if (sslhandler == null) { @@ -131,11 +131,11 @@ public final void messageReceived(T request, TransportChannel channel, Task task final Certificate[] peerCerts = sslhandler.engine().getSession().getPeerCertificates(); final Certificate[] localCerts = sslhandler.engine().getSession().getLocalCertificates(); - - if (peerCerts != null - && peerCerts.length > 0 - && peerCerts[0] instanceof X509Certificate - && localCerts != null && localCerts.length > 0 + + if (peerCerts != null + && peerCerts.length > 0 + && peerCerts[0] instanceof X509Certificate + && localCerts != null && localCerts.length > 0 && localCerts[0] instanceof X509Certificate) { final X509Certificate[] x509PeerCerts = Arrays.copyOf(peerCerts, peerCerts.length, X509Certificate[].class); final X509Certificate[] x509LocalCerts = Arrays.copyOf(localCerts, localCerts.length, X509Certificate[].class); @@ -168,7 +168,7 @@ public final void messageReceived(T request, TransportChannel channel, Task task errorHandler.logError(e, request, action, task, 0); throw e; } - + } protected TransportChannel getInnerChannel(TransportChannel transportChannel) throws Exception { @@ -182,12 +182,12 @@ protected TransportChannel getInnerChannel(TransportChannel transportChannel) th throw new RuntimeException("Unknown channel type " + transportChannel.getChannelType() + " does not implement getInnerChannel method."); } } - + protected void addAdditionalContextValues(final String action, final TransportRequest request, final X509Certificate[] localCerts, final X509Certificate[] peerCerts, final String principal) throws Exception { // no-op } - + protected void messageReceivedDecorate(final T request, final TransportRequestHandler actualHandler, final TransportChannel transportChannel, Task task) throws Exception { actualHandler.messageReceived(request, transportChannel, task); } diff --git a/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLTransportInterceptor.java b/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLTransportInterceptor.java index 165662d429..aa83265125 100644 --- a/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLTransportInterceptor.java +++ b/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLTransportInterceptor.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl.transport; @@ -28,7 +28,7 @@ import org.opensearch.transport.TransportRequestHandler; public final class SecuritySSLTransportInterceptor implements TransportInterceptor { - + protected final Logger log = LogManager.getLogger(this.getClass()); protected final ThreadPool threadPool; protected final PrincipalExtractor principalExtractor; @@ -49,6 +49,6 @@ public TransportRequestHandler interceptHandler( TransportRequestHandler actualHandler) { return new SecuritySSLRequestHandler(action, actualHandler, threadPool, principalExtractor, SSLConfig, errorHandler); } - - + + } diff --git a/src/main/java/org/opensearch/security/ssl/util/CertificateValidator.java b/src/main/java/org/opensearch/security/ssl/util/CertificateValidator.java index 0a12ffc2b5..b0a975b618 100644 --- a/src/main/java/org/opensearch/security/ssl/util/CertificateValidator.java +++ b/src/main/java/org/opensearch/security/ssl/util/CertificateValidator.java @@ -59,14 +59,14 @@ * Allows specifying Certificate Revocation List (CRL), as well as enabling * CRL Distribution Points Protocol (CRLDP) certificate extension support, * and also enabling On-Line Certificate Status Protocol (OCSP) support. - * + * * IMPORTANT: at least one of the above mechanisms *MUST* be configured and * operational, otherwise certificate validation *WILL FAIL* unconditionally. */ // CS-ENFORCE-SINGLE public class CertificateValidator { - + boolean isPreferCrl() { return preferCrl; } @@ -95,16 +95,16 @@ void setCheckOnlyEndEntities(boolean checkOnlyEndEntities) { private boolean _enableOCSP = false; /** Location of OCSP Responder */ private String _ocspResponderURL; - + private boolean preferCrl = false; private boolean checkOnlyEndEntities = true; private Date date = null; //current date - + /** - * creates an instance of the certificate validator + * creates an instance of the certificate validator * - * @param trustStore the truststore to use - * @param crls the Certificate Revocation List to use + * @param trustStore the truststore to use + * @param crls the Certificate Revocation List to use */ public CertificateValidator(KeyStore trustStore, Collection crls) { @@ -112,18 +112,18 @@ public CertificateValidator(KeyStore trustStore, Collection crls) { throw new InvalidParameterException("TrustStore must be specified for CertificateValidator."); } - + _trustStore = trustStore; _crls = crls; } - + public CertificateValidator(X509Certificate[] trustedCert, Collection crls) { if (trustedCert == null || trustedCert.length == 0) { throw new InvalidParameterException("trustedCert must be specified for CertificateValidator."); } - + _trustedCert = trustedCert; _crls = crls; } @@ -137,7 +137,7 @@ public void validate(Certificate[] certChain) throws CertificateException { if (item == null) continue; - + if (!(item instanceof X509Certificate)) { throw new IllegalStateException("Invalid certificate type in chain"); @@ -149,34 +149,34 @@ public void validate(Certificate[] certChain) throws CertificateException if (certList.isEmpty()) { throw new IllegalStateException("Invalid certificate chain"); - + } - + X509CertSelector certSelect = new X509CertSelector(); certSelect.setCertificate(certList.get(0)); - + CertPathBuilder certPathBuilder = CertPathBuilder.getInstance("PKIX"); PKIXRevocationChecker revocationChecker = (PKIXRevocationChecker) certPathBuilder.getRevocationChecker(); Set opts = new HashSet<>(); - + if(preferCrl) { opts.add(PKIXRevocationChecker.Option.PREFER_CRLS); } - + //opts.add(PKIXRevocationChecker.Option.SOFT_FAIL); - + //opts.add(PKIXRevocationChecker.Option.NO_FALLBACK); - + if(checkOnlyEndEntities) { opts.add(PKIXRevocationChecker.Option.ONLY_END_ENTITY); } - + revocationChecker.setOptions(opts); // Configure certification path builder parameters PKIXBuilderParameters pbParams = null; - + if(_trustStore != null) { pbParams = new PKIXBuilderParameters(_trustStore, certSelect); } else { @@ -189,25 +189,25 @@ public void validate(Certificate[] certChain) throws CertificateException pbParams = new PKIXBuilderParameters(trustAnchors, certSelect); } - + pbParams.addCertPathChecker(revocationChecker); - + pbParams.setDate(date); - + pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList))); - + // Set maximum certification path length pbParams.setMaxPathLength(_maxCertPathLength); - + // Enable revocation checking pbParams.setRevocationEnabled(true); - + // Set static Certificate Revocation List if (_crls != null && !_crls.isEmpty()) { pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(_crls))); } - + // Enable On-Line Certificate Status Protocol (OCSP) support if (_enableOCSP) { @@ -218,10 +218,10 @@ public void validate(Certificate[] certChain) throws CertificateException { System.setProperty("com.sun.security.enableCRLDP","true"); } - + // Build certification path - CertPathBuilderResult buildResult = CertPathBuilder.getInstance("PKIX").build(pbParams); - + CertPathBuilderResult buildResult = CertPathBuilder.getInstance("PKIX").build(pbParams); + // Validate certification path CertPathValidator.getInstance("PKIX").validate(buildResult.getCertPath(),pbParams); } @@ -255,9 +255,9 @@ public void setMaxCertPathLength(int maxCertPathLength) { _maxCertPathLength = maxCertPathLength; } - + /* ------------------------------------------------------------ */ - /** + /** * @return true if CRL Distribution Points support is enabled */ public boolean isEnableCRLDP() @@ -275,7 +275,7 @@ public void setEnableCRLDP(boolean enableCRLDP) } /* ------------------------------------------------------------ */ - /** + /** * @return true if On-Line Certificate Status Protocol support is enabled */ public boolean isEnableOCSP() @@ -293,7 +293,7 @@ public void setEnableOCSP(boolean enableOCSP) } /* ------------------------------------------------------------ */ - /** + /** * @return Location of the OCSP Responder */ public String getOcspResponderURL() diff --git a/src/main/java/org/opensearch/security/ssl/util/ExceptionUtils.java b/src/main/java/org/opensearch/security/ssl/util/ExceptionUtils.java index f06c4d9808..e2af22844f 100644 --- a/src/main/java/org/opensearch/security/ssl/util/ExceptionUtils.java +++ b/src/main/java/org/opensearch/security/ssl/util/ExceptionUtils.java @@ -1,10 +1,10 @@ /* * Copyright 2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl.util; @@ -20,30 +20,30 @@ import org.opensearch.OpenSearchException; public class ExceptionUtils { - + public static Throwable getRootCause(final Throwable e) { - + if(e == null) { return null; } - + final Throwable cause = e.getCause(); if(cause == null) { return e; } return getRootCause(cause); } - + public static Throwable findMsg(final Throwable e, String msg) { - + if(e == null) { return null; } - + if(e.getMessage() != null && e.getMessage().contains(msg)) { return e; } - + final Throwable cause = e.getCause(); if(cause == null) { return null; diff --git a/src/main/java/org/opensearch/security/ssl/util/SSLCertificateHelper.java b/src/main/java/org/opensearch/security/ssl/util/SSLCertificateHelper.java index ff36cc40a8..42b44a3817 100644 --- a/src/main/java/org/opensearch/security/ssl/util/SSLCertificateHelper.java +++ b/src/main/java/org/opensearch/security/ssl/util/SSLCertificateHelper.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl.util; @@ -40,20 +40,20 @@ public class SSLCertificateHelper { private static final Logger log = LogManager.getLogger(SSLCertificateHelper.class); private static boolean stripRootFromChain = true; //TODO check - + public static X509Certificate[] exportRootCertificates(final KeyStore ks, final String alias) throws KeyStoreException { logKeyStore(ks); - + final List trustedCerts = new ArrayList(); - + if (Strings.isNullOrEmpty(alias)) { - + if(log.isDebugEnabled()) { log.debug("No alias given, will trust all of the certificates in the store"); } - + final List aliases = toList(ks.aliases()); - + for (final String _alias : aliases) { if (ks.isCertificateEntry(_alias)) { @@ -79,12 +79,12 @@ public static X509Certificate[] exportRootCertificates(final KeyStore ks, final } return trustedCerts.toArray(new X509Certificate[0]); - } - + } + public static X509Certificate[] exportServerCertChain(final KeyStore ks, String alias) throws KeyStoreException { logKeyStore(ks); final List aliases = toList(ks.aliases()); - + if (Strings.isNullOrEmpty(alias)) { if(aliases.isEmpty()) { log.error("Keystore does not contain any aliases"); @@ -92,7 +92,7 @@ public static X509Certificate[] exportServerCertChain(final KeyStore ks, String alias = aliases.get(0); log.info("No alias given, use the first one: {}", alias); } - } + } final Certificate[] certs = ks.getCertificateChain(alias); if (certs != null && certs.length > 0) { @@ -103,7 +103,7 @@ public static X509Certificate[] exportServerCertChain(final KeyStore ks, String if (lastCertificate.getBasicConstraints() > -1 && lastCertificate.getSubjectX500Principal().equals(lastCertificate.getIssuerX500Principal())) { log.warn("Certificate chain for alias {} contains a root certificate", alias); - + if(stripRootFromChain ) { x509Certs = Arrays.copyOf(certs, certs.length-1, X509Certificate[].class); } @@ -143,7 +143,7 @@ public static PrivateKey exportDecryptedKey(final KeyStore ks, final String alia return null; } - + private static void logKeyStore(final KeyStore ks) { try { final List aliases = toList(ks.aliases()); @@ -175,14 +175,14 @@ private static void logKeyStore(final KeyStore ks) { log.error("Error logging keystore due to "+e, e); } } - + private static List toList(final Enumeration enumeration) { final List aliases = new ArrayList<>(); while (enumeration.hasMoreElements()) { aliases.add(enumeration.nextElement()); } - + return Collections.unmodifiableList(aliases); } } diff --git a/src/main/java/org/opensearch/security/ssl/util/SSLConfigConstants.java b/src/main/java/org/opensearch/security/ssl/util/SSLConfigConstants.java index 65eaec238a..63b2ae5502 100644 --- a/src/main/java/org/opensearch/security/ssl/util/SSLConfigConstants.java +++ b/src/main/java/org/opensearch/security/ssl/util/SSLConfigConstants.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl.util; @@ -88,15 +88,15 @@ public final class SSLConfigConstants { public static final String SECURITY_SSL_ALLOW_CLIENT_INITIATED_RENEGOTIATION = "plugins.security.ssl.allow_client_initiated_renegotiation"; public static final String DEFAULT_STORE_PASSWORD = "changeit"; //#16 - + public static final String JDK_TLS_REJECT_CLIENT_INITIATED_RENEGOTIATION = "jdk.tls.rejectClientInitiatedRenegotiation"; - + private static final String[] _SECURE_SSL_PROTOCOLS = {"TLSv1.3", "TLSv1.2", "TLSv1.1"}; - + public static final String[] getSecureSSLProtocols(Settings settings, boolean http) { List configuredProtocols = null; - + if(settings != null) { if(http) { configuredProtocols = settings.getAsList(SECURITY_SSL_HTTP_ENABLED_PROTOCOLS, Collections.emptyList()); @@ -104,26 +104,26 @@ public static final String[] getSecureSSLProtocols(Settings settings, boolean ht configuredProtocols = settings.getAsList(SECURITY_SSL_TRANSPORT_ENABLED_PROTOCOLS, Collections.emptyList()); } } - + if(configuredProtocols != null && configuredProtocols.size() > 0) { return configuredProtocols.toArray(new String[0]); } - + return _SECURE_SSL_PROTOCOLS.clone(); } - + // @formatter:off - private static final String[] _SECURE_SSL_CIPHERS = + private static final String[] _SECURE_SSL_CIPHERS = { //TLS__WITH_ - + //Example (including unsafe ones) //Protocol: TLS, SSL //Key Exchange RSA, Diffie-Hellman, ECDH, SRP, PSK //Authentication RSA, DSA, ECDSA //Bulk Ciphers RC4, 3DES, AES //Message Authentication HMAC-SHA256, HMAC-SHA1, HMAC-MD5 - + //thats what chrome 48 supports (https://cc.dcsec.uni-hannover.de/) //(c0,2b)ECDHE-ECDSA-AES128-GCM-SHA256128 BitKey exchange: ECDH, encryption: AES, MAC: SHA256. @@ -141,7 +141,7 @@ public static final String[] getSecureSSLProtocols(Settings settings, boolean ht //(00,35)RSA-AES256-SHA256 BitKey exchange: RSA, encryption: AES, MAC: SHA1. //(00,2f)RSA-AES128-SHA128 BitKey exchange: RSA, encryption: AES, MAC: SHA1. //(00,0a)RSA-3DES-EDE-SHA168 BitKey exchange: RSA, encryption: 3DES, MAC: SHA1. - + //thats what firefox 42 supports (https://cc.dcsec.uni-hannover.de/) //(c0,2b) ECDHE-ECDSA-AES128-GCM-SHA256 //(c0,2f) ECDHE-RSA-AES128-GCM-SHA256 @@ -176,18 +176,18 @@ public static final String[] getSecureSSLProtocols(Settings settings, boolean ht "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", - + //TLS 1.3 "TLS_AES_128_GCM_SHA256", "TLS_AES_256_GCM_SHA384", "TLS_CHACHA20_POLY1305_SHA256", //Open SSL >= 1.1.1 and Java >= 12 - + //TLS 1.2 CHACHA20 POLY1305 supported by Java >= 12 and //OpenSSL >= 1.1.0 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", - + //IBM "SSL_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "SSL_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", @@ -211,14 +211,14 @@ public static final String[] getSecureSSLProtocols(Settings settings, boolean ht "SSL_DHE_RSA_WITH_AES_256_CBC_SHA256", "SSL_DHE_DSS_WITH_AES_256_CBC_SHA", "SSL_DHE_RSA_WITH_AES_256_CBC_SHA" - + //some others //"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", //"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", - //"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", - //"TLS_DHE_RSA_WITH_AES_256_CBC_SHA", + //"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + //"TLS_DHE_RSA_WITH_AES_256_CBC_SHA", //"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", - //"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + //"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", //"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", //"TLS_DHE_RSA_WITH_AES_128_CBC_SHA", //"TLS_RSA_WITH_AES_128_CBC_SHA256", @@ -227,11 +227,11 @@ public static final String[] getSecureSSLProtocols(Settings settings, boolean ht //"TLS_RSA_WITH_AES_256_CBC_SHA", }; // @formatter:on - + public static final List getSecureSSLCiphers(Settings settings, boolean http) { - + List configuredCiphers = null; - + if(settings != null) { if(http) { configuredCiphers = settings.getAsList(SECURITY_SSL_HTTP_ENABLED_CIPHERS, Collections.emptyList()); @@ -239,14 +239,14 @@ public static final List getSecureSSLCiphers(Settings settings, boolean configuredCiphers = settings.getAsList(SECURITY_SSL_TRANSPORT_ENABLED_CIPHERS, Collections.emptyList()); } } - + if(configuredCiphers != null && configuredCiphers.size() > 0) { return configuredCiphers; } return Collections.unmodifiableList(Arrays.asList(_SECURE_SSL_CIPHERS)); } - + private SSLConfigConstants() { } diff --git a/src/main/java/org/opensearch/security/ssl/util/SSLRequestHelper.java b/src/main/java/org/opensearch/security/ssl/util/SSLRequestHelper.java index 87452f8a9c..42aad19a09 100644 --- a/src/main/java/org/opensearch/security/ssl/util/SSLRequestHelper.java +++ b/src/main/java/org/opensearch/security/ssl/util/SSLRequestHelper.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl.util; @@ -55,7 +55,7 @@ public class SSLRequestHelper { private static final Logger log = LogManager.getLogger(SSLRequestHelper.class); - + public static class SSLInfo { private final X509Certificate[] x509Certs; private final X509Certificate[] localCertificates; @@ -79,7 +79,7 @@ public SSLInfo(final X509Certificate[] x509Certs, final String principal, final public X509Certificate[] getX509Certs() { return x509Certs == null ? null : x509Certs.clone(); } - + public X509Certificate[] getLocalCertificates() { return localCertificates == null ? null : localCertificates.clone(); } @@ -106,7 +106,7 @@ public String toString() { @SuppressWarnings("removal") public static SSLInfo getSSLInfo(final Settings settings, final Path configPath, final RestRequest request, PrincipalExtractor principalExtractor) throws SSLPeerUnverifiedException { - + if(request == null || request.getHttpChannel() == null || !(request.getHttpChannel() instanceof Netty4HttpChannel)) { return null; } @@ -138,7 +138,7 @@ public static SSLInfo getSSLInfo(final Settings settings, final Path configPath, if (certs != null && certs.length > 0 && certs[0] instanceof X509Certificate) { x509Certs = Arrays.copyOf(certs, certs.length, X509Certificate[].class); final X509Certificate[] x509CertsF = x509Certs; - + final SecurityManager sm = System.getSecurityManager(); if (sm != null) { @@ -147,7 +147,7 @@ public static SSLInfo getSSLInfo(final Settings settings, final Path configPath, validationFailure = AccessController.doPrivileged(new PrivilegedAction() { @Override - public Boolean run() { + public Boolean run() { return !validate(x509CertsF, settings, configPath); } }); @@ -171,7 +171,7 @@ public Boolean run() { Certificate[] localCerts = session.getLocalCertificates(); return new SSLInfo(x509Certs, principal, protocol, cipher, localCerts==null?null:Arrays.copyOf(localCerts, localCerts.length, X509Certificate[].class)); } - + public static boolean containsBadHeader(final ThreadContext context, String prefix) { if (context != null) { for (final Entry header : context.getHeaders().entrySet()) { @@ -180,27 +180,27 @@ public static boolean containsBadHeader(final ThreadContext context, String pref } } } - + return false; } - + private static boolean validate(X509Certificate[] x509Certs, final Settings settings, final Path configPath) { - + final boolean validateCrl = settings.getAsBoolean(SSLConfigConstants.SECURITY_SSL_HTTP_CRL_VALIDATE, false); final boolean isTraceEnabled = log.isTraceEnabled(); if (isTraceEnabled) { log.trace("validateCrl: {}", validateCrl); } - + if(!validateCrl) { return true; } - + final Environment env = new Environment(settings, configPath); - + try { - + Collection crls = null; final String crlFile = settings.get(SSLConfigConstants.SSECURITY_SSL_HTTP_CRL_FILE); @@ -209,7 +209,7 @@ private static boolean validate(X509Certificate[] x509Certs, final Settings sett try(FileInputStream crlin = new FileInputStream(crl)) { crls = CertificateFactory.getInstance("X.509").generateCRLs(crlin); } - + if (isTraceEnabled) { log.trace("crls from file: {}", crls.size()); } @@ -218,15 +218,15 @@ private static boolean validate(X509Certificate[] x509Certs, final Settings sett log.trace("no crl file configured"); } } - + final String truststore = settings.get(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH); CertificateValidator validator = null; - + if(truststore != null) { final String truststoreType = settings.get(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_TYPE, "JKS"); final String truststorePassword = SECURITY_SSL_HTTP_TRUSTSTORE_PASSWORD.getSetting(settings); //final String truststoreAlias = settings.get(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_ALIAS, null); - + final KeyStore ts = KeyStore.getInstance(truststoreType); try(FileInputStream fin = new FileInputStream(new File(env.configDir().resolve(truststore).toAbsolutePath().toString()))) { ts.load(fin, (truststorePassword == null || truststorePassword.length() == 0) ?null:truststorePassword.toCharArray()); @@ -237,9 +237,9 @@ private static boolean validate(X509Certificate[] x509Certs, final Settings sett try(FileInputStream trin = new FileInputStream(trustedCas)) { Collection cert = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); validator = new CertificateValidator(cert.toArray(new X509Certificate[0]), crls); - } + } } - + validator.setEnableCRLDP(!settings.getAsBoolean(SSLConfigConstants.SECURITY_SSL_HTTP_CRL_DISABLE_CRLDP, false)); validator.setEnableOCSP(!settings.getAsBoolean(SSLConfigConstants.SECURITY_SSL_HTTP_CRL_DISABLE_OCSP, false)); validator.setCheckOnlyEndEntities(settings.getAsBoolean(SSLConfigConstants.SECURITY_SSL_HTTP_CRL_CHECK_ONLY_END_ENTITIES, true)); @@ -250,13 +250,13 @@ private static boolean validate(X509Certificate[] x509Certs, final Settings sett } validator.setDate(dateTimestamp==null?null:new Date(dateTimestamp.longValue())); validator.validate(x509Certs); - + return true; - + } catch (Exception e) { log.warn("Unable to validate CRL: ", ExceptionUtils.getRootCause(e)); } - + return false; } } diff --git a/src/main/java/org/opensearch/security/ssl/util/Utils.java b/src/main/java/org/opensearch/security/ssl/util/Utils.java index 2035c4fb1e..2a6fcd2550 100644 --- a/src/main/java/org/opensearch/security/ssl/util/Utils.java +++ b/src/main/java/org/opensearch/security/ssl/util/Utils.java @@ -1,10 +1,10 @@ /* * Copyright 2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl.util; @@ -23,18 +23,18 @@ public static T coalesce(T first, T... more) { if (first != null) { return first; } - + if(more == null || more.length == 0) { return null; } - + for (int i = 0; i < more.length; i++) { T t = more[i]; if(t != null) { return t; } } - + return null; } diff --git a/src/main/java/org/opensearch/security/support/ConfigConstants.java b/src/main/java/org/opensearch/security/support/ConfigConstants.java index 83281c9d0b..f5c64bccd3 100644 --- a/src/main/java/org/opensearch/security/support/ConfigConstants.java +++ b/src/main/java/org/opensearch/security/support/ConfigConstants.java @@ -49,7 +49,7 @@ public class ConfigConstants { 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"; @@ -57,7 +57,7 @@ public class ConfigConstants { 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"; @@ -65,7 +65,7 @@ public class ConfigConstants { 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"; @@ -76,7 +76,7 @@ public class ConfigConstants { 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"; /** @@ -118,7 +118,7 @@ public class ConfigConstants { 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 = "plugins.security.enable_snapshot_restore_privilege"; @@ -141,7 +141,7 @@ public class ConfigConstants { 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_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"; @@ -162,14 +162,14 @@ public class ConfigConstants { 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."; // 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"; @@ -188,22 +188,22 @@ public class ConfigConstants { 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 + // 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 = "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_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"; diff --git a/src/main/java/org/opensearch/security/support/HTTPHelper.java b/src/main/java/org/opensearch/security/support/HTTPHelper.java index e7554f120d..5e9fc78f8c 100644 --- a/src/main/java/org/opensearch/security/support/HTTPHelper.java +++ b/src/main/java/org/opensearch/security/support/HTTPHelper.java @@ -55,7 +55,7 @@ public static AuthCredentials extractCredentials(String authorizationHeader, Log // username:pass:word //blank password // username: - + final int firstColonIndex = decodedBasicHeader.indexOf(':'); String username = null; @@ -63,7 +63,7 @@ public static AuthCredentials extractCredentials(String authorizationHeader, Log if (firstColonIndex > 0) { username = decodedBasicHeader.substring(0, firstColonIndex); - + if(decodedBasicHeader.length() - 1 != firstColonIndex) { password = decodedBasicHeader.substring(firstColonIndex + 1); } else { @@ -83,20 +83,20 @@ public static AuthCredentials extractCredentials(String authorizationHeader, Log return null; } } - + public static boolean containsBadHeader(final RestRequest request) { - + final Map> headers; - + if (request != null && ( headers = request.getHeaders()) != null) { for (final String key: headers.keySet()) { - if ( key != null + if ( key != null && key.trim().toLowerCase().startsWith(ConfigConstants.OPENDISTRO_SECURITY_CONFIG_PREFIX.toLowerCase())) { return true; } } } - + return false; } } diff --git a/src/main/java/org/opensearch/security/support/HeaderHelper.java b/src/main/java/org/opensearch/security/support/HeaderHelper.java index 1a7484a781..af8da305d4 100644 --- a/src/main/java/org/opensearch/security/support/HeaderHelper.java +++ b/src/main/java/org/opensearch/security/support/HeaderHelper.java @@ -39,7 +39,7 @@ public static boolean isInterClusterRequest(final ThreadContext context) { } public static boolean isDirectRequest(final ThreadContext context) { - + return "direct".equals(context.getTransient(ConfigConstants.OPENDISTRO_SECURITY_CHANNEL_TYPE)) || context.getTransient(ConfigConstants.OPENDISTRO_SECURITY_CHANNEL_TYPE) == null; } @@ -49,7 +49,7 @@ public static boolean isExtensionRequest(final ThreadContext context) { return context.getTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_EXTENSION_REQUEST) == Boolean.TRUE; } // CS-ENFORCE-SINGLE - + public static String getSafeFromHeader(final ThreadContext context, final String headerName) { if (context == null || headerName == null || headerName.isEmpty()) { @@ -73,7 +73,7 @@ public static Serializable deserializeSafeFromHeader(final ThreadContext context return null; } - + public static boolean isTrustedClusterRequest(final ThreadContext context) { return context.getTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_TRUSTED_CLUSTER_REQUEST) == Boolean.TRUE; } diff --git a/src/main/java/org/opensearch/security/support/MapUtils.java b/src/main/java/org/opensearch/security/support/MapUtils.java index 65aa6f7f9d..a50505eae9 100644 --- a/src/main/java/org/opensearch/security/support/MapUtils.java +++ b/src/main/java/org/opensearch/security/support/MapUtils.java @@ -32,11 +32,11 @@ import java.util.Map; public class MapUtils { - + public static void deepTraverseMap(final Map map, final Callback cb) { deepTraverseMap(map, cb, null); } - + private static void deepTraverseMap(final Map map, final Callback cb, final List stack) { final List localStack; if(stack == null) { @@ -58,7 +58,7 @@ private static void deepTraverseMap(final Map map, final Callbac } } } - + public static interface Callback { public void call(String key, Map map, List stack); } diff --git a/src/main/java/org/opensearch/security/support/ModuleInfo.java b/src/main/java/org/opensearch/security/support/ModuleInfo.java index 994e49046c..c8558b1c13 100644 --- a/src/main/java/org/opensearch/security/support/ModuleInfo.java +++ b/src/main/java/org/opensearch/security/support/ModuleInfo.java @@ -36,16 +36,16 @@ import org.opensearch.common.io.stream.Writeable; public class ModuleInfo implements Serializable, Writeable{ - + private static final long serialVersionUID = -1077651823194285138L; - + private ModuleType moduleType; private String classname; private String classpath = ""; private String version = ""; private String buildTime = ""; private String gitsha1 = ""; - + public ModuleInfo(ModuleType moduleType, String classname) { assert(moduleType != null); this.moduleType = moduleType; @@ -73,7 +73,7 @@ public void setVersion(String version) { public void setBuildTime(String buildTime) { this.buildTime = buildTime; } - + public String getGitsha1() { return gitsha1; } @@ -85,7 +85,7 @@ public void setGitsha1(String gitsha1) { public ModuleType getModuleType() { return moduleType; } - + public Map getAsMap() { Map infoMap = new HashMap<>(); infoMap.put("type", moduleType.name()); @@ -99,7 +99,7 @@ public Map getAsMap() { infoMap.put("gitsha1", this.gitsha1); return infoMap; } - + @Override public void writeTo(StreamOutput out) throws IOException { out.writeEnum(moduleType); @@ -109,8 +109,8 @@ public void writeTo(StreamOutput out) throws IOException { out.writeString(buildTime); out.writeString(gitsha1); } - - + + /* (non-Javadoc) * @see java.lang.Object#hashCode() @@ -180,5 +180,5 @@ public boolean equals(Object obj) { public String toString() { return "Module [type=" + this.moduleType.name() + ", implementing class=" + this.classname + "]"; } - + } diff --git a/src/main/java/org/opensearch/security/support/PemKeyReader.java b/src/main/java/org/opensearch/security/support/PemKeyReader.java index fb3a595f9e..7d37fee4f3 100644 --- a/src/main/java/org/opensearch/security/support/PemKeyReader.java +++ b/src/main/java/org/opensearch/security/support/PemKeyReader.java @@ -72,12 +72,12 @@ import org.opensearch.env.Environment; public final class PemKeyReader { - + //private static final String[] EMPTY_STRING_ARRAY = new String[0]; protected static final Logger log = LogManager.getLogger(PemKeyReader.class); static final String JKS = "JKS"; static final String PKCS12 = "PKCS12"; - + private static final Pattern KEY_PATTERN = Pattern.compile( "-+BEGIN\\s+.*PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+" + // Header "([a-z0-9+/=\\r\\n]+)" + // Base64 text @@ -147,7 +147,7 @@ private static void safeClose(OutputStream out) { //ignore } } - + public static PrivateKey toPrivateKey(File keyFile, String keyPassword) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, InvalidAlgorithmParameterException, KeyException, IOException { if (keyFile == null) { @@ -155,7 +155,7 @@ public static PrivateKey toPrivateKey(File keyFile, String keyPassword) throws N } return getPrivateKeyFromByteBuffer(PemKeyReader.readPrivateKey(keyFile), keyPassword); } - + public static PrivateKey toPrivateKey(InputStream in, String keyPassword) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, InvalidAlgorithmParameterException, KeyException, IOException { if (in == null) { @@ -182,7 +182,7 @@ private static PrivateKey getPrivateKeyFromByteBuffer(byte[] encodedKey, String } } } - + private static PKCS8EncodedKeySpec generateKeySpec(char[] password, byte[] key) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, InvalidKeyException, InvalidAlgorithmParameterException { @@ -201,27 +201,27 @@ private static PKCS8EncodedKeySpec generateKeySpec(char[] password, byte[] key) return encryptedPrivateKeyInfo.getKeySpec(cipher); } - + public static X509Certificate loadCertificateFromFile(String file) throws Exception { if(file == null) { return null; } - + CertificateFactory fact = CertificateFactory.getInstance("X.509"); try(FileInputStream is = new FileInputStream(file)) { return (X509Certificate) fact.generateCertificate(is); } } - + public static X509Certificate loadCertificateFromStream(InputStream in) throws Exception { if(in == null) { return null; } - + CertificateFactory fact = CertificateFactory.getInstance("X.509"); return (X509Certificate) fact.generateCertificate(in); } - + public static KeyStore loadKeyStore(String storePath, String keyStorePassword, String type) throws Exception { if(storePath == null) { return null; @@ -230,36 +230,36 @@ public static KeyStore loadKeyStore(String storePath, String keyStorePassword, S if(type == null || !type.toUpperCase().equals(JKS) || !type.toUpperCase().equals(PKCS12)) { type = JKS; } - + final KeyStore store = KeyStore.getInstance(type.toUpperCase()); store.load(new FileInputStream(storePath), keyStorePassword==null?null:keyStorePassword.toCharArray()); return store; } public static PrivateKey loadKeyFromFile(String password, String keyFile) throws Exception { - + if(keyFile == null) { return null; } - + return PemKeyReader.toPrivateKey(new File(keyFile), password); } - + public static PrivateKey loadKeyFromStream(String password, InputStream in) throws Exception { - + if(in == null) { return null; } - + return PemKeyReader.toPrivateKey(in, password); } - + public static void checkPath(String keystoreFilePath, String fileNameLogOnly) { - + if (keystoreFilePath == null || keystoreFilePath.length() == 0) { throw new OpenSearchException("Empty file path for "+fileNameLogOnly); } - + if (Files.isDirectory(Paths.get(keystoreFilePath), LinkOption.NOFOLLOW_LINKS)) { throw new OpenSearchException("Is a directory: " + keystoreFilePath+" Expected a file for "+fileNameLogOnly); } @@ -268,34 +268,34 @@ public static void checkPath(String keystoreFilePath, String fileNameLogOnly) { throw new OpenSearchException("Unable to read " + keystoreFilePath + " ("+Paths.get(keystoreFilePath)+"). Please make sure this files exists and is readable regarding to permissions. Property: "+fileNameLogOnly); } } - + public static X509Certificate[] loadCertificatesFromFile(String file) throws Exception { if(file == null) { return null; } - + try(FileInputStream is = new FileInputStream(file)) { return loadCertificatesFromStream(is); } - + } public static X509Certificate[] loadCertificatesFromFile(File file) throws Exception { if(file == null) { return null; } - + try(FileInputStream is = new FileInputStream(file)) { return loadCertificatesFromStream(is); } - + } - + public static X509Certificate[] loadCertificatesFromStream(InputStream in) throws Exception { if(in == null) { return null; } - + CertificateFactory fact = CertificateFactory.getInstance("X.509"); Collection certs = fact.generateCertificates(in); X509Certificate[] x509Certs = new X509Certificate[certs.size()]; @@ -304,21 +304,21 @@ public static X509Certificate[] loadCertificatesFromStream(InputStream in) throw x509Certs[i++] = (X509Certificate) cert; } return x509Certs; - + } - + public static InputStream resolveStream(String propName, Settings settings) { final String content = settings.get(propName, null); - + if(content == null) { return null; } return new ByteArrayInputStream(content.getBytes(StandardCharsets.US_ASCII)); } - - public static String resolve(String propName, Settings settings, Path configPath, boolean mustBeValid) { + + public static String resolve(String propName, Settings settings, Path configPath, boolean mustBeValid) { final String originalPath = settings.get(propName, null); return resolve(originalPath, propName, settings, configPath, mustBeValid); } @@ -327,32 +327,32 @@ public static String resolve(String originalPath, String propName, Settings sett log.debug("Path is is {}", originalPath); String path = originalPath; final Environment env = new Environment(settings, configPath); - + if(env != null && originalPath != null && originalPath.length() > 0) { path = env.configDir().resolve(originalPath).toAbsolutePath().toString(); log.debug("Resolved {} to {} against {}", originalPath, path, env.configDir().toAbsolutePath().toString()); } - + if(mustBeValid) { checkPath(path, propName); } - + if("".equals(path)) { path = null; } - - return path; + + return path; } - + public static KeyStore toTruststore(final String trustCertificatesAliasPrefix, final X509Certificate[] trustCertificates) throws Exception { - + if(trustCertificates == null) { return null; } - + KeyStore ks = KeyStore.getInstance(JKS); ks.load(null); - + if(trustCertificates != null && trustCertificates.length > 0) { for (int i = 0; i < trustCertificates.length; i++) { X509Certificate x509Certificate = trustCertificates[i]; @@ -361,10 +361,10 @@ public static KeyStore toTruststore(final String trustCertificatesAliasPrefix, f } return ks; } - + public static KeyStore toKeystore(final String authenticationCertificateAlias, final char[] password, final X509Certificate authenticationCertificate[], final PrivateKey authenticationKey) throws Exception { - if(authenticationCertificateAlias != null && authenticationCertificate != null && authenticationKey != null) { + if(authenticationCertificateAlias != null && authenticationCertificate != null && authenticationKey != null) { KeyStore ks = KeyStore.getInstance(JKS); ks.load(null, null); ks.setKeyEntry(authenticationCertificateAlias, authenticationKey, password, authenticationCertificate); @@ -374,7 +374,7 @@ public static KeyStore toKeystore(final String authenticationCertificateAlias, f } } - + public static char[] randomChars(int len) { final SecureRandom r = new SecureRandom(); final char[] ret = new char[len]; diff --git a/src/main/java/org/opensearch/security/support/ReflectiveAttributeAccessors.java b/src/main/java/org/opensearch/security/support/ReflectiveAttributeAccessors.java index 8f12ffaf61..8ddc52f428 100644 --- a/src/main/java/org/opensearch/security/support/ReflectiveAttributeAccessors.java +++ b/src/main/java/org/opensearch/security/support/ReflectiveAttributeAccessors.java @@ -28,7 +28,7 @@ public static Function objectAttr(String name) { public static Function objectAttr(String name, Class type) { return new ReflectiveAttributeGetter(name, type); } - + public static Function protectedObjectAttr(String name, Class type) { return new ProtectedReflectiveAttributeGetter(name, type); } @@ -114,7 +114,7 @@ public R apply(O object) { } } - + static class ReflectiveAttributeSetter implements BiFunction { private final String attribute; private final String methodName; diff --git a/src/main/java/org/opensearch/security/support/SecurityJsonNode.java b/src/main/java/org/opensearch/security/support/SecurityJsonNode.java index 472ab2bb86..d1e2f4d34e 100644 --- a/src/main/java/org/opensearch/security/support/SecurityJsonNode.java +++ b/src/main/java/org/opensearch/security/support/SecurityJsonNode.java @@ -1,10 +1,10 @@ /* * 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.support; @@ -28,22 +28,22 @@ import org.opensearch.security.DefaultObjectMapper; public final class SecurityJsonNode { - + private final JsonNode node; public SecurityJsonNode(JsonNode node) { this.node = node; } - + public SecurityJsonNode get(String name) { if(isNull(node)) { return new SecurityJsonNode(null); } - + JsonNode val = node.get(name); return new SecurityJsonNode(val); } - + public String asString() { if(isNull(node)) { return null; @@ -51,11 +51,11 @@ public String asString() { return node.asText(null); } } - + private static boolean isNull(JsonNode node) { return node == null || node.isNull(); } - + public boolean isNull() { return isNull(this.node); } @@ -73,25 +73,25 @@ public SecurityJsonNode getDotted(String string) { for(String part: string.split("\\.")) { tmp = tmp.get(part); } - + return tmp; - + } public List asList() { if(isNull(node) || node.getNodeType() != JsonNodeType.ARRAY) { return null; } - + List retVal = new ArrayList(); - + for(int i=0; i> map, final String in .findAny() .orElse(null); } - + @SafeVarargs public static Map mapFromArray(T ... keyValues) { if(keyValues == null) { @@ -109,25 +109,25 @@ public static Map mapFromArray(T ... keyValues) { return null; } Map map = new HashMap<>(); - + for(int i = 0; i resolveOriginalIndices(RestoreSnapshotRequest restoreRequest) { final SnapshotInfo snapshotInfo = getSnapshotInfo(restoreRequest); @@ -57,17 +57,17 @@ public static List resolveOriginalIndices(RestoreSnapshotRequest restore return null; } else { return SnapshotUtils.filterIndices(snapshotInfo.indices(), restoreRequest.indices(), restoreRequest.indicesOptions()); - } - - + } + + } - + public static SnapshotInfo getSnapshotInfo(RestoreSnapshotRequest restoreRequest) { final RepositoriesService repositoriesService = Objects.requireNonNull(OpenSearchSecurityPlugin.GuiceHolder.getRepositoriesService(), "RepositoriesService not initialized"); final Repository repository = repositoriesService.repository(restoreRequest.repository()); final String threadName = Thread.currentThread().getName(); SnapshotInfo snapshotInfo = null; - + try { setCurrentThreadName("[" + ThreadPool.Names.GENERIC + "]"); for (SnapshotId snapshotId : PlainActionFuture.get(repository::getRepositoryData).getSnapshotIds()) { @@ -86,7 +86,7 @@ public static SnapshotInfo getSnapshotInfo(RestoreSnapshotRequest restoreRequest } return snapshotInfo; } - + @SuppressWarnings("removal") private static void setCurrentThreadName(final String name) { final SecurityManager sm = System.getSecurityManager(); @@ -94,7 +94,7 @@ private static void setCurrentThreadName(final String name) { if (sm != null) { sm.checkPermission(new SpecialPermission()); } - + AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { @@ -103,5 +103,5 @@ public Object run() { } }); } - + } diff --git a/src/main/java/org/opensearch/security/support/SourceFieldsContext.java b/src/main/java/org/opensearch/security/support/SourceFieldsContext.java index 175415a5b6..8f61bcbaf5 100644 --- a/src/main/java/org/opensearch/security/support/SourceFieldsContext.java +++ b/src/main/java/org/opensearch/security/support/SourceFieldsContext.java @@ -97,7 +97,7 @@ public String[] getExcludes() { public boolean hasIncludesOrExcludes() { return (includes != null && includes.length > 0) || (excludes != null && excludes.length > 0); } - + public boolean isFetchSource() { return fetchSource; } diff --git a/src/main/java/org/opensearch/security/support/WildcardMatcher.java b/src/main/java/org/opensearch/security/support/WildcardMatcher.java index f22f981fd2..302736fe67 100644 --- a/src/main/java/org/opensearch/security/support/WildcardMatcher.java +++ b/src/main/java/org/opensearch/security/support/WildcardMatcher.java @@ -296,7 +296,7 @@ public static List getAllMatchingPatterns(final Collection val = Migration.migrateConfig(SecurityDynamicConfiguration.fromNode(DefaultObjectMapper.YAML_MAPPER.readTree(file), CType.CONFIG, 1, 0, 0)); return backupAndWrite(file, val, backup); @@ -121,12 +121,12 @@ public static boolean migrateFile(File file, CType cType, boolean backup) { boolean roles = backupAndWrite(file, tup.v1(), backup); return roles && backupAndWrite(new File(file.getParent(),"tenants.yml"), tup.v2(), backup); } - + if(cType == CType.ROLESMAPPING) { SecurityDynamicConfiguration val = Migration.migrateRoleMappings(SecurityDynamicConfiguration.fromNode(DefaultObjectMapper.YAML_MAPPER.readTree(file), CType.ROLESMAPPING, 1, 0, 0)); return backupAndWrite(file, val, backup); } - + if(cType == CType.INTERNALUSERS) { SecurityDynamicConfiguration val = Migration.migrateInternalUsers(SecurityDynamicConfiguration.fromNode(DefaultObjectMapper.YAML_MAPPER.readTree(file), CType.INTERNALUSERS, 1, 0, 0)); return backupAndWrite(file, val, backup); @@ -147,11 +147,11 @@ public static boolean migrateFile(File file, CType cType, boolean backup) { } catch (Exception e) { System.out.println("Can not migrate "+file+" due to "+e); } - - + + return false; } - + private static boolean backupAndWrite(File file, SecurityDynamicConfiguration val, boolean backup) { try { if(val == null) { @@ -169,7 +169,7 @@ private static boolean backupAndWrite(File file, SecurityDynamicConfiguration System.out.println(" Details: "+e.getMessage()); e.printStackTrace(); } - + return false; } } diff --git a/src/main/java/org/opensearch/security/tools/SecurityAdmin.java b/src/main/java/org/opensearch/security/tools/SecurityAdmin.java index 2427a48f8a..738e0e6b20 100644 --- a/src/main/java/org/opensearch/security/tools/SecurityAdmin.java +++ b/src/main/java/org/opensearch/security/tools/SecurityAdmin.java @@ -162,7 +162,7 @@ public class SecurityAdmin { private static final Settings ENABLE_ALL_ALLOCATIONS_SETTINGS = Settings.builder() .put("cluster.routing.allocation.enable", "all") .build(); - + public static void main(final String[] args) { try { final int returnCode = execute(args); @@ -173,7 +173,7 @@ public static void main(final String[] args) { System.out.println(ExceptionsHelper.stackTrace(e)); System.out.println(); System.exit(-1); - } + } catch (IndexNotFoundException e) { System.out.println("ERR: No OpenSearch Security configuration index found. Please execute securityadmin with different command line parameters"); System.out.println("When you run it for the first time do not specify -us, -era, -dra or -rl"); @@ -181,16 +181,16 @@ public static void main(final String[] args) { System.exit(-1); } catch (Throwable e) { - + if (e instanceof OpenSearchException - && e.getMessage() != null + && e.getMessage() != null && e.getMessage().contains("no permissions")) { - System.out.println("ERR: You try to connect with a TLS node certificate instead of an admin client certificate"); + System.out.println("ERR: You try to connect with a TLS node certificate instead of an admin client certificate"); System.out.println(); System.exit(-1); } - + System.out.println("ERR: An unexpected "+e.getClass().getSimpleName()+" occured: "+e.getMessage()); System.out.println("Trace:"); System.out.println(ExceptionsHelper.stackTrace(e)); @@ -200,7 +200,7 @@ public static void main(final String[] args) { } public static int execute(final String[] args) throws Exception { - + System.out.println("Security Admin v7"); System.setProperty("security.nowarn.client","true"); System.setProperty("jdk.tls.rejectClientInitiatedRenegotiation","true"); @@ -256,16 +256,16 @@ public static int execute(final String[] args) throws Exception { options.addOption(Option.builder("backup").hasArg().argName("folder").desc("Backup configuration to folder").build()); options.addOption(Option.builder("migrate").hasArg().argName("folder").desc("Migrate and use folder to store migrated files").build()); - + options.addOption(Option.builder("rev").longOpt("resolve-env-vars").desc("Resolve/Substitute env vars in config with their value before uploading").build()); options.addOption(Option.builder("vc").numberOfArgs(1).optionalArg(true).argName("version").longOpt("validate-configs").desc("Validate config for version 6 or 7 (default 7)").build()); options.addOption(Option.builder("mo").longOpt("migrate-offline").hasArg().argName("folder").desc("Migrate and use folder to store migrated files").build()); - + //when adding new options also adjust validate(CommandLine line) - + String hostname = "localhost"; int port = 9200; String kspass = System.getenv(OPENDISTRO_SECURITY_KS_PASS); @@ -293,7 +293,7 @@ public static int execute(final String[] args) throws Exception { boolean deleteConfigIndex = false; boolean enableShardAllocation = false; boolean acceptRedCluster = false; - + String keypass = System.getenv(OPENDISTRO_SECURITY_KEYPASS); String cacert = null; String cert = null; @@ -316,28 +316,28 @@ public static int execute(final String[] args) throws Exception { CommandLineParser parser = new DefaultParser(); try { CommandLine line = parser.parse( options, args ); - + validate(line); - + hostname = line.getOptionValue("h", hostname); port = Integer.parseInt(line.getOptionValue("p", String.valueOf(port))); promptForPassword = line.hasOption("prompt"); - + if(kspass == null || kspass.isEmpty()) { kspass = line.getOptionValue("kspass",promptForPassword?null:"changeit"); } - + if(tspass == null || tspass.isEmpty()) { tspass = line.getOptionValue("tspass",promptForPassword?null:kspass); } cd = line.getOptionValue("cd", cd); - + if(!cd.endsWith(File.separator)) { cd += File.separator; } - + ks = line.getOptionValue("ks",ks); ts = line.getOptionValue("ts",ts); kst = line.getOptionValue("kst", kst); @@ -349,87 +349,87 @@ public static int execute(final String[] args) throws Exception { retrieve = line.hasOption("r"); ksAlias = line.getOptionValue("ksalias", ksAlias); index = line.getOptionValue("i", index); - + String enabledCiphersString = line.getOptionValue("ec", null); String enabledProtocolsString = line.getOptionValue("ep", null); - + if(enabledCiphersString != null) { enabledCiphers = enabledCiphersString.split(","); } - + if(enabledProtocolsString != null) { enabledProtocols = enabledProtocolsString.split(","); } - + updateSettings = line.hasOption("us")?Integer.parseInt(line.getOptionValue("us")):null; reload = line.hasOption("rl"); - + if(line.hasOption("era")) { replicaAutoExpand = true; } - + if(line.hasOption("dra")) { replicaAutoExpand = false; } - + failFast = line.hasOption("ff"); diagnose = line.hasOption("dg"); deleteConfigIndex = line.hasOption("dci"); enableShardAllocation = line.hasOption("esa"); acceptRedCluster = line.hasOption("arc"); - + cacert = line.getOptionValue("cacert"); cert = line.getOptionValue("cert"); key = line.getOptionValue("key"); keypass = line.getOptionValue("keypass", keypass); si = line.hasOption("si"); - + whoami = line.hasOption("w"); - + explicitReplicas = line.getOptionValue("er", explicitReplicas); - + backup = line.getOptionValue("backup"); - + migrate = line.getOptionValue("migrate"); - + resolveEnvVars = line.hasOption("rev"); - + validateConfig = !line.hasOption("vc")?null:Integer.parseInt(line.getOptionValue("vc", "7")); - + if(validateConfig != null && validateConfig.intValue() != 6 && validateConfig.intValue() != 7) { throw new ParseException("version must be 6 or 7"); } - + migrateOffline = line.getOptionValue("mo"); - + } catch( ParseException exp ) { System.out.println("ERR: Parsing failed. Reason: " + exp.getMessage()); formatter.printHelp("securityadmin.sh", options, true); return -1; } - + if(validateConfig != null) { System.out.println("Validate configuration for Version "+validateConfig.intValue()); return validateConfig(cd, file, type, validateConfig.intValue()); } - + if(migrateOffline != null) { System.out.println("Migrate "+migrateOffline+" offline"); final boolean retVal = Migrater.migrateDirectory(new File(migrateOffline), true); return retVal?0:-1; } - + System.out.print("Will connect to "+hostname+":"+port); Socket socket = new Socket(); - + try { - + socket.connect(new InetSocketAddress(hostname, port)); - + } catch (java.net.ConnectException ex) { System.out.println(); System.out.println("ERR: Seems there is no OpenSearch running on "+hostname+":"+port+" - Will exit"); @@ -450,13 +450,13 @@ public static int execute(final String[] args) throws Exception { kspass = promptForPassword("Keystore", "kspass", OPENDISTRO_SECURITY_KS_PASS); } } - + if(ts != null) { tst = tst==null?(ts.endsWith(".jks")?"JKS":"PKCS12"):tst; if(tspass == null && promptForPassword) { tspass = promptForPassword("Truststore", "tspass", OPENDISTRO_SECURITY_TS_PASS); } - } + } if(key != null) { @@ -549,7 +549,7 @@ public static int execute(final String[] args) throws Exception { System.out.println("Reload config on all nodes"); return 0; } - + if(si) { return (0); } @@ -558,9 +558,9 @@ public static int execute(final String[] args) throws Exception { System.out.println(whoAmIResNode.toPrettyString()); return (0); } - - - if(replicaAutoExpand != null) { + + + if(replicaAutoExpand != null) { Settings indexSettings = Settings.builder() .put("index.auto_expand_replicas", replicaAutoExpand?"0-all":"false") .build(); @@ -594,10 +594,10 @@ public static int execute(final String[] args) throws Exception { } else { System.out.println("ERR: Unable to enable shard allocation"); } - + return (successful?0:-1); - } - + } + if(failFast) { System.out.println("Fail-fast is activated"); } @@ -620,11 +620,11 @@ public static int execute(final String[] args) throws Exception { } catch (Exception e) { Throwable rootCause = ExceptionUtils.getRootCause(e); - + if(!failFast) { System.out.println("Cannot retrieve cluster state due to: "+e.getMessage()+". This is not an error, will keep on trying ..."); System.out.println(" Root cause: "+rootCause+" ("+e.getClass().getName()+"/"+rootCause.getClass().getName()+")"); - System.out.println(" * Try running securityadmin.sh with -icl (but no -cl) and -nhnv (If that works you need to check your clustername as well as hostnames in your TLS certificates)"); + System.out.println(" * Try running securityadmin.sh with -icl (but no -cl) and -nhnv (If that works you need to check your clustername as well as hostnames in your TLS certificates)"); System.out.println(" * Make sure that your keystore or PEM certificate is a client certificate (not a node certificate) and configured properly in opensearch.yml"); System.out.println(" * If this is not working, try running securityadmin.sh with --diagnose and see diagnose trace log file)"); System.out.println(" * Add --accept-red-cluster to allow securityadmin to operate on a red cluster."); @@ -634,12 +634,12 @@ public static int execute(final String[] args) throws Exception { System.out.println(" Root cause: "+rootCause+" ("+e.getClass().getName()+"/"+rootCause.getClass().getName()+")"); System.out.println(" * Try running securityadmin.sh with -icl (but no -cl) and -nhnv (If that works you need to check your clustername as well as hostnames in your TLS certificates)"); System.out.println(" * Make also sure that your keystore or PEM certificate is a client certificate (not a node certificate) and configured properly in opensearch.yml"); - System.out.println(" * If this is not working, try running securityadmin.sh with --diagnose and see diagnose trace log file)"); + System.out.println(" * If this is not working, try running securityadmin.sh with --diagnose and see diagnose trace log file)"); System.out.println(" * Add --accept-red-cluster to allow securityadmin to operate on a red cluster."); return (-1); } - + Thread.sleep(3000); continue; } @@ -651,7 +651,7 @@ public static int execute(final String[] args) throws Exception { System.out.println("ERR: Timed out while waiting for a green or yellow cluster state."); System.out.println(" * Try running securityadmin.sh with -icl (but no -cl) and -nhnv (If that works you need to check your clustername as well as hostnames in your TLS certificates)"); System.out.println(" * Make also sure that your keystore or PEM certificate is a client certificate (not a node certificate) and configured properly in opensearch.yml"); - System.out.println(" * If this is not working, try running securityadmin.sh with --diagnose and see diagnose trace log file)"); + System.out.println(" * If this is not working, try running securityadmin.sh with --diagnose and see diagnose trace log file)"); System.out.println(" * Add --accept-red-cluster to allow securityadmin to operate on a red cluster."); return (-1); } @@ -680,7 +680,7 @@ public static int execute(final String[] args) throws Exception { if(deleteConfigIndex) { return deleteConfigIndex(restHighLevelClient, index, indexExists); } - + if (!indexExists) { System.out.print(index +" index does not exists, attempt to create it ... "); final int created = createConfigIndex(restHighLevelClient, index, explicitReplicas); @@ -690,7 +690,7 @@ public static int execute(final String[] args) throws Exception { } else { System.out.println(index+" index already exists, so we do not need to create one."); - + try { ClusterHealthResponse clusterHealthResponse = restHighLevelClient.cluster().health(new ClusterHealthRequest(index), RequestOptions.DEFAULT); @@ -705,7 +705,7 @@ public static int execute(final String[] args) throws Exception { if (clusterHealthResponse.getStatus() == ClusterHealthStatus.YELLOW) { System.out.println("INFO: "+index+" index state is YELLOW, it seems you miss some replicas"); } - + } catch (Exception e) { if(!failFast) { System.out.println("Cannot retrieve "+index+" index state state due to "+e.getMessage()+". This is not an error, will keep on trying ..."); @@ -726,7 +726,7 @@ public static int execute(final String[] args) throws Exception { && securityIndex.getMappings() != null && securityIndex.getMappings().get(index) != null && securityIndex.getMappings().get(index).getSourceAsMap().containsKey("security")); - + if(legacy) { System.out.println("Legacy index '"+index+"' (ES 6) detected (or forced). You should migrate the configuration!"); } @@ -765,9 +765,9 @@ public static int execute(final String[] args) throws Exception { } boolean isCdAbs = new File(cd).isAbsolute(); - + System.out.println("Populate config from "+(isCdAbs?cd:new File(".", cd).getCanonicalPath())); - + if(file != null) { if(type != null) { System.out.println("Force type: "+type); @@ -828,7 +828,7 @@ private static boolean checkConfigUpdateResponse(Response response, int expected } else { System.out.println("SUCC: Expected " + expectedConfigCount + " config types for node " + n + " is " + n.get("updated_config_size").asInt() + " (" + n.get("updated_config_types") + ") due to: " + (n.get("message") == null ? "unknown reason" : n.get("message"))); } - + success = success && successNode; } @@ -843,7 +843,7 @@ private static boolean uploadFile(final RestHighLevelClient restHighLevelClient, final boolean populateEmptyIfMissing) { String id = _id; - + if(legacy) { id = _id; @@ -892,12 +892,12 @@ private static boolean retrieveFile(final RestHighLevelClient restHighLevelClien private static boolean retrieveFile(final RestHighLevelClient restHighLevelClient, final String filepath, final String index, final String _id, final boolean legacy, final boolean populateFileIfEmpty) { String id = _id; - + if(legacy) { id = _id; - + } - + System.out.println("Will retrieve '"+"/" +id+"' into "+filepath+" "+(legacy?"(legacy mode)":"")); try (Writer writer = new FileWriter(filepath, StandardCharsets.UTF_8)) { @@ -944,7 +944,7 @@ private static boolean retrieveFile(final RestHighLevelClient restHighLevelClien } catch (Exception e) { System.out.println(" FAIL: Get configuration for '"+_id+"' failed because of "+e.toString()); } - + return false; } @@ -962,23 +962,23 @@ private static BytesReference readXContent(final String content, final MediaType parser.close(); } } - + //validate return retVal; } - + private static String convertToYaml(String type, BytesReference bytes, boolean prettyPrint) throws IOException { - + try (XContentParser parser = JsonXContent.jsonXContent.createParser(NamedXContentRegistry.EMPTY, THROW_UNSUPPORTED_OPERATION, bytes.streamInput())) { parser.nextToken(); parser.nextToken(); - + if(!type.equals((parser.currentName()))) { return null; } - + parser.nextToken(); - + XContentBuilder builder = XContentFactory.yamlBuilder(); if (prettyPrint) { builder.prettyPrint(); @@ -991,7 +991,7 @@ private static String convertToYaml(String type, BytesReference bytes, boolean p protected static void generateDiagnoseTrace(final RestHighLevelClient restHighLevelClient) { final String date = DATE_FORMAT.format(new Date()); - + final StringBuilder sb = new StringBuilder(); sb.append("Diagnostic securityadmin trace"+System.lineSeparator()); sb.append("OpenSearch client version: "+Version.CURRENT+System.lineSeparator()); @@ -1061,19 +1061,19 @@ private static void validate(CommandLine line) throws ParseException { if(line.hasOption("ts") && line.hasOption("cacert")) { System.out.println("WARN: It makes no sense to specify -ts as well as -cacert"); } - + if(line.hasOption("ks") && line.hasOption("cert")) { System.out.println("WARN: It makes no sense to specify -ks as well as -cert"); } - + if(line.hasOption("ks") && line.hasOption("key")) { System.out.println("WARN: It makes no sense to specify -ks as well as -key"); } - + if(line.hasOption("cd") && line.hasOption("rl")) { System.out.println("WARN: It makes no sense to specify -cd as well as -r"); } - + if(line.hasOption("cd") && line.hasOption("f")) { System.out.println("WARN: It makes no sense to specify -cd as well as -f"); } @@ -1089,15 +1089,15 @@ private static void validate(CommandLine line) throws ParseException { if(!line.hasOption("vc") && !line.hasOption("ks") && !line.hasOption("cert") /*&& !line.hasOption("simple-auth")*/) { throw new ParseException("Specify at least -ks or -cert"); } - - if(!line.hasOption("vc") && !line.hasOption("mo") + + if(!line.hasOption("vc") && !line.hasOption("mo") && !line.hasOption("ts") && !line.hasOption("cacert")) { throw new ParseException("Specify at least -ts or -cacert"); } - + //TODO add more validation rules } - + private static String promptForPassword(String passwordName, String commandLineOption, String envVarName) throws Exception { final Console console = System.console(); if(console == null) { @@ -1132,7 +1132,7 @@ private static int issueWarnings(RestHighLevelClient restHighLevelClient) throws if(!ALLOW_MIXED) { return -1; } - + } else { System.out.println("OpenSearch Version: "+minVersion.toString()); } @@ -1161,14 +1161,14 @@ private static int deleteConfigIndex(RestHighLevelClient restHighLevelClient, St } else { System.out.print("No index '"+index+"' exists, so no need to delete it"); } - + return (success?0:-1); } private static int createConfigIndex(RestHighLevelClient restHighLevelClient, String index, String explicitReplicas) throws IOException { Map indexSettings = new HashMap<>(); indexSettings.put("index.number_of_shards", 1); - + if(explicitReplicas != null) { if(explicitReplicas.contains("-")) { indexSettings.put("index.auto_expand_replicas", explicitReplicas); @@ -1218,11 +1218,11 @@ private static int upload(RestHighLevelClient tc, String index, String cd, boole boolean success = uploadFile(tc, cd + "config.yml", index, "config", legacy, resolveEnvVars); success = uploadFile(tc, cd+"roles.yml", index, "roles", legacy, resolveEnvVars) && success; success = uploadFile(tc, cd+"roles_mapping.yml", index, "rolesmapping", legacy, resolveEnvVars) && success; - + success = uploadFile(tc, cd+"internal_users.yml", index, "internalusers", legacy, resolveEnvVars) && success; success = uploadFile(tc, cd+"action_groups.yml", index, "actiongroups", legacy, resolveEnvVars) && success; - + if(!legacy) { success = uploadFile(tc, cd+"tenants.yml", index, "tenants", legacy, resolveEnvVars) && success; } @@ -1252,18 +1252,18 @@ private static int migrate(RestHighLevelClient tc, String index, File backupDir, System.out.println("== Migration started =="); System.out.println("======================="); - + System.out.println("-> Backup current configuration to "+backupDir.getAbsolutePath()); - + if(backup(tc, index, backupDir, true) != 0) { return -1; } System.out.println(" done"); - + File v7Dir = new File(backupDir,"v7"); v7Dir.mkdirs(); - + try { System.out.println("-> Migrate configuration to new format and store it here: "+v7Dir.getAbsolutePath()); @@ -1303,13 +1303,13 @@ private static int migrate(RestHighLevelClient tc, String index, File backupDir, e.printStackTrace(); return -1; } - + System.out.println(" done"); - + System.out.println("-> Delete old "+index+" index"); deleteConfigIndex(tc, index, true); System.out.println(" done"); - + System.out.println("-> Upload new configuration into OpenSearch cluster"); int uploadResult = upload(tc, index, v7Dir.getAbsolutePath() + "/", false, expectedNodeCount, resolveEnvVars); @@ -1319,10 +1319,10 @@ private static int migrate(RestHighLevelClient tc, String index, File backupDir, }else { System.out.println(" ERR: unable to upload"); } - + return uploadResult; } - + private static String readTypeFromFile(File file) throws IOException { if(!file.exists() || !file.isFile()) { System.out.println("ERR: No such file "+file.getAbsolutePath()); @@ -1335,16 +1335,16 @@ private static String readTypeFromFile(File file) throws IOException { private static int validateConfig(String cd, String file, String type, int version) { if (file != null) { try { - + if(type == null) { type = readTypeFromFile(new File(file)); } - + if(type == null) { System.out.println("ERR: Unable to read type from "+file); return -1; } - + ConfigHelper.fromYamlFile(file, CType.fromString(type), version==7?2:1, 0, 0); return 0; } catch (Exception e) { @@ -1357,7 +1357,7 @@ private static int validateConfig(String cd, String file, String type, int versi success = validateConfigFile(cd+"roles.yml", CType.ROLES, version) && success; success = validateConfigFile(cd+"roles_mapping.yml", CType.ROLESMAPPING, version) && success; success = validateConfigFile(cd+"config.yml", CType.CONFIG, version) && success; - + if(new File(cd+"tenants.yml").exists() && version != 6) { success = validateConfigFile(cd+"tenants.yml", CType.TENANTS, version) && success; } @@ -1368,10 +1368,10 @@ private static int validateConfig(String cd, String file, String type, int versi return success?0:-1; } - + return -1; } - + private static boolean validateConfigFile(String file, CType cType, int version) { try { ConfigHelper.fromYamlFile(file, cType, version==7?2:1, 0, 0); diff --git a/src/main/java/org/opensearch/security/transport/DefaultInterClusterRequestEvaluator.java b/src/main/java/org/opensearch/security/transport/DefaultInterClusterRequestEvaluator.java index 6a7917b385..84087b5ed9 100644 --- a/src/main/java/org/opensearch/security/transport/DefaultInterClusterRequestEvaluator.java +++ b/src/main/java/org/opensearch/security/transport/DefaultInterClusterRequestEvaluator.java @@ -81,9 +81,9 @@ private WildcardMatcher getNodesDnToEvaluate() { @Override public boolean isInterClusterRequest(TransportRequest request, X509Certificate[] localCerts, X509Certificate[] peerCerts, final String principal) { - + String[] principals = new String[2]; - + if (principal != null && principal.length() > 0) { principals[0] = principal; principals[1] = principal.replace(" ",""); @@ -93,14 +93,14 @@ public boolean isInterClusterRequest(TransportRequest request, X509Certificate[] final boolean isTraceEnabled = log.isTraceEnabled(); if (principals[0] != null && nodesDn.matchAny(principals)) { - + if (isTraceEnabled) { log.trace("Treat certificate with principal {} as other node because of it matches one of {}", Arrays.toString(principals), nodesDn); } - + return true; - + } else { if (isTraceEnabled) { log.trace("Treat certificate with principal {} NOT as other node because we it does not matches one of {}", Arrays.toString(principals), diff --git a/src/main/java/org/opensearch/security/transport/InterClusterRequestEvaluator.java b/src/main/java/org/opensearch/security/transport/InterClusterRequestEvaluator.java index 38f4426420..81cfa9e345 100644 --- a/src/main/java/org/opensearch/security/transport/InterClusterRequestEvaluator.java +++ b/src/main/java/org/opensearch/security/transport/InterClusterRequestEvaluator.java @@ -42,18 +42,18 @@ public interface InterClusterRequestEvaluator { /** * Determine if request is a message from * another node in the cluster - * + * * @param request The transport request to evaluate * @param localCerts Local certs to use for evaluating the request which include criteria * specific to the implementation for confirming intercluster * communication - * + * * @param peerCerts Certs to use for evaluating the request which include criteria * specific to the implementation for confirming intercluster * communication - * + * * @param principal The principal evaluated by the configured principal extractor - * + * * @return True when determined to be intercluster, false otherwise */ boolean isInterClusterRequest(final TransportRequest request, final X509Certificate[] localCerts, final X509Certificate[] peerCerts, diff --git a/src/main/java/org/opensearch/security/transport/SecurityInterceptor.java b/src/main/java/org/opensearch/security/transport/SecurityInterceptor.java index e17560a000..5456d36d9c 100644 --- a/src/main/java/org/opensearch/security/transport/SecurityInterceptor.java +++ b/src/main/java/org/opensearch/security/transport/SecurityInterceptor.java @@ -142,7 +142,7 @@ public void sendRequestDecorate(AsyncSender sender || k.equals(ConfigConstants.OPENDISTRO_SECURITY_DOC_ALLOWLIST_HEADER) || k.equals(ConfigConstants.OPENDISTRO_SECURITY_FILTER_LEVEL_DLS_DONE) || k.equals(ConfigConstants.OPENDISTRO_SECURITY_DLS_MODE_HEADER) - || k.equals(ConfigConstants.OPENDISTRO_SECURITY_DLS_FILTER_LEVEL_QUERY_HEADER) + || k.equals(ConfigConstants.OPENDISTRO_SECURITY_DLS_FILTER_LEVEL_QUERY_HEADER) || (k.equals("_opendistro_security_source_field_context") && ! (request instanceof SearchRequest) && !(request instanceof GetRequest)) || k.startsWith("_opendistro_security_trace") || k.startsWith(ConfigConstants.OPENDISTRO_SECURITY_INITIAL_ACTION_CLASS_HEADER) @@ -269,18 +269,18 @@ public T read(StreamInput in) throws IOException { @Override public void handleResponse(T response) { - + ThreadContext threadContext = getThreadContext(); Map> responseHeaders = threadContext.getResponseHeaders(); List flsResponseHeader = responseHeaders.get(ConfigConstants.OPENDISTRO_SECURITY_FLS_FIELDS_HEADER); List dlsResponseHeader = responseHeaders.get(ConfigConstants.OPENDISTRO_SECURITY_DLS_QUERY_HEADER); List maskedFieldsResponseHeader = responseHeaders.get(ConfigConstants.OPENDISTRO_SECURITY_MASKED_FIELD_HEADER); - + contextToRestore.restore(); final boolean isDebugEnabled = log.isDebugEnabled(); - if (response instanceof ClusterSearchShardsResponse) { + if (response instanceof ClusterSearchShardsResponse) { if (flsResponseHeader != null && !flsResponseHeader.isEmpty()) { if (isDebugEnabled) { log.debug("add flsResponseHeader as transient"); diff --git a/src/main/java/org/opensearch/security/transport/SecurityRequestHandler.java b/src/main/java/org/opensearch/security/transport/SecurityRequestHandler.java index c6c80ba50e..4a2919fdb2 100644 --- a/src/main/java/org/opensearch/security/transport/SecurityRequestHandler.java +++ b/src/main/java/org/opensearch/security/transport/SecurityRequestHandler.java @@ -296,7 +296,7 @@ else if(!Strings.isNullOrEmpty(injectedUserHeader)) { } } } - + private void putInitialActionClassHeader(String initialActionClassValue, String resolvedActionClass) { if(initialActionClassValue == null) { if(getThreadContext().getHeader(ConfigConstants.OPENDISTRO_SECURITY_INITIAL_ACTION_CLASS_HEADER) == null) { diff --git a/src/main/java/org/opensearch/security/user/CustomAttributesAware.java b/src/main/java/org/opensearch/security/user/CustomAttributesAware.java index 89d62d3d5d..f5db96db8a 100644 --- a/src/main/java/org/opensearch/security/user/CustomAttributesAware.java +++ b/src/main/java/org/opensearch/security/user/CustomAttributesAware.java @@ -29,6 +29,6 @@ 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 index 83c7ea2eb5..86089afd35 100644 --- a/src/main/java/org/opensearch/security/user/User.java +++ b/src/main/java/org/opensearch/security/user/User.java @@ -56,7 +56,7 @@ public class User implements Serializable, Writeable, CustomAttributesAware { // 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; /** @@ -76,10 +76,10 @@ public User(final StreamInput in) throws IOException { 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) @@ -97,7 +97,7 @@ public User(final String name, final Collection roles, final AuthCredent if (roles != null) { this.addRoles(roles); } - + if(customAttributes != null) { this.attributes.putAll(customAttributes.getAttributes()); } @@ -106,7 +106,7 @@ public User(final String name, final Collection roles, final AuthCredent /** * 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 */ @@ -119,7 +119,7 @@ public final String getName() { } /** - * + * * @return A unmodifiable set of the backend roles this user is a member of */ public final Set getRoles() { @@ -128,7 +128,7 @@ public final Set getRoles() { /** * Associate this user with a backend role - * + * * @param role The backend role */ public final void addRole(final String role) { @@ -137,7 +137,7 @@ public final void addRole(final String role) { /** * Associate this user with a set of backend roles - * + * * @param roles The backend roles */ public final void addRoles(final Collection roles) { @@ -148,7 +148,7 @@ public final void addRoles(final Collection 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 */ @@ -158,7 +158,7 @@ public final boolean isUserInRole(final String role) { /** * Associate this user with a set of backend roles - * + * * @param roles The backend roles */ public final void addAttributes(final Map attributes) { @@ -166,7 +166,7 @@ public final void addAttributes(final Map attributes) { this.attributes.putAll(attributes); } } - + public final String getRequestedTenant() { return requestedTenant; } @@ -174,8 +174,8 @@ public final String getRequestedTenant() { public final void setRequestedTenant(String requestedTenant) { this.requestedTenant = requestedTenant; } - - + + public boolean isInjected() { return isInjected; } @@ -225,7 +225,7 @@ public final boolean equals(final Object obj) { /** * 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) { @@ -245,7 +245,7 @@ public void writeTo(StreamOutput out) throws IOException { /** * 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() { @@ -254,13 +254,13 @@ public synchronized final Map getCustomAttributesMap() { } 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); } diff --git a/src/main/java/org/opensearch/security/util/ratetracking/HeapBasedRateTracker.java b/src/main/java/org/opensearch/security/util/ratetracking/HeapBasedRateTracker.java index 37a9817b34..537d4d8fc7 100644 --- a/src/main/java/org/opensearch/security/util/ratetracking/HeapBasedRateTracker.java +++ b/src/main/java/org/opensearch/security/util/ratetracking/HeapBasedRateTracker.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.util.ratetracking; @@ -131,7 +131,7 @@ private void shiftFull(long timestamp) { this.startTime = timestamp; return; } - + int shiftOffset = this.timeOffsets[this.timeOffsetStart]; this.startTime += shiftOffset; diff --git a/src/main/java/org/opensearch/security/util/ratetracking/RateTracker.java b/src/main/java/org/opensearch/security/util/ratetracking/RateTracker.java index 5de531f0cb..c90680cd4a 100644 --- a/src/main/java/org/opensearch/security/util/ratetracking/RateTracker.java +++ b/src/main/java/org/opensearch/security/util/ratetracking/RateTracker.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.util.ratetracking; diff --git a/src/main/java/org/opensearch/security/util/ratetracking/SingleTryRateTracker.java b/src/main/java/org/opensearch/security/util/ratetracking/SingleTryRateTracker.java index c56639d04a..4f6bd371ed 100644 --- a/src/main/java/org/opensearch/security/util/ratetracking/SingleTryRateTracker.java +++ b/src/main/java/org/opensearch/security/util/ratetracking/SingleTryRateTracker.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.util.ratetracking; diff --git a/src/main/resources/static_config/static_roles.yml b/src/main/resources/static_config/static_roles.yml index 417e4f0ab7..dc80662d0e 100644 --- a/src/main/resources/static_config/static_roles.yml +++ b/src/main/resources/static_config/static_roles.yml @@ -62,7 +62,7 @@ own_index: allowed_actions: - "indices_all" - + manage_snapshots: reserved: true hidden: false @@ -76,7 +76,7 @@ manage_snapshots: allowed_actions: - "indices:data/write/index" - "indices:admin/create" - + kibana_server: reserved: true hidden: false @@ -141,7 +141,7 @@ logstash: allowed_actions: - "crud" - "create_index" - + readall_and_monitor: reserved: true hidden: false @@ -155,7 +155,7 @@ readall_and_monitor: - "*" allowed_actions: - "read" - + readall: reserved: true hidden: false @@ -168,4 +168,3 @@ readall: - "*" allowed_actions: - "read" - 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 0aeb4df082..54ca59bdd3 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 @@ -41,7 +41,7 @@ public class HTTPJwtAuthenticatorTest { final static byte[] secretKeyBytes = new byte[1024]; final static SecretKey secretKey; - + static { new SecureRandom().nextBytes(secretKeyBytes); secretKey = Keys.hmacShaKeyFor(secretKeyBytes); @@ -59,12 +59,12 @@ public void testNoKey() throws Exception { @Test public void testEmptyKey() throws Exception { - + final AuthCredentials credentials = extractCredentialsFromJwtHeader( Settings.builder().put("signing_key", ""), Jwts.builder().setSubject("Leonard McCoy")); - Assert.assertNull(credentials); + Assert.assertNull(credentials); } @Test @@ -195,7 +195,7 @@ public void testRolesMissing() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("roles_key", "roles"), - Jwts.builder().setSubject("Leonard McCoy")); + Jwts.builder().setSubject("Leonard McCoy")); Assert.assertNotNull(credentials); Assert.assertEquals("Leonard McCoy", credentials.getUsername()); @@ -207,7 +207,7 @@ public void testWrongSubjectKey() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("subject_key", "missing"), - Jwts.builder().claim("roles", "role1,role2").claim("asub", "Dr. Who")); + Jwts.builder().claim("roles", "role1,role2").claim("asub", "Dr. Who")); Assert.assertNull(credentials); } @@ -217,7 +217,7 @@ public void testAlternativeSubject() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("subject_key", "asub"), - Jwts.builder().setSubject("Leonard McCoy").claim("roles", "role1,role2").claim("asub", "Dr. Who")); + Jwts.builder().setSubject("Leonard McCoy").claim("roles", "role1,role2").claim("asub", "Dr. Who")); Assert.assertNotNull(credentials); Assert.assertEquals("Dr. Who", credentials.getUsername()); @@ -229,7 +229,7 @@ public void testNonStringAlternativeSubject() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("subject_key", "asub"), - Jwts.builder().setSubject("Leonard McCoy").claim("roles", "role1,role2").claim("asub", false)); + Jwts.builder().setSubject("Leonard McCoy").claim("roles", "role1,role2").claim("asub", false)); Assert.assertNotNull(credentials); Assert.assertEquals("false", credentials.getUsername()); @@ -260,7 +260,7 @@ public void testExp() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)), - Jwts.builder().setSubject("Expired").setExpiration(new Date(100))); + Jwts.builder().setSubject("Expired").setExpiration(new Date(100))); Assert.assertNull(credentials); } @@ -270,8 +270,8 @@ public void testNbf() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)), - Jwts.builder().setSubject("Expired").setNotBefore(new Date(System.currentTimeMillis()+(1000*36000)))); - + Jwts.builder().setSubject("Expired").setNotBefore(new Date(System.currentTimeMillis()+(1000*36000)))); + Assert.assertNull(credentials); } @@ -306,10 +306,10 @@ public void testES512() throws Exception { KeyPair pair = keyGen.generateKeyPair(); PrivateKey priv = pair.getPrivate(); PublicKey pub = pair.getPublic(); - + Settings settings = Settings.builder().put("signing_key", BaseEncoding.base64().encode(pub.getEncoded())).build(); String jwsToken = Jwts.builder().setSubject("Leonard McCoy").signWith(priv, SignatureAlgorithm.ES512).compact(); - + HTTPJwtAuthenticator jwtAuth = new HTTPJwtAuthenticator(settings, null); Map headers = new HashMap(); headers.put("Authorization", jwsToken); @@ -333,7 +333,7 @@ public void testRolesArray() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("roles_key", "roles"), builder); - + Assert.assertNotNull(credentials); Assert.assertEquals("John Doe", credentials.getUsername()); Assert.assertEquals(3, credentials.getBackendRoles().size()); @@ -348,7 +348,7 @@ public void testRequiredAudienceWithCorrectAudience() { final AuthCredentials credentials = extractCredentialsFromJwtHeader( Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("required_audience", "test_audience"), Jwts.builder().setSubject("Leonard McCoy").setAudience("test_audience")); - + Assert.assertNotNull(credentials); Assert.assertEquals("Leonard McCoy", credentials.getUsername()); } @@ -359,13 +359,13 @@ public void testRequiredAudienceWithIncorrectAudience() { final AuthCredentials credentials = extractCredentialsFromJwtHeader( Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("required_audience", "test_audience"), Jwts.builder().setSubject("Leonard McCoy").setAudience("wrong_audience")); - + Assert.assertNull(credentials); } @Test public void testRequiredIssuerWithCorrectAudience() { - + final AuthCredentials credentials = extractCredentialsFromJwtHeader( Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("required_issuer", "test_issuer"), Jwts.builder().setSubject("Leonard McCoy").setIssuer("test_issuer")); @@ -376,11 +376,11 @@ public void testRequiredIssuerWithCorrectAudience() { @Test public void testRequiredIssuerWithIncorrectAudience() { - + final AuthCredentials credentials = extractCredentialsFromJwtHeader( Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("required_issuer", "test_issuer"), Jwts.builder().setSubject("Leonard McCoy").setIssuer("wrong_issuer")); - + Assert.assertNull(credentials); } 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 6419e84891..9e1cfa80fd 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 @@ -18,6 +18,7 @@ import org.junit.BeforeClass; import org.junit.Test; +import org.opensearch.OpenSearchSecurityException; import org.opensearch.common.settings.Settings; import org.opensearch.security.user.AuthCredentials; import org.opensearch.security.util.FakeRestRequest; @@ -44,7 +45,11 @@ public static void tearDown() { @Test public void basicTest() { - Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); + Settings settings = Settings.builder() + .put("openid_connect_url", mockIdpServer.getDiscoverUri()) + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); @@ -55,12 +60,110 @@ public void basicTest() { Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(3, creds.getAttributes().size()); + Assert.assertEquals(4, creds.getAttributes().size()); + } + + + @Test + public void jwksUriTest() { + Settings settings = Settings.builder() + .put("jwks_uri", mockIdpServer.getJwksUri()) + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest( + ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_2), new HashMap<>()), null); + + Assert.assertNotNull(creds); + Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); + Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); + Assert.assertEquals(0, creds.getBackendRoles().size()); + Assert.assertEquals(4, creds.getAttributes().size()); + } + + @Test + public void jwksMissingRequiredIssuerInClaimTest() { + Settings settings = Settings.builder() + .put("jwks_uri", mockIdpServer.getJwksUri()) + .put("required_issuer", TestJwts.TEST_ISSUER) + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest( + ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_NO_ISSUER_OCT_1), new HashMap<>()), null); + + Assert.assertNull(creds); + } + + @Test + public void jwksNotMatchingRequiredIssuerInClaimTest() { + Settings settings = Settings.builder() + .put("jwks_uri", mockIdpServer.getJwksUri()) + .put("required_issuer", "Wrong Issuer") + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest( + ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_2), new HashMap<>()), null); + + Assert.assertNull(creds); + } + + @Test + public void jwksMissingRequiredAudienceInClaimTest() { + Settings settings = Settings.builder() + .put("jwks_uri", mockIdpServer.getJwksUri()) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest( + ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_NO_AUDIENCE_OCT_1), new HashMap<>()), null); + + Assert.assertNull(creds); + } + + @Test + public void jwksNotMatchingRequiredAudienceInClaimTest() { + Settings settings = Settings.builder() + .put("jwks_uri", mockIdpServer.getJwksUri()) + .put("required_audience", "Wrong Audience") + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest( + ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_2), new HashMap<>()), null); + + Assert.assertNull(creds); + } + + @Test + public void jwksUriMissingTest() { + var exception = Assert.assertThrows(Exception.class, () -> { + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(Settings.builder().build(), null); + jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_1), new HashMap<>()), + null); + }); + + Assert.assertEquals("Authentication backend failed", exception.getMessage()); + Assert.assertEquals(OpenSearchSecurityException.class, exception.getClass()); } @Test public void testEscapeKid() { - Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); + Settings settings = Settings.builder() + .put("openid_connect_url", mockIdpServer.getDiscoverUri()) + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); @@ -71,12 +174,16 @@ public void testEscapeKid() { Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(3, creds.getAttributes().size()); + Assert.assertEquals(4, creds.getAttributes().size()); } @Test public void bearerTest() { - Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); + Settings settings = Settings.builder() + .put("openid_connect_url", mockIdpServer.getDiscoverUri()) + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); @@ -89,13 +196,17 @@ public void bearerTest() { Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(3, creds.getAttributes().size()); + Assert.assertEquals(4, creds.getAttributes().size()); } @Test public void testRoles() throws Exception { - Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()) - .put("roles_key", TestJwts.ROLES_CLAIM).build(); + Settings settings = Settings.builder() + .put("openid_connect_url", mockIdpServer.getDiscoverUri()) + .put("roles_key", TestJwts.ROLES_CLAIM) + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); @@ -112,20 +223,22 @@ public void testExp() throws Exception { Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - + AuthCredentials creds = jwtAuth.extractCredentials( new FakeRestRequest(ImmutableMap.of("Authorization", "Bearer " + TestJwts.MC_COY_EXPIRED_SIGNED_OCT_1), new HashMap()), null); Assert.assertNull(creds); - } + } @Test public void testExpInSkew() throws Exception { Settings settings = Settings.builder() .put("openid_connect_url", mockIdpServer.getDiscoverUri()) .put("jwt_clock_skew_tolerance_seconds", "10") + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) .build(); HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); @@ -136,7 +249,7 @@ public void testExpInSkew() throws Exception { AuthCredentials creds = jwtAuth.extractCredentials( new FakeRestRequest( ImmutableMap.of( - "Authorization", + "Authorization", "Bearer "+TestJwts.createMcCoySignedOct1(notBeforeDate, expiringDate)), new HashMap()), null); @@ -149,6 +262,8 @@ public void testNbf() throws Exception { Settings settings = Settings.builder() .put("openid_connect_url", mockIdpServer.getDiscoverUri()) .put("jwt_clock_skew_tolerance_seconds", "0") + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) .build(); HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); @@ -159,7 +274,7 @@ public void testNbf() throws Exception { AuthCredentials creds = jwtAuth.extractCredentials( new FakeRestRequest( ImmutableMap.of( - "Authorization", + "Authorization", "Bearer "+TestJwts.createMcCoySignedOct1(notBeforeDate, expiringDate)), new HashMap()), null); @@ -172,6 +287,8 @@ public void testNbfInSkew() throws Exception { Settings settings = Settings.builder() .put("openid_connect_url", mockIdpServer.getDiscoverUri()) .put("jwt_clock_skew_tolerance_seconds", "10") + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) .build(); HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); @@ -186,13 +303,17 @@ public void testNbfInSkew() throws Exception { null); Assert.assertNotNull(creds); - } + } @Test public void testRS256() throws Exception { - Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); + Settings settings = Settings.builder() + .put("openid_connect_url", mockIdpServer.getDiscoverUri()) + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); @@ -203,7 +324,7 @@ public void testRS256() throws Exception { Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(3, creds.getAttributes().size()); + Assert.assertEquals(4, creds.getAttributes().size()); } @Test @@ -221,7 +342,11 @@ public void testBadSignature() throws Exception { @Test public void testPeculiarJsonEscaping() { - Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); + Settings settings = Settings.builder() + .put("openid_connect_url", mockIdpServer.getDiscoverUri()) + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); @@ -233,7 +358,7 @@ public void testPeculiarJsonEscaping() { Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(3, creds.getAttributes().size()); + Assert.assertEquals(4, creds.getAttributes().size()); } } diff --git a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/MockIpdServer.java b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/MockIpdServer.java index 21a9d239c3..35e51919cb 100644 --- a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/MockIpdServer.java +++ b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/MockIpdServer.java @@ -118,6 +118,10 @@ public String getDiscoverUri() { return uri + CTX_DISCOVER; } + public String getJwksUri() { + return uri + CTX_KEYS; + } + public int getPort() { return port; } 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 4400dd1cdc..4285ee07ae 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 @@ -40,7 +40,7 @@ public void basicTest() throws Exception { Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(3, creds.getAttributes().size()); + Assert.assertEquals(4, creds.getAttributes().size()); } finally { try { @@ -92,7 +92,7 @@ public void noAlgTest() throws Exception { Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(3, creds.getAttributes().size()); + Assert.assertEquals(4, creds.getAttributes().size()); } finally { try { mockIdpServer.close(); @@ -145,7 +145,7 @@ public void keyExchangeTest() throws Exception { Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(3, creds.getAttributes().size()); + Assert.assertEquals(4, creds.getAttributes().size()); creds = jwtAuth.extractCredentials( new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.NoKid.MC_COY_SIGNED_RSA_2), @@ -170,7 +170,7 @@ public void keyExchangeTest() throws Exception { Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(3, creds.getAttributes().size()); + Assert.assertEquals(4, creds.getAttributes().size()); } finally { try { @@ -194,7 +194,7 @@ public void keyExchangeTest() throws Exception { Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(3, creds.getAttributes().size()); + Assert.assertEquals(4, creds.getAttributes().size()); } finally { try { diff --git a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/TestJwts.java b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/TestJwts.java index 217e64926c..0bac7159ac 100644 --- a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/TestJwts.java +++ b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/TestJwts.java @@ -33,12 +33,25 @@ class TestJwts { static final String MCCOY_SUBJECT = "Leonard McCoy"; - static final JwtToken MC_COY = create(MCCOY_SUBJECT, TEST_AUDIENCE, ROLES_CLAIM, TEST_ROLES_STRING); + static final String TEST_ISSUER = "TestIssuer"; - static final JwtToken MC_COY_EXPIRED = create(MCCOY_SUBJECT, TEST_AUDIENCE, ROLES_CLAIM, TEST_ROLES_STRING, JwtConstants.CLAIM_EXPIRY, 10); + static final JwtToken MC_COY = create(MCCOY_SUBJECT, TEST_AUDIENCE, TEST_ISSUER, ROLES_CLAIM, TEST_ROLES_STRING); + + static final JwtToken MC_COY_2 = create(MCCOY_SUBJECT, TEST_AUDIENCE, TEST_ISSUER, ROLES_CLAIM, TEST_ROLES_STRING); + + static final JwtToken MC_COY_NO_AUDIENCE = create(MCCOY_SUBJECT, null, TEST_ISSUER, ROLES_CLAIM, TEST_ROLES_STRING); + + static final JwtToken MC_COY_NO_ISSUER = create(MCCOY_SUBJECT, TEST_AUDIENCE, null, ROLES_CLAIM, TEST_ROLES_STRING); + + static final JwtToken MC_COY_EXPIRED = create(MCCOY_SUBJECT, TEST_AUDIENCE, TEST_ISSUER, ROLES_CLAIM, TEST_ROLES_STRING, JwtConstants.CLAIM_EXPIRY, 10); static final String MC_COY_SIGNED_OCT_1 = createSigned(MC_COY, TestJwk.OCT_1); + static final String MC_COY_SIGNED_OCT_2 = createSigned(MC_COY_2, TestJwk.OCT_2); + + static final String MC_COY_SIGNED_NO_AUDIENCE_OCT_1 = createSigned(MC_COY_NO_AUDIENCE, TestJwk.OCT_1); + static final String MC_COY_SIGNED_NO_ISSUER_OCT_1 = createSigned(MC_COY_NO_ISSUER, TestJwk.OCT_1); + static final String MC_COY_SIGNED_OCT_1_INVALID_KID = createSigned(MC_COY, TestJwk.FORWARD_SLASH_KID_OCT_1); static final String MC_COY_SIGNED_RSA_1 = createSigned(MC_COY, TestJwk.RSA_1); @@ -57,11 +70,16 @@ static class PeculiarEscaping { static final String MC_COY_SIGNED_RSA_1 = createSignedWithPeculiarEscaping(MC_COY, TestJwk.RSA_1); } - static JwtToken create(String subject, String audience, Object... moreClaims) { + static JwtToken create(String subject, String audience, String issuer, Object... moreClaims) { JwtClaims claims = new JwtClaims(); claims.setSubject(subject); - claims.setAudience(audience); + if (audience != null) { + claims.setAudience(audience); + } + if (issuer != null) { + claims.setIssuer(issuer); + } if (moreClaims != null) { for (int i = 0; i < moreClaims.length; i += 2) { @@ -108,9 +126,9 @@ static String createSignedWithPeculiarEscaping(JwtToken baseJwt, JsonWebKey jwk) static String createMcCoySignedOct1(long nbf, long exp) { JwtToken jwt_token = create( - MCCOY_SUBJECT, TEST_AUDIENCE, - ROLES_CLAIM, TEST_ROLES_STRING, - JwtConstants.CLAIM_NOT_BEFORE, nbf, + MCCOY_SUBJECT, TEST_AUDIENCE, + TEST_ISSUER, ROLES_CLAIM, TEST_ROLES_STRING, + JwtConstants.CLAIM_NOT_BEFORE, nbf, JwtConstants.CLAIM_EXPIRY, exp); return createSigned(jwt_token, TestJwk.OCT_1); diff --git a/src/test/java/com/amazon/dlic/auth/http/saml/MockSamlIdpServer.java b/src/test/java/com/amazon/dlic/auth/http/saml/MockSamlIdpServer.java index 4f4a8c9640..89dee6151f 100644 --- a/src/test/java/com/amazon/dlic/auth/http/saml/MockSamlIdpServer.java +++ b/src/test/java/com/amazon/dlic/auth/http/saml/MockSamlIdpServer.java @@ -464,7 +464,7 @@ private String createSamlAuthResponse(AuthnRequest authnRequest) { attribute.getAttributeValues().add(createXSAny(AttributeValue.DEFAULT_ELEMENT_NAME, role)); } } - + if (signResponses) { Signature signature = createSamlElement(Signature.class); assertion.setSignature(signature); diff --git a/src/test/java/org/opensearch/node/PluginAwareNode.java b/src/test/java/org/opensearch/node/PluginAwareNode.java index 39c93e6b8e..35dcd8b699 100644 --- a/src/test/java/org/opensearch/node/PluginAwareNode.java +++ b/src/test/java/org/opensearch/node/PluginAwareNode.java @@ -33,7 +33,7 @@ import org.opensearch.plugins.Plugin; public class PluginAwareNode extends Node { - + private final boolean clusterManagerEligible; @SafeVarargs @@ -41,7 +41,7 @@ public PluginAwareNode(boolean clusterManagerEligible, final Settings preparedSe super(InternalSettingsPreparer.prepareEnvironment(preparedSettings, Collections.emptyMap(), null, () -> System.getenv("HOSTNAME")), Arrays.asList(plugins), true); this.clusterManagerEligible = clusterManagerEligible; } - + public boolean isClusterManagerEligible() { return clusterManagerEligible; diff --git a/src/test/java/org/opensearch/security/AdvancedSecurityMigrationTests.java b/src/test/java/org/opensearch/security/AdvancedSecurityMigrationTests.java index 3b069a2339..e8ac049385 100644 --- a/src/test/java/org/opensearch/security/AdvancedSecurityMigrationTests.java +++ b/src/test/java/org/opensearch/security/AdvancedSecurityMigrationTests.java @@ -50,8 +50,11 @@ public void testPluginEnabledDataNodeWithSSlOnlyClusterManagerNode_ReqOnSSLNode( final Settings advSecSettings = getAdvSecSettings().build(); final Settings sslOnlySettings = getSSLOnlyModeSettings().build(); - setupGenericNodes(Arrays.asList(sslOnlySettings, advSecSettings, advSecSettings, sslOnlySettings), - Arrays.asList(true, false, false, true), ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA); + setupGenericNodes( + Arrays.asList(sslOnlySettings, advSecSettings, advSecSettings, sslOnlySettings), + Arrays.asList(true, false, false, true), + ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA + ); Thread.sleep(10000); commonTestsForAdvancedSecurityMigration(nonSslRestHelper(), null); @@ -67,8 +70,11 @@ public void testPluginEnabledDataNodeWithSSlOnlyClusterManagerNode_ReqOnAdvSecNo final Settings advSecSettings = getAdvSecSettings().build(); final Settings sslOnlySettings = getSSLOnlyModeSettings().build(); - setupGenericNodes(Arrays.asList(advSecSettings, sslOnlySettings, advSecSettings, sslOnlySettings), - Arrays.asList(false, true, false, true), ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA); + setupGenericNodes( + Arrays.asList(advSecSettings, sslOnlySettings, advSecSettings, sslOnlySettings), + Arrays.asList(false, true, false, true), + ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA + ); Thread.sleep(10000); commonTestsForAdvancedSecurityMigration(nonSslRestHelper(), encodeBasicHeader("admin", "admin")); @@ -84,11 +90,14 @@ public void testPluginEnabledClusterManagerNodeWithSSlOnlyDataNode_ReqOnSSLNode( final Settings advSecSettings = getAdvSecSettings().build(); final Settings sslOnlySettings = getSSLOnlyModeSettings().build(); - setupGenericNodes(Arrays.asList(sslOnlySettings, sslOnlySettings, advSecSettings, advSecSettings), - Arrays.asList(true, true, false, false), ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA); + setupGenericNodes( + Arrays.asList(sslOnlySettings, sslOnlySettings, advSecSettings, advSecSettings), + Arrays.asList(true, true, false, false), + ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA + ); Thread.sleep(10000); - commonTestsForAdvancedSecurityMigration(nonSslRestHelper(),null); + commonTestsForAdvancedSecurityMigration(nonSslRestHelper(), null); } /** @@ -101,8 +110,11 @@ public void testPluginEnabledClusterManagerNodeWithSSlOnlyDataNode_ReqOnAdvSecNo final Settings advSecSettings = getAdvSecSettings().build(); final Settings sslOnlySettings = getSSLOnlyModeSettings().build(); - setupGenericNodes(Arrays.asList(advSecSettings, sslOnlySettings, sslOnlySettings, advSecSettings), - Arrays.asList(false, true, true, false), ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA); + setupGenericNodes( + Arrays.asList(advSecSettings, sslOnlySettings, sslOnlySettings, advSecSettings), + Arrays.asList(false, true, true, false), + ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA + ); Thread.sleep(10000); commonTestsForAdvancedSecurityMigration(nonSslRestHelper(), encodeBasicHeader("admin", "admin")); @@ -118,11 +130,14 @@ public void testPluginEnabledDataNodeWithDisabledClusterManagerNode_ReqOnDisable final Settings advSecSettings = getAdvSecSettingsDualMode().build(); final Settings disabledSettings = getDisabledSettings().build(); - setupGenericNodes(Arrays.asList(disabledSettings, advSecSettings, advSecSettings, disabledSettings), - Arrays.asList(false, false, false, false), ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA); + setupGenericNodes( + Arrays.asList(disabledSettings, advSecSettings, advSecSettings, disabledSettings), + Arrays.asList(false, false, false, false), + ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA + ); Thread.sleep(10000); - commonTestsForAdvancedSecurityMigration(nonSslRestHelper(),null); + commonTestsForAdvancedSecurityMigration(nonSslRestHelper(), null); } /** @@ -135,8 +150,11 @@ public void testPluginEnabledDataNodeWithDisabledClusterManagerNode_ReqOnAdvSecN final Settings advSecSettings = getAdvSecSettingsDualMode().build(); final Settings disabledSettings = getDisabledSettings().build(); - setupGenericNodes(Arrays.asList(advSecSettings, disabledSettings, advSecSettings, disabledSettings), - Arrays.asList(false, false, false, false), ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA); + setupGenericNodes( + Arrays.asList(advSecSettings, disabledSettings, advSecSettings, disabledSettings), + Arrays.asList(false, false, false, false), + ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA + ); Thread.sleep(10000); commonTestsForAdvancedSecurityMigration(nonSslRestHelper(), encodeBasicHeader("admin", "admin")); @@ -152,8 +170,11 @@ public void testPluginEnabledClusterManagerNodeWithDisabledDataNode_ReqOnDisable final Settings advSecSettings = getAdvSecSettingsDualMode().build(); final Settings disabledSettings = getDisabledSettings().build(); - setupGenericNodes(Arrays.asList(disabledSettings, disabledSettings, advSecSettings, advSecSettings), - Arrays.asList(false, false, false, false), ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA); + setupGenericNodes( + Arrays.asList(disabledSettings, disabledSettings, advSecSettings, advSecSettings), + Arrays.asList(false, false, false, false), + ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA + ); Thread.sleep(10000); commonTestsForAdvancedSecurityMigration(nonSslRestHelper(), null); @@ -169,8 +190,11 @@ public void testPluginEnabledClusterManagerNodeWithDisabledDataNode_ReqOnAdvSecN final Settings advSecSettings = getAdvSecSettingsDualMode().build(); final Settings disabledSettings = getDisabledSettings().build(); - setupGenericNodes(Arrays.asList(advSecSettings, disabledSettings, advSecSettings, advSecSettings), - Arrays.asList(false, false, false, false), ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA); + setupGenericNodes( + Arrays.asList(advSecSettings, disabledSettings, advSecSettings, advSecSettings), + Arrays.asList(false, false, false, false), + ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA + ); Thread.sleep(10000); commonTestsForAdvancedSecurityMigration(nonSslRestHelper(), encodeBasicHeader("admin", "admin")); @@ -178,13 +202,17 @@ public void testPluginEnabledClusterManagerNodeWithDisabledDataNode_ReqOnAdvSecN @Test public void testWithPassiveAuthDisabled() throws Exception { - final Settings advSecSettings = getAdvSecSettings() - .put(ConfigConstants.SECURITY_UNSUPPORTED_PASSIVE_INTERTRANSPORT_AUTH_INITIALLY, false) - .build(); + final Settings advSecSettings = getAdvSecSettings().put( + ConfigConstants.SECURITY_UNSUPPORTED_PASSIVE_INTERTRANSPORT_AUTH_INITIALLY, + false + ).build(); final Settings sslOnlySettings = getSSLOnlyModeSettings().build(); - setupGenericNodes(Arrays.asList(sslOnlySettings, sslOnlySettings, advSecSettings, advSecSettings), - Arrays.asList(true, true, false, false), ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA); + setupGenericNodes( + Arrays.asList(sslOnlySettings, sslOnlySettings, advSecSettings, advSecSettings), + Arrays.asList(true, true, false, false), + ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA + ); Thread.sleep(10000); RestHelper.HttpResponse res; @@ -196,15 +224,19 @@ public void testWithPassiveAuthDisabled() throws Exception { @Test public void testWithPassiveAuthDisabledDynamic() throws Exception { - final Settings advSecSettings = getAdvSecSettingsDualMode() - .put(ConfigConstants.SECURITY_UNSUPPORTED_PASSIVE_INTERTRANSPORT_AUTH_INITIALLY, false) - .build(); + final Settings advSecSettings = getAdvSecSettingsDualMode().put( + ConfigConstants.SECURITY_UNSUPPORTED_PASSIVE_INTERTRANSPORT_AUTH_INITIALLY, + false + ).build(); final Settings disabledSettings = getDisabledSettings().build(); - setupGenericNodes(Arrays.asList(disabledSettings, disabledSettings, advSecSettings, advSecSettings), - Arrays.asList(false, false, false, false), ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA); + setupGenericNodes( + Arrays.asList(disabledSettings, disabledSettings, advSecSettings, advSecSettings), + Arrays.asList(false, false, false, false), + ClusterConfiguration.ONE_CLUSTER_MANAGER_THREE_DATA + ); - Thread.sleep(5*1000); + Thread.sleep(5 * 1000); RestHelper.HttpResponse res; RestHelper rh = nonSslRestHelper(); @@ -214,7 +246,7 @@ public void testWithPassiveAuthDisabledDynamic() throws Exception { } private void commonTestsForAdvancedSecurityMigration(final RestHelper rh, final Header basicHeaders) throws Exception { - Thread.sleep(5*1000); + Thread.sleep(5 * 1000); RestHelper.HttpResponse res; res = rh.executePutRequest("testindex", getIndexSettingsForAdvSec(), basicHeaders); @@ -250,50 +282,47 @@ private void commonTestsForAnIndex(final RestHelper rh, final String index, fina private Settings.Builder getAdvSecSettings() { return Settings.builder() - .put(ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX, true) - .put(ConfigConstants.SECURITY_UNSUPPORTED_PASSIVE_INTERTRANSPORT_AUTH_INITIALLY, true) - .put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true) - .put("node.attr.custom_node", true); + .put(ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX, true) + .put(ConfigConstants.SECURITY_UNSUPPORTED_PASSIVE_INTERTRANSPORT_AUTH_INITIALLY, true) + .put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true) + .put("node.attr.custom_node", true); } private Settings.Builder getAdvSecSettingsDualMode() { - return getAdvSecSettings() - .put(ConfigConstants.SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED, true); + return getAdvSecSettings().put(ConfigConstants.SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED, true); } private Settings.Builder getSSLOnlyModeSettings() { - return Settings.builder() - .put(ConfigConstants.SECURITY_SSL_ONLY, true); + return Settings.builder().put(ConfigConstants.SECURITY_SSL_ONLY, true); } private Settings.Builder getDisabledSettings() { - return Settings.builder() - .put(ConfigConstants.SECURITY_DISABLED, true); + return Settings.builder().put(ConfigConstants.SECURITY_DISABLED, true); } // Create index with shards only in adv sec nodes private String getIndexSettingsForAdvSec() { - return "{\n" + - " \"settings\" : {\n" + - " \"index\" : {\n" + - " \"number_of_shards\" : 2, \n" + - " \"number_of_replicas\" : 1, \n" + - " \"routing.allocation.include.custom_node\" : true \n" + - " }\n" + - " }\n" + - "}"; + return "{\n" + + " \"settings\" : {\n" + + " \"index\" : {\n" + + " \"number_of_shards\" : 2, \n" + + " \"number_of_replicas\" : 1, \n" + + " \"routing.allocation.include.custom_node\" : true \n" + + " }\n" + + " }\n" + + "}"; } // Create index with shards only in non adv sec nodes private String getIndexSettingForSSLOnlyNode() { - return "{\n" + - " \"settings\" : {\n" + - " \"index\" : {\n" + - " \"number_of_shards\" : 2, \n" + - " \"number_of_replicas\" : 1, \n" + - " \"routing.allocation.exclude.custom_node\" : true \n" + - " }\n" + - " }\n" + - "}"; + return "{\n" + + " \"settings\" : {\n" + + " \"index\" : {\n" + + " \"number_of_shards\" : 2, \n" + + " \"number_of_replicas\" : 1, \n" + + " \"routing.allocation.exclude.custom_node\" : true \n" + + " }\n" + + " }\n" + + "}"; } } diff --git a/src/test/java/org/opensearch/security/AggregationTests.java b/src/test/java/org/opensearch/security/AggregationTests.java index c2feddd6b6..728965f82d 100644 --- a/src/test/java/org/opensearch/security/AggregationTests.java +++ b/src/test/java/org/opensearch/security/AggregationTests.java @@ -46,37 +46,74 @@ public class AggregationTests extends SingleClusterTest { @Test public void testBasicAggregations() throws Exception { - final Settings settings = Settings.builder() - .build(); - + final Settings settings = Settings.builder().build(); + setup(settings); final RestHelper rh = nonSslRestHelper(); - + try (Client tc = getClient()) { - tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("xyz").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("starfleet","starfleet_academy","starfleet_library").alias("sf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire","vulcangov").alias("nonsf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("xyz").alias("alias1"))).actionGet(); + tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); + tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + + tc.index(new IndexRequest("xyz").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction( + AliasActions.add().indices("starfleet", "starfleet_academy", "starfleet_library").alias("sf") + ) + ) + .actionGet(); + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire", "vulcangov").alias("nonsf")) + ) + .actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))) + .actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("xyz").alias("alias1"))) + .actionGet(); } - + HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("_search?pretty", "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":40}}}}",encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest( + "_search?pretty", + "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":40}}}}", + encodeBasicHeader("nagilum", "nagilum") + )).getStatusCode() + ); System.out.println(res.getBody()); assertNotContains(res, "*xception*"); assertNotContains(res, "*erial*"); @@ -88,8 +125,15 @@ public void testBasicAggregations() throws Exception { assertContains(res, "*xyz*"); assertContains(res, "*role01_role02*"); assertContains(res, "*\"failed\" : 0*"); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("*/_search?pretty", "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":40}}}}",encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest( + "*/_search?pretty", + "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":40}}}}", + encodeBasicHeader("nagilum", "nagilum") + )).getStatusCode() + ); System.out.println(res.getBody()); assertNotContains(res, "*xception*"); assertNotContains(res, "*erial*"); @@ -101,8 +145,15 @@ public void testBasicAggregations() throws Exception { assertContains(res, "*xyz*"); assertContains(res, "*role01_role02*"); assertContains(res, "*\"failed\" : 0*"); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("_search?pretty", "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":40}}}}",encodeBasicHeader("worf", "worf"))).getStatusCode()); + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest( + "_search?pretty", + "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":40}}}}", + encodeBasicHeader("worf", "worf") + )).getStatusCode() + ); System.out.println(res.getBody()); assertNotContains(res, "*xception*"); assertNotContains(res, "*erial*"); @@ -114,9 +165,16 @@ public void testBasicAggregations() throws Exception { assertContains(res, "*public*"); assertContains(res, "*xyz*"); assertContains(res, "*\"failed\" : 0*"); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executePostRequest("_search?pretty", "{\"size\":0,\"aggs\":{\"myindices\":{\"terms\":{\"field\":\"_index\",\"size\":40}}}}",encodeBasicHeader("worf", "worf"))).getStatusCode()); - + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executePostRequest( + "_search?pretty", + "{\"size\":0,\"aggs\":{\"myindices\":{\"terms\":{\"field\":\"_index\",\"size\":40}}}}", + encodeBasicHeader("worf", "worf") + )).getStatusCode() + ); + } - + } diff --git a/src/test/java/org/opensearch/security/AlwaysFalseInterClusterRequestEvaluator.java b/src/test/java/org/opensearch/security/AlwaysFalseInterClusterRequestEvaluator.java index 7fdf2d8bfc..b741dd2c70 100644 --- a/src/test/java/org/opensearch/security/AlwaysFalseInterClusterRequestEvaluator.java +++ b/src/test/java/org/opensearch/security/AlwaysFalseInterClusterRequestEvaluator.java @@ -32,7 +32,6 @@ import org.opensearch.security.transport.InterClusterRequestEvaluator; import org.opensearch.transport.TransportRequest; - public class AlwaysFalseInterClusterRequestEvaluator implements InterClusterRequestEvaluator { public AlwaysFalseInterClusterRequestEvaluator(Settings settings) { @@ -40,14 +39,22 @@ public AlwaysFalseInterClusterRequestEvaluator(Settings settings) { } @Override - public boolean isInterClusterRequest(TransportRequest request, X509Certificate[] localCerts, X509Certificate[] peerCerts, - String principal) { - - if(localCerts == null || peerCerts == null || principal == null - || localCerts.length == 0 || peerCerts.length == 0 || principal.length() == 0) { + public boolean isInterClusterRequest( + TransportRequest request, + X509Certificate[] localCerts, + X509Certificate[] peerCerts, + String principal + ) { + + if (localCerts == null + || peerCerts == null + || principal == null + || localCerts.length == 0 + || peerCerts.length == 0 + || principal.length() == 0) { return true; } - + return false; } diff --git a/src/test/java/org/opensearch/security/ConfigTests.java b/src/test/java/org/opensearch/security/ConfigTests.java index c5b8c089e4..519faa612d 100644 --- a/src/test/java/org/opensearch/security/ConfigTests.java +++ b/src/test/java/org/opensearch/security/ConfigTests.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security; @@ -46,89 +46,97 @@ import org.opensearch.security.test.SingleClusterTest; public class ConfigTests { - + private static final ObjectMapper YAML = new ObjectMapper(new YAMLFactory()); - + @Test public void testEmptyConfig() throws Exception { Assert.assertTrue(SecurityDynamicConfiguration.empty().deepClone() != SecurityDynamicConfiguration.empty()); } - + @Test public void testMigrate() throws Exception { - Tuple, SecurityDynamicConfiguration> rolesResult = Migration.migrateRoles((SecurityDynamicConfiguration)load("./legacy/securityconfig_v6/roles.yml", CType.ROLES), - (SecurityDynamicConfiguration)load("./legacy/securityconfig_v6/roles_mapping.yml", CType.ROLESMAPPING)); - + Tuple, SecurityDynamicConfiguration> rolesResult = Migration.migrateRoles( + (SecurityDynamicConfiguration) load("./legacy/securityconfig_v6/roles.yml", CType.ROLES), + (SecurityDynamicConfiguration) load("./legacy/securityconfig_v6/roles_mapping.yml", CType.ROLESMAPPING) + ); + System.out.println(Strings.toString(XContentType.JSON, rolesResult.v2(), true, false)); System.out.println(Strings.toString(XContentType.JSON, rolesResult.v1(), true, false)); - - - SecurityDynamicConfiguration actionGroupsResult = Migration.migrateActionGroups((SecurityDynamicConfiguration)load("./legacy/securityconfig_v6/action_groups.yml", CType.ACTIONGROUPS)); + + SecurityDynamicConfiguration actionGroupsResult = Migration.migrateActionGroups( + (SecurityDynamicConfiguration) load("./legacy/securityconfig_v6/action_groups.yml", CType.ACTIONGROUPS) + ); System.out.println(Strings.toString(XContentType.JSON, actionGroupsResult, true, false)); - SecurityDynamicConfiguration configResult =Migration.migrateConfig((SecurityDynamicConfiguration)load("./legacy/securityconfig_v6/config.yml", CType.CONFIG)); + SecurityDynamicConfiguration configResult = Migration.migrateConfig( + (SecurityDynamicConfiguration) load("./legacy/securityconfig_v6/config.yml", CType.CONFIG) + ); System.out.println(Strings.toString(XContentType.JSON, configResult, true, false)); - SecurityDynamicConfiguration internalUsersResult = Migration.migrateInternalUsers((SecurityDynamicConfiguration)load("./legacy/securityconfig_v6/internal_users.yml", CType.INTERNALUSERS)); + SecurityDynamicConfiguration internalUsersResult = Migration.migrateInternalUsers( + (SecurityDynamicConfiguration) load("./legacy/securityconfig_v6/internal_users.yml", CType.INTERNALUSERS) + ); System.out.println(Strings.toString(XContentType.JSON, internalUsersResult, true, false)); - SecurityDynamicConfiguration rolemappingsResult = Migration.migrateRoleMappings((SecurityDynamicConfiguration)load("./legacy/securityconfig_v6/roles_mapping.yml", CType.ROLESMAPPING)); + SecurityDynamicConfiguration rolemappingsResult = Migration.migrateRoleMappings( + (SecurityDynamicConfiguration) load("./legacy/securityconfig_v6/roles_mapping.yml", CType.ROLESMAPPING) + ); System.out.println(Strings.toString(XContentType.JSON, rolemappingsResult, true, false)); } - + @Test public void testParseSg67Config() throws Exception { check("./legacy/securityconfig_v6/action_groups.yml", CType.ACTIONGROUPS); check("./action_groups.yml", CType.ACTIONGROUPS); - + check("./legacy/securityconfig_v6/config.yml", CType.CONFIG); check("./config.yml", CType.CONFIG); - + check("./legacy/securityconfig_v6/roles.yml", CType.ROLES); check("./roles.yml", CType.ROLES); - + check("./legacy/securityconfig_v6/internal_users.yml", CType.INTERNALUSERS); check("./internal_users.yml", CType.INTERNALUSERS); - + check("./legacy/securityconfig_v6/roles_mapping.yml", CType.ROLESMAPPING); check("./roles_mapping.yml", CType.ROLESMAPPING); - + check("./tenants.yml", CType.TENANTS); - + } - + private void check(String file, CType cType) throws Exception { final String adjustedFilePath = SingleClusterTest.TEST_RESOURCE_RELATIVE_PATH + file; JsonNode jsonNode = YAML.readTree(FileUtils.readFileToString(new File(adjustedFilePath), "UTF-8")); int configVersion = 1; System.out.println("%%%%%%%% THIS IS A LINE OF INTEREST %%%%%%%"); - if(jsonNode.get("_meta") != null) { + if (jsonNode.get("_meta") != null) { Assert.assertEquals(jsonNode.get("_meta").get("type").asText(), cType.toLCString()); configVersion = jsonNode.get("_meta").get("config_version").asInt(); } + System.out.println("%%%%%%%% THIS IS A LINE OF INTEREST: CONFIG VERSION: " + configVersion + "%%%%%%%"); - System.out.println("%%%%%%%% THIS IS A LINE OF INTEREST: CONFIG VERSION: "+ configVersion + "%%%%%%%"); - SecurityDynamicConfiguration dc = load(file, cType); Assert.assertNotNull(dc); - //Assert.assertTrue(dc.getCEntries().size() > 0); + // Assert.assertTrue(dc.getCEntries().size() > 0); String jsonSerialize = DefaultObjectMapper.objectMapper.writeValueAsString(dc); SecurityDynamicConfiguration conf = SecurityDynamicConfiguration.fromJson(jsonSerialize, cType, configVersion, 0, 0); SecurityDynamicConfiguration.fromJson(Strings.toString(XContentType.JSON, conf), cType, configVersion, 0, 0); - + } - + private SecurityDynamicConfiguration load(String file, CType cType) throws Exception { final String adjustedFilePath = SingleClusterTest.TEST_RESOURCE_RELATIVE_PATH + file; JsonNode jsonNode = YAML.readTree(FileUtils.readFileToString(new File(adjustedFilePath), "UTF-8")); int configVersion = 1; System.out.println("%%%%%%%% THIS IS A LINE OF INTEREST LOAD: CONFIG VERSION: %%%%%%%"); - if(jsonNode.get("_meta") != null) { + if (jsonNode.get("_meta") != null) { Assert.assertEquals(jsonNode.get("_meta").get("type").asText(), cType.toLCString()); configVersion = jsonNode.get("_meta").get("config_version").asInt(); } - System.out.println("%%%%%%%% THIS IS A LINE OF INTEREST: CONFIG VERSION: "+ configVersion + "%%%%%%%"); + System.out.println("%%%%%%%% THIS IS A LINE OF INTEREST: CONFIG VERSION: " + configVersion + "%%%%%%%"); return SecurityDynamicConfiguration.fromNode(jsonNode, cType, configVersion, 0, 0); } } diff --git a/src/test/java/org/opensearch/security/DataStreamIntegrationTests.java b/src/test/java/org/opensearch/security/DataStreamIntegrationTests.java index 78c9ab7818..773244c7ea 100644 --- a/src/test/java/org/opensearch/security/DataStreamIntegrationTests.java +++ b/src/test/java/org/opensearch/security/DataStreamIntegrationTests.java @@ -19,25 +19,29 @@ import org.opensearch.security.test.helper.rest.RestHelper; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; - public class DataStreamIntegrationTests extends SingleClusterTest { - final String bulkDocsBody = - "{ \"create\" : {} }" + System.lineSeparator() + - "{ \"@timestamp\" : \"2099-03-08T11:04:05.000Z\", \"user\" : { \"id\" : \"vlb44hny\", \"name\": \"Sam\"}, \"message\" : \"Login attempt failed\" }" + System.lineSeparator() + - "{ \"create\" : {} }" + System.lineSeparator() + - "{ \"@timestamp\" : \"2099-03-08T11:04:05.000Z\", \"user\" : { \"id\" : \"8a4f500d\", \"name\": \"Dam\"}, \"message\" : \"Login successful\" }" + System.lineSeparator() + - "{ \"create\" : {} }" + System.lineSeparator() + - "{ \"@timestamp\" : \"2099-03-08T11:04:05.000Z\", \"user\" : { \"id\" : \"l7gk7f82\", \"name\": \"Pam\"}, \"message\" : \"Login attempt failed\" }" + System.lineSeparator(); + final String bulkDocsBody = "{ \"create\" : {} }" + + System.lineSeparator() + + "{ \"@timestamp\" : \"2099-03-08T11:04:05.000Z\", \"user\" : { \"id\" : \"vlb44hny\", \"name\": \"Sam\"}, \"message\" : \"Login attempt failed\" }" + + System.lineSeparator() + + "{ \"create\" : {} }" + + System.lineSeparator() + + "{ \"@timestamp\" : \"2099-03-08T11:04:05.000Z\", \"user\" : { \"id\" : \"8a4f500d\", \"name\": \"Dam\"}, \"message\" : \"Login successful\" }" + + System.lineSeparator() + + "{ \"create\" : {} }" + + System.lineSeparator() + + "{ \"@timestamp\" : \"2099-03-08T11:04:05.000Z\", \"user\" : { \"id\" : \"l7gk7f82\", \"name\": \"Pam\"}, \"message\" : \"Login attempt failed\" }" + + System.lineSeparator(); final String searchQuery1 = "{ \"seq_no_primary_term\" : true, \"query\": { \"match\": { \"user.id\": \"8a4f500d\"}}}"; final String searchQuery2 = "{ \"seq_no_primary_term\" : true, \"query\": { \"match\": { \"user.id\": \"l7gk7f82\"}}}"; public String getIndexTemplateBody() { - return "{\"index_patterns\": [ \"my-data-stream*\" ], \"data_stream\": { }, \"priority\": 200, \"template\": {\"settings\": { } } }"; + return "{\"index_patterns\": [ \"my-data-stream*\" ], \"data_stream\": { }, \"priority\": 200, \"template\": {\"settings\": { } } }"; } - public void createSampleDataStreams(RestHelper rh) throws Exception{ + public void createSampleDataStreams(RestHelper rh) throws Exception { // Valid index-template is required to create data-streams rh.executePutRequest("/_index_template/my-data-stream-template", getIndexTemplateBody(), encodeBasicHeader("ds1", "nagilum")); @@ -55,10 +59,18 @@ public void testCreateDataStream() throws Exception { RestHelper rh = nonSslRestHelper(); HttpResponse response; - response = rh.executePutRequest("/_index_template/my-data-stream-template", getIndexTemplateBody(), encodeBasicHeader("ds0", "nagilum")); + response = rh.executePutRequest( + "/_index_template/my-data-stream-template", + getIndexTemplateBody(), + encodeBasicHeader("ds0", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); - response = rh.executePutRequest("/_index_template/my-data-stream-template", getIndexTemplateBody(), encodeBasicHeader("ds1", "nagilum")); + response = rh.executePutRequest( + "/_index_template/my-data-stream-template", + getIndexTemplateBody(), + encodeBasicHeader("ds1", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executePutRequest("/_data_stream/my-data-stream11", getIndexTemplateBody(), encodeBasicHeader("ds0", "nagilum")); diff --git a/src/test/java/org/opensearch/security/EncryptionInTransitMigrationTests.java b/src/test/java/org/opensearch/security/EncryptionInTransitMigrationTests.java index 5535d8a924..462cd591e6 100644 --- a/src/test/java/org/opensearch/security/EncryptionInTransitMigrationTests.java +++ b/src/test/java/org/opensearch/security/EncryptionInTransitMigrationTests.java @@ -44,7 +44,7 @@ private void testSslOnlyMode(boolean dualModeEnabled) throws Exception { HttpResponse res = rh.executeGetRequest("_opendistro/_security/sslinfo"); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - res = rh.executePutRequest("/xyz/_doc/1","{\"a\":5}"); + res = rh.executePutRequest("/xyz/_doc/1", "{\"a\":5}"); Assert.assertEquals(HttpStatus.SC_CREATED, res.getStatusCode()); res = rh.executeGetRequest("/_mappings"); @@ -58,21 +58,29 @@ private void testSslOnlyMode(boolean dualModeEnabled) throws Exception { Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("\"plugins.security_config.ssl_dual_mode_enabled\":\"true\"")); - String disableDualModeClusterSetting = "{ \"persistent\": { \"" + ConfigConstants.SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED + "\": false } }"; + String disableDualModeClusterSetting = "{ \"persistent\": { \"" + + ConfigConstants.SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED + + "\": false } }"; res = rh.executePutRequest("_cluster/settings", disableDualModeClusterSetting); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertEquals("{\"acknowledged\":true,\"persistent\":{\"plugins\":{\"security_config\":{\"ssl_dual_mode_enabled\":\"false\"}}},\"transient\":{}}", res.getBody()); - + Assert.assertEquals( + "{\"acknowledged\":true,\"persistent\":{\"plugins\":{\"security_config\":{\"ssl_dual_mode_enabled\":\"false\"}}},\"transient\":{}}", + res.getBody() + ); res = rh.executeGetRequest("_cluster/settings?flat_settings&include_defaults"); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("\"plugins.security_config.ssl_dual_mode_enabled\":\"false\"")); - String enableDualModeClusterSetting = "{ \"persistent\": { \"" + ConfigConstants.SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED + "\": true } }"; + String enableDualModeClusterSetting = "{ \"persistent\": { \"" + + ConfigConstants.SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED + + "\": true } }"; res = rh.executePutRequest("_cluster/settings", enableDualModeClusterSetting); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertEquals("{\"acknowledged\":true,\"persistent\":{\"plugins\":{\"security_config\":{\"ssl_dual_mode_enabled\":\"true\"}}},\"transient\":{}}", res.getBody()); - + Assert.assertEquals( + "{\"acknowledged\":true,\"persistent\":{\"plugins\":{\"security_config\":{\"ssl_dual_mode_enabled\":\"true\"}}},\"transient\":{}}", + res.getBody() + ); res = rh.executeGetRequest("_cluster/settings?flat_settings&include_defaults"); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); @@ -80,8 +88,10 @@ private void testSslOnlyMode(boolean dualModeEnabled) throws Exception { res = rh.executePutRequest("_cluster/settings", disableDualModeClusterSetting); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertEquals("{\"acknowledged\":true,\"persistent\":{\"plugins\":{\"security_config\":{\"ssl_dual_mode_enabled\":\"false\"}}},\"transient\":{}}", res.getBody()); - + Assert.assertEquals( + "{\"acknowledged\":true,\"persistent\":{\"plugins\":{\"security_config\":{\"ssl_dual_mode_enabled\":\"false\"}}},\"transient\":{}}", + res.getBody() + ); res = rh.executeGetRequest("_cluster/settings?flat_settings&include_defaults"); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); @@ -118,23 +128,19 @@ public void testSslOnlyModeDualModeWithNonSSLDataNode() throws Exception { @Test public void testDualModeSettingFallback() throws Exception { final Settings legacySettings = Settings.builder() - .put(ConfigConstants.LEGACY_OPENDISTRO_SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED, true) - .build(); + .put(ConfigConstants.LEGACY_OPENDISTRO_SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED, true) + .build(); Assert.assertEquals(SecuritySettings.SSL_DUAL_MODE_SETTING.get(legacySettings), true); final Settings legacySettings2 = Settings.builder() - .put(ConfigConstants.LEGACY_OPENDISTRO_SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED, false) - .build(); + .put(ConfigConstants.LEGACY_OPENDISTRO_SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED, false) + .build(); Assert.assertEquals(SecuritySettings.SSL_DUAL_MODE_SETTING.get(legacySettings2), false); - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED, true) - .build(); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED, true).build(); Assert.assertEquals(SecuritySettings.SSL_DUAL_MODE_SETTING.get(settings), true); - final Settings settings2 = Settings.builder() - .put(ConfigConstants.SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED, false) - .build(); + final Settings settings2 = Settings.builder().put(ConfigConstants.SECURITY_CONFIG_SSL_DUAL_MODE_ENABLED, false).build(); Assert.assertEquals(SecuritySettings.SSL_DUAL_MODE_SETTING.get(settings2), false); } } diff --git a/src/test/java/org/opensearch/security/HealthTests.java b/src/test/java/org/opensearch/security/HealthTests.java index 4cba4030e6..a31e22dff4 100644 --- a/src/test/java/org/opensearch/security/HealthTests.java +++ b/src/test/java/org/opensearch/security/HealthTests.java @@ -37,39 +37,48 @@ import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; public class HealthTests extends SingleClusterTest { - + @Test public void testHealth() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig(), Settings.EMPTY); - + RestHelper rh = nonSslRestHelper(); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_opendistro/_security/health?pretty&mode=lenient")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("_opendistro/_security/health?pretty&mode=lenient")).getStatusCode() + ); System.out.println(res.getBody()); assertContains(res, "*UP*"); assertNotContains(res, "*DOWN*"); assertNotContains(res, "*strict*"); - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); System.out.println(res.getBody()); assertContains(res, "*UP*"); assertContains(res, "*strict*"); assertNotContains(res, "*DOWN*"); } - + @Test public void testHealthUnitialized() throws Exception { setup(Settings.EMPTY, null, Settings.EMPTY, false); - + RestHelper rh = nonSslRestHelper(); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_opendistro/_security/health?pretty&mode=lenient")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("_opendistro/_security/health?pretty&mode=lenient")).getStatusCode() + ); System.out.println(res.getBody()); assertContains(res, "*UP*"); assertNotContains(res, "*DOWN*"); assertNotContains(res, "*strict*"); - - Assert.assertEquals(HttpStatus.SC_SERVICE_UNAVAILABLE, (res = rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); + + Assert.assertEquals( + HttpStatus.SC_SERVICE_UNAVAILABLE, + (res = rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode() + ); System.out.println(res.getBody()); assertContains(res, "*DOWN*"); assertContains(res, "*strict*"); diff --git a/src/test/java/org/opensearch/security/HttpIntegrationTests.java b/src/test/java/org/opensearch/security/HttpIntegrationTests.java index d9ed9c34df..a4011b05f6 100644 --- a/src/test/java/org/opensearch/security/HttpIntegrationTests.java +++ b/src/test/java/org/opensearch/security/HttpIntegrationTests.java @@ -64,205 +64,373 @@ public class HttpIntegrationTests extends SingleClusterTest { @Test public void testHTTPBasic() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS+".worf", "knuddel","nonexists") - .build(); + .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS + ".worf", "knuddel", "nonexists") + .build(); setup(settings); final RestHelper rh = nonSslRestHelper(); - - try (Client tc = getClient()) { - tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("v2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("v3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("starfleet","starfleet_academy","starfleet_library").alias("sf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire","vulcangov").alias("nonsf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))).actionGet(); - - } - - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("").getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("_search").getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeDeleteRequest("nonexistentindex*", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest(".nonexistentindex*", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest(".opendistro_security/_doc/2", "{}",encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_NOT_FOUND, rh.executeGetRequest(".opendistro_security/_doc/0", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_NOT_FOUND, rh.executeGetRequest("xxxxyyyy/_doc/0", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("abc", "abc:abc")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("userwithnopassword", "")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("userwithblankpassword", "")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("worf", "wrongpasswd")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", new BasicHeader("Authorization", "Basic "+"wrongheader")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", new BasicHeader("Authorization", "Basic ")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", new BasicHeader("Authorization", "Basic")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", new BasicHeader("Authorization", "")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("picard", "picard")).getStatusCode()); - - for(int i=0; i< 10; i++) { - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("worf", "wrongpasswd")).getStatusCode()); - } - - Assert.assertEquals(HttpStatus.SC_OK, rh.executePutRequest("/theindex","{}",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_CREATED, rh.executePutRequest("/theindex/_doc/1?refresh=true","{\"a\":0}",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); - //Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("/theindex/_analyze?text=this+is+a+test",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); - //Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("_analyze?text=this+is+a+test",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeDeleteRequest("/theindex",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeDeleteRequest("/klingonempire",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("starfleet/_search", encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("_search", encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeDeleteRequest(".opendistro_security/", encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("/.opendistro_security/_close", null,encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("/.opendistro_security/_upgrade", null,encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest("/.opendistro_security/_mapping","{}",encodeBasicHeader("worf", "worf")).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest(".opendistro_security/", encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest(".opendistro_security/_doc/2", "{}",encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest(".opendistro_security/_doc/0",encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeDeleteRequest(".opendistro_security/_doc/0",encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest(".opendistro_security/_doc/0","{}",encodeBasicHeader("worf", "worf")).getStatusCode()); - - HttpResponse resc = rh.executeGetRequest("_cat/indices/public?v",encodeBasicHeader("bug108", "nagilum")); - Assert.assertTrue(resc.getBody().contains("green")); - Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("role01_role02/_search?pretty",encodeBasicHeader("user_role01_role02_role03", "user_role01_role02_role03")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("role01_role02/_search?pretty",encodeBasicHeader("user_role01", "user_role01")).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("spock/_search?pretty",encodeBasicHeader("spock", "spock")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("spock/_search?pretty",encodeBasicHeader("kirk", "kirk")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("kirk/_search?pretty",encodeBasicHeader("kirk", "kirk")).getStatusCode()); - - //all - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest(".opendistro_security/_mget","{\"ids\" : [\"0\"]}",encodeBasicHeader("worf", "worf")).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf")).getStatusCode()); - - try (Client tc = getClient()) { - tc.index(new IndexRequest(".opendistro_security").id("roles").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("roles", FileHelper.readYamlContent("roles_deny.yml"))).actionGet(); - ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[]{"roles"})).actionGet(); - Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); - } - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf")).getStatusCode()); - - try (Client tc = getClient()) { - tc.index(new IndexRequest(".opendistro_security").id("roles").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("roles", FileHelper.readYamlContent("roles.yml"))).actionGet(); - ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[]{"roles"})).actionGet(); - Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); - } - - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf")).getStatusCode()); - HttpResponse res = rh.executeGetRequest("_search?pretty", encodeBasicHeader("nagilum", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertTrue(res.getBody().contains("\"value\" : 11")); - Assert.assertTrue(!res.getBody().contains(".opendistro_security")); - - res = rh.executeGetRequest("_nodes/stats?pretty", encodeBasicHeader("nagilum", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertTrue(res.getBody().contains("total_in_bytes")); - Assert.assertTrue(res.getBody().contains("max_file_descriptors")); - Assert.assertTrue(res.getBody().contains("buffer_pools")); - Assert.assertFalse(res.getBody().contains("\"nodes\" : { }")); - - res = rh.executePostRequest("*/_upgrade", "", encodeBasicHeader("nagilum", "nagilum")); - System.out.println(res.getBody()); - System.out.println(res.getStatusReason()); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - - String bulkBody = - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"field1\" : \"value1\" }" +System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator(); - - res = rh.executePostRequest("_bulk", bulkBody, encodeBasicHeader("writer", "writer")); - System.out.println(res.getBody()); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertTrue(res.getBody().contains("\"errors\":false")); - Assert.assertTrue(res.getBody().contains("\"status\":201")); - - res = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("security_tenant", "unittesttenant"), encodeBasicHeader("worf", "worf")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertTrue(res.getBody().contains("tenant")); - Assert.assertTrue(res.getBody().contains("unittesttenant")); - Assert.assertTrue(res.getBody().contains("\"kltentrw\":true")); - Assert.assertTrue(res.getBody().contains("\"user_name\":\"worf\"")); - - res = rh.executeGetRequest("_opendistro/_security/authinfo", encodeBasicHeader("worf", "worf")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertTrue(res.getBody().contains("tenant")); - Assert.assertTrue(res.getBody().contains("\"user_requested_tenant\":null")); - Assert.assertTrue(res.getBody().contains("\"kltentrw\":true")); - Assert.assertTrue(res.getBody().contains("\"user_name\":\"worf\"")); - Assert.assertTrue(res.getBody().contains("\"custom_attribute_names\":[]")); - Assert.assertFalse(res.getBody().contains("attributes=")); - - res = rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("custattr", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertTrue(res.getBody().contains("tenants")); - Assert.assertTrue(res.getBody().contains("\"user_requested_tenant\" : null")); - Assert.assertTrue(res.getBody().contains("\"user_name\" : \"custattr\"")); - Assert.assertTrue(res.getBody().contains("\"custom_attribute_names\" : [")); - Assert.assertTrue(res.getBody().contains("attr.internal.c3")); - Assert.assertTrue(res.getBody().contains("attr.internal.c1")); - - res = rh.executeGetRequest("v2/_search", encodeBasicHeader("custattr", "nagilum")); - Assert.assertEquals(res.getBody(), HttpStatus.SC_OK, res.getStatusCode()); - - res = rh.executeGetRequest("v3/_search", encodeBasicHeader("custattr", "nagilum")); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); - - final String reindex = "{"+ - "\"source\": {"+ - "\"index\": \"starfleet\""+ - "},"+ - "\"dest\": {"+ - "\"index\": \"copysf\""+ - "}"+ - "}"; - - res = rh.executePostRequest("_reindex?pretty", reindex, encodeBasicHeader("nagilum", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertTrue(res.getBody().contains("\"total\" : 1")); - Assert.assertTrue(res.getBody().contains("\"batches\" : 1")); - Assert.assertTrue(res.getBody().contains("\"failures\" : [ ]")); - - //rest impersonation - res = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as","knuddel"), encodeBasicHeader("worf", "worf")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertTrue(res.getBody().contains("name=knuddel")); - Assert.assertTrue(res.getBody().contains("attr.internal.test1")); - Assert.assertFalse(res.getBody().contains("worf")); - - res = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as","nonexists"), encodeBasicHeader("worf", "worf")); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); - - res = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as","notallowed"), encodeBasicHeader("worf", "worf")); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); + + try (Client tc = getClient()) { + tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); + tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("v2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("v3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction( + AliasActions.add().indices("starfleet", "starfleet_academy", "starfleet_library").alias("sf") + ) + ) + .actionGet(); + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire", "vulcangov").alias("nonsf")) + ) + .actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))) + .actionGet(); + + } + + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("").getStatusCode()); + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("_search").getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("worf", "worf")).getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeDeleteRequest("nonexistentindex*", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest(".nonexistentindex*", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest(".opendistro_security/_doc/2", "{}", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_NOT_FOUND, + rh.executeGetRequest(".opendistro_security/_doc/0", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_NOT_FOUND, + rh.executeGetRequest("xxxxyyyy/_doc/0", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("abc", "abc:abc")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_UNAUTHORIZED, + rh.executeGetRequest("", encodeBasicHeader("userwithnopassword", "")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_UNAUTHORIZED, + rh.executeGetRequest("", encodeBasicHeader("userwithblankpassword", "")).getStatusCode() + ); + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("worf", "wrongpasswd")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_UNAUTHORIZED, + rh.executeGetRequest("", new BasicHeader("Authorization", "Basic " + "wrongheader")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_UNAUTHORIZED, + rh.executeGetRequest("", new BasicHeader("Authorization", "Basic ")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_UNAUTHORIZED, + rh.executeGetRequest("", new BasicHeader("Authorization", "Basic")).getStatusCode() + ); + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", new BasicHeader("Authorization", "")).getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("picard", "picard")).getStatusCode()); + + for (int i = 0; i < 10; i++) { + Assert.assertEquals( + HttpStatus.SC_UNAUTHORIZED, + rh.executeGetRequest("", encodeBasicHeader("worf", "wrongpasswd")).getStatusCode() + ); + } + + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePutRequest("/theindex", "{}", encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_CREATED, + rh.executePutRequest("/theindex/_doc/1?refresh=true", "{\"a\":0}", encodeBasicHeader("theindexadmin", "theindexadmin")) + .getStatusCode() + ); + // Assert.assertEquals(HttpStatus.SC_OK, + // rh.executeGetRequest("/theindex/_analyze?text=this+is+a+test",encodeBasicHeader("theindexadmin", + // "theindexadmin")).getStatusCode()); + // Assert.assertEquals(HttpStatus.SC_FORBIDDEN, + // rh.executeGetRequest("_analyze?text=this+is+a+test",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeDeleteRequest("/theindex", encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeDeleteRequest("/klingonempire", encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode() + ); + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("starfleet/_search", encodeBasicHeader("worf", "worf")).getStatusCode()); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("_search", encodeBasicHeader("worf", "worf")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeDeleteRequest(".opendistro_security/", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest("/.opendistro_security/_close", null, encodeBasicHeader("worf", "worf")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest("/.opendistro_security/_upgrade", null, encodeBasicHeader("worf", "worf")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest("/.opendistro_security/_mapping", "{}", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeGetRequest(".opendistro_security/", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest(".opendistro_security/_doc/2", "{}", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeGetRequest(".opendistro_security/_doc/0", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeDeleteRequest(".opendistro_security/_doc/0", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest(".opendistro_security/_doc/0", "{}", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + + HttpResponse resc = rh.executeGetRequest("_cat/indices/public?v", encodeBasicHeader("bug108", "nagilum")); + Assert.assertTrue(resc.getBody().contains("green")); + Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); + + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest( + "role01_role02/_search?pretty", + encodeBasicHeader("user_role01_role02_role03", "user_role01_role02_role03") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeGetRequest("role01_role02/_search?pretty", encodeBasicHeader("user_role01", "user_role01")).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("spock/_search?pretty", encodeBasicHeader("spock", "spock")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeGetRequest("spock/_search?pretty", encodeBasicHeader("kirk", "kirk")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("kirk/_search?pretty", encodeBasicHeader("kirk", "kirk")).getStatusCode() + ); + + // all + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest(".opendistro_security/_mget", "{\"ids\" : [\"0\"]}", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + + try (Client tc = getClient()) { + tc.index( + new IndexRequest(".opendistro_security").id("roles") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("roles", FileHelper.readYamlContent("roles_deny.yml")) + ).actionGet(); + ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[] { "roles" })) + .actionGet(); + Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); } + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + + try (Client tc = getClient()) { + tc.index( + new IndexRequest(".opendistro_security").id("roles") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("roles", FileHelper.readYamlContent("roles.yml")) + ).actionGet(); + ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[] { "roles" })) + .actionGet(); + Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); + } + + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + HttpResponse res = rh.executeGetRequest("_search?pretty", encodeBasicHeader("nagilum", "nagilum")); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("\"value\" : 11")); + Assert.assertTrue(!res.getBody().contains(".opendistro_security")); + + res = rh.executeGetRequest("_nodes/stats?pretty", encodeBasicHeader("nagilum", "nagilum")); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("total_in_bytes")); + Assert.assertTrue(res.getBody().contains("max_file_descriptors")); + Assert.assertTrue(res.getBody().contains("buffer_pools")); + Assert.assertFalse(res.getBody().contains("\"nodes\" : { }")); + + res = rh.executePostRequest("*/_upgrade", "", encodeBasicHeader("nagilum", "nagilum")); + System.out.println(res.getBody()); + System.out.println(res.getStatusReason()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + + String bulkBody = "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"field1\" : \"value1\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator(); + + res = rh.executePostRequest("_bulk", bulkBody, encodeBasicHeader("writer", "writer")); + System.out.println(res.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("\"errors\":false")); + Assert.assertTrue(res.getBody().contains("\"status\":201")); + + res = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader("security_tenant", "unittesttenant"), + encodeBasicHeader("worf", "worf") + ); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("tenant")); + Assert.assertTrue(res.getBody().contains("unittesttenant")); + Assert.assertTrue(res.getBody().contains("\"kltentrw\":true")); + Assert.assertTrue(res.getBody().contains("\"user_name\":\"worf\"")); + + res = rh.executeGetRequest("_opendistro/_security/authinfo", encodeBasicHeader("worf", "worf")); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("tenant")); + Assert.assertTrue(res.getBody().contains("\"user_requested_tenant\":null")); + Assert.assertTrue(res.getBody().contains("\"kltentrw\":true")); + Assert.assertTrue(res.getBody().contains("\"user_name\":\"worf\"")); + Assert.assertTrue(res.getBody().contains("\"custom_attribute_names\":[]")); + Assert.assertFalse(res.getBody().contains("attributes=")); + + res = rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("custattr", "nagilum")); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("tenants")); + Assert.assertTrue(res.getBody().contains("\"user_requested_tenant\" : null")); + Assert.assertTrue(res.getBody().contains("\"user_name\" : \"custattr\"")); + Assert.assertTrue(res.getBody().contains("\"custom_attribute_names\" : [")); + Assert.assertTrue(res.getBody().contains("attr.internal.c3")); + Assert.assertTrue(res.getBody().contains("attr.internal.c1")); + + res = rh.executeGetRequest("v2/_search", encodeBasicHeader("custattr", "nagilum")); + Assert.assertEquals(res.getBody(), HttpStatus.SC_OK, res.getStatusCode()); + + res = rh.executeGetRequest("v3/_search", encodeBasicHeader("custattr", "nagilum")); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); + + final String reindex = "{" + + "\"source\": {" + + "\"index\": \"starfleet\"" + + "}," + + "\"dest\": {" + + "\"index\": \"copysf\"" + + "}" + + "}"; + + res = rh.executePostRequest("_reindex?pretty", reindex, encodeBasicHeader("nagilum", "nagilum")); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("\"total\" : 1")); + Assert.assertTrue(res.getBody().contains("\"batches\" : 1")); + Assert.assertTrue(res.getBody().contains("\"failures\" : [ ]")); + + // rest impersonation + res = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader("opendistro_security_impersonate_as", "knuddel"), + encodeBasicHeader("worf", "worf") + ); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("name=knuddel")); + Assert.assertTrue(res.getBody().contains("attr.internal.test1")); + Assert.assertFalse(res.getBody().contains("worf")); + + res = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader("opendistro_security_impersonate_as", "nonexists"), + encodeBasicHeader("worf", "worf") + ); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); + + res = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader("opendistro_security_impersonate_as", "notallowed"), + encodeBasicHeader("worf", "worf") + ); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); + } + @Test public void testHTTPSCompressionEnabled() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .put("http.compression",true) - .build(); + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .put("http.compression", true) + .build(); setup(Settings.EMPTY, new DynamicSecurityConfig(), settings, true); - final RestHelper rh = restHelper(); //ssl resthelper + final RestHelper rh = restHelper(); // ssl resthelper HttpResponse res = rh.executeGetRequest("_opendistro/_security/sslinfo", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); @@ -274,16 +442,16 @@ public void testHTTPSCompressionEnabled() throws Exception { assertNotContains(res, "*\"compression\":\"false\"*"); assertContains(res, "*\"compression\":\"true\"*"); } - + @Test public void testHTTPSCompression() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .build(); + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .build(); setup(Settings.EMPTY, new DynamicSecurityConfig(), settings, true); - final RestHelper rh = restHelper(); //ssl resthelper + final RestHelper rh = restHelper(); // ssl resthelper HttpResponse res = rh.executeGetRequest("_opendistro/_security/sslinfo", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); @@ -298,78 +466,92 @@ public void testHTTPSCompression() throws Exception { @Test public void testHTTPAnon() throws Exception { - - setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_anon.yml"), Settings.EMPTY, true); - - RestHelper rh = nonSslRestHelper(); - - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("").getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("worf", "wrong")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - - HttpResponse resc = rh.executeGetRequest("_opendistro/_security/authinfo"); - Assert.assertTrue(resc.getBody().contains("opendistro_security_anonymous")); - Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - - resc = rh.executeGetRequest("_opendistro/_security/authinfo?pretty=true"); - System.out.println(resc.getBody()); - Assert.assertTrue(resc.getBody().contains("\"remote_address\" : \"")); //check pretty print - Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - - resc = rh.executeGetRequest("_opendistro/_security/authinfo", encodeBasicHeader("nagilum", "nagilum")); - System.out.println(resc.getBody()); - Assert.assertTrue(resc.getBody().contains("nagilum")); - Assert.assertFalse(resc.getBody().contains("opendistro_security_anonymous")); - Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - - try (Client tc = getClient()) { - tc.index(new IndexRequest(".opendistro_security").id("config").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("config", FileHelper.readYamlContent("config.yml"))).actionGet(); - tc.index(new IndexRequest(".opendistro_security").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("internalusers").source("internalusers", FileHelper.readYamlContent("internal_users.yml"))).actionGet(); - ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[]{"config","roles","rolesmapping","internalusers","actiongroups"})).actionGet(); - Assert.assertFalse(cur.hasFailures()); - Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); - } - - - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("").getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("_opendistro/_security/authinfo").getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("worf", "wrong")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + + setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_anon.yml"), Settings.EMPTY, true); + + RestHelper rh = nonSslRestHelper(); + + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("").getStatusCode()); + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("worf", "wrong")).getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + + HttpResponse resc = rh.executeGetRequest("_opendistro/_security/authinfo"); + Assert.assertTrue(resc.getBody().contains("opendistro_security_anonymous")); + Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); + + resc = rh.executeGetRequest("_opendistro/_security/authinfo?pretty=true"); + System.out.println(resc.getBody()); + Assert.assertTrue(resc.getBody().contains("\"remote_address\" : \"")); // check pretty print + Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); + + resc = rh.executeGetRequest("_opendistro/_security/authinfo", encodeBasicHeader("nagilum", "nagilum")); + System.out.println(resc.getBody()); + Assert.assertTrue(resc.getBody().contains("nagilum")); + Assert.assertFalse(resc.getBody().contains("opendistro_security_anonymous")); + Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); + + try (Client tc = getClient()) { + tc.index( + new IndexRequest(".opendistro_security").id("config") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("config", FileHelper.readYamlContent("config.yml")) + ).actionGet(); + tc.index( + new IndexRequest(".opendistro_security").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("internalusers") + .source("internalusers", FileHelper.readYamlContent("internal_users.yml")) + ).actionGet(); + ConfigUpdateResponse cur = tc.execute( + ConfigUpdateAction.INSTANCE, + new ConfigUpdateRequest(new String[] { "config", "roles", "rolesmapping", "internalusers", "actiongroups" }) + ).actionGet(); + Assert.assertFalse(cur.hasFailures()); + Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); + } + + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("").getStatusCode()); + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("_opendistro/_security/authinfo").getStatusCode()); + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("worf", "wrong")).getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); } @Test public void testHTTPClientCert() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.clientauth_mode","REQUIRE") - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .putList(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_PROTOCOLS, "TLSv1.1","TLSv1.2") - .putList(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_CIPHERS, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256") - .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_PROTOCOLS, "TLSv1.1","TLSv1.2") - .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_CIPHERS, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256") - .build(); - + .put("plugins.security.ssl.http.clientauth_mode", "REQUIRE") + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .putList(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_PROTOCOLS, "TLSv1.1", "TLSv1.2") + .putList(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_CIPHERS, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256") + .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_PROTOCOLS, "TLSv1.1", "TLSv1.2") + .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_CIPHERS, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256") + .build(); + setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_clientcert.yml"), settings, true); - + try (Client tc = getClient()) { - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[]{"config","roles","rolesmapping","internalusers","actiongroups"})).actionGet(); + tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + ConfigUpdateResponse cur = tc.execute( + ConfigUpdateAction.INSTANCE, + new ConfigUpdateRequest(new String[] { "config", "roles", "rolesmapping", "internalusers", "actiongroups" }) + ).actionGet(); Assert.assertFalse(cur.hasFailures()); Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); } - + RestHelper rh = restHelper(); - + rh.enableHTTPClientSSL = true; rh.trustHTTPServerCertificate = true; rh.sendAdminCertificate = true; rh.keystore = "spock-keystore.jks"; Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_search").getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest(".opendistro_security/_doc/x", "{}").getStatusCode()); - + rh.keystore = "kirk-keystore.jks"; Assert.assertEquals(HttpStatus.SC_CREATED, rh.executePutRequest(".opendistro_security/_doc/y", "{}").getStatusCode()); HttpResponse res; @@ -380,13 +562,13 @@ public void testHTTPClientCert() throws Exception { @Test @Ignore public void testHTTPPlaintextErrMsg() throws Exception { - + try { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .put("plugins.security.ssl.http.enabled", true) - .build(); + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .put("plugins.security.ssl.http.enabled", true) + .build(); setup(settings); RestHelper rh = nonSslRestHelper(); rh.executeGetRequest("", encodeBasicHeader("worf", "worf")); @@ -395,27 +577,75 @@ public void testHTTPPlaintextErrMsg() throws Exception { String log = FileUtils.readFileToString(new File("unittest.log"), StandardCharsets.UTF_8); Assert.assertTrue(log, log.contains("speaks http plaintext instead of ssl, will close the channel")); } catch (Exception e) { - Assert.fail("NoHttpResponseException expected but was "+e.getClass()+"#"+e.getMessage()); + Assert.fail("NoHttpResponseException expected but was " + e.getClass() + "#" + e.getMessage()); } } - @Test public void testHTTPProxyDefault() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_proxy.yml"), Settings.EMPTY, true); RestHelper rh = nonSslRestHelper(); - + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("").getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"),new BasicHeader("x-proxy-user", "scotty"), encodeBasicHeader("nagilum-wrong", "nagilum-wrong")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"),new BasicHeader("x-proxy-user-wrong", "scotty"), encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, rh.executeGetRequest("", new BasicHeader("x-forwarded-for", "a"),new BasicHeader("x-proxy-user", "scotty"), encodeBasicHeader("nagilum-wrong", "nagilum-wrong")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, rh.executeGetRequest("", new BasicHeader("x-forwarded-for", "a,b,c"),new BasicHeader("x-proxy-user", "scotty")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"),new BasicHeader("x-proxy-user", "scotty")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"),new BasicHeader("X-Proxy-User", "scotty")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"),new BasicHeader("x-proxy-user", "scotty"),new BasicHeader("x-proxy-roles", "starfleet,engineer")).getStatusCode()); - + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest( + "", + new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"), + new BasicHeader("x-proxy-user", "scotty"), + encodeBasicHeader("nagilum-wrong", "nagilum-wrong") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest( + "", + new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"), + new BasicHeader("x-proxy-user-wrong", "scotty"), + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_INTERNAL_SERVER_ERROR, + rh.executeGetRequest( + "", + new BasicHeader("x-forwarded-for", "a"), + new BasicHeader("x-proxy-user", "scotty"), + encodeBasicHeader("nagilum-wrong", "nagilum-wrong") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_INTERNAL_SERVER_ERROR, + rh.executeGetRequest("", new BasicHeader("x-forwarded-for", "a,b,c"), new BasicHeader("x-proxy-user", "scotty")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest( + "", + new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"), + new BasicHeader("x-proxy-user", "scotty") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest( + "", + new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"), + new BasicHeader("X-Proxy-User", "scotty") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest( + "", + new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"), + new BasicHeader("x-proxy-user", "scotty"), + new BasicHeader("x-proxy-roles", "starfleet,engineer") + ).getStatusCode() + ); + } @Test @@ -423,140 +653,282 @@ public void testHTTPProxyRolesSeparator() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_proxy_custom.yml"), Settings.EMPTY, true); RestHelper rh = nonSslRestHelper(); // separator is configured as ";" so separating roles with "," leads to one (wrong) backend role - HttpResponse res = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"),new BasicHeader("user", "scotty"),new BasicHeader("roles", "starfleet,engineer")); - Assert.assertTrue("Expected one backend role since separator is incorrect", res.getBody().contains("\"backend_roles\":[\"starfleet,engineer\"]")); + HttpResponse res = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"), + new BasicHeader("user", "scotty"), + new BasicHeader("roles", "starfleet,engineer") + ); + Assert.assertTrue( + "Expected one backend role since separator is incorrect", + res.getBody().contains("\"backend_roles\":[\"starfleet,engineer\"]") + ); // correct separator, now we should see two backend roles - res = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"),new BasicHeader("user", "scotty"),new BasicHeader("roles", "starfleet;engineer")); - Assert.assertTrue("Expected two backend roles string since separator is correct: " + res.getBody(), res.getBody().contains("\"backend_roles\":[\"starfleet\",\"engineer\"]")); - + res = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"), + new BasicHeader("user", "scotty"), + new BasicHeader("roles", "starfleet;engineer") + ); + Assert.assertTrue( + "Expected two backend roles string since separator is correct: " + res.getBody(), + res.getBody().contains("\"backend_roles\":[\"starfleet\",\"engineer\"]") + ); + } @Test - public void testHTTPBasic2() throws Exception { - - setup(Settings.EMPTY, new DynamicSecurityConfig(), Settings.EMPTY); - - try (Client tc = getClient()) { - - tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); - - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("starfleet","starfleet_academy","starfleet_library").alias("sf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire","vulcangov").alias("nonsf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))).actionGet(); - } - - RestHelper rh = nonSslRestHelper(); - - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("").getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeDeleteRequest("nonexistentindex*", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest(".nonexistentindex*", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest(".opendistro_security/_doc/2", "{}",encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_NOT_FOUND, rh.executeGetRequest(".opendistro_security/_doc/0", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_NOT_FOUND, rh.executeGetRequest("xxxxyyyy/_doc/0", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("abc", "abc:abc")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("userwithnopassword", "")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("userwithblankpassword", "")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("worf", "wrongpasswd")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", new BasicHeader("Authorization", "Basic "+"wrongheader")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", new BasicHeader("Authorization", "Basic ")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", new BasicHeader("Authorization", "Basic")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", new BasicHeader("Authorization", "")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("picard", "picard")).getStatusCode()); - - for(int i=0; i< 10; i++) { - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("worf", "wrongpasswd")).getStatusCode()); - } - - Assert.assertEquals(HttpStatus.SC_OK, rh.executePutRequest("/theindex","{}",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_CREATED, rh.executePutRequest("/theindex/_doc/1?refresh=true","{\"a\":0}",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); - //Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("/theindex/_analyze?text=this+is+a+test",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); - //Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("_analyze?text=this+is+a+test",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeDeleteRequest("/theindex",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeDeleteRequest("/klingonempire",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("starfleet/_search", encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("_search", encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeDeleteRequest(".opendistro_security/", encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("/.opendistro_security/_close", null,encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("/.opendistro_security/_upgrade", null,encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest("/.opendistro_security/_mapping","{}",encodeBasicHeader("worf", "worf")).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest(".opendistro_security/", encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest(".opendistro_security/_doc/2", "{}",encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest(".opendistro_security/_doc/0",encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeDeleteRequest(".opendistro_security/_doc/0",encodeBasicHeader("worf", "worf")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest(".opendistro_security/_doc/0","{}",encodeBasicHeader("worf", "worf")).getStatusCode()); - - HttpResponse resc = rh.executeGetRequest("_cat/indices/public",encodeBasicHeader("bug108", "nagilum")); - System.out.println(resc.getBody()); - //Assert.assertTrue(resc.getBody().contains("green")); - Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("role01_role02/_search?pretty",encodeBasicHeader("user_role01_role02_role03", "user_role01_role02_role03")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("role01_role02/_search?pretty",encodeBasicHeader("user_role01", "user_role01")).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("spock/_search?pretty",encodeBasicHeader("spock", "spock")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("spock/_search?pretty",encodeBasicHeader("kirk", "kirk")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("kirk/_search?pretty",encodeBasicHeader("kirk", "kirk")).getStatusCode()); - - System.out.println("ok"); - //all - - + public void testHTTPBasic2() throws Exception { + + setup(Settings.EMPTY, new DynamicSecurityConfig(), Settings.EMPTY); + + try (Client tc = getClient()) { + + tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); + + tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.index( + new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + + tc.index( + new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + + tc.index( + new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + + tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction( + AliasActions.add().indices("starfleet", "starfleet_academy", "starfleet_library").alias("sf") + ) + ) + .actionGet(); + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire", "vulcangov").alias("nonsf")) + ) + .actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))) + .actionGet(); + } + + RestHelper rh = nonSslRestHelper(); + + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("").getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("worf", "worf")).getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeDeleteRequest("nonexistentindex*", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest(".nonexistentindex*", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest(".opendistro_security/_doc/2", "{}", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_NOT_FOUND, + rh.executeGetRequest(".opendistro_security/_doc/0", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_NOT_FOUND, + rh.executeGetRequest("xxxxyyyy/_doc/0", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("abc", "abc:abc")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_UNAUTHORIZED, + rh.executeGetRequest("", encodeBasicHeader("userwithnopassword", "")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_UNAUTHORIZED, + rh.executeGetRequest("", encodeBasicHeader("userwithblankpassword", "")).getStatusCode() + ); + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("worf", "wrongpasswd")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_UNAUTHORIZED, + rh.executeGetRequest("", new BasicHeader("Authorization", "Basic " + "wrongheader")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_UNAUTHORIZED, + rh.executeGetRequest("", new BasicHeader("Authorization", "Basic ")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_UNAUTHORIZED, + rh.executeGetRequest("", new BasicHeader("Authorization", "Basic")).getStatusCode() + ); + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", new BasicHeader("Authorization", "")).getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("picard", "picard")).getStatusCode()); + + for (int i = 0; i < 10; i++) { + Assert.assertEquals( + HttpStatus.SC_UNAUTHORIZED, + rh.executeGetRequest("", encodeBasicHeader("worf", "wrongpasswd")).getStatusCode() + ); } - + + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePutRequest("/theindex", "{}", encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_CREATED, + rh.executePutRequest("/theindex/_doc/1?refresh=true", "{\"a\":0}", encodeBasicHeader("theindexadmin", "theindexadmin")) + .getStatusCode() + ); + // Assert.assertEquals(HttpStatus.SC_OK, + // rh.executeGetRequest("/theindex/_analyze?text=this+is+a+test",encodeBasicHeader("theindexadmin", + // "theindexadmin")).getStatusCode()); + // Assert.assertEquals(HttpStatus.SC_FORBIDDEN, + // rh.executeGetRequest("_analyze?text=this+is+a+test",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeDeleteRequest("/theindex", encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeDeleteRequest("/klingonempire", encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode() + ); + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("starfleet/_search", encodeBasicHeader("worf", "worf")).getStatusCode()); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("_search", encodeBasicHeader("worf", "worf")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeDeleteRequest(".opendistro_security/", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest("/.opendistro_security/_close", null, encodeBasicHeader("worf", "worf")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest("/.opendistro_security/_upgrade", null, encodeBasicHeader("worf", "worf")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest("/.opendistro_security/_mapping", "{}", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeGetRequest(".opendistro_security/", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest(".opendistro_security/_doc/2", "{}", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeGetRequest(".opendistro_security/_doc/0", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeDeleteRequest(".opendistro_security/_doc/0", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest(".opendistro_security/_doc/0", "{}", encodeBasicHeader("worf", "worf")).getStatusCode() + ); + + HttpResponse resc = rh.executeGetRequest("_cat/indices/public", encodeBasicHeader("bug108", "nagilum")); + System.out.println(resc.getBody()); + // Assert.assertTrue(resc.getBody().contains("green")); + Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); + + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest( + "role01_role02/_search?pretty", + encodeBasicHeader("user_role01_role02_role03", "user_role01_role02_role03") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeGetRequest("role01_role02/_search?pretty", encodeBasicHeader("user_role01", "user_role01")).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("spock/_search?pretty", encodeBasicHeader("spock", "spock")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeGetRequest("spock/_search?pretty", encodeBasicHeader("kirk", "kirk")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("kirk/_search?pretty", encodeBasicHeader("kirk", "kirk")).getStatusCode() + ); + + System.out.println("ok"); + // all + + } + @Test public void testBulk() throws Exception { - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH") - .build(); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH").build(); setup(Settings.EMPTY, new DynamicSecurityConfig().setSecurityRoles("roles_bulk.yml"), settings); final RestHelper rh = nonSslRestHelper(); - - String bulkBody = - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"field1\" : \"value1\" }" +System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator(); - + + String bulkBody = "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"field1\" : \"value1\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator(); + HttpResponse res = rh.executePostRequest("_bulk", bulkBody, encodeBasicHeader("bulk", "nagilum")); System.out.println(res.getBody()); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("\"errors\":false")); Assert.assertTrue(res.getBody().contains("\"status\":201")); } @Test public void testBulkWithOneIndexFailure() throws Exception { - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH") - .build(); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH").build(); setup(Settings.EMPTY, new DynamicSecurityConfig().setSecurityRoles("roles_bulk.yml"), settings); final RestHelper rh = nonSslRestHelper(); - String bulkBody = - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"a\" : \"b\" }" +System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"myindex\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"a\" : \"b\" }"+System.lineSeparator(); + String bulkBody = "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"a\" : \"b\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"myindex\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"a\" : \"b\" }" + + System.lineSeparator(); HttpResponse res = rh.executePostRequest("_bulk?refresh=true", bulkBody, encodeBasicHeader("bulk_test_user", "nagilum")); System.out.println(res.getBody()); @@ -569,64 +941,101 @@ public void testBulkWithOneIndexFailure() throws Exception { @Test public void test557() throws Exception { - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH") - .build(); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH").build(); setup(Settings.EMPTY, new DynamicSecurityConfig(), settings); - + try (Client tc = getClient()) { - + tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); - - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + + tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.index( + new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + } - + final RestHelper rh = nonSslRestHelper(); - HttpResponse res = rh.executePostRequest("/*/_search", "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":10}}}}", encodeBasicHeader("nagilum", "nagilum")); + HttpResponse res = rh.executePostRequest( + "/*/_search", + "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":10}}}}", + encodeBasicHeader("nagilum", "nagilum") + ); System.out.println(res.getBody()); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("starfleet_academy")); - res = rh.executePostRequest("/*/_search", "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":10}}}}", encodeBasicHeader("557", "nagilum")); + res = rh.executePostRequest( + "/*/_search", + "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":10}}}}", + encodeBasicHeader("557", "nagilum") + ); System.out.println(res.getBody()); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertTrue(res.getBody().contains("starfleet_academy")); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("starfleet_academy")); } - + @Test public void testITT1635() throws Exception { - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH") - .build(); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH").build(); setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_dnfof.yml").setSecurityRoles("roles_itt1635.yml"), settings); - + try (Client tc = getClient()) { - - tc.index(new IndexRequest("esb-prod-1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("esb-prod-2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("esb-prod-3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("esb-prod-4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":4}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("esb-prod-5").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":5}", XContentType.JSON)).actionGet(); - - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("esb-prod-1","esb-prod-2","esb-prod-3","esb-prod-4","esb-prod-5").alias("esb-prod-all"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("esb-prod-1").alias("esb-alias-1"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("esb-prod-2").alias("esb-alias-2"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("esb-prod-3").alias("esb-alias-3"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("esb-prod-4").alias("esb-alias-4"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("esb-prod-5").alias("esb-alias-5"))).actionGet(); + + tc.index(new IndexRequest("esb-prod-1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("esb-prod-2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("esb-prod-3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("esb-prod-4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":4}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("esb-prod-5").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":5}", XContentType.JSON)) + .actionGet(); + + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction( + AliasActions.add() + .indices("esb-prod-1", "esb-prod-2", "esb-prod-3", "esb-prod-4", "esb-prod-5") + .alias("esb-prod-all") + ) + ) + .actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("esb-prod-1").alias("esb-alias-1"))) + .actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("esb-prod-2").alias("esb-alias-2"))) + .actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("esb-prod-3").alias("esb-alias-3"))) + .actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("esb-prod-4").alias("esb-alias-4"))) + .actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("esb-prod-5").alias("esb-alias-5"))) + .actionGet(); } - + final RestHelper rh = nonSslRestHelper(); System.out.println("###1"); HttpResponse res = rh.executeGetRequest("/esb-prod-*/_search?pretty", encodeBasicHeader("itt1635", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); System.out.println("###2"); res = rh.executeGetRequest("/esb-alias-*/_search?pretty", encodeBasicHeader("itt1635", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); @@ -634,49 +1043,82 @@ public void testITT1635() throws Exception { res = rh.executeGetRequest("/esb-prod-all/_search?pretty", encodeBasicHeader("itt1635", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); } - + @Test public void testTenantInfo() throws Exception { - final Settings settings = Settings.builder() - .build(); + final Settings settings = Settings.builder().build(); setup(Settings.EMPTY, new DynamicSecurityConfig(), settings); - + /* - + [admin_1, praxisrw, abcdef_2_2, kltentro, praxisro, kltentrw] - admin_1==.kibana_-1139640511_admin1 - praxisrw==.kibana_-1386441176_praxisrw - abcdef_2_2==.kibana_-634608247_abcdef22 - kltentro==.kibana_-2014056171_kltentro - praxisro==.kibana_-1386441184_praxisro - kltentrw==.kibana_-2014056163_kltentrw - + admin_1==.kibana_-1139640511_admin1 + praxisrw==.kibana_-1386441176_praxisrw + abcdef_2_2==.kibana_-634608247_abcdef22 + kltentro==.kibana_-2014056171_kltentro + praxisro==.kibana_-1386441184_praxisro + kltentrw==.kibana_-2014056163_kltentrw + */ - + try (Client tc = getClient()) { - - tc.index(new IndexRequest(".kibana-6").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest(".kibana_-1139640511_admin1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest(".kibana_-1386441176_praxisrw").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest(".kibana_-634608247_abcdef22").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest(".kibana_-12345_123456").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest(".kibana2_-12345_123456").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest(".kibana_9876_xxx_ccc").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest(".kibana_fff_eee").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)).actionGet(); - - - tc.index(new IndexRequest("esb-prod-5").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":5}", XContentType.JSON)).actionGet(); - - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices(".kibana-6").alias(".kibana"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("esb-prod-5").alias(".kibana_-2014056163_kltentrw"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("esb-prod-5").alias("esb-alias-5"))).actionGet(); + + tc.index(new IndexRequest(".kibana-6").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest(".kibana_-1139640511_admin1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":3}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest(".kibana_-1386441176_praxisrw").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":3}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest(".kibana_-634608247_abcdef22").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":3}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest(".kibana_-12345_123456").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":3}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest(".kibana2_-12345_123456").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":3}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest(".kibana_9876_xxx_ccc").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":3}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest(".kibana_fff_eee").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON) + ).actionGet(); + + tc.index(new IndexRequest("esb-prod-5").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":5}", XContentType.JSON)) + .actionGet(); + + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices(".kibana-6").alias(".kibana"))) + .actionGet(); + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction( + AliasActions.add().indices("esb-prod-5").alias(".kibana_-2014056163_kltentrw") + ) + ) + .actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("esb-prod-5").alias("esb-alias-5"))) + .actionGet(); } - + final RestHelper rh = nonSslRestHelper(); HttpResponse res = rh.executeGetRequest("_opendistro/_security/tenantinfo?pretty", encodeBasicHeader("itt1635", "nagilum")); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); res = rh.executeGetRequest("_opendistro/_security/tenantinfo?pretty", encodeBasicHeader("kibanaserver", "kibanaserver")); System.out.println(res.getBody()); @@ -691,17 +1133,21 @@ public void testTenantInfo() throws Exception { Assert.assertFalse(res.getBody().contains("xxx")); Assert.assertFalse(res.getBody().contains(".kibana2")); } - + @Test public void testRestImpersonation() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS+".worf", "someotherusernotininternalusersfile") - .build(); + .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS + ".worf", "someotherusernotininternalusersfile") + .build(); setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_rest_impersonation.yml"), settings); final RestHelper rh = nonSslRestHelper(); - - //rest impersonation - HttpResponse res = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as","someotherusernotininternalusersfile"), encodeBasicHeader("worf", "worf")); + + // rest impersonation + HttpResponse res = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader("opendistro_security_impersonate_as", "someotherusernotininternalusersfile"), + encodeBasicHeader("worf", "worf") + ); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("name=someotherusernotininternalusersfile")); Assert.assertFalse(res.getBody().contains("worf")); @@ -709,16 +1155,14 @@ public void testRestImpersonation() throws Exception { @Test public void testSslOnlyMode() throws Exception { - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .build(); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_SSL_ONLY, true).build(); setupSslOnlyMode(settings); final RestHelper rh = nonSslRestHelper(); HttpResponse res = rh.executeGetRequest("_opendistro/_security/sslinfo"); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - res = rh.executePutRequest("/xyz/_doc/1","{\"a\":5}"); + res = rh.executePutRequest("/xyz/_doc/1", "{\"a\":5}"); Assert.assertEquals(HttpStatus.SC_CREATED, res.getStatusCode()); res = rh.executeGetRequest("/_mappings"); @@ -736,10 +1180,13 @@ public void testAll() throws Exception { try (Client tc = getClient()) { tc.index(new IndexRequest("abcdef").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) - .actionGet(); + .actionGet(); } - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("_all/_search", encodeBasicHeader("worf", "worf")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeGetRequest("_all/_search", encodeBasicHeader("worf", "worf")).getStatusCode() + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("*/_search", encodeBasicHeader("worf", "worf")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("_search", encodeBasicHeader("worf", "worf")).getStatusCode()); } diff --git a/src/test/java/org/opensearch/security/IndexIntegrationTests.java b/src/test/java/org/opensearch/security/IndexIntegrationTests.java index 8f2ee960bd..6a8703842e 100644 --- a/src/test/java/org/opensearch/security/IndexIntegrationTests.java +++ b/src/test/java/org/opensearch/security/IndexIntegrationTests.java @@ -59,68 +59,103 @@ public class IndexIntegrationTests extends SingleClusterTest { @Test public void testComposite() throws Exception { - - setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("composite_config.yml").setSecurityRoles("roles_composite.yml"), Settings.EMPTY, true); + + setup( + Settings.EMPTY, + new DynamicSecurityConfig().setConfig("composite_config.yml").setSecurityRoles("roles_composite.yml"), + Settings.EMPTY, + true + ); final RestHelper rh = nonSslRestHelper(); - + try (Client tc = getClient()) { - tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); + tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); } - - String msearchBody = - "{\"index\":\"starfleet\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ - "{\"index\":\"klingonempire\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ - "{\"index\":\"public\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); - - + + String msearchBody = "{\"index\":\"starfleet\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator() + + "{\"index\":\"klingonempire\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator() + + "{\"index\":\"public\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); + HttpResponse resc = rh.executePostRequest("_msearch", msearchBody, encodeBasicHeader("worf", "worf")); Assert.assertEquals(200, resc.getStatusCode()); Assert.assertTrue(resc.getBody(), resc.getBody().contains("\"_index\":\"klingonempire\"")); Assert.assertTrue(resc.getBody(), resc.getBody().contains("hits")); Assert.assertTrue(resc.getBody(), resc.getBody().contains("no permissions for [indices:data/read/search]")); - + } - + @Test public void testBulkShards() throws Exception { - + setup(Settings.EMPTY, new DynamicSecurityConfig().setSecurityRoles("roles_bs.yml"), Settings.EMPTY, true); final RestHelper rh = nonSslRestHelper(); - + try (Client tc = getClient()) { - //create indices and mapping upfront - tc.index(new IndexRequest("test").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"field2\":\"init\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("lorem").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"field2\":\"init\"}", XContentType.JSON)).actionGet(); + // create indices and mapping upfront + tc.index(new IndexRequest("test").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"field2\":\"init\"}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("lorem").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"field2\":\"init\"}", XContentType.JSON)) + .actionGet(); } - - String bulkBody = - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value1\" }" +System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"3\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"4\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"5\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"lorem\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"lorem\", \"_id\" : \"2\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"lorem\", \"_id\" : \"3\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"lorem\", \"_id\" : \"4\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"lorem\", \"_id\" : \"5\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ - "{ \"delete\" : { \"_index\" : \"lorem\", \"_id\" : \"5\" } }"+System.lineSeparator(); - + + String bulkBody = "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value1\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"3\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"4\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"5\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"lorem\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"lorem\", \"_id\" : \"2\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"lorem\", \"_id\" : \"3\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"lorem\", \"_id\" : \"4\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"lorem\", \"_id\" : \"5\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator() + + "{ \"delete\" : { \"_index\" : \"lorem\", \"_id\" : \"5\" } }" + + System.lineSeparator(); + System.out.println("############ _bulk"); HttpResponse res = rh.executePostRequest("_bulk?refresh=true&pretty=true", bulkBody, encodeBasicHeader("worf", "worf")); System.out.println(res.getBody()); @@ -128,129 +163,177 @@ public void testBulkShards() throws Exception { Assert.assertTrue(res.getBody().contains("\"errors\" : true")); Assert.assertTrue(res.getBody().contains("\"status\" : 201")); Assert.assertTrue(res.getBody().contains("no permissions for")); - + System.out.println("############ check shards"); System.out.println(rh.executeGetRequest("_cat/shards?v", encodeBasicHeader("nagilum", "nagilum"))); - } @Test public void testCreateIndex() throws Exception { - + setup(); RestHelper rh = nonSslRestHelper(); - + HttpResponse res; - Assert.assertEquals("Unable to create index 'nag'", HttpStatus.SC_OK, rh.executePutRequest("nag1", null, encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals("Unable to create index 'starfleet_library'", HttpStatus.SC_OK, rh.executePutRequest("starfleet_library", null, encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - + Assert.assertEquals( + "Unable to create index 'nag'", + HttpStatus.SC_OK, + rh.executePutRequest("nag1", null, encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + "Unable to create index 'starfleet_library'", + HttpStatus.SC_OK, + rh.executePutRequest("starfleet_library", null, encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + clusterHelper.waitForCluster(ClusterHealthStatus.GREEN, TimeValue.timeValueSeconds(10), clusterInfo.numNodes); - - Assert.assertEquals("Unable to close index 'starfleet_library'", HttpStatus.SC_OK, rh.executePostRequest("starfleet_library/_close", null, encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - - Assert.assertEquals("Unable to open index 'starfleet_library'", HttpStatus.SC_OK, (res = rh.executePostRequest("starfleet_library/_open", null, encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + + Assert.assertEquals( + "Unable to close index 'starfleet_library'", + HttpStatus.SC_OK, + rh.executePostRequest("starfleet_library/_close", null, encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + + Assert.assertEquals( + "Unable to open index 'starfleet_library'", + HttpStatus.SC_OK, + (res = rh.executePostRequest("starfleet_library/_open", null, encodeBasicHeader("nagilum", "nagilum"))).getStatusCode() + ); Assert.assertTrue("open index 'starfleet_library' not acknowledged", res.getBody().contains("acknowledged")); Assert.assertFalse("open index 'starfleet_library' not acknowledged", res.getBody().contains("false")); - + clusterHelper.waitForCluster(ClusterHealthStatus.GREEN, TimeValue.timeValueSeconds(10), clusterInfo.numNodes); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest("public", null, encodeBasicHeader("spock", "spock")).getStatusCode()); - - + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest("public", null, encodeBasicHeader("spock", "spock")).getStatusCode() + ); + } @Test public void testFilteredAlias() throws Exception { - + setup(); - + try (Client tc = getClient()) { - tc.index(new IndexRequest("theindex").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("otherindex").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().alias("alias1").filter(QueryBuilders.termQuery("_type", "type1")).index("theindex"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().alias("alias2").filter(QueryBuilders.termQuery("_type", "type2")).index("theindex"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().alias("alias3").filter(QueryBuilders.termQuery("_type", "type2")).index("otherindex"))).actionGet(); + tc.index(new IndexRequest("theindex").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("otherindex").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction( + AliasActions.add().alias("alias1").filter(QueryBuilders.termQuery("_type", "type1")).index("theindex") + ) + ) + .actionGet(); + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction( + AliasActions.add().alias("alias2").filter(QueryBuilders.termQuery("_type", "type2")).index("theindex") + ) + ) + .actionGet(); + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction( + AliasActions.add().alias("alias3").filter(QueryBuilders.termQuery("_type", "type2")).index("otherindex") + ) + ) + .actionGet(); } - - + RestHelper rh = nonSslRestHelper(); - - //opendistro_security_user1 -> worf - //opendistro_security_user2 -> picard - + + // opendistro_security_user1 -> worf + // opendistro_security_user2 -> picard + HttpResponse resc = rh.executeGetRequest("alias*/_search", encodeBasicHeader("worf", "worf")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - - resc = rh.executeGetRequest("theindex/_search", encodeBasicHeader("nagilum", "nagilum")); + + resc = rh.executeGetRequest("theindex/_search", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - - resc = rh.executeGetRequest("alias3/_search", encodeBasicHeader("nagilum", "nagilum")); + + resc = rh.executeGetRequest("alias3/_search", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - resc = rh.executeGetRequest("_cat/indices", encodeBasicHeader("nagilum", "nagilum")); + resc = rh.executeGetRequest("_cat/indices", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - + } - + @Test public void testIndexTypeEvaluation() throws Exception { - + setup(); try (Client tc = getClient()) { - tc.index(new IndexRequest("foo1").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("foo2").id("2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("foo").id("3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("fooba").id("4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":4}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("foo1").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("foo2").id("2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON) + ).actionGet(); + tc.index(new IndexRequest("foo").id("3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("fooba").id("4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":4}", XContentType.JSON) + ).actionGet(); try { - tc.index(new IndexRequest("x#a").id("4a").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":4}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("x#a").id("4a").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":4}", XContentType.JSON) + ).actionGet(); Assert.fail("Indexname can contain #"); } catch (InvalidIndexNameException e) { - //expected + // expected } } - + RestHelper rh = nonSslRestHelper(); - + HttpResponse resc = rh.executeGetRequest("/foo1/_search?pretty", encodeBasicHeader("baz", "worf")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("\"content\" : 1")); - + resc = rh.executeGetRequest("/foo2/_search?pretty", encodeBasicHeader("baz", "worf")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("\"content\" : 2")); - + resc = rh.executeGetRequest("/foo/_search?pretty", encodeBasicHeader("baz", "worf")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("\"content\" : 3")); - - //resc = rh.executeGetRequest("/fooba/z/_search?pretty", encodeBasicHeader("baz", "worf")); - //Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + + // resc = rh.executeGetRequest("/fooba/z/_search?pretty", encodeBasicHeader("baz", "worf")); + // Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); + resc = rh.executeGetRequest("/foo1/_doc/1?pretty", encodeBasicHeader("baz", "worf")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("\"found\" : true")); Assert.assertTrue(resc.getBody().contains("\"content\" : 1")); - + resc = rh.executeGetRequest("/foo2/_doc/2?pretty", encodeBasicHeader("baz", "worf")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("\"content\" : 2")); Assert.assertTrue(resc.getBody().contains("\"found\" : true")); - + resc = rh.executeGetRequest("/foo/_doc/3?pretty", encodeBasicHeader("baz", "worf")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("\"content\" : 3")); Assert.assertTrue(resc.getBody().contains("\"found\" : true")); - - //resc = rh.executeGetRequest("/fooba/z/4?pretty", encodeBasicHeader("baz", "worf")); - //Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - - //resc = rh.executeGetRequest("/foo*/_search?pretty", encodeBasicHeader("baz", "worf")); - //Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + + // resc = rh.executeGetRequest("/fooba/z/4?pretty", encodeBasicHeader("baz", "worf")); + // Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); + + // resc = rh.executeGetRequest("/foo*/_search?pretty", encodeBasicHeader("baz", "worf")); + // Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); + resc = rh.executeGetRequest("/foo*,-fooba/_search?pretty", encodeBasicHeader("baz", "worf")); Assert.assertEquals(200, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("\"content\" : 1")); @@ -259,77 +342,178 @@ public void testIndexTypeEvaluation() throws Exception { @Test public void testIndices() throws Exception { - + setup(); - + try (Client tc = getClient()) { - tc.index(new IndexRequest("nopermindex").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("logstash-1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("logstash-2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("logstash-3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("logstash-4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.index(new IndexRequest("nopermindex").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.index(new IndexRequest("logstash-1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("logstash-2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("logstash-3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("logstash-4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd", SecurityUtils.EN_Locale); sdf.setTimeZone(TimeZone.getTimeZone("UTC")); - + String date = sdf.format(new Date()); - tc.index(new IndexRequest("logstash-"+date).setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("logstash-" + date).setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); } - + RestHelper rh = nonSslRestHelper(); - + HttpResponse res = null; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash-1/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - //nonexistent index with permissions - Assert.assertEquals(HttpStatus.SC_NOT_FOUND, (res = rh.executeGetRequest("/logstash-nonex/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - //existent index without permissions - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/nopermindex/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - //nonexistent index without permissions - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/does-not-exist-and-no-perm/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - //nonexistent and existent index with permissions - Assert.assertEquals(HttpStatus.SC_NOT_FOUND, (res = rh.executeGetRequest("/logstash-nonex,logstash-1/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - //existent index with permissions - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash-1/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - //nonexistent index with failed login - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, (res = rh.executeGetRequest("/logstash-nonex/_search", encodeBasicHeader("nouser", "nosuer"))).getStatusCode()); - - //nonexistent index with no login - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, (res = rh.executeGetRequest("/logstash-nonex/_search")).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/_all/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/*/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/nopermindex,logstash-1,nonexist/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/logstash-1,nonexist/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/nonexist/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/%3Clogstash-%7Bnow%2Fd%7D%3E/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/%3Cnonex-%7Bnow%2Fd%7D%3E/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/%3Clogstash-%7Bnow%2Fd%7D%3E,logstash-*/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/%3Clogstash-%7Bnow%2Fd%7D%3E,logstash-1/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_CREATED, (res = rh.executePutRequest("/logstash-b/_doc/1", "{}",encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePutRequest("/%3Clogstash-cnew-%7Bnow%2Fd%7D%3E", "{}",encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_CREATED, (res = rh.executePutRequest("/%3Clogstash-new-%7Bnow%2Fd%7D%3E/_doc/1", "{}",encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/_cat/indices?v" ,encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/logstash-1/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))) + .getStatusCode() + ); + + // nonexistent index with permissions + Assert.assertEquals( + HttpStatus.SC_NOT_FOUND, + (res = rh.executeGetRequest("/logstash-nonex/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))) + .getStatusCode() + ); + + // existent index without permissions + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executeGetRequest("/nopermindex/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))) + .getStatusCode() + ); + + // nonexistent index without permissions + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executeGetRequest( + "/does-not-exist-and-no-perm/_search", + encodeBasicHeader("opendistro_security_logstash", "nagilum") + )).getStatusCode() + ); + + // nonexistent and existent index with permissions + Assert.assertEquals( + HttpStatus.SC_NOT_FOUND, + (res = rh.executeGetRequest("/logstash-nonex,logstash-1/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))) + .getStatusCode() + ); + + // existent index with permissions + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/logstash-1/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))) + .getStatusCode() + ); + + // nonexistent index with failed login + Assert.assertEquals( + HttpStatus.SC_UNAUTHORIZED, + (res = rh.executeGetRequest("/logstash-nonex/_search", encodeBasicHeader("nouser", "nosuer"))).getStatusCode() + ); + + // nonexistent index with no login + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, (res = rh.executeGetRequest("/logstash-nonex/_search")).getStatusCode()); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executeGetRequest("/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executeGetRequest("/_all/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executeGetRequest("/*/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executeGetRequest( + "/nopermindex,logstash-1,nonexist/_search", + encodeBasicHeader("opendistro_security_logstash", "nagilum") + )).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executeGetRequest("/logstash-1,nonexist/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))) + .getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executeGetRequest("/nonexist/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest( + "/%3Clogstash-%7Bnow%2Fd%7D%3E/_search", + encodeBasicHeader("opendistro_security_logstash", "nagilum") + )).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executeGetRequest("/%3Cnonex-%7Bnow%2Fd%7D%3E/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))) + .getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest( + "/%3Clogstash-%7Bnow%2Fd%7D%3E,logstash-*/_search", + encodeBasicHeader("opendistro_security_logstash", "nagilum") + )).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest( + "/%3Clogstash-%7Bnow%2Fd%7D%3E,logstash-1/_search", + encodeBasicHeader("opendistro_security_logstash", "nagilum") + )).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_CREATED, + (res = rh.executePutRequest("/logstash-b/_doc/1", "{}", encodeBasicHeader("opendistro_security_logstash", "nagilum"))) + .getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePutRequest( + "/%3Clogstash-cnew-%7Bnow%2Fd%7D%3E", + "{}", + encodeBasicHeader("opendistro_security_logstash", "nagilum") + )).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_CREATED, + (res = rh.executePutRequest( + "/%3Clogstash-new-%7Bnow%2Fd%7D%3E/_doc/1", + "{}", + encodeBasicHeader("opendistro_security_logstash", "nagilum") + )).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/_cat/indices?v", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("logstash-b")); @@ -337,86 +521,126 @@ public void testIndices() throws Exception { Assert.assertTrue(res.getBody().contains("logstash-cnew-20")); Assert.assertFalse(res.getBody().contains("<")); } - + @Test public void testAliases() throws Exception { - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH") - .build(); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH").build(); setup(settings); - + try (Client tc = getClient()) { - tc.index(new IndexRequest("nopermindex").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("logstash-1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("logstash-2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("logstash-3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("logstash-4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("logstash-5").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("logstash-del").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("logstash-del-ok").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); + tc.index(new IndexRequest("nopermindex").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.index(new IndexRequest("logstash-1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("logstash-2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("logstash-3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("logstash-4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("logstash-5").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("logstash-del").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("logstash-del-ok").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); String date = new SimpleDateFormat("YYYY.MM.dd").format(new Date()); - tc.index(new IndexRequest("logstash-"+date).setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("nopermindex").alias("nopermalias"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices(".opendistro_security").alias("mysgi"))).actionGet(); + tc.index( + new IndexRequest("logstash-" + date).setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("nopermindex").alias("nopermalias"))) + .actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices(".opendistro_security").alias("mysgi"))) + .actionGet(); } - + RestHelper rh = nonSslRestHelper(); - + HttpResponse res = null; - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executePostRequest("/mysgi/_doc", "{}",encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/mysgi/_search?pretty", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executePostRequest("/mysgi/_doc", "{}", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/mysgi/_search?pretty", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode() + ); assertContains(res, "*\"hits\" : {*\"value\" : 0,*\"hits\" : [ ]*"); - + System.out.println("#### add alias to allowed index"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePutRequest("/logstash-1/_alias/alog1", "",encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePutRequest("/logstash-1/_alias/alog1", "", encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode() + ); System.out.println("#### add alias to not existing (no perm)"); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executePutRequest("/nonexitent/_alias/alnp", "",encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); - + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executePutRequest("/nonexitent/_alias/alnp", "", encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode() + ); + System.out.println("#### add alias to not existing (with perm)"); - Assert.assertEquals(HttpStatus.SC_NOT_FOUND, (res = rh.executePutRequest("/logstash-nonex/_alias/alnp", "",encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); - + Assert.assertEquals( + HttpStatus.SC_NOT_FOUND, + (res = rh.executePutRequest("/logstash-nonex/_alias/alnp", "", encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode() + ); + System.out.println("#### add alias to not allowed index"); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executePutRequest("/nopermindex/_alias/alnp", "",encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); - - String aliasRemoveIndex = "{"+ - "\"actions\" : ["+ - "{ \"add\": { \"index\": \"logstash-del-ok\", \"alias\": \"logstash-del\" } },"+ - "{ \"remove_index\": { \"index\": \"logstash-del\" } } "+ - "]"+ - "}"; - + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executePutRequest("/nopermindex/_alias/alnp", "", encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode() + ); + + String aliasRemoveIndex = "{" + + "\"actions\" : [" + + "{ \"add\": { \"index\": \"logstash-del-ok\", \"alias\": \"logstash-del\" } }," + + "{ \"remove_index\": { \"index\": \"logstash-del\" } } " + + "]" + + "}"; + System.out.println("#### remove_index"); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executePostRequest("/_aliases", aliasRemoveIndex,encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executePostRequest("/_aliases", aliasRemoveIndex, encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode() + ); - System.out.println("#### get alias for permitted index"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash-1/_alias/alog1", encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/logstash-1/_alias/alog1", encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode() + ); - System.out.println("#### get alias for all indices"); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/_alias/alog1", encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executeGetRequest("/_alias/alog1", encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode() + ); - System.out.println("#### get alias no perm"); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/_alias/nopermalias", encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); - - String alias = - "{"+ - "\"aliases\": {"+ - "\"alias1\": {}"+ - "}"+ - "}"; - - + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executeGetRequest("/_alias/nopermalias", encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode() + ); + + String alias = "{" + "\"aliases\": {" + "\"alias1\": {}" + "}" + "}"; + System.out.println("#### create alias along with index"); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executePutRequest("/beats-withalias", alias,encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executePutRequest("/beats-withalias", alias, encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode() + ); } @Test @@ -425,83 +649,90 @@ public void testIndexResolveInvalidIndexName() throws Exception { final RestHelper rh = nonSslRestHelper(); // invalid_index_name_exception should be thrown and responded when invalid index name is mentioned in requests. - HttpResponse res = rh.executeGetRequest(URLEncoder.encode("_##pdt_data/_search", "UTF-8"), encodeBasicHeader("ccsresolv", "nagilum")); + HttpResponse res = rh.executeGetRequest( + URLEncoder.encode("_##pdt_data/_search", "UTF-8"), + encodeBasicHeader("ccsresolv", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("invalid_index_name_exception")); } - + @Test public void testCCSIndexResolve() throws Exception { - + setup(); final RestHelper rh = nonSslRestHelper(); try (Client tc = getClient()) { - tc.index(new IndexRequest(".abc-6").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); + tc.index(new IndexRequest(".abc-6").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); } - //ccsresolv has perm for ?abc* + // ccsresolv has perm for ?abc* HttpResponse res = rh.executeGetRequest("ggg:.abc-6,.abc-6/_search", encodeBasicHeader("ccsresolv", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); res = rh.executeGetRequest("/*:.abc-6,.abc-6/_search", encodeBasicHeader("ccsresolv", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - //TODO: Change for 25.0 to be forbidden (possible bug in ES regarding ccs wildcard) + // TODO: Change for 25.0 to be forbidden (possible bug in ES regarding ccs wildcard) } @Test @Ignore public void testCCSIndexResolve2() throws Exception { - + setup(); final RestHelper rh = nonSslRestHelper(); try (Client tc = getClient()) { - tc.index(new IndexRequest(".abc").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("xyz").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("noperm").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)).actionGet(); + tc.index(new IndexRequest(".abc").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("xyz").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("noperm").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)) + .actionGet(); } - + HttpResponse res = rh.executeGetRequest("/*:.abc,.abc/_search", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertTrue(res.getBody(),res.getBody().contains("\"content\":1")); - + Assert.assertTrue(res.getBody(), res.getBody().contains("\"content\":1")); + res = rh.executeGetRequest("/ba*bcuzh/_search", encodeBasicHeader("nagilum", "nagilum")); - Assert.assertTrue(res.getBody(),res.getBody().contains("\"content\":12")); + Assert.assertTrue(res.getBody(), res.getBody().contains("\"content\":12")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - + res = rh.executeGetRequest("/*:.abc/_search", encodeBasicHeader("nagilum", "nagilum")); - Assert.assertTrue(res.getBody(),res.getBody().contains("\"content\":1")); + Assert.assertTrue(res.getBody(), res.getBody().contains("\"content\":1")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - + res = rh.executeGetRequest("/*:xyz,xyz/_search", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertTrue(res.getBody(),res.getBody().contains("\"content\":2")); - - //res = rh.executeGetRequest("/*noexist/_search", encodeBasicHeader("nagilum", "nagilum")); - //Assert.assertEquals(HttpStatus.SC_NOT_FOUND, res.getStatusCode()); - + Assert.assertTrue(res.getBody(), res.getBody().contains("\"content\":2")); + + // res = rh.executeGetRequest("/*noexist/_search", encodeBasicHeader("nagilum", "nagilum")); + // Assert.assertEquals(HttpStatus.SC_NOT_FOUND, res.getStatusCode()); + res = rh.executeGetRequest("/*:.abc/_search", encodeBasicHeader("nagilum", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertTrue(res.getBody(),res.getBody().contains("\"content\":1")); - + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody(), res.getBody().contains("\"content\":1")); + res = rh.executeGetRequest("/*:xyz/_search", encodeBasicHeader("nagilum", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertTrue(res.getBody(),res.getBody().contains("\"content\":2")); - + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody(), res.getBody().contains("\"content\":2")); + res = rh.executeGetRequest("/.abc/_search", encodeBasicHeader("ccsresolv", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); res = rh.executeGetRequest("/xyz/_search", encodeBasicHeader("ccsresolv", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); res = rh.executeGetRequest("/*:.abc,.abc/_search", encodeBasicHeader("ccsresolv", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); res = rh.executeGetRequest("/*:xyz,xyz/_search", encodeBasicHeader("ccsresolv", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); res = rh.executeGetRequest("/*:.abc/_search", encodeBasicHeader("ccsresolv", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); res = rh.executeGetRequest("/*:xyz/_search", encodeBasicHeader("ccsresolv", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); res = rh.executeGetRequest("/*:noperm/_search", encodeBasicHeader("ccsresolv", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); res = rh.executeGetRequest("/*:noperm/_search", encodeBasicHeader("ccsresolv", "nagilum")); @@ -515,24 +746,32 @@ public void testCCSIndexResolve2() throws Exception { @Test public void testIndexResolveIgnoreUnavailable() throws Exception { - setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_respect_indices_options.yml").setSecurityRoles("roles_bs.yml"), Settings.EMPTY, true); + setup( + Settings.EMPTY, + new DynamicSecurityConfig().setConfig("config_respect_indices_options.yml").setSecurityRoles("roles_bs.yml"), + Settings.EMPTY, + true + ); final RestHelper rh = nonSslRestHelper(); try (Client tc = getClient()) { - //create indices and mapping upfront - tc.index(new IndexRequest("test").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"field2\":\"init\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("lorem").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"field2\":\"init\"}", XContentType.JSON)).actionGet(); + // create indices and mapping upfront + tc.index(new IndexRequest("test").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"field2\":\"init\"}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("lorem").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"field2\":\"init\"}", XContentType.JSON)) + .actionGet(); } - String msearchBody = - "{\"index\": [\"tes*\",\"-security\",\"-missing\"], \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"match_all\":{}}}"+System.lineSeparator(); + String msearchBody = "{\"index\": [\"tes*\",\"-security\",\"-missing\"], \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"match_all\":{}}}" + + System.lineSeparator(); HttpResponse resc = rh.executePostRequest("_msearch", msearchBody, encodeBasicHeader("worf", "worf")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody(), resc.getBody().contains("\"total\":{\"value\":1")); } - + @Test public void testIndexResolveIndicesAlias() throws Exception { @@ -540,24 +779,29 @@ public void testIndexResolveIndicesAlias() throws Exception { final RestHelper rh = nonSslRestHelper(); try (Client tc = getClient()) { - //create indices and mapping upfront - tc.index(new IndexRequest("foo-index").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"field2\":\"init\"}", XContentType.JSON)).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("foo-index").alias("foo-alias"))).actionGet(); + // create indices and mapping upfront + tc.index( + new IndexRequest("foo-index").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"field2\":\"init\"}", XContentType.JSON) + ).actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("foo-index").alias("foo-alias"))) + .actionGet(); tc.admin().indices().delete(new DeleteIndexRequest("foo-index")).actionGet(); } - + HttpResponse resc = rh.executeGetRequest("/_cat/aliases", encodeBasicHeader("nagilum", "nagilum")); Assert.assertFalse(resc.getBody().contains("foo")); resc = rh.executeGetRequest("/foo-alias/_search", encodeBasicHeader("foo_index", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + resc = rh.executeGetRequest("/foo-index/_search", encodeBasicHeader("foo_index", "nagilum")); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, resc.getStatusCode()); - + resc = rh.executeGetRequest("/foo-alias/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, resc.getStatusCode()); - + } @Test @@ -567,8 +811,10 @@ public void testIndexResolveMinus() throws Exception { final RestHelper rh = nonSslRestHelper(); try (Client tc = getClient()) { - //create indices and mapping upfront - tc.index(new IndexRequest("foo-abc").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"field2\":\"init\"}", XContentType.JSON)).actionGet(); + // create indices and mapping upfront + tc.index( + new IndexRequest("foo-abc").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"field2\":\"init\"}", XContentType.JSON) + ).actionGet(); } HttpResponse resc = rh.executeGetRequest("/**/_search", encodeBasicHeader("foo_all", "nagilum")); @@ -576,30 +822,30 @@ public void testIndexResolveMinus() throws Exception { resc = rh.executeGetRequest("/*/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + resc = rh.executeGetRequest("/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + resc = rh.executeGetRequest("/**,-foo*/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + resc = rh.executeGetRequest("/*,-foo*/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + resc = rh.executeGetRequest("/*,-*security/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); resc = rh.executeGetRequest("/*,-*security/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - + resc = rh.executeGetRequest("/*,-*security,-foo*/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - + resc = rh.executeGetRequest("/_all,-*security/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + resc = rh.executeGetRequest("/_all,-*security/_search", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, resc.getStatusCode()); - + } } diff --git a/src/test/java/org/opensearch/security/IndexTemplateClusterPermissionsCheckTest.java b/src/test/java/org/opensearch/security/IndexTemplateClusterPermissionsCheckTest.java index b2c483abd7..03d26e2062 100644 --- a/src/test/java/org/opensearch/security/IndexTemplateClusterPermissionsCheckTest.java +++ b/src/test/java/org/opensearch/security/IndexTemplateClusterPermissionsCheckTest.java @@ -20,45 +20,55 @@ import org.opensearch.security.test.helper.rest.RestHelper; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class IndexTemplateClusterPermissionsCheckTest extends SingleClusterTest{ - private RestHelper rh; +public class IndexTemplateClusterPermissionsCheckTest extends SingleClusterTest { + private RestHelper rh; - final static String indexTemplateBody = "{ \"index_patterns\": [\"sem1234*\"], \"template\": { \"settings\": { \"number_of_shards\": 2, \"number_of_replicas\": 1 }, \"mappings\": { \"properties\": { \"timestamp\": { \"type\": \"date\", \"format\": \"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis\" }, \"value\": { \"type\": \"double\" } } } } }"; + final static String indexTemplateBody = + "{ \"index_patterns\": [\"sem1234*\"], \"template\": { \"settings\": { \"number_of_shards\": 2, \"number_of_replicas\": 1 }, \"mappings\": { \"properties\": { \"timestamp\": { \"type\": \"date\", \"format\": \"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis\" }, \"value\": { \"type\": \"double\" } } } } }"; - private String getFailureResponseReason(String user) { - return "no permissions for [indices:admin/index_template/put] and User [name=" + user + ", backend_roles=[], requestedTenant=null]"; - } + private String getFailureResponseReason(String user) { + return "no permissions for [indices:admin/index_template/put] and User [name=" + user + ", backend_roles=[], requestedTenant=null]"; + } - @Before - public void setupRestHelper() throws Exception{ - setup(); - rh = nonSslRestHelper(); - } - @Test - public void testPutIndexTemplateByNonPrivilegedUser() throws Exception { - String expectedFailureResponse = getFailureResponseReason("ds4"); + @Before + public void setupRestHelper() throws Exception { + setup(); + rh = nonSslRestHelper(); + } - // should fail, as user `ds3` doesn't have correct permissions - HttpResponse response = rh.executePutRequest("/_index_template/sem1234", indexTemplateBody, encodeBasicHeader("ds4", "nagilum")); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); - Assert.assertEquals(expectedFailureResponse, response.findValueInJson("error.root_cause[0].reason")); - } + @Test + public void testPutIndexTemplateByNonPrivilegedUser() throws Exception { + String expectedFailureResponse = getFailureResponseReason("ds4"); - @Test - public void testPutIndexTemplateByPrivilegedUser() throws Exception { - // should pass, as user `sem-user` has correct permissions - HttpResponse response = rh.executePutRequest("/_index_template/sem1234", indexTemplateBody, encodeBasicHeader("sem-user", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - } + // should fail, as user `ds3` doesn't have correct permissions + HttpResponse response = rh.executePutRequest("/_index_template/sem1234", indexTemplateBody, encodeBasicHeader("ds4", "nagilum")); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); + Assert.assertEquals(expectedFailureResponse, response.findValueInJson("error.root_cause[0].reason")); + } - @Test - public void testPutIndexTemplateAsIndexLevelPermission() throws Exception { - String expectedFailureResponse = getFailureResponseReason("sem-user2"); + @Test + public void testPutIndexTemplateByPrivilegedUser() throws Exception { + // should pass, as user `sem-user` has correct permissions + HttpResponse response = rh.executePutRequest( + "/_index_template/sem1234", + indexTemplateBody, + encodeBasicHeader("sem-user", "nagilum") + ); + Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); + } - // should fail, as user `sem-user2` is assigned `put-template` permission as index-level, not cluster-level - HttpResponse response = rh.executePutRequest("/_index_template/sem1234", indexTemplateBody, encodeBasicHeader("sem-user2", "nagilum")); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); - Assert.assertEquals(expectedFailureResponse, response.findValueInJson("error.root_cause[0].reason")); - } + @Test + public void testPutIndexTemplateAsIndexLevelPermission() throws Exception { + String expectedFailureResponse = getFailureResponseReason("sem-user2"); + // should fail, as user `sem-user2` is assigned `put-template` permission as index-level, not cluster-level + HttpResponse response = rh.executePutRequest( + "/_index_template/sem1234", + indexTemplateBody, + encodeBasicHeader("sem-user2", "nagilum") + ); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); + Assert.assertEquals(expectedFailureResponse, response.findValueInJson("error.root_cause[0].reason")); } + +} diff --git a/src/test/java/org/opensearch/security/InitializationIntegrationTests.java b/src/test/java/org/opensearch/security/InitializationIntegrationTests.java index 17ced9e325..0fec953472 100644 --- a/src/test/java/org/opensearch/security/InitializationIntegrationTests.java +++ b/src/test/java/org/opensearch/security/InitializationIntegrationTests.java @@ -65,26 +65,34 @@ public class InitializationIntegrationTests extends SingleClusterTest { @Test public void testEnsureInitViaRestDoesWork() throws Exception { - + final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .build(); + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .build(); setup(Settings.EMPTY, null, settings, false); - final RestHelper rh = restHelper(); //ssl resthelper + final RestHelper rh = restHelper(); // ssl resthelper rh.enableHTTPClientSSL = true; rh.trustHTTPServerCertificate = true; rh.sendAdminCertificate = true; - Assert.assertEquals(HttpStatus.SC_SERVICE_UNAVAILABLE, rh.executePutRequest(".opendistro_security/_doc/0", "{}", encodeBasicHeader("___", "")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_SERVICE_UNAVAILABLE, rh.executePutRequest(".opendistro_security/_doc/config", "{}", encodeBasicHeader("___", "")).getStatusCode()); - - + Assert.assertEquals( + HttpStatus.SC_SERVICE_UNAVAILABLE, + rh.executePutRequest(".opendistro_security/_doc/0", "{}", encodeBasicHeader("___", "")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_SERVICE_UNAVAILABLE, + rh.executePutRequest(".opendistro_security/_doc/config", "{}", encodeBasicHeader("___", "")).getStatusCode() + ); + rh.keystore = "kirk-keystore.jks"; - Assert.assertEquals(HttpStatus.SC_CREATED, rh.executePutRequest(".opendistro_security/_doc/config", "{}", encodeBasicHeader("___", "")).getStatusCode()); - + Assert.assertEquals( + HttpStatus.SC_CREATED, + rh.executePutRequest(".opendistro_security/_doc/config", "{}", encodeBasicHeader("___", "")).getStatusCode() + ); + Assert.assertFalse(rh.executeSimpleRequest("_nodes/stats?pretty").contains("\"tx_size_in_bytes\" : 0")); Assert.assertFalse(rh.executeSimpleRequest("_nodes/stats?pretty").contains("\"rx_count\" : 0")); Assert.assertFalse(rh.executeSimpleRequest("_nodes/stats?pretty").contains("\"rx_size_in_bytes\" : 0")); @@ -96,28 +104,38 @@ public void testEnsureInitViaRestDoesWork() throws Exception { public void testInitWithInjectedUser() throws Exception { final Settings settings = Settings.builder() - .putList("path.repo", repositoryPath.getRoot().getAbsolutePath()) - .put("plugins.security.unsupported.inject_user.enabled", true) - .build(); + .putList("path.repo", repositoryPath.getRoot().getAbsolutePath()) + .put("plugins.security.unsupported.inject_user.enabled", true) + .build(); setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_disable_all.yml"), settings, true); RestHelper rh = nonSslRestHelper(); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executePutRequest(".opendistro_security/_doc/0", "{}", encodeBasicHeader("___", "")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executePutRequest(".opendistro_security/_doc/config", "{}", encodeBasicHeader("___", "")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_UNAUTHORIZED, + rh.executePutRequest(".opendistro_security/_doc/0", "{}", encodeBasicHeader("___", "")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_UNAUTHORIZED, + rh.executePutRequest(".opendistro_security/_doc/config", "{}", encodeBasicHeader("___", "")).getStatusCode() + ); } @Test public void testWhoAmI() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .build(); - setup(Settings.EMPTY, new DynamicSecurityConfig().setSecurityInternalUsers("internal_empty.yml") - .setSecurityRoles("roles_deny.yml"), settings, true); + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .build(); + setup( + Settings.EMPTY, + new DynamicSecurityConfig().setSecurityInternalUsers("internal_empty.yml").setSecurityRoles("roles_deny.yml"), + settings, + true + ); try (RestHighLevelClient restHighLevelClient = getRestClient(clusterInfo, "spock-keystore.jks", "truststore.jks")) { Response whoAmIRes = restHighLevelClient.getLowLevelClient().performRequest(new Request("GET", "/_plugins/_security/whoami")); @@ -135,14 +153,25 @@ public void testWhoAmI() throws Exception { @Test public void testWhoAmIForceHttp1() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .build(); - setup(Settings.EMPTY, new DynamicSecurityConfig().setSecurityInternalUsers("internal_empty.yml") - .setSecurityRoles("roles_deny.yml"), settings, true); - - try (RestHighLevelClient restHighLevelClient = getRestClient(clusterInfo, "spock-keystore.jks", "truststore.jks", HttpVersionPolicy.FORCE_HTTP_1)) { + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .build(); + setup( + Settings.EMPTY, + new DynamicSecurityConfig().setSecurityInternalUsers("internal_empty.yml").setSecurityRoles("roles_deny.yml"), + settings, + true + ); + + try ( + RestHighLevelClient restHighLevelClient = getRestClient( + clusterInfo, + "spock-keystore.jks", + "truststore.jks", + HttpVersionPolicy.FORCE_HTTP_1 + ) + ) { Response whoAmIRes = restHighLevelClient.getLowLevelClient().performRequest(new Request("GET", "/_plugins/_security/whoami")); Assert.assertEquals(whoAmIRes.getStatusLine().getStatusCode(), 200); // The HTTP/1.1 is forced and should be used instead @@ -157,46 +186,87 @@ public void testWhoAmIForceHttp1() throws Exception { @Test public void testConfigHotReload() throws Exception { - + setup(); RestHelper rh = nonSslRestHelper(); Header spock = encodeBasicHeader("spock", "spock"); - + for (Iterator iterator = clusterInfo.httpAdresses.iterator(); iterator.hasNext();) { TransportAddress TransportAddress = (TransportAddress) iterator.next(); - HttpResponse res = rh.executeRequest(new HttpGet("http://"+TransportAddress.getAddress()+":"+TransportAddress.getPort() + "/" + "_opendistro/_security/authinfo?pretty=true"), spock); + HttpResponse res = rh.executeRequest( + new HttpGet( + "http://" + + TransportAddress.getAddress() + + ":" + + TransportAddress.getPort() + + "/" + + "_opendistro/_security/authinfo?pretty=true" + ), + spock + ); Assert.assertTrue(res.getBody().contains("spock")); Assert.assertFalse(res.getBody().contains("additionalrole")); Assert.assertTrue(res.getBody().contains("vulcan")); } - + try (Client tc = getClient()) { Assert.assertEquals(clusterInfo.numNodes, tc.admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); - tc.index(new IndexRequest(".opendistro_security").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("internalusers").source("internalusers", FileHelper.readYamlContent("internal_users_spock_add_roles.yml"))).actionGet(); - ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[]{"config","roles","rolesmapping","internalusers","actiongroups"})).actionGet(); - Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); - } - + tc.index( + new IndexRequest(".opendistro_security").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("internalusers") + .source("internalusers", FileHelper.readYamlContent("internal_users_spock_add_roles.yml")) + ).actionGet(); + ConfigUpdateResponse cur = tc.execute( + ConfigUpdateAction.INSTANCE, + new ConfigUpdateRequest(new String[] { "config", "roles", "rolesmapping", "internalusers", "actiongroups" }) + ).actionGet(); + Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); + } + for (Iterator iterator = clusterInfo.httpAdresses.iterator(); iterator.hasNext();) { TransportAddress TransportAddress = (TransportAddress) iterator.next(); - log.debug("http://"+TransportAddress.getAddress()+":"+TransportAddress.getPort()); - HttpResponse res = rh.executeRequest(new HttpGet("http://"+TransportAddress.getAddress()+":"+TransportAddress.getPort() + "/" + "_opendistro/_security/authinfo?pretty=true"), spock); + log.debug("http://" + TransportAddress.getAddress() + ":" + TransportAddress.getPort()); + HttpResponse res = rh.executeRequest( + new HttpGet( + "http://" + + TransportAddress.getAddress() + + ":" + + TransportAddress.getPort() + + "/" + + "_opendistro/_security/authinfo?pretty=true" + ), + spock + ); Assert.assertTrue(res.getBody().contains("spock")); Assert.assertTrue(res.getBody().contains("additionalrole1")); Assert.assertTrue(res.getBody().contains("additionalrole2")); Assert.assertFalse(res.getBody().contains("starfleet")); } - + try (Client tc = getClient()) { Assert.assertEquals(clusterInfo.numNodes, tc.admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); - tc.index(new IndexRequest(".opendistro_security").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("config").source("config", FileHelper.readYamlContent("config_anon.yml"))).actionGet(); - ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[]{"config"})).actionGet(); - Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); + tc.index( + new IndexRequest(".opendistro_security").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("config") + .source("config", FileHelper.readYamlContent("config_anon.yml")) + ).actionGet(); + ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[] { "config" })) + .actionGet(); + Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); } - + for (Iterator iterator = clusterInfo.httpAdresses.iterator(); iterator.hasNext();) { TransportAddress TransportAddress = (TransportAddress) iterator.next(); - HttpResponse res = rh.executeRequest(new HttpGet("http://"+TransportAddress.getAddress()+":"+TransportAddress.getPort() + "/" + "_opendistro/_security/authinfo?pretty=true")); + HttpResponse res = rh.executeRequest( + new HttpGet( + "http://" + + TransportAddress.getAddress() + + ":" + + TransportAddress.getPort() + + "/" + + "_opendistro/_security/authinfo?pretty=true" + ) + ); log.debug(res.getBody()); Assert.assertTrue(res.getBody().contains("role_host1")); Assert.assertTrue(res.getBody().contains("opendistro_security_anonymous")); @@ -208,13 +278,11 @@ public void testConfigHotReload() throws Exception { @Test public void testDefaultConfig() throws Exception { - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX, true) - .build(); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX, true).build(); setup(Settings.EMPTY, null, settings, false); RestHelper rh = nonSslRestHelper(); Thread.sleep(10000); - + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("admin", "admin")).getStatusCode()); HttpResponse res = rh.executeGetRequest("/_cluster/health", encodeBasicHeader("admin", "admin")); Assert.assertEquals(res.getBody(), HttpStatus.SC_OK, res.getStatusCode()); @@ -223,14 +291,17 @@ public void testDefaultConfig() throws Exception { @Test public void testInvalidDefaultConfig() throws Exception { try { - final String defaultInitDirectory = ClusterHelper.updateDefaultDirectory(new File(TEST_RESOURCE_RELATIVE_PATH + "invalid_config").getAbsolutePath()); - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX, true) - .build(); + final String defaultInitDirectory = ClusterHelper.updateDefaultDirectory( + new File(TEST_RESOURCE_RELATIVE_PATH + "invalid_config").getAbsolutePath() + ); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX, true).build(); setup(Settings.EMPTY, null, settings, false); RestHelper rh = nonSslRestHelper(); Thread.sleep(10000); - Assert.assertEquals(HttpStatus.SC_SERVICE_UNAVAILABLE, rh.executeGetRequest("", encodeBasicHeader("admin", "admin")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_SERVICE_UNAVAILABLE, + rh.executeGetRequest("", encodeBasicHeader("admin", "admin")).getStatusCode() + ); ClusterHelper.updateDefaultDirectory(defaultInitDirectory); restart(Settings.EMPTY, null, settings, false); @@ -244,21 +315,32 @@ public void testInvalidDefaultConfig() throws Exception { @Test public void testDisabled() throws Exception { - + final Settings settings = Settings.builder().put("plugins.security.disabled", true).build(); - + setup(Settings.EMPTY, null, settings, false); RestHelper rh = nonSslRestHelper(); - + HttpResponse resc = rh.executeGetRequest("_search"); Assert.assertEquals(200, resc.getStatusCode()); - Assert.assertTrue(resc.getBody(), resc.getBody().contains("hits")); + Assert.assertTrue(resc.getBody(), resc.getBody().contains("hits")); } @Test - public void testDiscoveryWithoutInitialization() throws Exception { + public void testDiscoveryWithoutInitialization() throws Exception { setup(Settings.EMPTY, null, Settings.EMPTY, false); - Assert.assertEquals(clusterInfo.numNodes, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getNumberOfNodes()); - Assert.assertEquals(ClusterHealthStatus.GREEN, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus()); + Assert.assertEquals( + clusterInfo.numNodes, + clusterHelper.nodeClient() + .admin() + .cluster() + .health(new ClusterHealthRequest().waitForGreenStatus()) + .actionGet() + .getNumberOfNodes() + ); + Assert.assertEquals( + ClusterHealthStatus.GREEN, + clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus() + ); } } diff --git a/src/test/java/org/opensearch/security/IntegrationTests.java b/src/test/java/org/opensearch/security/IntegrationTests.java index 226551a5ae..399d226bd9 100644 --- a/src/test/java/org/opensearch/security/IntegrationTests.java +++ b/src/test/java/org/opensearch/security/IntegrationTests.java @@ -62,60 +62,76 @@ public class IntegrationTests extends SingleClusterTest { @Test - public void testSearchScroll() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS+".worf", "knuddel","nonexists") + public void testSearchScroll() throws Exception { + final Settings settings = Settings.builder() + .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS + ".worf", "knuddel", "nonexists") .build(); - setup(settings); - final RestHelper rh = nonSslRestHelper(); + setup(settings); + final RestHelper rh = nonSslRestHelper(); try (Client tc = getClient()) { - for(int i=0; i<3; i++) - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); + for (int i = 0; i < 3; i++) + tc.index( + new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); } - - + System.out.println("########search"); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res=rh.executeGetRequest("vulcangov/_search?scroll=1m&pretty=true", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); - + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("vulcangov/_search?scroll=1m&pretty=true", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode() + ); + System.out.println(res.getBody()); int start = res.getBody().indexOf("_scroll_id") + 15; - String scrollid = res.getBody().substring(start, res.getBody().indexOf("\"", start+1)); + String scrollid = res.getBody().substring(start, res.getBody().indexOf("\"", start + 1)); System.out.println(scrollid); System.out.println("########search scroll"); - Assert.assertEquals(HttpStatus.SC_OK, (res=rh.executePostRequest("/_search/scroll?pretty=true", "{\"scroll_id\" : \""+scrollid+"\"}", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); - + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest( + "/_search/scroll?pretty=true", + "{\"scroll_id\" : \"" + scrollid + "\"}", + encodeBasicHeader("nagilum", "nagilum") + )).getStatusCode() + ); System.out.println("########search done"); - - + } @Test public void testDnParsingCertAuth() throws Exception { - Settings settings = Settings.builder() - .put("username_attribute", "cn") - .put("roles_attribute", "l") - .build(); + Settings settings = Settings.builder().put("username_attribute", "cn").put("roles_attribute", "l").build(); HTTPClientCertAuthenticator auth = new HTTPClientCertAuthenticator(settings, null); Assert.assertEquals("abc", auth.extractCredentials(null, newThreadContext("cn=abc,cn=xxx,l=ert,st=zui,c=qwe")).getUsername()); Assert.assertEquals("abc", auth.extractCredentials(null, newThreadContext("cn=abc,l=ert,st=zui,c=qwe")).getUsername()); - Assert.assertEquals("abc", auth.extractCredentials(null, newThreadContext("CN=abc,L=ert,st=zui,c=qwe")).getUsername()); + Assert.assertEquals("abc", auth.extractCredentials(null, newThreadContext("CN=abc,L=ert,st=zui,c=qwe")).getUsername()); Assert.assertEquals("abc", auth.extractCredentials(null, newThreadContext("l=ert,cn=abc,st=zui,c=qwe")).getUsername()); Assert.assertNull(auth.extractCredentials(null, newThreadContext("L=ert,CN=abc,c,st=zui,c=qwe"))); Assert.assertEquals("abc", auth.extractCredentials(null, newThreadContext("l=ert,st=zui,c=qwe,cn=abc")).getUsername()); - Assert.assertEquals("abc", auth.extractCredentials(null, newThreadContext("L=ert,st=zui,c=qwe,CN=abc")).getUsername()); - Assert.assertEquals("L=ert,st=zui,c=qwe", auth.extractCredentials(null, newThreadContext("L=ert,st=zui,c=qwe")).getUsername()); - Assert.assertArrayEquals(new String[] {"ert"}, auth.extractCredentials(null, newThreadContext("cn=abc,l=ert,st=zui,c=qwe")).getBackendRoles().toArray(new String[0])); - Assert.assertArrayEquals(new String[] {"bleh", "ert"}, new TreeSet<>(auth.extractCredentials(null, newThreadContext("cn=abc,l=ert,L=bleh,st=zui,c=qwe")).getBackendRoles()).toArray(new String[0])); - - settings = Settings.builder() - .build(); + Assert.assertEquals("abc", auth.extractCredentials(null, newThreadContext("L=ert,st=zui,c=qwe,CN=abc")).getUsername()); + Assert.assertEquals("L=ert,st=zui,c=qwe", auth.extractCredentials(null, newThreadContext("L=ert,st=zui,c=qwe")).getUsername()); + Assert.assertArrayEquals( + new String[] { "ert" }, + auth.extractCredentials(null, newThreadContext("cn=abc,l=ert,st=zui,c=qwe")).getBackendRoles().toArray(new String[0]) + ); + Assert.assertArrayEquals( + new String[] { "bleh", "ert" }, + new TreeSet<>(auth.extractCredentials(null, newThreadContext("cn=abc,l=ert,L=bleh,st=zui,c=qwe")).getBackendRoles()).toArray( + new String[0] + ) + ); + + settings = Settings.builder().build(); auth = new HTTPClientCertAuthenticator(settings, null); - Assert.assertEquals("cn=abc,l=ert,st=zui,c=qwe", auth.extractCredentials(null, newThreadContext("cn=abc,l=ert,st=zui,c=qwe")).getUsername()); + Assert.assertEquals( + "cn=abc,l=ert,st=zui,c=qwe", + auth.extractCredentials(null, newThreadContext("cn=abc,l=ert,st=zui,c=qwe")).getUsername() + ); } - + private ThreadContext newThreadContext(String sslPrincipal) { ThreadContext threadContext = new ThreadContext(Settings.EMPTY); threadContext.putTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_PRINCIPAL, sslPrincipal); @@ -124,51 +140,70 @@ private ThreadContext newThreadContext(String sslPrincipal) { @Test public void testDNSpecials() throws Exception { - + final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("node-untspec5-keystore.p12")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "1") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE, "PKCS12") - .putList(ConfigConstants.SECURITY_NODES_DN, "EMAILADDRESS=unt@tst.com,CN=node-untspec5.example.com,OU=SSL,O=Te\\, st,L=Test,C=DE") - .putList(ConfigConstants.SECURITY_AUTHCZ_ADMIN_DN, "EMAILADDRESS=unt@xxx.com,CN=node-untspec6.example.com,OU=SSL,O=Te\\, st,L=Test,C=DE") - .put(ConfigConstants.SECURITY_CERT_OID,"1.2.3.4.5.6") - .build(); - - + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("node-untspec5-keystore.p12") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "1") + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE, "PKCS12") + .putList( + ConfigConstants.SECURITY_NODES_DN, + "EMAILADDRESS=unt@tst.com,CN=node-untspec5.example.com,OU=SSL,O=Te\\, st,L=Test,C=DE" + ) + .putList( + ConfigConstants.SECURITY_AUTHCZ_ADMIN_DN, + "EMAILADDRESS=unt@xxx.com,CN=node-untspec6.example.com,OU=SSL,O=Te\\, st,L=Test,C=DE" + ) + .put(ConfigConstants.SECURITY_CERT_OID, "1.2.3.4.5.6") + .build(); + Settings tcSettings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("node-untspec6-keystore.p12")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE, "PKCS12") - .build(); - + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("node-untspec6-keystore.p12") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE, "PKCS12") + .build(); + setup(tcSettings, new DynamicSecurityConfig(), settings, true); RestHelper rh = nonSslRestHelper(); - + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("").getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("worf", "worf")).getStatusCode()); - + } - + @Test public void testDNSpecials1() throws Exception { - + final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("node-untspec5-keystore.p12")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "1") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE, "PKCS12") - .putList("plugins.security.nodes_dn", "EMAILADDRESS=unt@tst.com,CN=node-untspec5.example.com,OU=SSL,O=Te\\, st,L=Test,C=DE") - .putList("plugins.security.authcz.admin_dn", "EMAILADDREss=unt@xxx.com, cn=node-untspec6.example.com, OU=SSL,O=Te\\, st,L=Test, c=DE") - .put("plugins.security.cert.oid","1.2.3.4.5.6") - .build(); - - + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("node-untspec5-keystore.p12") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "1") + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE, "PKCS12") + .putList("plugins.security.nodes_dn", "EMAILADDRESS=unt@tst.com,CN=node-untspec5.example.com,OU=SSL,O=Te\\, st,L=Test,C=DE") + .putList( + "plugins.security.authcz.admin_dn", + "EMAILADDREss=unt@xxx.com, cn=node-untspec6.example.com, OU=SSL,O=Te\\, st,L=Test, c=DE" + ) + .put("plugins.security.cert.oid", "1.2.3.4.5.6") + .build(); + Settings tcSettings = Settings.builder() - .put("plugins.security.ssl.transport.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-untspec6-keystore.p12")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE, "PKCS12") - .build(); - + .put( + "plugins.security.ssl.transport.keystore_filepath", + FileHelper.getAbsoluteFilePathFromClassPath("node-untspec6-keystore.p12") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE, "PKCS12") + .build(); + setup(tcSettings, new DynamicSecurityConfig(), settings, true); RestHelper rh = nonSslRestHelper(); - + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("").getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("worf", "worf")).getStatusCode()); } @@ -181,203 +216,274 @@ public void testEnsureOpenSSLAvailability() { @Test public void testMultiget() throws Exception { - + setup(); - + try (Client tc = getClient()) { - tc.index(new IndexRequest("mindex1").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("mindex2").id("2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("mindex1").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("mindex2").id("2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON) + ).actionGet(); } - - //opendistro_security_multiget -> picard - - - String mgetBody = "{"+ - "\"docs\" : ["+ - "{"+ - "\"_index\" : \"mindex1\","+ - "\"_id\" : \"1\""+ - " },"+ - " {"+ - "\"_index\" : \"mindex2\","+ - " \"_id\" : \"2\""+ - "}"+ - "]"+ - "}"; - - RestHelper rh = nonSslRestHelper(); - HttpResponse resc = rh.executePostRequest("_mget?refresh=true", mgetBody, encodeBasicHeader("picard", "picard")); - System.out.println(resc.getBody()); - Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - Assert.assertFalse(resc.getBody().contains("type2")); - + + // opendistro_security_multiget -> picard + + String mgetBody = "{" + + "\"docs\" : [" + + "{" + + "\"_index\" : \"mindex1\"," + + "\"_id\" : \"1\"" + + " }," + + " {" + + "\"_index\" : \"mindex2\"," + + " \"_id\" : \"2\"" + + "}" + + "]" + + "}"; + + RestHelper rh = nonSslRestHelper(); + HttpResponse resc = rh.executePostRequest("_mget?refresh=true", mgetBody, encodeBasicHeader("picard", "picard")); + System.out.println(resc.getBody()); + Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); + Assert.assertFalse(resc.getBody().contains("type2")); + } @Test public void testRestImpersonation() throws Exception { - + final Settings settings = Settings.builder() - .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS+".spock", "knuddel","userwhonotexists").build(); - + .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS + ".spock", "knuddel", "userwhonotexists") + .build(); + setup(settings); - + RestHelper rh = nonSslRestHelper(); - - //knuddel: - // hash: _rest_impersonation_only_ - + + // knuddel: + // hash: _rest_impersonation_only_ + HttpResponse resp; - resp = rh.executeGetRequest("/_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as", "knuddel"), encodeBasicHeader("worf", "worf")); + resp = rh.executeGetRequest( + "/_opendistro/_security/authinfo", + new BasicHeader("opendistro_security_impersonate_as", "knuddel"), + encodeBasicHeader("worf", "worf") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resp.getStatusCode()); - - resp = rh.executeGetRequest("/_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as", "knuddel"), encodeBasicHeader("spock", "spock")); + + resp = rh.executeGetRequest( + "/_opendistro/_security/authinfo", + new BasicHeader("opendistro_security_impersonate_as", "knuddel"), + encodeBasicHeader("spock", "spock") + ); Assert.assertEquals(HttpStatus.SC_OK, resp.getStatusCode()); Assert.assertTrue(resp.getBody().contains("name=knuddel")); Assert.assertFalse(resp.getBody().contains("spock")); - - resp = rh.executeGetRequest("/_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as", "userwhonotexists"), encodeBasicHeader("spock", "spock")); + + resp = rh.executeGetRequest( + "/_opendistro/_security/authinfo", + new BasicHeader("opendistro_security_impersonate_as", "userwhonotexists"), + encodeBasicHeader("spock", "spock") + ); System.out.println(resp.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resp.getStatusCode()); - - resp = rh.executeGetRequest("/_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as", "invalid"), encodeBasicHeader("spock", "spock")); + + resp = rh.executeGetRequest( + "/_opendistro/_security/authinfo", + new BasicHeader("opendistro_security_impersonate_as", "invalid"), + encodeBasicHeader("spock", "spock") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resp.getStatusCode()); } @Test public void testSingle() throws Exception { - + setup(); - + try (Client tc = getClient()) { - tc.index(new IndexRequest("shakespeare").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[]{"config","roles","rolesmapping","internalusers","actiongroups"})).actionGet(); + tc.index( + new IndexRequest("shakespeare").id("1") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + + ConfigUpdateResponse cur = tc.execute( + ConfigUpdateAction.INSTANCE, + new ConfigUpdateRequest(new String[] { "config", "roles", "rolesmapping", "internalusers", "actiongroups" }) + ).actionGet(); Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); } - + RestHelper rh = nonSslRestHelper(); - //opendistro_security_shakespeare -> picard - + // opendistro_security_shakespeare -> picard + HttpResponse resc = rh.executeGetRequest("shakespeare/_search", encodeBasicHeader("picard", "picard")); System.out.println(resc.getBody()); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("\"content\":1")); - + resc = rh.executeHeadRequest("shakespeare", encodeBasicHeader("picard", "picard")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - + } @Test public void testSpecialUsernames() throws Exception { - - setup(); + + setup(); RestHelper rh = nonSslRestHelper(); - + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("bug.99", "nagilum")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("a", "b")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("\"'+-,;_?*@<>!$%&/()=#", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("", encodeBasicHeader("\"'+-,;_?*@<>!$%&/()=#", "nagilum")).getStatusCode() + ); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("§ÄÖÜäöüß", "nagilum")).getStatusCode()); - + } @Test public void testXff() throws Exception { - + setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_xff.yml"), Settings.EMPTY, true); RestHelper rh = nonSslRestHelper(); - HttpResponse resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("x-forwarded-for", "10.0.0.7"), encodeBasicHeader("worf", "worf")); + HttpResponse resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader("x-forwarded-for", "10.0.0.7"), + encodeBasicHeader("worf", "worf") + ); Assert.assertEquals(200, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("10.0.0.7")); } @Test public void testRegexExcludes() throws Exception { - + setup(Settings.EMPTY, new DynamicSecurityConfig(), Settings.EMPTY); try (Client tc = getClient()) { - tc.index(new IndexRequest("indexa").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"indexa\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("indexb").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"indexb\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("isallowed").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"isallowed\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("special").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"special\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("alsonotallowed").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"alsonotallowed\":1}", XContentType.JSON)).actionGet(); + tc.index(new IndexRequest("indexa").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"indexa\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("indexb").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"indexb\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("isallowed").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"isallowed\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("special").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"special\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("alsonotallowed").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"alsonotallowed\":1}", XContentType.JSON) + ).actionGet(); } - + RestHelper rh = nonSslRestHelper(); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("index*/_search",encodeBasicHeader("rexclude", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("indexa/_search",encodeBasicHeader("rexclude", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("isallowed/_search",encodeBasicHeader("rexclude", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("special/_search",encodeBasicHeader("rexclude", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("alsonotallowed/_search",encodeBasicHeader("rexclude", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("index*/_search", encodeBasicHeader("rexclude", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("indexa/_search", encodeBasicHeader("rexclude", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("isallowed/_search", encodeBasicHeader("rexclude", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeGetRequest("special/_search", encodeBasicHeader("rexclude", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executeGetRequest("alsonotallowed/_search", encodeBasicHeader("rexclude", "nagilum")).getStatusCode() + ); } - + @Test public void testMultiRoleSpan() throws Exception { - + setup(); final RestHelper rh = nonSslRestHelper(); try (Client tc = getClient()) { - tc.index(new IndexRequest("mindex_1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("mindex_2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)).actionGet(); + tc.index(new IndexRequest("mindex_1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("mindex_2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)) + .actionGet(); } - + HttpResponse res = rh.executeGetRequest("/mindex_1,mindex_2/_search", encodeBasicHeader("mindex12", "nagilum")); System.out.println(res.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); Assert.assertFalse(res.getBody().contains("\"content\":1")); Assert.assertFalse(res.getBody().contains("\"content\":2")); - + try (Client tc = getClient()) { - tc.index(new IndexRequest(".opendistro_security").id("config").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("config", FileHelper.readYamlContent("config_multirolespan.yml"))).actionGet(); - - ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[]{"config"})).actionGet(); + tc.index( + new IndexRequest(".opendistro_security").id("config") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("config", FileHelper.readYamlContent("config_multirolespan.yml")) + ).actionGet(); + + ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[] { "config" })) + .actionGet(); Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); } - + res = rh.executeGetRequest("/mindex_1,mindex_2/_search", encodeBasicHeader("mindex12", "nagilum")); System.out.println(res.getBody()); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("\"content\":1")); Assert.assertTrue(res.getBody().contains("\"content\":2")); - + } - + @Test public void testMultiRoleSpan2() throws Exception { - + setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_multirolespan.yml"), Settings.EMPTY); final RestHelper rh = nonSslRestHelper(); try (Client tc = getClient()) { - tc.index(new IndexRequest("mindex_1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("mindex_2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("mindex_3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("mindex_4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)).actionGet(); + tc.index(new IndexRequest("mindex_1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("mindex_2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("mindex_3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("mindex_4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)) + .actionGet(); } - + HttpResponse res = rh.executeGetRequest("/mindex_1,mindex_2/_search", encodeBasicHeader("mindex12", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - + res = rh.executeGetRequest("/mindex_1,mindex_3/_search", encodeBasicHeader("mindex12", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); res = rh.executeGetRequest("/mindex_1,mindex_4/_search", encodeBasicHeader("mindex12", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); - + } - + @Test public void testSecurityUnderscore() throws Exception { - + setup(); final RestHelper rh = nonSslRestHelper(); - - HttpResponse res = rh.executePostRequest("abc_xyz_2018_05_24/_doc/1", "{\"content\":1}", encodeBasicHeader("underscore", "nagilum")); - + + HttpResponse res = rh.executePostRequest( + "abc_xyz_2018_05_24/_doc/1", + "{\"content\":1}", + encodeBasicHeader("underscore", "nagilum") + ); + res = rh.executeGetRequest("abc_xyz_2018_05_24/_doc/1", encodeBasicHeader("underscore", "nagilum")); - Assert.assertTrue(res.getBody(),res.getBody().contains("\"content\":1")); + Assert.assertTrue(res.getBody(), res.getBody().contains("\"content\":1")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); res = rh.executeGetRequest("abc_xyz_2018_05_24/_refresh", encodeBasicHeader("underscore", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); @@ -391,45 +497,52 @@ public void testDeleteByQueryDnfof() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_dnfof.yml"), Settings.EMPTY); try (Client tc = getClient()) { - for(int i=0; i<3; i++) { - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); + for (int i = 0; i < 3; i++) { + tc.index( + new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); } } RestHelper rh = nonSslRestHelper(); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res=rh.executePostRequest("/vulcango*/_delete_by_query?refresh=true&wait_for_completion=true&pretty=true", "{\"query\" : {\"match_all\" : {}}}", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest( + "/vulcango*/_delete_by_query?refresh=true&wait_for_completion=true&pretty=true", + "{\"query\" : {\"match_all\" : {}}}", + encodeBasicHeader("nagilum", "nagilum") + )).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"deleted\" : 3")); } @Test public void testUpdate() throws Exception { - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH") - .build(); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH").build(); setup(settings); final RestHelper rh = nonSslRestHelper(); try (Client tc = getClient()) { - tc.index(new IndexRequest("indexc").id("0") - .setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"content\":1}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("indexc").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); } - HttpResponse res = rh.executePostRequest("indexc/_update/0?pretty=true&refresh=true", "{\"doc\" : {\"content\":2}}", - encodeBasicHeader("user_c", "user_c")); + HttpResponse res = rh.executePostRequest( + "indexc/_update/0?pretty=true&refresh=true", + "{\"doc\" : {\"content\":2}}", + encodeBasicHeader("user_c", "user_c") + ); System.out.println(res.getBody()); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); } - @Test public void testDnfof() throws Exception { - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH") - .build(); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH").build(); setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_dnfof.yml"), settings); final RestHelper rh = nonSslRestHelper(); @@ -437,49 +550,95 @@ public void testDnfof() throws Exception { try (Client tc = getClient()) { tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); - tc.index(new IndexRequest("indexa").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":\"indexa\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("indexb").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":\"indexb\"}", XContentType.JSON)).actionGet(); - - - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("starfleet","starfleet_academy","starfleet_library").alias("sf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire","vulcangov").alias("nonsf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))).actionGet(); + tc.index( + new IndexRequest("indexa").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":\"indexa\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("indexb").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":\"indexb\"}", XContentType.JSON) + ).actionGet(); + + tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction( + AliasActions.add().indices("starfleet", "starfleet_academy", "starfleet_library").alias("sf") + ) + ) + .actionGet(); + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire", "vulcangov").alias("nonsf")) + ) + .actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))) + .actionGet(); } HttpResponse resc; - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("indexa,indexb/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("indexa,indexb/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); Assert.assertTrue(resc.getBody(), resc.getBody().contains("indexa")); Assert.assertFalse(resc.getBody(), resc.getBody().contains("indexb")); Assert.assertFalse(resc.getBody(), resc.getBody().contains("exception")); Assert.assertFalse(resc.getBody(), resc.getBody().contains("permission")); - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("indexa,indexb/_search?pretty", encodeBasicHeader("user_b", "user_b"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("indexa,indexb/_search?pretty", encodeBasicHeader("user_b", "user_b"))).getStatusCode() + ); System.out.println(resc.getBody()); Assert.assertFalse(resc.getBody(), resc.getBody().contains("indexa")); Assert.assertTrue(resc.getBody(), resc.getBody().contains("indexb")); Assert.assertFalse(resc.getBody(), resc.getBody().contains("exception")); Assert.assertFalse(resc.getBody(), resc.getBody().contains("permission")); - String msearchBody = - "{\"index\":\"indexa\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ - "{\"index\":\"indexb\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ - "{\"index\":\"index*\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); + String msearchBody = "{\"index\":\"indexa\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator() + + "{\"index\":\"indexb\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator() + + "{\"index\":\"index*\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); System.out.println("#### msearch"); resc = rh.executePostRequest("_msearch?pretty", msearchBody, encodeBasicHeader("user_a", "user_a")); Assert.assertEquals(200, resc.getStatusCode()); @@ -501,106 +660,145 @@ public void testDnfof() throws Exception { Assert.assertEquals(3, resc.getBody().split("\"status\" : 200").length); Assert.assertEquals(2, resc.getBody().split("\"status\" : 403").length); - msearchBody = - "{\"index\":\"indexc\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ - "{\"index\":\"indexd\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); + msearchBody = "{\"index\":\"indexc\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator() + + "{\"index\":\"indexd\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); resc = rh.executePostRequest("_msearch?pretty", msearchBody, encodeBasicHeader("user_b", "user_b")); Assert.assertEquals(403, resc.getStatusCode()); - String mgetBody = "{"+ - "\"docs\" : ["+ - "{"+ - "\"_index\" : \"indexa\","+ - "\"_id\" : \"0\""+ - " },"+ - " {"+ - "\"_index\" : \"indexb\","+ - " \"_id\" : \"0\""+ - "}"+ - "]"+ - "}"; + String mgetBody = "{" + + "\"docs\" : [" + + "{" + + "\"_index\" : \"indexa\"," + + "\"_id\" : \"0\"" + + " }," + + " {" + + "\"_index\" : \"indexb\"," + + " \"_id\" : \"0\"" + + "}" + + "]" + + "}"; System.out.println("#### mget"); - resc = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("user_b", "user_b")); + resc = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("user_b", "user_b")); Assert.assertEquals(200, resc.getStatusCode()); Assert.assertFalse(resc.getBody(), resc.getBody().contains("\"content\" : \"indexa\"")); Assert.assertTrue(resc.getBody(), resc.getBody().contains("\"content\" : \"indexb\"")); Assert.assertTrue(resc.getBody(), resc.getBody().contains("exception")); Assert.assertTrue(resc.getBody(), resc.getBody().contains("permission")); - mgetBody = "{"+ - "\"docs\" : ["+ - "{"+ - "\"_index\" : \"indexx\","+ - "\"_id\" : \"0\""+ - " },"+ - " {"+ - "\"_index\" : \"indexy\","+ - " \"_id\" : \"0\""+ - "}"+ - "]"+ - "}"; - - resc = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("user_b", "user_b")); + mgetBody = "{" + + "\"docs\" : [" + + "{" + + "\"_index\" : \"indexx\"," + + "\"_id\" : \"0\"" + + " }," + + " {" + + "\"_index\" : \"indexy\"," + + " \"_id\" : \"0\"" + + "}" + + "]" + + "}"; + + resc = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("user_b", "user_b")); Assert.assertEquals(403, resc.getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); Assert.assertTrue(resc.getBody(), resc.getBody().contains("indexa")); Assert.assertFalse(resc.getBody(), resc.getBody().contains("indexb")); - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("index*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("index*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); Assert.assertTrue(resc.getBody(), resc.getBody().contains("indexa")); Assert.assertFalse(resc.getBody(), resc.getBody().contains("indexb")); Assert.assertFalse(resc.getBody(), resc.getBody().contains("exception")); Assert.assertFalse(resc.getBody(), resc.getBody().contains("permission")); - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("indexa/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("indexa/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("indexb/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("indexb/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("_all/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("_all/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("notexists/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("notexists/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - - Assert.assertEquals(HttpStatus.SC_NOT_FOUND, (resc=rh.executeGetRequest("permitnotexistentindex/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + + Assert.assertEquals( + HttpStatus.SC_NOT_FOUND, + (resc = rh.executeGetRequest("permitnotexistentindex/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("permitnotexistentindex*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("permitnotexistentindex*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - Assert.assertEquals(HttpStatus.SC_NOT_FOUND, (resc=rh.executeGetRequest("indexanbh,indexabb*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_NOT_FOUND, + (resc = rh.executeGetRequest("indexanbh,indexabb*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf"))).getStatusCode() + ); System.out.println(resc.getBody()); System.out.println("#### _all/_mapping/field/*"); - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("_all/_mapping/field/*", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("_all/_mapping/field/*", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode() + ); System.out.println(resc.getBody()); } - @Test public void testNoDnfof() throws Exception { - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH") - .build(); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH").build(); setup(Settings.EMPTY, new DynamicSecurityConfig(), settings); final RestHelper rh = nonSslRestHelper(); @@ -608,39 +806,83 @@ public void testNoDnfof() throws Exception { try (Client tc = getClient()) { tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); - tc.index(new IndexRequest("indexa").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":\"indexa\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("indexb").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":\"indexb\"}", XContentType.JSON)).actionGet(); - - - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("starfleet","starfleet_academy","starfleet_library").alias("sf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire","vulcangov").alias("nonsf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))).actionGet(); + tc.index( + new IndexRequest("indexa").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":\"indexa\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("indexb").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":\"indexb\"}", XContentType.JSON) + ).actionGet(); + + tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction( + AliasActions.add().indices("starfleet", "starfleet_academy", "starfleet_library").alias("sf") + ) + ) + .actionGet(); + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire", "vulcangov").alias("nonsf")) + ) + .actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))) + .actionGet(); } HttpResponse resc; - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("indexa,indexb/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("indexa,indexb/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("indexa,indexb/_search?pretty", encodeBasicHeader("user_b", "user_b"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("indexa,indexb/_search?pretty", encodeBasicHeader("user_b", "user_b"))).getStatusCode() + ); System.out.println(resc.getBody()); - String msearchBody = - "{\"index\":\"indexa\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ - "{\"index\":\"indexb\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); + String msearchBody = "{\"index\":\"indexa\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator() + + "{\"index\":\"indexb\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); System.out.println("#### msearch a"); resc = rh.executePostRequest("_msearch?pretty", msearchBody, encodeBasicHeader("user_a", "user_a")); Assert.assertEquals(200, resc.getStatusCode()); @@ -659,11 +901,14 @@ public void testNoDnfof() throws Exception { Assert.assertTrue(resc.getBody(), resc.getBody().contains("exception")); Assert.assertTrue(resc.getBody(), resc.getBody().contains("permission")); - msearchBody = - "{\"index\":\"indexc\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ - "{\"index\":\"indexd\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); + msearchBody = "{\"index\":\"indexc\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator() + + "{\"index\":\"indexd\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); System.out.println("#### msearch b2"); resc = rh.executePostRequest("_msearch?pretty", msearchBody, encodeBasicHeader("user_b", "user_b")); @@ -676,82 +921,120 @@ public void testNoDnfof() throws Exception { int count = resc.getBody().split("\"status\" : 403").length; Assert.assertEquals(3, count); - String mgetBody = "{"+ - "\"docs\" : ["+ - "{"+ - "\"_index\" : \"indexa\","+ - "\"_id\" : \"0\""+ - " },"+ - " {"+ - "\"_index\" : \"indexb\","+ - " \"_id\" : \"0\""+ - "}"+ - "]"+ - "}"; - - resc = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("user_b", "user_b")); + String mgetBody = "{" + + "\"docs\" : [" + + "{" + + "\"_index\" : \"indexa\"," + + "\"_id\" : \"0\"" + + " }," + + " {" + + "\"_index\" : \"indexb\"," + + " \"_id\" : \"0\"" + + "}" + + "]" + + "}"; + + resc = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("user_b", "user_b")); Assert.assertEquals(200, resc.getStatusCode()); Assert.assertFalse(resc.getBody(), resc.getBody().contains("\"content\" : \"indexa\"")); Assert.assertTrue(resc.getBody(), resc.getBody().contains("indexb")); Assert.assertTrue(resc.getBody(), resc.getBody().contains("exception")); Assert.assertTrue(resc.getBody(), resc.getBody().contains("permission")); - mgetBody = "{"+ - "\"docs\" : ["+ - "{"+ - "\"_index\" : \"indexx\","+ - "\"_id\" : \"0\""+ - " },"+ - " {"+ - "\"_index\" : \"indexy\","+ - " \"_id\" : \"0\""+ - "}"+ - "]"+ - "}"; - - resc = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("user_b", "user_b")); + mgetBody = "{" + + "\"docs\" : [" + + "{" + + "\"_index\" : \"indexx\"," + + "\"_id\" : \"0\"" + + " }," + + " {" + + "\"_index\" : \"indexy\"," + + " \"_id\" : \"0\"" + + "}" + + "]" + + "}"; + + resc = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("user_b", "user_b")); Assert.assertEquals(200, resc.getStatusCode()); Assert.assertTrue(resc.getBody(), resc.getBody().contains("exception")); count = resc.getBody().split("root_cause").length; Assert.assertEquals(3, count); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("index*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("index*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("indexa/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("indexa/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("indexb/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("indexb/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("_all/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("_all/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("notexists/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("notexists/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - Assert.assertEquals(HttpStatus.SC_NOT_FOUND, (resc=rh.executeGetRequest("indexanbh,indexabb*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_NOT_FOUND, + (resc = rh.executeGetRequest("indexanbh,indexabb*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); System.out.println(resc.getBody()); - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf"))).getStatusCode() + ); System.out.println(resc.getBody()); System.out.println("#### _all/_mapping/field/*"); - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("_all/_mapping/field/*", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("_all/_mapping/field/*", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode() + ); System.out.println(resc.getBody()); System.out.println("#### _mapping/field/*"); - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("_mapping/field/*", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("_mapping/field/*", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode() + ); System.out.println(resc.getBody()); System.out.println("#### */_mapping/field/*"); - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("*/_mapping/field/*", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("*/_mapping/field/*", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode() + ); System.out.println(resc.getBody()); } @@ -760,43 +1043,58 @@ public void testSecurityIndexSecurity() throws Exception { setup(); final RestHelper rh = nonSslRestHelper(); - HttpResponse res = rh.executePutRequest(".opendistro_security/_mapping?pretty", "{\"properties\": {\"name\":{\"type\":\"text\"}}}", - encodeBasicHeader("nagilum", "nagilum")); + HttpResponse res = rh.executePutRequest( + ".opendistro_security/_mapping?pretty", + "{\"properties\": {\"name\":{\"type\":\"text\"}}}", + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); - res = rh.executePutRequest("*dis*rit*/_mapping?pretty", "{\"properties\": {\"name\":{\"type\":\"text\"}}}", - encodeBasicHeader("nagilum", "nagilum")); + res = rh.executePutRequest( + "*dis*rit*/_mapping?pretty", + "{\"properties\": {\"name\":{\"type\":\"text\"}}}", + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); - res = rh.executePutRequest("*/_mapping?pretty", "{\"properties\": {\"name\":{\"type\":\"text\"}}}", - encodeBasicHeader("nagilum", "nagilum")); + res = rh.executePutRequest( + "*/_mapping?pretty", + "{\"properties\": {\"name\":{\"type\":\"text\"}}}", + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); - res = rh.executePutRequest("_all/_mapping?pretty", "{\"properties\": {\"name\":{\"type\":\"text\"}}}", - encodeBasicHeader("nagilum", "nagilum")); + res = rh.executePutRequest( + "_all/_mapping?pretty", + "{\"properties\": {\"name\":{\"type\":\"text\"}}}", + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); - res = rh.executePostRequest(".opendistro_security/_close", "", - encodeBasicHeader("nagilum", "nagilum")); + res = rh.executePostRequest(".opendistro_security/_close", "", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); - res = rh.executeDeleteRequest(".opendistro_security", - encodeBasicHeader("nagilum", "nagilum")); - res = rh.executeDeleteRequest("_all", - encodeBasicHeader("nagilum", "nagilum")); + res = rh.executeDeleteRequest(".opendistro_security", encodeBasicHeader("nagilum", "nagilum")); + res = rh.executeDeleteRequest("_all", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); - res = rh.executePutRequest(".opendistro_security/_settings", "{\"index\" : {\"number_of_replicas\" : 2}}", - encodeBasicHeader("nagilum", "nagilum")); + res = rh.executePutRequest( + ".opendistro_security/_settings", + "{\"index\" : {\"number_of_replicas\" : 2}}", + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); - res = rh.executePutRequest(".opendistro_secur*/_settings", "{\"index\" : {\"number_of_replicas\" : 2}}", - encodeBasicHeader("nagilum", "nagilum")); + res = rh.executePutRequest( + ".opendistro_secur*/_settings", + "{\"index\" : {\"number_of_replicas\" : 2}}", + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); -// res = rh.executePostRequest(".opendistro_security/_freeze", "", -// encodeBasicHeader("nagilum", "nagilum")); -// Assert.assertTrue(res.getStatusCode() >= 400); + // res = rh.executePostRequest(".opendistro_security/_freeze", "", + // encodeBasicHeader("nagilum", "nagilum")); + // Assert.assertTrue(res.getStatusCode() >= 400); String bulkBody = "{ \"index\" : { \"_index\" : \".opendistro_security\", \"_id\" : \"1\" } }\n" - + "{ \"field1\" : \"value1\" }\n" - + "{ \"index\" : { \"_index\" : \".opendistro_security\", \"_id\" : \"2\" } }\n" - + "{ \"field2\" : \"value2\" }\n" - + "{ \"index\" : { \"_index\" : \"myindex\", \"_id\" : \"2\" } }\n" - + "{ \"field2\" : \"value2\" }\n" - + "{ \"delete\" : { \"_index\" : \".opendistro_security\", \"_id\" : \"config\" } }\n"; + + "{ \"field1\" : \"value1\" }\n" + + "{ \"index\" : { \"_index\" : \".opendistro_security\", \"_id\" : \"2\" } }\n" + + "{ \"field2\" : \"value2\" }\n" + + "{ \"index\" : { \"_index\" : \"myindex\", \"_id\" : \"2\" } }\n" + + "{ \"field2\" : \"value2\" }\n" + + "{ \"delete\" : { \"_index\" : \".opendistro_security\", \"_id\" : \"config\" } }\n"; res = rh.executePostRequest("_bulk?refresh=true&pretty", bulkBody, encodeBasicHeader("nagilum", "nagilum")); JsonNode jsonNode = readTree(res.getBody()); System.out.println(res.getBody()); @@ -813,6 +1111,6 @@ public void testMonitorHealth() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig(), Settings.EMPTY); RestHelper rh = nonSslRestHelper(); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_cat/health",encodeBasicHeader("picard", "picard")).getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_cat/health", encodeBasicHeader("picard", "picard")).getStatusCode()); } } diff --git a/src/test/java/org/opensearch/security/PitIntegrationTests.java b/src/test/java/org/opensearch/security/PitIntegrationTests.java index 11c624eba6..035cc2ce3e 100644 --- a/src/test/java/org/opensearch/security/PitIntegrationTests.java +++ b/src/test/java/org/opensearch/security/PitIntegrationTests.java @@ -37,86 +37,75 @@ public void testPitExplicitAPIAccess() throws Exception { RestHelper rh = nonSslRestHelper(); try (Client tc = getClient()) { // create alias - tc.admin().indices().create(new CreateIndexRequest("pit_1") - .alias(new Alias("alias"))) - .actionGet(); + tc.admin().indices().create(new CreateIndexRequest("pit_1").alias(new Alias("alias"))).actionGet(); // create index - tc.index(new IndexRequest("pit_2").id("2").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE). - source("{\"content\":2}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("pit_2").id("2") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source("{\"content\":2}", XContentType.JSON) + ).actionGet(); } RestHelper.HttpResponse resc; // Create point in time in index should be successful since the user has permission for index - resc = rh.executePostRequest("/alias/_search/point_in_time?keep_alive=100m", "", - encodeBasicHeader("pit-1", "nagilum")); + resc = rh.executePostRequest("/alias/_search/point_in_time?keep_alive=100m", "", encodeBasicHeader("pit-1", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - String pitId1 = resc.findValueInJson("pit_id"); + String pitId1 = resc.findValueInJson("pit_id"); // Create point in time in index for which the user does not have permission - resc = rh.executePostRequest("/pit_2/_search/point_in_time?keep_alive=100m", "", - encodeBasicHeader("pit-1", "nagilum")); + resc = rh.executePostRequest("/pit_2/_search/point_in_time?keep_alive=100m", "", encodeBasicHeader("pit-1", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); // Create point in time in index for which the user has permission for - resc = rh.executePostRequest("/pit_2/_search/point_in_time?keep_alive=100m", "", - encodeBasicHeader("pit-2", "nagilum")); + resc = rh.executePostRequest("/pit_2/_search/point_in_time?keep_alive=100m", "", encodeBasicHeader("pit-2", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - String pitId2 = resc.findValueInJson("pit_id"); - resc = rh.executePostRequest("/pit*/_search/point_in_time?keep_alive=100m", "", - encodeBasicHeader("all-pit", "nagilum")); + String pitId2 = resc.findValueInJson("pit_id"); + resc = rh.executePostRequest("/pit*/_search/point_in_time?keep_alive=100m", "", encodeBasicHeader("all-pit", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); // PIT segments should work since there is atleast one PIT for which user has access for - resc = rh.executeGetRequest("/_cat/pit_segments", - "{\"pit_id\":\"" + pitId1 +"\"}", - encodeBasicHeader("pit-1", "nagilum")); + resc = rh.executeGetRequest("/_cat/pit_segments", "{\"pit_id\":\"" + pitId1 + "\"}", encodeBasicHeader("pit-1", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); // PIT segments should work since there is atleast one PIT for which user has access for - resc = rh.executeGetRequest("/_cat/pit_segments", - "{\"pit_id\":\"" + pitId1 +"\"}", - encodeBasicHeader("pit-1", "nagilum")); + resc = rh.executeGetRequest("/_cat/pit_segments", "{\"pit_id\":\"" + pitId1 + "\"}", encodeBasicHeader("pit-1", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); // Should throw error since user does not have access for pitId2 - resc = rh.executeGetRequest("/_cat/pit_segments", - "{\"pit_id\":\"" + pitId2 +"\"}", - encodeBasicHeader("pit-1", "nagilum")); + resc = rh.executeGetRequest("/_cat/pit_segments", "{\"pit_id\":\"" + pitId2 + "\"}", encodeBasicHeader("pit-1", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); // Should throw error since user does not have access for pitId2 - resc = rh.executeGetRequest("/_cat/pit_segments", - "{\"pit_id\":[\"" + pitId1 +"\",\"" + pitId2 + "\"]}", - encodeBasicHeader("pit-1", "nagilum")); + resc = rh.executeGetRequest( + "/_cat/pit_segments", + "{\"pit_id\":[\"" + pitId1 + "\",\"" + pitId2 + "\"]}", + encodeBasicHeader("pit-1", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); // Delete explicit PITs should work for PIT for which user has access for - resc = rh.executeDeleteRequest("/_search/point_in_time", - "{\"pit_id\":\"" + pitId1 +"\"}", - encodeBasicHeader("pit-1", "nagilum")); + resc = rh.executeDeleteRequest("/_search/point_in_time", "{\"pit_id\":\"" + pitId1 + "\"}", encodeBasicHeader("pit-1", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertEquals(pitId1, resc.findValueInJson("pits[0].pit_id")); Assert.assertEquals("true", resc.findValueInJson("pits[0].successful")); // Should throw error since user does not have access for pitId2 - resc = rh.executeDeleteRequest("/_search/point_in_time", - "{\"pit_id\":\"" + pitId2 +"\"}", - encodeBasicHeader("pit-1", "nagilum")); + resc = rh.executeDeleteRequest("/_search/point_in_time", "{\"pit_id\":\"" + pitId2 + "\"}", encodeBasicHeader("pit-1", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); // Should throw error since user does not have access for pitId2 - resc = rh.executeDeleteRequest("/_search/point_in_time", - "{\"pit_id\":[\"" + pitId1 +"\",\"" + pitId2 + "\"]}", - encodeBasicHeader("pit-1", "nagilum")); + resc = rh.executeDeleteRequest( + "/_search/point_in_time", + "{\"pit_id\":[\"" + pitId1 + "\",\"" + pitId2 + "\"]}", + encodeBasicHeader("pit-1", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); // Delete explicit PITs should work for PIT for which user has access for - resc = rh.executeDeleteRequest("/_search/point_in_time", - "{\"pit_id\":\"" + pitId2 +"\"}", - encodeBasicHeader("pit-2", "nagilum")); + resc = rh.executeDeleteRequest("/_search/point_in_time", "{\"pit_id\":\"" + pitId2 + "\"}", encodeBasicHeader("pit-2", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertEquals(pitId2, resc.findValueInJson("pits[0].pit_id")); Assert.assertEquals("true", resc.findValueInJson("pits[0].successful")); @@ -130,40 +119,41 @@ public void testPitAllAPIAccess() throws Exception { // Create two indices try (Client tc = getClient()) { - tc.index(new IndexRequest("pit_1").id("1").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE). - source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("pit_2").id("2").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE). - source("{\"content\":2}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("pit_1").id("1") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("pit_2").id("2") + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source("{\"content\":2}", XContentType.JSON) + ).actionGet(); } RestHelper.HttpResponse resc; // Create point in time in index should be successful since the user has permission for index - resc = rh.executePostRequest("/pit_1/_search/point_in_time?keep_alive=100m", "", - encodeBasicHeader("pit-1", "nagilum")); + resc = rh.executePostRequest("/pit_1/_search/point_in_time?keep_alive=100m", "", encodeBasicHeader("pit-1", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); String pitId1 = resc.findValueInJson("pit_id"); // Create point in time in index for which the user does not have permission - resc = rh.executePostRequest("/pit_2/_search/point_in_time?keep_alive=100m", "", - encodeBasicHeader("pit-1", "nagilum")); + resc = rh.executePostRequest("/pit_2/_search/point_in_time?keep_alive=100m", "", encodeBasicHeader("pit-1", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); // Create point in time in index for which the user has permission for - resc = rh.executePostRequest("/pit_2/_search/point_in_time?keep_alive=100m", "", - encodeBasicHeader("pit-2", "nagilum")); + resc = rh.executePostRequest("/pit_2/_search/point_in_time?keep_alive=100m", "", encodeBasicHeader("pit-2", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); String pitId2 = resc.findValueInJson("pit_id"); // Throw security error if user does not have all index permission - resc = rh.executeGetRequest("/_search/point_in_time/_all", - encodeBasicHeader("pit-1", "nagilum")); + resc = rh.executeGetRequest("/_search/point_in_time/_all", encodeBasicHeader("pit-1", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); // List all PITs should work for user with all index access - resc = rh.executeGetRequest("/_search/point_in_time/_all", - encodeBasicHeader("all-pit", "nagilum")); + resc = rh.executeGetRequest("/_search/point_in_time/_all", encodeBasicHeader("all-pit", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); List pitList = new ArrayList<>(); pitList.add(pitId1); @@ -172,24 +162,19 @@ public void testPitAllAPIAccess() throws Exception { pitList.contains(resc.findValueInJson("pits[1].pit_id")); // Throw security error if user does not have all index permission - resc = rh.executeGetRequest("/_cat/pit_segments/_all", - encodeBasicHeader("pit-1", "nagilum")); + resc = rh.executeGetRequest("/_cat/pit_segments/_all", encodeBasicHeader("pit-1", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); // PIT segments should work for user with all index access - resc = rh.executeGetRequest("/_cat/pit_segments/_all", - encodeBasicHeader("all-pit", "nagilum")); + resc = rh.executeGetRequest("/_cat/pit_segments/_all", encodeBasicHeader("all-pit", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - // Throw security error if user does not have all index permission - resc = rh.executeDeleteRequest("/_search/point_in_time/_all", - encodeBasicHeader("pit-1", "nagilum")); + resc = rh.executeDeleteRequest("/_search/point_in_time/_all", encodeBasicHeader("pit-1", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); // Delete all PITs should work for user with all index access - resc = rh.executeDeleteRequest("/_search/point_in_time/_all", - encodeBasicHeader("all-pit", "nagilum")); + resc = rh.executeDeleteRequest("/_search/point_in_time/_all", encodeBasicHeader("all-pit", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); pitList.contains(resc.findValueInJson("pits[0].pit_id")); pitList.contains(resc.findValueInJson("pits[1].pit_id")); @@ -202,8 +187,8 @@ public void testPitAllAPIAccess() throws Exception { public void testDataStreamWithPits() throws Exception { setup(); RestHelper rh = nonSslRestHelper(); - String indexTemplate = "{\"index_patterns\": [ \"my-data-stream*\" ], \"data_stream\": { }, \"priority\": 200, " + - "\"template\": {\"settings\": { } } }"; + String indexTemplate = "{\"index_patterns\": [ \"my-data-stream*\" ], \"data_stream\": { }, \"priority\": 200, " + + "\"template\": {\"settings\": { } } }"; rh.executePutRequest("/_index_template/my-data-stream-template", indexTemplate, encodeBasicHeader("ds1", "nagilum")); @@ -212,32 +197,25 @@ public void testDataStreamWithPits() throws Exception { RestHelper.HttpResponse resc; // create pit should work since user has permission on data stream - resc = rh.executePostRequest("/my-data-stream11/_search/point_in_time?keep_alive=100m", "", - encodeBasicHeader("pit-1", "nagilum")); + resc = rh.executePostRequest("/my-data-stream11/_search/point_in_time?keep_alive=100m", "", encodeBasicHeader("pit-1", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - String pitId1 = resc.findValueInJson("pit_id"); + String pitId1 = resc.findValueInJson("pit_id"); // PIT segments works since the user has access for backing indices - resc = rh.executeGetRequest("/_cat/pit_segments", - "{\"pit_id\":\"" + pitId1 +"\"}", - encodeBasicHeader("pit-1", "nagilum")); + resc = rh.executeGetRequest("/_cat/pit_segments", "{\"pit_id\":\"" + pitId1 + "\"}", encodeBasicHeader("pit-1", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); // create pit should work since user has permission on data stream - resc = rh.executePostRequest("/my-data-stream21/_search/point_in_time?keep_alive=100m", "", - encodeBasicHeader("pit-2", "nagilum")); + resc = rh.executePostRequest("/my-data-stream21/_search/point_in_time?keep_alive=100m", "", encodeBasicHeader("pit-2", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - String pitId2 = resc.findValueInJson("pit_id"); + String pitId2 = resc.findValueInJson("pit_id"); // since pit-3 doesn't have permission to backing data stream indices, throw security error - resc = rh.executeGetRequest("/_cat/pit_segments", - "{\"pit_id\":\"" + pitId2 +"\"}", - encodeBasicHeader("pit-3", "nagilum")); + resc = rh.executeGetRequest("/_cat/pit_segments", "{\"pit_id\":\"" + pitId2 + "\"}", encodeBasicHeader("pit-3", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); // Delete all PITs should work for user with all index access - resc = rh.executeDeleteRequest("/_search/point_in_time/_all", - encodeBasicHeader("all-pit", "nagilum")); + resc = rh.executeDeleteRequest("/_search/point_in_time/_all", encodeBasicHeader("all-pit", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); } } diff --git a/src/test/java/org/opensearch/security/PrivilegesEvaluationTest.java b/src/test/java/org/opensearch/security/PrivilegesEvaluationTest.java index 1f9668c641..b7af395daa 100644 --- a/src/test/java/org/opensearch/security/PrivilegesEvaluationTest.java +++ b/src/test/java/org/opensearch/security/PrivilegesEvaluationTest.java @@ -31,21 +31,27 @@ public void resolveTestHidden() throws Exception { try (Client client = getClient()) { - client.index(new IndexRequest("hidden_test_not_hidden").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source(XContentType.JSON, "index", - "hidden_test_not_hidden", "b", "y", "date", "1985/01/01")).actionGet(); - - client.admin().indices().create(new CreateIndexRequest(".hidden_test_actually_hidden").settings(ImmutableMap.of("index.hidden", true))) - .actionGet(); - client.index(new IndexRequest(".hidden_test_actually_hidden").id("test").source("a", "b").setRefreshPolicy(RefreshPolicy.IMMEDIATE)) - .actionGet(); + client.index( + new IndexRequest("hidden_test_not_hidden").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source(XContentType.JSON, "index", "hidden_test_not_hidden", "b", "y", "date", "1985/01/01") + ).actionGet(); + + client.admin() + .indices() + .create(new CreateIndexRequest(".hidden_test_actually_hidden").settings(ImmutableMap.of("index.hidden", true))) + .actionGet(); + client.index( + new IndexRequest(".hidden_test_actually_hidden").id("test").source("a", "b").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + ).actionGet(); } RestHelper rh = nonSslRestHelper(); - RestHelper.HttpResponse httpResponse = rh.executeGetRequest("/*hidden_test*/_search?expand_wildcards=all&pretty=true", - encodeBasicHeader("hidden_test", "nagilum")); + RestHelper.HttpResponse httpResponse = rh.executeGetRequest( + "/*hidden_test*/_search?expand_wildcards=all&pretty=true", + encodeBasicHeader("hidden_test", "nagilum") + ); Assert.assertEquals(httpResponse.getBody(), 403, httpResponse.getStatusCode()); - httpResponse = rh.executeGetRequest("/hidden_test_not_hidden?pretty=true", - encodeBasicHeader("hidden_test", "nagilum")); + httpResponse = rh.executeGetRequest("/hidden_test_not_hidden?pretty=true", encodeBasicHeader("hidden_test", "nagilum")); Assert.assertEquals(httpResponse.getBody(), 200, httpResponse.getStatusCode()); } } diff --git a/src/test/java/org/opensearch/security/ResolveAPITests.java b/src/test/java/org/opensearch/security/ResolveAPITests.java index 2c297e3bbe..088702acd9 100644 --- a/src/test/java/org/opensearch/security/ResolveAPITests.java +++ b/src/test/java/org/opensearch/security/ResolveAPITests.java @@ -32,9 +32,8 @@ import org.opensearch.security.test.SingleClusterTest; import org.opensearch.security.test.helper.rest.RestHelper; - public class ResolveAPITests extends SingleClusterTest { - + protected final Logger log = LogManager.getLogger(this.getClass()); @Test @@ -48,7 +47,10 @@ public void testResolveDnfofFalse() throws Exception { final RestHelper rh = nonSslRestHelper(); RestHelper.HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_resolve/index/*?pretty", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("_resolve/index/*?pretty", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode() + ); log.debug(res.getBody()); assertNotContains(res, "*xception*"); assertNotContains(res, "*erial*"); @@ -59,7 +61,10 @@ public void testResolveDnfofFalse() throws Exception { assertContains(res, "*xyz*"); assertContains(res, "*role01_role02*"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_resolve/index/starfleet*?pretty", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("_resolve/index/starfleet*?pretty", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode() + ); log.debug(res.getBody()); assertNotContains(res, "*xception*"); assertNotContains(res, "*erial*"); @@ -72,10 +77,16 @@ public void testResolveDnfofFalse() throws Exception { assertContains(res, "*starfleet_academy*"); assertContains(res, "*starfleet_library*"); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("_resolve/index/*?pretty", encodeBasicHeader("worf", "worf"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executeGetRequest("_resolve/index/*?pretty", encodeBasicHeader("worf", "worf"))).getStatusCode() + ); log.debug(res.getBody()); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_resolve/index/starfleet*?pretty", encodeBasicHeader("worf", "worf"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("_resolve/index/starfleet*?pretty", encodeBasicHeader("worf", "worf"))).getStatusCode() + ); log.debug(res.getBody()); assertContains(res, "*starfleet*"); assertContains(res, "*starfleet_academy*"); @@ -92,7 +103,10 @@ public void testResolveDnfofTrue() throws Exception { final RestHelper rh = nonSslRestHelper(); RestHelper.HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_resolve/index/*?pretty", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("_resolve/index/*?pretty", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode() + ); log.debug(res.getBody()); assertNotContains(res, "*xception*"); assertNotContains(res, "*erial*"); @@ -103,7 +117,10 @@ public void testResolveDnfofTrue() throws Exception { assertContains(res, "*xyz*"); assertContains(res, "*role01_role02*"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_resolve/index/starfleet*?pretty", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("_resolve/index/starfleet*?pretty", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode() + ); log.debug(res.getBody()); assertNotContains(res, "*xception*"); assertNotContains(res, "*erial*"); @@ -116,7 +133,10 @@ public void testResolveDnfofTrue() throws Exception { assertContains(res, "*starfleet_academy*"); assertContains(res, "*starfleet_library*"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_resolve/index/*?pretty", encodeBasicHeader("worf", "worf"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("_resolve/index/*?pretty", encodeBasicHeader("worf", "worf"))).getStatusCode() + ); log.debug(res.getBody()); assertNotContains(res, "*xception*"); assertNotContains(res, "*erial*"); @@ -127,7 +147,10 @@ public void testResolveDnfofTrue() throws Exception { assertContains(res, "*public*"); assertContains(res, "*xyz*"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_resolve/index/starfleet*?pretty", encodeBasicHeader("worf", "worf"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("_resolve/index/starfleet*?pretty", encodeBasicHeader("worf", "worf"))).getStatusCode() + ); log.debug(res.getBody()); assertNotContains(res, "*xception*"); assertNotContains(res, "*erial*"); @@ -140,30 +163,87 @@ public void testResolveDnfofTrue() throws Exception { assertContains(res, "*starfleet_academy*"); assertContains(res, "*starfleet_library*"); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("_resolve/index/vulcangov*?pretty", encodeBasicHeader("worf", "worf"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executeGetRequest("_resolve/index/vulcangov*?pretty", encodeBasicHeader("worf", "worf"))).getStatusCode() + ); log.debug(res.getBody()); } private void setupIndices() { try (Client tc = getClient()) { tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet_academy").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet_library").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("klingonempire").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("public").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("spock").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("kirk").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("role01_role02").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("xyz").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(IndicesAliasesRequest.AliasActions.add().indices("starfleet","starfleet_academy","starfleet_library").alias("sf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(IndicesAliasesRequest.AliasActions.add().indices("klingonempire","vulcangov").alias("nonsf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(IndicesAliasesRequest.AliasActions.add().indices("public").alias("unrestricted"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(IndicesAliasesRequest.AliasActions.add().indices("xyz").alias("alias1"))).actionGet(); + tc.index( + new IndexRequest("vulcangov").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("starfleet").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("starfleet_academy").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("starfleet_library").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("klingonempire").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("public").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + + tc.index( + new IndexRequest("spock").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("kirk").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("role01_role02").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + + tc.index( + new IndexRequest("xyz").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction( + IndicesAliasesRequest.AliasActions.add().indices("starfleet", "starfleet_academy", "starfleet_library").alias("sf") + ) + ) + .actionGet(); + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction( + IndicesAliasesRequest.AliasActions.add().indices("klingonempire", "vulcangov").alias("nonsf") + ) + ) + .actionGet(); + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction( + IndicesAliasesRequest.AliasActions.add().indices("public").alias("unrestricted") + ) + ) + .actionGet(); + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction(IndicesAliasesRequest.AliasActions.add().indices("xyz").alias("alias1")) + ) + .actionGet(); } } } diff --git a/src/test/java/org/opensearch/security/RolesInjectorIntegTest.java b/src/test/java/org/opensearch/security/RolesInjectorIntegTest.java index d14f8d6600..0ab9736378 100644 --- a/src/test/java/org/opensearch/security/RolesInjectorIntegTest.java +++ b/src/test/java/org/opensearch/security/RolesInjectorIntegTest.java @@ -63,14 +63,21 @@ public RolesInjectorPlugin(final Settings settings, final Path configPath) { } @Override - public Collection createComponents(Client client, ClusterService clusterService, ThreadPool threadPool, - ResourceWatcherService resourceWatcherService, ScriptService scriptService, - NamedXContentRegistry xContentRegistry, Environment environment, - NodeEnvironment nodeEnvironment, NamedWriteableRegistry namedWriteableRegistry, - IndexNameExpressionResolver indexNameExpressionResolver, - Supplier repositoriesServiceSupplier) { - if(injectedRoles != null) - threadPool.getThreadContext().putTransient(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_ROLES, injectedRoles); + public Collection createComponents( + Client client, + ClusterService clusterService, + ThreadPool threadPool, + ResourceWatcherService resourceWatcherService, + ScriptService scriptService, + NamedXContentRegistry xContentRegistry, + Environment environment, + NodeEnvironment nodeEnvironment, + NamedWriteableRegistry namedWriteableRegistry, + IndexNameExpressionResolver indexNameExpressionResolver, + Supplier repositoriesServiceSupplier + ) { + if (injectedRoles != null) threadPool.getThreadContext() + .putTransient(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_ROLES, injectedRoles); return new ArrayList<>(); } } @@ -79,26 +86,42 @@ public Collection createComponents(Client client, ClusterService cluster public void testRolesInject() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig().setSecurityRoles("roles.yml"), Settings.EMPTY); - Assert.assertEquals(clusterInfo.numNodes, clusterHelper.nodeClient().admin().cluster().health( - new ClusterHealthRequest().waitForGreenStatus()).actionGet().getNumberOfNodes()); - Assert.assertEquals(ClusterHealthStatus.GREEN, clusterHelper.nodeClient().admin().cluster(). - health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus()); - - final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) - .put(minimumSecuritySettings(Settings.EMPTY).get(0)) - .put("cluster.name", clusterInfo.clustername) - .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") - .put("path.logs", "./target/data/" + clusterInfo.clustername + "/cert/logs") - .put("path.home", "./target") - .put("node.name", "testclient") - .put("discovery.initial_state_timeout", "8s") - .put("plugins.security.allow_default_init_securityindex", "true") - .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost + ":" + clusterInfo.nodePort) - .build(); - - //1. Without roles injection. - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, - OpenSearchSecurityPlugin.class, RolesInjectorPlugin.class).start()) { + Assert.assertEquals( + clusterInfo.numNodes, + clusterHelper.nodeClient() + .admin() + .cluster() + .health(new ClusterHealthRequest().waitForGreenStatus()) + .actionGet() + .getNumberOfNodes() + ); + Assert.assertEquals( + ClusterHealthStatus.GREEN, + clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus() + ); + + final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) + .put(minimumSecuritySettings(Settings.EMPTY).get(0)) + .put("cluster.name", clusterInfo.clustername) + .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") + .put("path.logs", "./target/data/" + clusterInfo.clustername + "/cert/logs") + .put("path.home", "./target") + .put("node.name", "testclient") + .put("discovery.initial_state_timeout", "8s") + .put("plugins.security.allow_default_init_securityindex", "true") + .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost + ":" + clusterInfo.nodePort) + .build(); + + // 1. Without roles injection. + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + RolesInjectorPlugin.class + ).start() + ) { waitForInit(node.client()); CreateIndexResponse cir = node.client().admin().indices().create(new CreateIndexRequest("captain-logs-1")).actionGet(); @@ -107,10 +130,18 @@ public void testRolesInject() throws Exception { Assert.assertTrue(ier.isExists()); } - //2. With invalid roles, must throw security exception. + // 2. With invalid roles, must throw security exception. RolesInjectorPlugin.injectedRoles = "invalid_user|invalid_role"; Exception exception = null; - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class, RolesInjectorPlugin.class).start()) { + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + RolesInjectorPlugin.class + ).start() + ) { waitForInit(node.client()); CreateIndexResponse cir = node.client().admin().indices().create(new CreateIndexRequest("captain-logs-2")).actionGet(); @@ -122,9 +153,17 @@ public void testRolesInject() throws Exception { Assert.assertNotNull(exception); Assert.assertTrue(exception.getMessage().contains("indices:admin/create")); - //3. With valid roles - which has permission to create index. + // 3. With valid roles - which has permission to create index. RolesInjectorPlugin.injectedRoles = "valid_user|opendistro_security_all_access"; - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class, RolesInjectorPlugin.class).start()) { + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + RolesInjectorPlugin.class + ).start() + ) { waitForInit(node.client()); CreateIndexResponse cir = node.client().admin().indices().create(new CreateIndexRequest("captain-logs-3")).actionGet(); diff --git a/src/test/java/org/opensearch/security/RolesValidationIntegTest.java b/src/test/java/org/opensearch/security/RolesValidationIntegTest.java index 1b4aee3e51..89e0cd2e45 100644 --- a/src/test/java/org/opensearch/security/RolesValidationIntegTest.java +++ b/src/test/java/org/opensearch/security/RolesValidationIntegTest.java @@ -57,14 +57,22 @@ public RolesValidationPlugin(final Settings settings, final Path configPath) { } @Override - public Collection createComponents(Client client, ClusterService clusterService, ThreadPool threadPool, - ResourceWatcherService resourceWatcherService, ScriptService scriptService, - NamedXContentRegistry xContentRegistry, Environment environment, - NodeEnvironment nodeEnvironment, NamedWriteableRegistry namedWriteableRegistry, - IndexNameExpressionResolver indexNameExpressionResolver, - Supplier repositoriesServiceSupplier) { - if(rolesValidation != null) { - threadPool.getThreadContext().putTransient(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_ROLES, "test|opendistro_security_all_access"); + public Collection createComponents( + Client client, + ClusterService clusterService, + ThreadPool threadPool, + ResourceWatcherService resourceWatcherService, + ScriptService scriptService, + NamedXContentRegistry xContentRegistry, + Environment environment, + NodeEnvironment nodeEnvironment, + NamedWriteableRegistry namedWriteableRegistry, + IndexNameExpressionResolver indexNameExpressionResolver, + Supplier repositoriesServiceSupplier + ) { + if (rolesValidation != null) { + threadPool.getThreadContext() + .putTransient(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_ROLES, "test|opendistro_security_all_access"); threadPool.getThreadContext().putTransient(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_ROLES_VALIDATION, rolesValidation); } return new ArrayList<>(); @@ -75,21 +83,28 @@ public Collection createComponents(Client client, ClusterService cluster public void testRolesValidation() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig().setSecurityRoles("roles.yml"), Settings.EMPTY); - final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) - .put(minimumSecuritySettings(Settings.EMPTY).get(0)) - .put("cluster.name", clusterInfo.clustername) - .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") - .put("path.logs", "./target/data/" + clusterInfo.clustername + "/cert/logs") - .put("path.home", "./target") - .put("node.name", "testclient") - .put("discovery.initial_state_timeout", "8s") - .put("plugins.security.allow_default_init_securityindex", "true") - .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost + ":" + clusterInfo.nodePort) - .build(); + final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) + .put(minimumSecuritySettings(Settings.EMPTY).get(0)) + .put("cluster.name", clusterInfo.clustername) + .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") + .put("path.logs", "./target/data/" + clusterInfo.clustername + "/cert/logs") + .put("path.home", "./target") + .put("node.name", "testclient") + .put("discovery.initial_state_timeout", "8s") + .put("plugins.security.allow_default_init_securityindex", "true") + .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost + ":" + clusterInfo.nodePort) + .build(); // 1. Without roles validation - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, - OpenSearchSecurityPlugin.class, RolesValidationPlugin.class).start()) { + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + RolesValidationPlugin.class + ).start() + ) { waitForInit(node.client()); CreateIndexResponse cir = node.client().admin().indices().create(new CreateIndexRequest("captain-logs-1")).actionGet(); Assert.assertTrue(cir.isAcknowledged()); @@ -100,8 +115,15 @@ public void testRolesValidation() throws Exception { OpenSearchSecurityException exception = null; // 2. with roles invalid to the user RolesValidationPlugin.rolesValidation = "invalid_role"; - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, - OpenSearchSecurityPlugin.class, RolesValidationPlugin.class).start()) { + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + RolesValidationPlugin.class + ).start() + ) { waitForInit(node.client()); CreateIndexResponse cir = node.client().admin().indices().create(new CreateIndexRequest("captain-logs-2")).actionGet(); } catch (OpenSearchSecurityException ex) { @@ -112,8 +134,15 @@ public void testRolesValidation() throws Exception { // 3. with roles valid to the user RolesValidationPlugin.rolesValidation = "opendistro_security_all_access"; - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, - OpenSearchSecurityPlugin.class, RolesValidationPlugin.class).start()) { + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + RolesValidationPlugin.class + ).start() + ) { waitForInit(node.client()); CreateIndexResponse cir = node.client().admin().indices().create(new CreateIndexRequest("captain-logs-3")).actionGet(); Assert.assertTrue(cir.isAcknowledged()); diff --git a/src/test/java/org/opensearch/security/SecurityAdminIEndpointsTests.java b/src/test/java/org/opensearch/security/SecurityAdminIEndpointsTests.java index bc5d174739..b8da89e2dc 100644 --- a/src/test/java/org/opensearch/security/SecurityAdminIEndpointsTests.java +++ b/src/test/java/org/opensearch/security/SecurityAdminIEndpointsTests.java @@ -28,35 +28,45 @@ public void testNoSSL() throws Exception { setup(settings); final RestHelper rh = nonSslRestHelper(); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, - rh.executePutRequest("_plugins/_security/configupdate?config_types=roles", "{}", encodeBasicHeader("nagilum", "nagilum")) - .getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest("_plugins/_security/configupdate?config_types=roles", "{}", encodeBasicHeader("nagilum", "nagilum")) + .getStatusCode() + ); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executePutRequest("_plugins/_security/configupdate", "").getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, - rh.executePutRequest("_plugins/_security/configupdate?config_types=xxx", "", encodeBasicHeader("nagilum", "nagilum")) - .getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest("_plugins/_security/configupdate?config_types=xxx", "", encodeBasicHeader("nagilum", "nagilum")) + .getStatusCode() + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("_plugins/_security/whoami").getStatusCode()); } @Test public void testEndpoints() throws Exception { - final Settings settings = Settings.builder().put("plugins.security.ssl.http.enabled", true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .putList("plugins.security.nodes_dn", "CN=node-*.example.com,OU=SSL,O=Test,L=Test,C=DE").build(); + final Settings settings = Settings.builder() + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .putList("plugins.security.nodes_dn", "CN=node-*.example.com,OU=SSL,O=Test,L=Test,C=DE") + .build(); setup(settings); final RestHelper rh = restHelper(); rh.enableHTTPClientSSL = true; rh.trustHTTPServerCertificate = true; rh.sendAdminCertificate = false; - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, - rh.executePutRequest("_plugins/_security/configupdate?config_types=roles", "{}", encodeBasicHeader("nagilum", "nagilum")) - .getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest("_plugins/_security/configupdate?config_types=roles", "{}", encodeBasicHeader("nagilum", "nagilum")) + .getStatusCode() + ); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executePutRequest("_plugins/_security/configupdate", "").getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, - rh.executePutRequest("_plugins/_security/configupdate?config_types=xxx", "", encodeBasicHeader("nagilum", "nagilum")) - .getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest("_plugins/_security/configupdate?config_types=xxx", "", encodeBasicHeader("nagilum", "nagilum")) + .getStatusCode() + ); RestHelper.HttpResponse res; Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_plugins/_security/whoami")).getStatusCode()); @@ -71,13 +81,17 @@ public void testEndpoints() throws Exception { assertContains(res, "*\"is_admin\":false*"); assertContains(res, "*\"is_node_certificate_request\":true*"); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, - rh.executePutRequest("_plugins/_security/configupdate?config_types=roles", "{}", encodeBasicHeader("nagilum", "nagilum")) - .getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest("_plugins/_security/configupdate?config_types=roles", "{}", encodeBasicHeader("nagilum", "nagilum")) + .getStatusCode() + ); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executePutRequest("_plugins/_security/configupdate", "").getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, - rh.executePutRequest("_plugins/_security/configupdate?config_types=xxx", "", encodeBasicHeader("nagilum", "nagilum")) - .getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest("_plugins/_security/configupdate?config_types=xxx", "", encodeBasicHeader("nagilum", "nagilum")) + .getStatusCode() + ); rh.keystore = "spock-keystore.jks"; @@ -87,13 +101,17 @@ public void testEndpoints() throws Exception { assertContains(res, "*\"is_admin\":false*"); assertContains(res, "*\"is_node_certificate_request\":false*"); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, - rh.executePutRequest("_plugins/_security/configupdate?config_types=roles", "{}", encodeBasicHeader("nagilum", "nagilum")) - .getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest("_plugins/_security/configupdate?config_types=roles", "{}", encodeBasicHeader("nagilum", "nagilum")) + .getStatusCode() + ); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executePutRequest("_plugins/_security/configupdate", "").getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, - rh.executePutRequest("_plugins/_security/configupdate?config_types=xxx", "", encodeBasicHeader("nagilum", "nagilum")) - .getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePutRequest("_plugins/_security/configupdate?config_types=xxx", "", encodeBasicHeader("nagilum", "nagilum")) + .getStatusCode() + ); rh.keystore = "kirk-keystore.jks"; @@ -103,14 +121,25 @@ public void testEndpoints() throws Exception { assertContains(res, "*\"is_admin\":true*"); assertContains(res, "*\"is_node_certificate_request\":false*"); - Assert.assertEquals(HttpStatus.SC_OK, - rh.executePutRequest("_plugins/_security/configupdate?config_types=roles", "{}", encodeBasicHeader("nagilum", "nagilum")) - .getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePutRequest("_plugins/_security/configupdate?config_types=roles", "{}", encodeBasicHeader("nagilum", "nagilum")) + .getStatusCode() + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, rh.executePutRequest("_plugins/_security/configupdate", "").getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executePutRequest("_plugins/_security/configupdate?config_types=roles", "").getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePutRequest("_plugins/_security/configupdate?config_types=unknown_xxx", "", - encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePutRequest("_plugins/_security/configupdate?config_types=roles", "").getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePutRequest( + "_plugins/_security/configupdate?config_types=unknown_xxx", + "", + encodeBasicHeader("nagilum", "nagilum") + )).getStatusCode() + ); assertContains(res, "*\"successful\":0*failed_node_exception*"); } diff --git a/src/test/java/org/opensearch/security/SecurityAdminInvalidConfigsTests.java b/src/test/java/org/opensearch/security/SecurityAdminInvalidConfigsTests.java index 18f5c06529..6cb89dc18f 100644 --- a/src/test/java/org/opensearch/security/SecurityAdminInvalidConfigsTests.java +++ b/src/test/java/org/opensearch/security/SecurityAdminInvalidConfigsTests.java @@ -42,133 +42,153 @@ public class SecurityAdminInvalidConfigsTests extends SingleClusterTest { - @Test - public void testSecurityAdminDuplicateKey() throws Exception { - final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .build(); - setup(settings); - - final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - - List argsAsList = new ArrayList<>(); - argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); - argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk-keystore.jks").toFile().getAbsolutePath()); - argsAsList.add("-p"); - argsAsList.add(String.valueOf(clusterInfo.httpPort)); - argsAsList.add("-cn"); - argsAsList.add(clusterInfo.clustername); - argsAsList.add("-cd"); - argsAsList.add(new File("./src/test/resources/invalid_dupkey").getAbsolutePath()); - argsAsList.add("-nhnv"); - - - int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); - Assert.assertNotEquals(0, returnCode); - - RestHelper rh = restHelper(); - - Assert.assertEquals(HttpStatus.SC_OK, (rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - } - - @Test - public void testSecurityAdminDuplicateKeyReload() throws Exception { - testSecurityAdminDuplicateKey(); - - final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - - List argsAsList = new ArrayList<>(); - argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); - argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk-keystore.jks").toFile().getAbsolutePath()); - argsAsList.add("-p"); - argsAsList.add(String.valueOf(clusterInfo.httpPort)); - argsAsList.add("-cn"); - argsAsList.add(clusterInfo.clustername); - argsAsList.add("-rl"); - argsAsList.add("-nhnv"); - - - int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); - Assert.assertEquals(0, returnCode); - - RestHelper rh = restHelper(); - - Assert.assertEquals(HttpStatus.SC_OK, (rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - } - - @Test - public void testSecurityAdminDuplicateKeySingleFile() throws Exception { - final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .build(); - setup(settings); - - final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - - List argsAsList = new ArrayList<>(); - argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); - argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk-keystore.jks").toFile().getAbsolutePath()); - argsAsList.add("-p"); - argsAsList.add(String.valueOf(clusterInfo.httpPort)); - argsAsList.add("-cn"); - argsAsList.add(clusterInfo.clustername); - argsAsList.add("-f"); - argsAsList.add(new File("./src/test/resources/invalid_dupkey/roles_mapping.yml").getAbsolutePath()); - argsAsList.add("-t"); - argsAsList.add("rolesmapping"); - argsAsList.add("-nhnv"); - - - int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); - Assert.assertNotEquals(0, returnCode); - - RestHelper rh = restHelper(); - - Assert.assertEquals(HttpStatus.SC_OK, (rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - } - - @Test - public void testSecurityAdminDuplicateKeyReloadSingleFile() throws Exception { - testSecurityAdminDuplicateKeySingleFile(); - - final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - - List argsAsList = new ArrayList<>(); - argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); - argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk-keystore.jks").toFile().getAbsolutePath()); - argsAsList.add("-p"); - argsAsList.add(String.valueOf(clusterInfo.httpPort)); - argsAsList.add("-cn"); - argsAsList.add(clusterInfo.clustername); - argsAsList.add("-rl"); - argsAsList.add("-nhnv"); - - - int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); - Assert.assertEquals(0, returnCode); - - RestHelper rh = restHelper(); - - Assert.assertEquals(HttpStatus.SC_OK, (rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - } + @Test + public void testSecurityAdminDuplicateKey() throws Exception { + final Settings settings = Settings.builder() + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .build(); + setup(settings); + + final String prefix = getResourceFolder() == null ? "" : getResourceFolder() + "/"; + + List argsAsList = new ArrayList<>(); + argsAsList.add("-ts"); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); + argsAsList.add("-ks"); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add("-p"); + argsAsList.add(String.valueOf(clusterInfo.httpPort)); + argsAsList.add("-cn"); + argsAsList.add(clusterInfo.clustername); + argsAsList.add("-cd"); + argsAsList.add(new File("./src/test/resources/invalid_dupkey").getAbsolutePath()); + argsAsList.add("-nhnv"); + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + Assert.assertNotEquals(0, returnCode); + + RestHelper rh = restHelper(); + + Assert.assertEquals(HttpStatus.SC_OK, (rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + } + + @Test + public void testSecurityAdminDuplicateKeyReload() throws Exception { + testSecurityAdminDuplicateKey(); + + final String prefix = getResourceFolder() == null ? "" : getResourceFolder() + "/"; + + List argsAsList = new ArrayList<>(); + argsAsList.add("-ts"); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); + argsAsList.add("-ks"); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add("-p"); + argsAsList.add(String.valueOf(clusterInfo.httpPort)); + argsAsList.add("-cn"); + argsAsList.add(clusterInfo.clustername); + argsAsList.add("-rl"); + argsAsList.add("-nhnv"); + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + Assert.assertEquals(0, returnCode); + + RestHelper rh = restHelper(); + + Assert.assertEquals(HttpStatus.SC_OK, (rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + } + + @Test + public void testSecurityAdminDuplicateKeySingleFile() throws Exception { + final Settings settings = Settings.builder() + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .build(); + setup(settings); + + final String prefix = getResourceFolder() == null ? "" : getResourceFolder() + "/"; + + List argsAsList = new ArrayList<>(); + argsAsList.add("-ts"); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); + argsAsList.add("-ks"); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add("-p"); + argsAsList.add(String.valueOf(clusterInfo.httpPort)); + argsAsList.add("-cn"); + argsAsList.add(clusterInfo.clustername); + argsAsList.add("-f"); + argsAsList.add(new File("./src/test/resources/invalid_dupkey/roles_mapping.yml").getAbsolutePath()); + argsAsList.add("-t"); + argsAsList.add("rolesmapping"); + argsAsList.add("-nhnv"); + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + Assert.assertNotEquals(0, returnCode); + + RestHelper rh = restHelper(); + + Assert.assertEquals(HttpStatus.SC_OK, (rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + } + + @Test + public void testSecurityAdminDuplicateKeyReloadSingleFile() throws Exception { + testSecurityAdminDuplicateKeySingleFile(); + + final String prefix = getResourceFolder() == null ? "" : getResourceFolder() + "/"; + + List argsAsList = new ArrayList<>(); + argsAsList.add("-ts"); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); + argsAsList.add("-ks"); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add("-p"); + argsAsList.add(String.valueOf(clusterInfo.httpPort)); + argsAsList.add("-cn"); + argsAsList.add(clusterInfo.clustername); + argsAsList.add("-rl"); + argsAsList.add("-nhnv"); + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + Assert.assertEquals(0, returnCode); + + RestHelper rh = restHelper(); + + Assert.assertEquals(HttpStatus.SC_OK, (rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + } } diff --git a/src/test/java/org/opensearch/security/SecurityAdminTests.java b/src/test/java/org/opensearch/security/SecurityAdminTests.java index bd032fc332..681d04fc3e 100644 --- a/src/test/java/org/opensearch/security/SecurityAdminTests.java +++ b/src/test/java/org/opensearch/security/SecurityAdminTests.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security; @@ -43,34 +43,33 @@ import static org.junit.Assert.assertThrows; public class SecurityAdminTests extends SingleClusterTest { - + @Test public void testSecurityAdmin() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .build(); + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .build(); setup(Settings.EMPTY, null, settings, false); - - final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - + + final String prefix = getResourceFolder() == null ? "" : getResourceFolder() + "/"; + List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk-keystore.jks").toFile().getAbsolutePath()); argsAsList.add("-p"); argsAsList.add(String.valueOf(clusterInfo.httpPort)); argsAsList.add("-cn"); argsAsList.add(clusterInfo.clustername); addDirectoryPath(argsAsList, TEST_RESOURCE_ABSOLUTE_PATH); argsAsList.add("-nhnv"); - - - int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + RestHelper rh = restHelper(); Assert.assertEquals(HttpStatus.SC_OK, (rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); @@ -79,79 +78,89 @@ public void testSecurityAdmin() throws Exception { @Test public void testSecurityAdminHostnameVerificationEnforced() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.pemtrustedcas_filepath", FileHelper.getAbsoluteFilePathFromClassPath("securityadmin/root-ca.pem")) - .put("plugins.security.ssl.http.pemcert_filepath", FileHelper.getAbsoluteFilePathFromClassPath("securityadmin/node.crt.pem")) - .put("plugins.security.ssl.http.pemkey_filepath", FileHelper.getAbsoluteFilePathFromClassPath("securityadmin/node.key.pem")) - .putList("plugins.security.authcz.admin_dn", List.of("CN=kirk,OU=client,O=client,L=test,C=de")) - .build(); + .put("plugins.security.ssl.http.enabled", true) + .put( + "plugins.security.ssl.http.pemtrustedcas_filepath", + FileHelper.getAbsoluteFilePathFromClassPath("securityadmin/root-ca.pem") + ) + .put("plugins.security.ssl.http.pemcert_filepath", FileHelper.getAbsoluteFilePathFromClassPath("securityadmin/node.crt.pem")) + .put("plugins.security.ssl.http.pemkey_filepath", FileHelper.getAbsoluteFilePathFromClassPath("securityadmin/node.key.pem")) + .putList("plugins.security.authcz.admin_dn", List.of("CN=kirk,OU=client,O=client,L=test,C=de")) + .build(); setup(Settings.EMPTY, null, settings, false); - final String prefix = getResourceFolder()==null?"securityadmin/":getResourceFolder()+"/securityadmin/"; + final String prefix = getResourceFolder() == null ? "securityadmin/" : getResourceFolder() + "/securityadmin/"; List argsAsList = new ArrayList<>(); argsAsList.add("-cacert"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"root-ca.pem").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "root-ca.pem").toFile().getAbsolutePath()); argsAsList.add("-cert"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk.crt.pem").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk.crt.pem").toFile().getAbsolutePath()); argsAsList.add("-key"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk.key.pem").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk.key.pem").toFile().getAbsolutePath()); argsAsList.add("-p"); argsAsList.add(String.valueOf(clusterInfo.httpPort)); argsAsList.add("-icl"); addDirectoryPath(argsAsList, TEST_RESOURCE_ABSOLUTE_PATH); - final IOException expectedException = assertThrows(IOException.class, () -> SecurityAdmin.execute(argsAsList.toArray(new String[0]))); - final String expectedMessagePattern = "Certificate for <.+> doesn't match any of the subject alternative names: \\[node-.\\.example\\.com\\]"; + final IOException expectedException = assertThrows( + IOException.class, + () -> SecurityAdmin.execute(argsAsList.toArray(new String[0])) + ); + final String expectedMessagePattern = + "Certificate for <.+> doesn't match any of the subject alternative names: \\[node-.\\.example\\.com\\]"; assertThat(expectedException.getMessage(), matchesPattern(expectedMessagePattern)); } @Test public void testSecurityAdminHostnameVerificationNotEnforced() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.pemtrustedcas_filepath", FileHelper.getAbsoluteFilePathFromClassPath("securityadmin/root-ca.pem")) - .put("plugins.security.ssl.http.pemcert_filepath", FileHelper.getAbsoluteFilePathFromClassPath("securityadmin/node.crt.pem")) - .put("plugins.security.ssl.http.pemkey_filepath", FileHelper.getAbsoluteFilePathFromClassPath("securityadmin/node.key.pem")) - .putList("plugins.security.authcz.admin_dn", List.of("CN=kirk,OU=client,O=client,L=test,C=de")) - .build(); + .put("plugins.security.ssl.http.enabled", true) + .put( + "plugins.security.ssl.http.pemtrustedcas_filepath", + FileHelper.getAbsoluteFilePathFromClassPath("securityadmin/root-ca.pem") + ) + .put("plugins.security.ssl.http.pemcert_filepath", FileHelper.getAbsoluteFilePathFromClassPath("securityadmin/node.crt.pem")) + .put("plugins.security.ssl.http.pemkey_filepath", FileHelper.getAbsoluteFilePathFromClassPath("securityadmin/node.key.pem")) + .putList("plugins.security.authcz.admin_dn", List.of("CN=kirk,OU=client,O=client,L=test,C=de")) + .build(); setup(Settings.EMPTY, null, settings, false); - final String prefix = getResourceFolder()==null?"securityadmin/":getResourceFolder()+"/securityadmin/"; + final String prefix = getResourceFolder() == null ? "securityadmin/" : getResourceFolder() + "/securityadmin/"; List argsAsList = new ArrayList<>(); argsAsList.add("-cacert"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"root-ca.pem").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "root-ca.pem").toFile().getAbsolutePath()); argsAsList.add("-cert"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk.crt.pem").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk.crt.pem").toFile().getAbsolutePath()); argsAsList.add("-key"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk.key.pem").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk.key.pem").toFile().getAbsolutePath()); argsAsList.add("-p"); argsAsList.add(String.valueOf(clusterInfo.httpPort)); argsAsList.add("-icl"); addDirectoryPath(argsAsList, TEST_RESOURCE_ABSOLUTE_PATH); argsAsList.add("-nhnv"); - int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); } @Test public void testSecurityAdminInvalidCert() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .build(); + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .build(); setup(Settings.EMPTY, null, settings, false); - final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; + final String prefix = getResourceFolder() == null ? "" : getResourceFolder() + "/"; List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk-keystore.jks").toFile().getAbsolutePath()); argsAsList.add("-p"); argsAsList.add(String.valueOf(clusterInfo.httpPort)); argsAsList.add("-cn"); @@ -159,7 +168,7 @@ public void testSecurityAdminInvalidCert() throws Exception { addDirectoryPath(argsAsList, TEST_RESOURCE_ABSOLUTE_PATH); argsAsList.add("-nhnv"); - int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); RestHelper rh = restHelper(); @@ -168,9 +177,9 @@ public void testSecurityAdminInvalidCert() throws Exception { argsAsList = new ArrayList<>(); argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"spock-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "spock-keystore.jks").toFile().getAbsolutePath()); argsAsList.add("-p"); argsAsList.add(String.valueOf(clusterInfo.httpPort)); argsAsList.add("-cn"); @@ -179,17 +188,16 @@ public void testSecurityAdminInvalidCert() throws Exception { argsAsList.add("--diagnose"); argsAsList.add("-nhnv"); - - returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(-1, returnCode); Assert.assertEquals(HttpStatus.SC_OK, (rh.executeGetRequest("_plugins/_security/health?pretty")).getStatusCode()); argsAsList = new ArrayList<>(); argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"node-0-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "node-0-keystore.jks").toFile().getAbsolutePath()); argsAsList.add("-p"); argsAsList.add(String.valueOf(clusterInfo.httpPort)); argsAsList.add("-cn"); @@ -197,7 +205,7 @@ public void testSecurityAdminInvalidCert() throws Exception { addDirectoryPath(argsAsList, TEST_RESOURCE_ABSOLUTE_PATH); argsAsList.add("-nhnv"); - returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(-1, returnCode); Assert.assertEquals(HttpStatus.SC_OK, (rh.executeGetRequest("_plugins/_security/health?pretty")).getStatusCode()); @@ -206,92 +214,90 @@ public void testSecurityAdminInvalidCert() throws Exception { @Test public void testSecurityAdminV6Update() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .build(); + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .build(); setup(Settings.EMPTY, null, settings, false); - - final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - + + final String prefix = getResourceFolder() == null ? "" : getResourceFolder() + "/"; + List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk-keystore.jks").toFile().getAbsolutePath()); argsAsList.add("-p"); argsAsList.add(String.valueOf(clusterInfo.httpPort)); argsAsList.add("-cn"); argsAsList.add(clusterInfo.clustername); addDirectoryPath(argsAsList, new File("./legacy/securityconfig_v6").getAbsolutePath()); argsAsList.add("-nhnv"); - - - int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertNotEquals(0, returnCode); - + RestHelper rh = restHelper(); Assert.assertEquals(HttpStatus.SC_SERVICE_UNAVAILABLE, rh.executeGetRequest("_opendistro/_security/health?pretty").getStatusCode()); - //System.out.println(res.getBody()); - //assertContains(res, "*UP*"); - //assertContains(res, "*strict*"); - //assertNotContains(res, "*DOWN*"); + // System.out.println(res.getBody()); + // assertContains(res, "*UP*"); + // assertContains(res, "*strict*"); + // assertNotContains(res, "*DOWN*"); } - + @Test public void testSecurityAdminRegularUpdate() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .build(); + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .build(); setup(Settings.EMPTY, null, settings, true); - - final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - + + final String prefix = getResourceFolder() == null ? "" : getResourceFolder() + "/"; + List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk-keystore.jks").toFile().getAbsolutePath()); argsAsList.add("-p"); argsAsList.add(String.valueOf(clusterInfo.httpPort)); argsAsList.add("-cn"); argsAsList.add(clusterInfo.clustername); addDirectoryPath(argsAsList, TEST_RESOURCE_ABSOLUTE_PATH); argsAsList.add("-nhnv"); - - - int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + RestHelper rh = restHelper(); HttpResponse res; - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); System.out.println(res.getBody()); assertContains(res, "*UP*"); assertContains(res, "*strict*"); assertNotContains(res, "*DOWN*"); } - + @Test public void testSecurityAdminSingularV7Updates() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .build(); + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .build(); setup(Settings.EMPTY, new DynamicSecurityConfig(), settings, true); - - final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - + + final String prefix = getResourceFolder() == null ? "" : getResourceFolder() + "/"; + List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk-keystore.jks").toFile().getAbsolutePath()); argsAsList.add("-p"); argsAsList.add(String.valueOf(clusterInfo.httpPort)); argsAsList.add("-cn"); @@ -301,16 +307,15 @@ public void testSecurityAdminSingularV7Updates() throws Exception { argsAsList.add("-t"); argsAsList.add("config"); argsAsList.add("-nhnv"); - - - int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + argsAsList = new ArrayList<>(); argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk-keystore.jks").toFile().getAbsolutePath()); argsAsList.add("-p"); argsAsList.add(String.valueOf(clusterInfo.httpPort)); argsAsList.add("-cn"); @@ -320,16 +325,15 @@ public void testSecurityAdminSingularV7Updates() throws Exception { argsAsList.add("-t"); argsAsList.add("rolesmapping"); argsAsList.add("-nhnv"); - - - returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + argsAsList = new ArrayList<>(); argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk-keystore.jks").toFile().getAbsolutePath()); argsAsList.add("-p"); argsAsList.add(String.valueOf(clusterInfo.httpPort)); argsAsList.add("-cn"); @@ -339,37 +343,36 @@ public void testSecurityAdminSingularV7Updates() throws Exception { argsAsList.add("-t"); argsAsList.add("tenants"); argsAsList.add("-nhnv"); - - - returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + RestHelper rh = restHelper(); HttpResponse res; - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); System.out.println(res.getBody()); assertContains(res, "*UP*"); assertContains(res, "*strict*"); assertNotContains(res, "*DOWN*"); } - + @Test public void testSecurityAdminSingularV6Updates() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .build(); + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .build(); setup(Settings.EMPTY, new DynamicSecurityConfig(), settings, true); - final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - + final String prefix = getResourceFolder() == null ? "" : getResourceFolder() + "/"; + List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk-keystore.jks").toFile().getAbsolutePath()); argsAsList.add("-p"); argsAsList.add(String.valueOf(clusterInfo.httpPort)); argsAsList.add("-cn"); @@ -379,205 +382,209 @@ public void testSecurityAdminSingularV6Updates() throws Exception { argsAsList.add("-t"); argsAsList.add("config"); argsAsList.add("-nhnv"); - - int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertNotEquals(0, returnCode); - RestHelper rh = restHelper(); HttpResponse res; - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); System.out.println(res.getBody()); assertContains(res, "*UP*"); assertContains(res, "*strict*"); assertNotContains(res, "*DOWN*"); } - + @Test public void testSecurityAdminInvalidYml() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .build(); + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .build(); setup(Settings.EMPTY, new DynamicSecurityConfig(), settings, true); - final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - + final String prefix = getResourceFolder() == null ? "" : getResourceFolder() + "/"; + List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk-keystore.jks").toFile().getAbsolutePath()); argsAsList.add("-p"); argsAsList.add(String.valueOf(clusterInfo.httpPort)); argsAsList.add("-cn"); argsAsList.add(clusterInfo.clustername); argsAsList.add("-f"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"roles_invalidxcontent.yml").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "roles_invalidxcontent.yml").toFile().getAbsolutePath()); argsAsList.add("-t"); argsAsList.add("roles"); argsAsList.add("-nhnv"); - - - int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertNotEquals(0, returnCode); - + RestHelper rh = restHelper(); HttpResponse res; - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); System.out.println(res.getBody()); assertContains(res, "*UP*"); assertContains(res, "*strict*"); assertNotContains(res, "*DOWN*"); } - + @Test public void testSecurityAdminReloadInvalidConfig() throws Exception { final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .build(); + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .build(); setup(Settings.EMPTY, new DynamicSecurityConfig(), settings, true); - final RestHelper rh = restHelper(); //ssl resthelper + final RestHelper rh = restHelper(); // ssl resthelper rh.enableHTTPClientSSL = true; rh.trustHTTPServerCertificate = true; rh.sendAdminCertificate = true; rh.keystore = "kirk-keystore.jks"; - System.out.println(rh.executePutRequest(".opendistro_security/_doc/roles", FileHelper.loadFile("roles_invalidxcontent.yml")).getBody());; - Assert.assertEquals(HttpStatus.SC_OK, rh.executePutRequest(".opendistro_security/_doc/roles", "{\"roles\":\"dummy\"}").getStatusCode()); - - - final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - + System.out.println( + rh.executePutRequest(".opendistro_security/_doc/roles", FileHelper.loadFile("roles_invalidxcontent.yml")).getBody() + ); + ; + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePutRequest(".opendistro_security/_doc/roles", "{\"roles\":\"dummy\"}").getStatusCode() + ); + + final String prefix = getResourceFolder() == null ? "" : getResourceFolder() + "/"; + List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk-keystore.jks").toFile().getAbsolutePath()); argsAsList.add("-p"); argsAsList.add(String.valueOf(clusterInfo.httpPort)); argsAsList.add("-cn"); argsAsList.add(clusterInfo.clustername); argsAsList.add("-rl"); argsAsList.add("-nhnv"); - - - int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertNotEquals(0, returnCode); - + HttpResponse res; - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); assertContains(res, "*UP*"); assertContains(res, "*strict*"); assertNotContains(res, "*DOWN*"); } - + @Test public void testSecurityAdminValidateConfig() throws Exception { List argsAsList = new ArrayList<>(); addDirectoryPath(argsAsList, TEST_RESOURCE_ABSOLUTE_PATH); argsAsList.add("-vc"); - - int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + argsAsList = new ArrayList<>(); argsAsList.add("-f"); argsAsList.add(new File(PROJECT_ROOT_RELATIVE_PATH + "src/test/resources/roles.yml").getAbsolutePath()); argsAsList.add("-vc"); - - returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + argsAsList = new ArrayList<>(); argsAsList.add("-f"); argsAsList.add(new File(PROJECT_ROOT_RELATIVE_PATH + "src/main/resources/static_config/static_roles.yml").getAbsolutePath()); argsAsList.add("-vc"); - - returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + argsAsList = new ArrayList<>(); argsAsList.add("-f"); - argsAsList.add(new File(PROJECT_ROOT_RELATIVE_PATH + "src/main/resources/static_config/static_action_groups.yml").getAbsolutePath()); + argsAsList.add( + new File(PROJECT_ROOT_RELATIVE_PATH + "src/main/resources/static_config/static_action_groups.yml").getAbsolutePath() + ); argsAsList.add("-vc"); - - returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + argsAsList = new ArrayList<>(); argsAsList.add("-f"); argsAsList.add(new File(PROJECT_ROOT_RELATIVE_PATH + "src/main/resources/static_config/static_tenants.yml").getAbsolutePath()); argsAsList.add("-vc"); - - returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + argsAsList = new ArrayList<>(); argsAsList.add("-f"); argsAsList.add(TEST_RESOURCE_ABSOLUTE_PATH + "roles.yml"); argsAsList.add("-vc"); argsAsList.add("-t"); argsAsList.add("config"); - - returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertNotEquals(0, returnCode); - + argsAsList = new ArrayList<>(); argsAsList.add("-ks"); argsAsList.add(TEST_RESOURCE_ABSOLUTE_PATH); argsAsList.add("-vc"); - - returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertNotEquals(0, returnCode); - + argsAsList = new ArrayList<>(); addDirectoryPath(argsAsList, TEST_RESOURCE_ABSOLUTE_PATH + "legacy/securityconfig_v6"); argsAsList.add("-vc"); - - returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertNotEquals(0, returnCode); - + argsAsList = new ArrayList<>(); addDirectoryPath(argsAsList, TEST_RESOURCE_ABSOLUTE_PATH + "legacy/securityconfig_v6"); argsAsList.add("-vc"); argsAsList.add("6"); - - returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + argsAsList = new ArrayList<>(); addDirectoryPath(argsAsList, TEST_RESOURCE_ABSOLUTE_PATH); argsAsList.add("-vc"); argsAsList.add("8"); - - returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); + + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertNotEquals(0, returnCode); } @Test public void testIsLegacySecurityIndexOnV7Index() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .build(); + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .build(); setup(Settings.EMPTY, null, settings, false); - - final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - + + final String prefix = getResourceFolder() == null ? "" : getResourceFolder() + "/"; + List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks").toFile().getAbsolutePath()); argsAsList.add("-ks"); - argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"kirk-keystore.jks").toFile().getAbsolutePath()); + argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix + "kirk-keystore.jks").toFile().getAbsolutePath()); argsAsList.add("-p"); argsAsList.add(String.valueOf(clusterInfo.httpPort)); argsAsList.add("-cn"); @@ -588,7 +595,7 @@ public void testIsLegacySecurityIndexOnV7Index() throws Exception { // Execute first time to create the index int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos); PrintStream old = System.out; @@ -600,7 +607,9 @@ public void testIsLegacySecurityIndexOnV7Index() throws Exception { System.out.flush(); System.setOut(old); String standardOut = baos.toString(); - String legacyIndexOutput = "Legacy index '"+ConfigConstants.OPENDISTRO_SECURITY_DEFAULT_CONFIG_INDEX+"' (ES 6) detected (or forced). You should migrate the configuration!"; + String legacyIndexOutput = "Legacy index '" + + ConfigConstants.OPENDISTRO_SECURITY_DEFAULT_CONFIG_INDEX + + "' (ES 6) detected (or forced). You should migrate the configuration!"; Assert.assertFalse(standardOut.contains(legacyIndexOutput)); } diff --git a/src/test/java/org/opensearch/security/SecurityRolesTests.java b/src/test/java/org/opensearch/security/SecurityRolesTests.java index ee8e1ea150..24a6bafbb8 100644 --- a/src/test/java/org/opensearch/security/SecurityRolesTests.java +++ b/src/test/java/org/opensearch/security/SecurityRolesTests.java @@ -40,76 +40,89 @@ public class SecurityRolesTests extends SingleClusterTest { - @Test - public void testSecurityRolesAnon() throws Exception { - - setup(Settings.EMPTY, new DynamicSecurityConfig() - .setSecurityInternalUsers("internal_users_sr.yml") - .setConfig("config_anon.yml"), Settings.EMPTY, true); - - RestHelper rh = nonSslRestHelper(); - - HttpResponse resc = rh.executeGetRequest("_opendistro/_security/authinfo?pretty"); - Assert.assertTrue(resc.getBody().contains("anonymous")); - Assert.assertFalse(resc.getBody().contains("xyz_sr")); - Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - - resc = rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("sr_user", "nagilum")); - Assert.assertTrue(resc.getBody().contains("sr_user")); - Assert.assertTrue(resc.getBody().contains("xyz_sr")); - Assert.assertFalse(resc.getBody().contains("opendistro_security_kibana_server")); - Assert.assertTrue(resc.getBody().contains("backend_roles=[abc_ber]")); - Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - } - - @Test - public void testSecurityRoles() throws Exception { - - setup(Settings.EMPTY, new DynamicSecurityConfig() - .setSecurityRolesMapping("roles_mapping.yml") - .setSecurityInternalUsers("internal_users_sr.yml"), Settings.EMPTY, true); - - RestHelper rh = nonSslRestHelper(); - rh.sendAdminCertificate = false; - - HttpResponse resc = rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("sr_user", "nagilum")); - Assert.assertTrue(resc.getBody().contains("sr_user")); - Assert.assertTrue(resc.getBody().contains("xyz_sr")); - - // Opendistro_security_roles cannot contain roles that don't exist. - Assert.assertFalse(resc.getBody().contains("xyz_sr_non_existent")); - - // Opendistro_security_roles can contain reserved roles. - Assert.assertTrue(resc.getBody().contains("xyz_sr_reserved")); - - // Opendistro_security_roles cannot contain roles that are hidden in rolesmapping.yml. - Assert.assertFalse(resc.getBody().contains("xyz_sr_hidden")); - - Assert.assertTrue(resc.getBody().contains("backend_roles=[abc_ber]")); - Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - } - - @Test - public void testSecurityRolesImpersonation() throws Exception { - - Settings settings = Settings.builder() - .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS+".sr_user", "sr_impuser") - .build(); - - setup(Settings.EMPTY, new DynamicSecurityConfig() - .setSecurityInternalUsers("internal_users_sr.yml"), settings, true); - - RestHelper rh = nonSslRestHelper(); - - HttpResponse resc = rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("sr_user", "nagilum"), new BasicHeader("opendistro_security_impersonate_as", "sr_impuser")); - Assert.assertFalse(resc.getBody().contains("sr_user")); - Assert.assertTrue(resc.getBody().contains("sr_impuser")); - Assert.assertFalse(resc.getBody().contains("xyz_sr")); - Assert.assertTrue(resc.getBody().contains("xyz_impsr")); - Assert.assertTrue(resc.getBody().contains("backend_roles=[ert_ber]")); - Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - - resc = rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("sr_user", "nagilum"), new BasicHeader("opendistro_security_impersonate_as", "sr_impuser")); - Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - } + @Test + public void testSecurityRolesAnon() throws Exception { + + setup( + Settings.EMPTY, + new DynamicSecurityConfig().setSecurityInternalUsers("internal_users_sr.yml").setConfig("config_anon.yml"), + Settings.EMPTY, + true + ); + + RestHelper rh = nonSslRestHelper(); + + HttpResponse resc = rh.executeGetRequest("_opendistro/_security/authinfo?pretty"); + Assert.assertTrue(resc.getBody().contains("anonymous")); + Assert.assertFalse(resc.getBody().contains("xyz_sr")); + Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); + + resc = rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("sr_user", "nagilum")); + Assert.assertTrue(resc.getBody().contains("sr_user")); + Assert.assertTrue(resc.getBody().contains("xyz_sr")); + Assert.assertFalse(resc.getBody().contains("opendistro_security_kibana_server")); + Assert.assertTrue(resc.getBody().contains("backend_roles=[abc_ber]")); + Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); + } + + @Test + public void testSecurityRoles() throws Exception { + + setup( + Settings.EMPTY, + new DynamicSecurityConfig().setSecurityRolesMapping("roles_mapping.yml").setSecurityInternalUsers("internal_users_sr.yml"), + Settings.EMPTY, + true + ); + + RestHelper rh = nonSslRestHelper(); + rh.sendAdminCertificate = false; + + HttpResponse resc = rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("sr_user", "nagilum")); + Assert.assertTrue(resc.getBody().contains("sr_user")); + Assert.assertTrue(resc.getBody().contains("xyz_sr")); + + // Opendistro_security_roles cannot contain roles that don't exist. + Assert.assertFalse(resc.getBody().contains("xyz_sr_non_existent")); + + // Opendistro_security_roles can contain reserved roles. + Assert.assertTrue(resc.getBody().contains("xyz_sr_reserved")); + + // Opendistro_security_roles cannot contain roles that are hidden in rolesmapping.yml. + Assert.assertFalse(resc.getBody().contains("xyz_sr_hidden")); + + Assert.assertTrue(resc.getBody().contains("backend_roles=[abc_ber]")); + Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); + } + + @Test + public void testSecurityRolesImpersonation() throws Exception { + + Settings settings = Settings.builder() + .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS + ".sr_user", "sr_impuser") + .build(); + + setup(Settings.EMPTY, new DynamicSecurityConfig().setSecurityInternalUsers("internal_users_sr.yml"), settings, true); + + RestHelper rh = nonSslRestHelper(); + + HttpResponse resc = rh.executeGetRequest( + "_opendistro/_security/authinfo?pretty", + encodeBasicHeader("sr_user", "nagilum"), + new BasicHeader("opendistro_security_impersonate_as", "sr_impuser") + ); + Assert.assertFalse(resc.getBody().contains("sr_user")); + Assert.assertTrue(resc.getBody().contains("sr_impuser")); + Assert.assertFalse(resc.getBody().contains("xyz_sr")); + Assert.assertTrue(resc.getBody().contains("xyz_impsr")); + Assert.assertTrue(resc.getBody().contains("backend_roles=[ert_ber]")); + Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); + + resc = rh.executeGetRequest( + "*/_search?pretty", + encodeBasicHeader("sr_user", "nagilum"), + new BasicHeader("opendistro_security_impersonate_as", "sr_impuser") + ); + Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); + } } diff --git a/src/test/java/org/opensearch/security/SlowIntegrationTests.java b/src/test/java/org/opensearch/security/SlowIntegrationTests.java index 6a90ef8e71..0e7585a08d 100644 --- a/src/test/java/org/opensearch/security/SlowIntegrationTests.java +++ b/src/test/java/org/opensearch/security/SlowIntegrationTests.java @@ -53,100 +53,155 @@ public class SlowIntegrationTests extends SingleClusterTest { @Test public void testCustomInterclusterRequestEvaluator() throws Exception { - + final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_INTERCLUSTER_REQUEST_EVALUATOR_CLASS, "org.opensearch.security.AlwaysFalseInterClusterRequestEvaluator") - .put("discovery.initial_state_timeout","8s") - .build(); - setup(Settings.EMPTY, null, settings, false, ClusterConfiguration.DEFAULT ,5,1); - Assert.assertEquals(1, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getNumberOfNodes()); - Assert.assertEquals(ClusterHealthStatus.GREEN, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus()); + .put( + ConfigConstants.SECURITY_INTERCLUSTER_REQUEST_EVALUATOR_CLASS, + "org.opensearch.security.AlwaysFalseInterClusterRequestEvaluator" + ) + .put("discovery.initial_state_timeout", "8s") + .build(); + setup(Settings.EMPTY, null, settings, false, ClusterConfiguration.DEFAULT, 5, 1); + Assert.assertEquals( + 1, + clusterHelper.nodeClient() + .admin() + .cluster() + .health(new ClusterHealthRequest().waitForGreenStatus()) + .actionGet() + .getNumberOfNodes() + ); + Assert.assertEquals( + ClusterHealthStatus.GREEN, + clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus() + ); } @SuppressWarnings("resource") @Test public void testNodeClientAllowedWithServerCertificate() throws Exception { setup(); - Assert.assertEquals(clusterInfo.numNodes, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getNumberOfNodes()); - Assert.assertEquals(ClusterHealthStatus.GREEN, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus()); - - - final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) - .put(minimumSecuritySettings(Settings.EMPTY).get(0)) - .put("cluster.name", clusterInfo.clustername) - .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") - .put("path.logs", "./target/data/" + clusterInfo.clustername + "/cert/logs") - .put("path.home", "./target") - .put("node.name", "transportclient") - .put("discovery.initial_state_timeout","8s") - .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost+":"+clusterInfo.nodePort) - .build(); - + Assert.assertEquals( + clusterInfo.numNodes, + clusterHelper.nodeClient() + .admin() + .cluster() + .health(new ClusterHealthRequest().waitForGreenStatus()) + .actionGet() + .getNumberOfNodes() + ); + Assert.assertEquals( + ClusterHealthStatus.GREEN, + clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus() + ); + + final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) + .put(minimumSecuritySettings(Settings.EMPTY).get(0)) + .put("cluster.name", clusterInfo.clustername) + .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") + .put("path.logs", "./target/data/" + clusterInfo.clustername + "/cert/logs") + .put("path.home", "./target") + .put("node.name", "transportclient") + .put("discovery.initial_state_timeout", "8s") + .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost + ":" + clusterInfo.nodePort) + .build(); + log.debug("Start node client"); - + try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class).start()) { - Assert.assertFalse(node.client().admin().cluster().health(new ClusterHealthRequest().waitForNodes(String.valueOf(clusterInfo.numNodes+1))).actionGet().isTimedOut()); - Assert.assertEquals(clusterInfo.numNodes+1, node.client().admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); + Assert.assertFalse( + node.client() + .admin() + .cluster() + .health(new ClusterHealthRequest().waitForNodes(String.valueOf(clusterInfo.numNodes + 1))) + .actionGet() + .isTimedOut() + ); + Assert.assertEquals( + clusterInfo.numNodes + 1, + node.client().admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size() + ); } } - + @SuppressWarnings("resource") @Test public void testNodeClientDisallowedWithNonServerCertificate() throws Exception { setup(); - Assert.assertEquals(clusterInfo.numNodes, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getNumberOfNodes()); - Assert.assertEquals(ClusterHealthStatus.GREEN, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus()); - - - final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) - .put(minimumSecuritySettings(Settings.EMPTY).get(0)) - .put("cluster.name", clusterInfo.clustername) - .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") - .put("path.logs", "./target/data/" + clusterInfo.clustername + "/cert/logs") - .put("path.home", "./target") - .put("node.name", "transportclient") - .put("discovery.initial_state_timeout","8s") - .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost+":"+clusterInfo.nodePort) - .put("plugins.security.ssl.transport.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("kirk-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS,"kirk") - .build(); - + Assert.assertEquals( + clusterInfo.numNodes, + clusterHelper.nodeClient() + .admin() + .cluster() + .health(new ClusterHealthRequest().waitForGreenStatus()) + .actionGet() + .getNumberOfNodes() + ); + Assert.assertEquals( + ClusterHealthStatus.GREEN, + clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus() + ); + + final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) + .put(minimumSecuritySettings(Settings.EMPTY).get(0)) + .put("cluster.name", clusterInfo.clustername) + .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") + .put("path.logs", "./target/data/" + clusterInfo.clustername + "/cert/logs") + .put("path.home", "./target") + .put("node.name", "transportclient") + .put("discovery.initial_state_timeout", "8s") + .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost + ":" + clusterInfo.nodePort) + .put("plugins.security.ssl.transport.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("kirk-keystore.jks")) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "kirk") + .build(); + log.debug("Start node client"); try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class).start()) { Thread.sleep(10000); - Assert.assertEquals(1, node.client().admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); + Assert.assertEquals(1, node.client().admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); } catch (Exception e) { Assert.fail(e.toString()); } - + } - + @SuppressWarnings("resource") @Test public void testNodeClientDisallowedWithNonServerCertificate2() throws Exception { setup(); - Assert.assertEquals(clusterInfo.numNodes, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getNumberOfNodes()); - Assert.assertEquals(ClusterHealthStatus.GREEN, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus()); - - final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) - .put(minimumSecuritySettings(Settings.EMPTY).get(0)) - .put("cluster.name", clusterInfo.clustername) - .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") - .put("path.logs", "./target/data/" + clusterInfo.clustername + "/cert/logs") - .put("path.home", "./target") - .put("node.name", "transportclient") - .put("discovery.initial_state_timeout","8s") - .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost+":"+clusterInfo.nodePort) - .put("plugins.security.ssl.transport.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("spock-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS,"spock") - .build(); - + Assert.assertEquals( + clusterInfo.numNodes, + clusterHelper.nodeClient() + .admin() + .cluster() + .health(new ClusterHealthRequest().waitForGreenStatus()) + .actionGet() + .getNumberOfNodes() + ); + Assert.assertEquals( + ClusterHealthStatus.GREEN, + clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus() + ); + + final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) + .put(minimumSecuritySettings(Settings.EMPTY).get(0)) + .put("cluster.name", clusterInfo.clustername) + .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") + .put("path.logs", "./target/data/" + clusterInfo.clustername + "/cert/logs") + .put("path.home", "./target") + .put("node.name", "transportclient") + .put("discovery.initial_state_timeout", "8s") + .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost + ":" + clusterInfo.nodePort) + .put("plugins.security.ssl.transport.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("spock-keystore.jks")) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "spock") + .build(); + log.debug("Start node client"); - + try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class).start()) { Thread.sleep(10000); - Assert.assertEquals(1, node.client().admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); + Assert.assertEquals(1, node.client().admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); } catch (Exception e) { Assert.fail(e.toString()); } @@ -155,19 +210,26 @@ public void testNodeClientDisallowedWithNonServerCertificate2() throws Exception @Test public void testDelayInSecurityIndexInitialization() throws Exception { final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX, true) - .put("cluster.routing.allocation.exclude._ip", "127.0.0.1") - .build(); + .put(ConfigConstants.SECURITY_ALLOW_DEFAULT_INIT_SECURITYINDEX, true) + .put("cluster.routing.allocation.exclude._ip", "127.0.0.1") + .build(); try { setup(Settings.EMPTY, null, settings, false); Assert.fail("Expected IOException here due to red cluster state"); } catch (IOException e) { // Index request has a default timeout of 1 minute, adding buffer between nodes initialization and cluster health check - Thread.sleep(1000*80); - // Ideally, we would want to remove this cluster setting, but default settings cannot be removed. So overriding with a reserved IP address - clusterHelper.nodeClient().admin().cluster().updateSettings( - new ClusterUpdateSettingsRequest().transientSettings(Settings.builder().put("cluster.routing.allocation.exclude._ip", "192.0.2.0").build())); - this.clusterInfo = clusterHelper.waitForCluster(ClusterHealthStatus.GREEN, TimeValue.timeValueSeconds(10),3); + Thread.sleep(1000 * 80); + // Ideally, we would want to remove this cluster setting, but default settings cannot be removed. So overriding with a reserved + // IP address + clusterHelper.nodeClient() + .admin() + .cluster() + .updateSettings( + new ClusterUpdateSettingsRequest().transientSettings( + Settings.builder().put("cluster.routing.allocation.exclude._ip", "192.0.2.0").build() + ) + ); + this.clusterInfo = clusterHelper.waitForCluster(ClusterHealthStatus.GREEN, TimeValue.timeValueSeconds(10), 3); } RestHelper rh = nonSslRestHelper(); Thread.sleep(10000); diff --git a/src/test/java/org/opensearch/security/SnapshotRestoreTests.java b/src/test/java/org/opensearch/security/SnapshotRestoreTests.java index 8e869e250d..1c884a8e5d 100644 --- a/src/test/java/org/opensearch/security/SnapshotRestoreTests.java +++ b/src/test/java/org/opensearch/security/SnapshotRestoreTests.java @@ -54,7 +54,6 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; - public class SnapshotRestoreTests extends SingleClusterTest { private ClusterConfiguration currentClusterConfig = ClusterConfiguration.DEFAULT; @@ -62,233 +61,711 @@ public class SnapshotRestoreTests extends SingleClusterTest { public void testSnapshotEnableSecurityIndexRestore() throws Exception { final Settings settings = Settings.builder() - .putList("path.repo", repositoryPath.getRoot().getAbsolutePath()) - .put("plugins.security.check_snapshot_restore_write_privileges", false) - .put("plugins.security.unsupported.restore.securityindex.enabled", true) - .build(); + .putList("path.repo", repositoryPath.getRoot().getAbsolutePath()) + .put("plugins.security.check_snapshot_restore_write_privileges", false) + .put("plugins.security.unsupported.restore.securityindex.enabled", true) + .build(); setup(settings, currentClusterConfig); try (Client tc = getClient()) { - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.admin().cluster().putRepository(new PutRepositoryRequest("vulcangov").type("fs").settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/vulcangov"))).actionGet(); - tc.admin().cluster().createSnapshot(new CreateSnapshotRequest("vulcangov", "vulcangov_1").indices("vulcangov").includeGlobalState(true).waitForCompletion(true)).actionGet(); - - tc.admin().cluster().putRepository(new PutRepositoryRequest(".opendistro_security").type("fs").settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/.opendistro_security"))).actionGet(); - tc.admin().cluster().createSnapshot(new CreateSnapshotRequest(".opendistro_security", "opendistro_security_1").indices(".opendistro_security").includeGlobalState(false).waitForCompletion(true)).actionGet(); - - tc.admin().cluster().putRepository(new PutRepositoryRequest("all").type("fs").settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/all"))).actionGet(); - tc.admin().cluster().createSnapshot(new CreateSnapshotRequest("all", "all_1").indices("*").includeGlobalState(false).waitForCompletion(true)).actionGet(); + tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.admin() + .cluster() + .putRepository( + new PutRepositoryRequest("vulcangov").type("fs") + .settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/vulcangov")) + ) + .actionGet(); + tc.admin() + .cluster() + .createSnapshot( + new CreateSnapshotRequest("vulcangov", "vulcangov_1").indices("vulcangov") + .includeGlobalState(true) + .waitForCompletion(true) + ) + .actionGet(); + + tc.admin() + .cluster() + .putRepository( + new PutRepositoryRequest(".opendistro_security").type("fs") + .settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/.opendistro_security")) + ) + .actionGet(); + tc.admin() + .cluster() + .createSnapshot( + new CreateSnapshotRequest(".opendistro_security", "opendistro_security_1").indices(".opendistro_security") + .includeGlobalState(false) + .waitForCompletion(true) + ) + .actionGet(); + + tc.admin() + .cluster() + .putRepository( + new PutRepositoryRequest("all").type("fs") + .settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/all")) + ) + .actionGet(); + tc.admin() + .cluster() + .createSnapshot(new CreateSnapshotRequest("all", "all_1").indices("*").includeGlobalState(false).waitForCompletion(true)) + .actionGet(); } RestHelper rh = nonSslRestHelper(); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/vulcangov", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/vulcangov/vulcangov_1", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","{ \"include_global_state\": true, \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_with_global_state_$1\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/vulcangov", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/vulcangov/vulcangov_1", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "{ \"include_global_state\": true, \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_with_global_state_$1\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // worf not allowed to restore vulcangov index - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","", encodeBasicHeader("worf", "worf")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "", + encodeBasicHeader("worf", "worf") + ).getStatusCode() + ); // Try to restore vulcangov index as .opendistro_security index, not possible since Security index is open - Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","{ \"indices\": \"vulcangov\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \".opendistro_security\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_INTERNAL_SERVER_ERROR, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "{ \"indices\": \"vulcangov\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \".opendistro_security\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // Try to restore .opendistro_security index. - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/.opendistro_security", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/.opendistro_security/opendistro_security_1", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/.opendistro_security", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/.opendistro_security/opendistro_security_1", encodeBasicHeader("nagilum", "nagilum")) + .getStatusCode() + ); // 500 because Security index is open - Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, rh.executePostRequest("_snapshot/.opendistro_security/opendistro_security_1/_restore?wait_for_completion=true","", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_INTERNAL_SERVER_ERROR, + rh.executePostRequest( + "_snapshot/.opendistro_security/opendistro_security_1/_restore?wait_for_completion=true", + "", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // Try to restore .opendistro_security index as .opendistro_security_copy index - Assert.assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/.opendistro_security/opendistro_security_1/_restore?wait_for_completion=true","{ \"indices\": \".opendistro_security\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"opendistro_security_copy\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/.opendistro_security/opendistro_security_1/_restore?wait_for_completion=true", + "{ \"indices\": \".opendistro_security\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"opendistro_security_copy\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // Try to restore all indices. - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/all", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/all/all_1", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/all", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/all/all_1", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); // 500 because Security index is open - Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, rh.executePostRequest("_snapshot/all/all_1/_restore?wait_for_completion=true","", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_INTERNAL_SERVER_ERROR, + rh.executePostRequest("_snapshot/all/all_1/_restore?wait_for_completion=true", "", encodeBasicHeader("nagilum", "nagilum")) + .getStatusCode() + ); // Try to restore vulcangov index as .opendistro_security index -> 500 because Security index is open - Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, rh.executePostRequest("_snapshot/all/all_1/_restore?wait_for_completion=true","{ \"indices\": \"vulcangov\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \".opendistro_security\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - // Try to restore .opendistro_security index as .opendistro_security_copy index. Delete opendistro_security_copy first, was created in test above - Assert.assertEquals(HttpStatus.SC_OK, rh.executeDeleteRequest("opendistro_security_copy", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/all/all_1/_restore?wait_for_completion=true","{ \"indices\": \".opendistro_security\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"opendistro_security_copy\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_INTERNAL_SERVER_ERROR, + rh.executePostRequest( + "_snapshot/all/all_1/_restore?wait_for_completion=true", + "{ \"indices\": \"vulcangov\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \".opendistro_security\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); + // Try to restore .opendistro_security index as .opendistro_security_copy index. Delete opendistro_security_copy first, was created + // in test above + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeDeleteRequest("opendistro_security_copy", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/all/all_1/_restore?wait_for_completion=true", + "{ \"indices\": \".opendistro_security\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"opendistro_security_copy\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // Try to restore an unknown snapshot - Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, rh.executePostRequest("_snapshot/all/unknown-snapshot/_restore?wait_for_completion=true", "", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_INTERNAL_SERVER_ERROR, + rh.executePostRequest( + "_snapshot/all/unknown-snapshot/_restore?wait_for_completion=true", + "", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // close and restore Security index - Assert.assertEquals(HttpStatus.SC_OK, rh.executePostRequest(".opendistro_security/_close", "", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/.opendistro_security/opendistro_security_1/_restore?wait_for_completion=true","", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executePostRequest(".opendistro_security/_open", "", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest(".opendistro_security/_close", "", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/.opendistro_security/opendistro_security_1/_restore?wait_for_completion=true", + "", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest(".opendistro_security/_open", "", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); } @Test public void testSnapshot() throws Exception { final Settings settings = Settings.builder() - .putList("path.repo", repositoryPath.getRoot().getAbsolutePath()) - .put("plugins.security.check_snapshot_restore_write_privileges", false) - .build(); + .putList("path.repo", repositoryPath.getRoot().getAbsolutePath()) + .put("plugins.security.check_snapshot_restore_write_privileges", false) + .build(); setup(settings, currentClusterConfig); try (Client tc = getClient()) { - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.admin().cluster().putRepository(new PutRepositoryRequest("vulcangov").type("fs").settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/vulcangov"))).actionGet(); - tc.admin().cluster().createSnapshot(new CreateSnapshotRequest("vulcangov", "vulcangov_1").indices("vulcangov").includeGlobalState(true).waitForCompletion(true)).actionGet(); - - tc.admin().cluster().putRepository(new PutRepositoryRequest(".opendistro_security").type("fs").settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/.opendistro_security"))).actionGet(); - tc.admin().cluster().createSnapshot(new CreateSnapshotRequest(".opendistro_security", "opendistro_security_1").indices(".opendistro_security").includeGlobalState(false).waitForCompletion(true)).actionGet(); - - tc.admin().cluster().putRepository(new PutRepositoryRequest("all").type("fs").settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/all"))).actionGet(); - tc.admin().cluster().createSnapshot(new CreateSnapshotRequest("all", "all_1").indices("*").includeGlobalState(false).waitForCompletion(true)).actionGet(); + tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.admin() + .cluster() + .putRepository( + new PutRepositoryRequest("vulcangov").type("fs") + .settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/vulcangov")) + ) + .actionGet(); + tc.admin() + .cluster() + .createSnapshot( + new CreateSnapshotRequest("vulcangov", "vulcangov_1").indices("vulcangov") + .includeGlobalState(true) + .waitForCompletion(true) + ) + .actionGet(); + + tc.admin() + .cluster() + .putRepository( + new PutRepositoryRequest(".opendistro_security").type("fs") + .settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/.opendistro_security")) + ) + .actionGet(); + tc.admin() + .cluster() + .createSnapshot( + new CreateSnapshotRequest(".opendistro_security", "opendistro_security_1").indices(".opendistro_security") + .includeGlobalState(false) + .waitForCompletion(true) + ) + .actionGet(); + + tc.admin() + .cluster() + .putRepository( + new PutRepositoryRequest("all").type("fs") + .settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/all")) + ) + .actionGet(); + tc.admin() + .cluster() + .createSnapshot(new CreateSnapshotRequest("all", "all_1").indices("*").includeGlobalState(false).waitForCompletion(true)) + .actionGet(); } RestHelper rh = nonSslRestHelper(); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/vulcangov", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/vulcangov/vulcangov_1", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","{ \"include_global_state\": true, \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_with_global_state_$1\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","", encodeBasicHeader("worf", "worf")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/vulcangov", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/vulcangov/vulcangov_1", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "{ \"include_global_state\": true, \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_with_global_state_$1\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "", + encodeBasicHeader("worf", "worf") + ).getStatusCode() + ); // Try to restore vulcangov index as .opendistro_security index - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","{ \"indices\": \"vulcangov\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \".opendistro_security\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "{ \"indices\": \"vulcangov\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \".opendistro_security\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // Try to restore .opendistro_security index. - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/.opendistro_security", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/.opendistro_security/opendistro_security_1", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/.opendistro_security/opendistro_security_1/_restore?wait_for_completion=true","", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/.opendistro_security", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/.opendistro_security/opendistro_security_1", encodeBasicHeader("nagilum", "nagilum")) + .getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/.opendistro_security/opendistro_security_1/_restore?wait_for_completion=true", + "", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // Try to restore .opendistro_security index as .opendistro_security_copy index - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/.opendistro_security/opendistro_security_1/_restore?wait_for_completion=true","{ \"indices\": \".opendistro_security\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"opendistro_security_copy\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/.opendistro_security/opendistro_security_1/_restore?wait_for_completion=true", + "{ \"indices\": \".opendistro_security\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"opendistro_security_copy\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // Try to restore all indices. - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/all", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/all/all_1", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/all/all_1/_restore?wait_for_completion=true","", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/all", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/all/all_1", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest("_snapshot/all/all_1/_restore?wait_for_completion=true", "", encodeBasicHeader("nagilum", "nagilum")) + .getStatusCode() + ); // Try to restore .opendistro_security index as .opendistro_security_copy index - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/all/all_1/_restore?wait_for_completion=true","{ \"indices\": \"vulcangov\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \".opendistro_security\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/all/all_1/_restore?wait_for_completion=true", + "{ \"indices\": \"vulcangov\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \".opendistro_security\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // Try to restore .opendistro_security index as .opendistro_security_copy index - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/all/all_1/_restore?wait_for_completion=true","{ \"indices\": \".opendistro_security\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"opendistro_security_copy\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/all/all_1/_restore?wait_for_completion=true", + "{ \"indices\": \".opendistro_security\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"opendistro_security_copy\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // Try to restore an unknown snapshot - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/all/unknown-snapshot/_restore?wait_for_completion=true", "", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - // Assert.assertEquals(HttpStatus.SC_FORBIDDEN, executePostRequest("_snapshot/all/unknown-snapshot/_restore?wait_for_completion=true","{ \"indices\": \"the-unknown-index\" }", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/all/unknown-snapshot/_restore?wait_for_completion=true", + "", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); + // Assert.assertEquals(HttpStatus.SC_FORBIDDEN, + // executePostRequest("_snapshot/all/unknown-snapshot/_restore?wait_for_completion=true","{ \"indices\": \"the-unknown-index\" }", + // encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); } @Test public void testSnapshotCheckWritePrivileges() throws Exception { - final Settings settings = Settings.builder() - .putList("path.repo", repositoryPath.getRoot().getAbsolutePath()) - .build(); + final Settings settings = Settings.builder().putList("path.repo", repositoryPath.getRoot().getAbsolutePath()).build(); setup(settings, currentClusterConfig); try (Client tc = getClient()) { - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.admin().cluster().putRepository(new PutRepositoryRequest("vulcangov").type("fs").settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/vulcangov"))).actionGet(); - tc.admin().cluster().createSnapshot(new CreateSnapshotRequest("vulcangov", "vulcangov_1").indices("vulcangov").includeGlobalState(true).waitForCompletion(true)).actionGet(); - - tc.admin().cluster().putRepository(new PutRepositoryRequest(".opendistro_security").type("fs").settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/.opendistro_security"))).actionGet(); - tc.admin().cluster().createSnapshot(new CreateSnapshotRequest(".opendistro_security", "opendistro_security_1").indices(".opendistro_security").includeGlobalState(false).waitForCompletion(true)).actionGet(); - - tc.admin().cluster().putRepository(new PutRepositoryRequest("all").type("fs").settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/all"))).actionGet(); - tc.admin().cluster().createSnapshot(new CreateSnapshotRequest("all", "all_1").indices("*").includeGlobalState(false).waitForCompletion(true)).actionGet(); - - ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[]{"config","roles","rolesmapping","internalusers","actiongroups"})).actionGet(); + tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.admin() + .cluster() + .putRepository( + new PutRepositoryRequest("vulcangov").type("fs") + .settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/vulcangov")) + ) + .actionGet(); + tc.admin() + .cluster() + .createSnapshot( + new CreateSnapshotRequest("vulcangov", "vulcangov_1").indices("vulcangov") + .includeGlobalState(true) + .waitForCompletion(true) + ) + .actionGet(); + + tc.admin() + .cluster() + .putRepository( + new PutRepositoryRequest(".opendistro_security").type("fs") + .settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/.opendistro_security")) + ) + .actionGet(); + tc.admin() + .cluster() + .createSnapshot( + new CreateSnapshotRequest(".opendistro_security", "opendistro_security_1").indices(".opendistro_security") + .includeGlobalState(false) + .waitForCompletion(true) + ) + .actionGet(); + + tc.admin() + .cluster() + .putRepository( + new PutRepositoryRequest("all").type("fs") + .settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/all")) + ) + .actionGet(); + tc.admin() + .cluster() + .createSnapshot(new CreateSnapshotRequest("all", "all_1").indices("*").includeGlobalState(false).waitForCompletion(true)) + .actionGet(); + + ConfigUpdateResponse cur = tc.execute( + ConfigUpdateAction.INSTANCE, + new ConfigUpdateRequest(new String[] { "config", "roles", "rolesmapping", "internalusers", "actiongroups" }) + ).actionGet(); Assert.assertFalse(cur.hasFailures()); Assert.assertEquals(currentClusterConfig.getNodes(), cur.getNodes().size()); } RestHelper rh = nonSslRestHelper(); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/vulcangov", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/vulcangov/vulcangov_1", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","{ \"include_global_state\": true, \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_with_global_state_$1\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","", encodeBasicHeader("worf", "worf")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/vulcangov", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/vulcangov/vulcangov_1", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "{ \"include_global_state\": true, \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_with_global_state_$1\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "", + encodeBasicHeader("worf", "worf") + ).getStatusCode() + ); // Try to restore vulcangov index as .opendistro_security index - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","{ \"indices\": \"vulcangov\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \".opendistro_security\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "{ \"indices\": \"vulcangov\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \".opendistro_security\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // Try to restore .opendistro_security index. - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/.opendistro_security", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/.opendistro_security/opendistro_security_1", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/.opendistro_security/opendistro_security_1/_restore?wait_for_completion=true","", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/.opendistro_security", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/.opendistro_security/opendistro_security_1", encodeBasicHeader("nagilum", "nagilum")) + .getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/.opendistro_security/opendistro_security_1/_restore?wait_for_completion=true", + "", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // Try to restore .opendistro_security index as .opendistro_security_copy index - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/.opendistro_security/opendistro_security_1/_restore?wait_for_completion=true","{ \"indices\": \".opendistro_security\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"opendistro_security_copy\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/.opendistro_security/opendistro_security_1/_restore?wait_for_completion=true", + "{ \"indices\": \".opendistro_security\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"opendistro_security_copy\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // Try to restore all indices. - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/all", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/all/all_1", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/all/all_1/_restore?wait_for_completion=true","", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/all", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/all/all_1", encodeBasicHeader("nagilum", "nagilum")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest("_snapshot/all/all_1/_restore?wait_for_completion=true", "", encodeBasicHeader("nagilum", "nagilum")) + .getStatusCode() + ); // Try to restore .opendistro_security index as .opendistro_security_copy index - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/all/all_1/_restore?wait_for_completion=true","{ \"indices\": \"vulcangov\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \".opendistro_security\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/all/all_1/_restore?wait_for_completion=true", + "{ \"indices\": \"vulcangov\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \".opendistro_security\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // Try to restore .opendistro_security index as .opendistro_security_copy index - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/all/all_1/_restore?wait_for_completion=true","{ \"indices\": \".opendistro_security\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"opendistro_security_copy\" }", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/all/all_1/_restore?wait_for_completion=true", + "{ \"indices\": \".opendistro_security\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"opendistro_security_copy\" }", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // Try to restore an unknown snapshot - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/all/unknown-snapshot/_restore?wait_for_completion=true", "", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/all/unknown-snapshot/_restore?wait_for_completion=true", + "", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); // Tests snapshot with write permissions (OK) - Assert.assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"$1_restore_1\" }", encodeBasicHeader("restoreuser", "restoreuser")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"$1_restore_2a\" }", encodeBasicHeader("restoreuser", "restoreuser")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"$1_restore_1\" }", + encodeBasicHeader("restoreuser", "restoreuser") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"$1_restore_2a\" }", + encodeBasicHeader("restoreuser", "restoreuser") + ).getStatusCode() + ); // Test snapshot with write permissions (OK) - Assert.assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"$1_no_restore_1\" }", encodeBasicHeader("restoreuser", "restoreuser")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"$1_no_restore_2\" }", encodeBasicHeader("restoreuser", "restoreuser")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"$1_no_restore_3\" }", encodeBasicHeader("restoreuser", "restoreuser")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true","{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"$1_no_restore_4\" }", encodeBasicHeader("restoreuser", "restoreuser")).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"$1_no_restore_1\" }", + encodeBasicHeader("restoreuser", "restoreuser") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"$1_no_restore_2\" }", + encodeBasicHeader("restoreuser", "restoreuser") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"$1_no_restore_3\" }", + encodeBasicHeader("restoreuser", "restoreuser") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/vulcangov/vulcangov_1/_restore?wait_for_completion=true", + "{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"$1_no_restore_4\" }", + encodeBasicHeader("restoreuser", "restoreuser") + ).getStatusCode() + ); } @Test public void testSnapshotRestore() throws Exception { - final Settings settings = Settings.builder() - .putList("path.repo", repositoryPath.getRoot().getAbsolutePath()) - .build(); + final Settings settings = Settings.builder().putList("path.repo", repositoryPath.getRoot().getAbsolutePath()).build(); - setup(Settings.EMPTY, new DynamicSecurityConfig().setSecurityActionGroups("action_groups_packaged.yml"), settings, true, currentClusterConfig); + setup( + Settings.EMPTY, + new DynamicSecurityConfig().setSecurityActionGroups("action_groups_packaged.yml"), + settings, + true, + currentClusterConfig + ); try (Client tc = getClient()) { - tc.index(new IndexRequest("testsnap1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("testsnap2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("testsnap3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("testsnap4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("testsnap5").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("testsnap6").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.admin().cluster().putRepository(new PutRepositoryRequest("bckrepo").type("fs").settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/bckrepo"))).actionGet(); + tc.index(new IndexRequest("testsnap1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("testsnap2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("testsnap3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("testsnap4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("testsnap5").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("testsnap6").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.admin() + .cluster() + .putRepository( + new PutRepositoryRequest("bckrepo").type("fs") + .settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/bckrepo")) + ) + .actionGet(); } RestHelper rh = nonSslRestHelper(); - String putSnapshot = - "{"+ - "\"indices\": \"testsnap1\","+ - "\"ignore_unavailable\": false,"+ - "\"include_global_state\": false"+ - "}"; - - Assert.assertEquals(HttpStatus.SC_OK, rh.executePutRequest("_snapshot/bckrepo/"+putSnapshot.hashCode()+"?wait_for_completion=true&pretty", putSnapshot, encodeBasicHeader("snapresuser", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/bckrepo/"+putSnapshot.hashCode()+"/_restore?wait_for_completion=true&pretty","{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", encodeBasicHeader("snapresuser", "nagilum")).getStatusCode()); - - putSnapshot = - "{"+ - "\"indices\": \".opendistro_security\","+ - "\"ignore_unavailable\": false,"+ - "\"include_global_state\": false"+ - "}"; - - Assert.assertEquals(HttpStatus.SC_OK, rh.executePutRequest("_snapshot/bckrepo/"+putSnapshot.hashCode()+"?wait_for_completion=true&pretty", putSnapshot, encodeBasicHeader("snapresuser", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/bckrepo/"+putSnapshot.hashCode()+"/_restore?wait_for_completion=true&pretty","{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", encodeBasicHeader("snapresuser", "nagilum")).getStatusCode()); - - - putSnapshot = - "{"+ - "\"indices\": \"testsnap2\","+ - "\"ignore_unavailable\": false,"+ - "\"include_global_state\": true"+ - "}"; - - Assert.assertEquals(HttpStatus.SC_OK, rh.executePutRequest("_snapshot/bckrepo/"+putSnapshot.hashCode()+"?wait_for_completion=true&pretty", putSnapshot, encodeBasicHeader("snapresuser", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/bckrepo/"+putSnapshot.hashCode()+"/_restore?wait_for_completion=true&pretty","{ \"include_global_state\": true, \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", encodeBasicHeader("snapresuser", "nagilum")).getStatusCode()); + String putSnapshot = "{" + + "\"indices\": \"testsnap1\"," + + "\"ignore_unavailable\": false," + + "\"include_global_state\": false" + + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePutRequest( + "_snapshot/bckrepo/" + putSnapshot.hashCode() + "?wait_for_completion=true&pretty", + putSnapshot, + encodeBasicHeader("snapresuser", "nagilum") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/bckrepo/" + putSnapshot.hashCode() + "/_restore?wait_for_completion=true&pretty", + "{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", + encodeBasicHeader("snapresuser", "nagilum") + ).getStatusCode() + ); + + putSnapshot = "{" + + "\"indices\": \".opendistro_security\"," + + "\"ignore_unavailable\": false," + + "\"include_global_state\": false" + + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePutRequest( + "_snapshot/bckrepo/" + putSnapshot.hashCode() + "?wait_for_completion=true&pretty", + putSnapshot, + encodeBasicHeader("snapresuser", "nagilum") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/bckrepo/" + putSnapshot.hashCode() + "/_restore?wait_for_completion=true&pretty", + "{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", + encodeBasicHeader("snapresuser", "nagilum") + ).getStatusCode() + ); + + putSnapshot = "{" + "\"indices\": \"testsnap2\"," + "\"ignore_unavailable\": false," + "\"include_global_state\": true" + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePutRequest( + "_snapshot/bckrepo/" + putSnapshot.hashCode() + "?wait_for_completion=true&pretty", + putSnapshot, + encodeBasicHeader("snapresuser", "nagilum") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/bckrepo/" + putSnapshot.hashCode() + "/_restore?wait_for_completion=true&pretty", + "{ \"include_global_state\": true, \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", + encodeBasicHeader("snapresuser", "nagilum") + ).getStatusCode() + ); } @Test @@ -297,33 +774,74 @@ public void testSnapshotRestoreSpecialIndicesPatterns() throws Exception { final List listOfIndexesToTest = Arrays.asList("foo", "bar", "baz"); - final Settings settings = Settings.builder() - .putList("path.repo", repositoryPath.getRoot().getAbsolutePath()) - .build(); + final Settings settings = Settings.builder().putList("path.repo", repositoryPath.getRoot().getAbsolutePath()).build(); - setup(Settings.EMPTY, new DynamicSecurityConfig().setSecurityActionGroups("action_groups_packaged.yml"), settings, true, currentClusterConfig); + setup( + Settings.EMPTY, + new DynamicSecurityConfig().setSecurityActionGroups("action_groups_packaged.yml"), + settings, + true, + currentClusterConfig + ); try (Client tc = getClient()) { for (String index : listOfIndexesToTest) { tc.admin().indices().create(new CreateIndexRequest(index)).actionGet(); - tc.index(new IndexRequest(index).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).id("document1").source("{ \"foo\": \"bar\" }", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest(index).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .id("document1") + .source("{ \"foo\": \"bar\" }", XContentType.JSON) + ).actionGet(); } } - try (Client tc = getClient()) { - tc.admin().cluster().putRepository(new PutRepositoryRequest("all").type("fs").settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/all"))).actionGet(); - tc.admin().cluster().createSnapshot(new CreateSnapshotRequest("all", "all_1").indices(listOfIndexesToTest).includeGlobalState(false).waitForCompletion(true)).actionGet(); - } + try (Client tc = getClient()) { + tc.admin() + .cluster() + .putRepository( + new PutRepositoryRequest("all").type("fs") + .settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/all")) + ) + .actionGet(); + tc.admin() + .cluster() + .createSnapshot( + new CreateSnapshotRequest("all", "all_1").indices(listOfIndexesToTest).includeGlobalState(false).waitForCompletion(true) + ) + .actionGet(); + } RestHelper rh = nonSslRestHelper(); - Assert.assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/all/all_1/_restore?wait_for_completion=true","{\"indices\": \"b*,-bar\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"wild_first_restored_index_$1\"}", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/all/all_1/_restore?wait_for_completion=true","{\"indices\": \"-bar,b*\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"neg_first_restored_index_$1\"}", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - String wild_first_body = rh.executePostRequest("_snapshot/all/all_1/_restore?wait_for_completion=true","{\"indices\": \"b*,-bar\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"wild_first_restored_index_$1\"}", encodeBasicHeader("nagilum", "nagilum")).getBody(); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/all/all_1/_restore?wait_for_completion=true", + "{\"indices\": \"b*,-bar\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"wild_first_restored_index_$1\"}", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/all/all_1/_restore?wait_for_completion=true", + "{\"indices\": \"-bar,b*\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"neg_first_restored_index_$1\"}", + encodeBasicHeader("nagilum", "nagilum") + ).getStatusCode() + ); + String wild_first_body = rh.executePostRequest( + "_snapshot/all/all_1/_restore?wait_for_completion=true", + "{\"indices\": \"b*,-bar\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"wild_first_restored_index_$1\"}", + encodeBasicHeader("nagilum", "nagilum") + ).getBody(); assertThat(wild_first_body, not(containsString("wild_first_restored_index_foo"))); assertThat(wild_first_body, not(containsString("wild_first_restored_index_bar"))); assertThat(wild_first_body, containsString("wild_first_restored_index_baz")); - String neg_first_body = rh.executePostRequest("_snapshot/all/all_1/_restore?wait_for_completion=true","{\"indices\": \"-bar,b*\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"negate_first_restored_index_$1\"}", encodeBasicHeader("nagilum", "nagilum")).getBody(); + String neg_first_body = rh.executePostRequest( + "_snapshot/all/all_1/_restore?wait_for_completion=true", + "{\"indices\": \"-bar,b*\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"negate_first_restored_index_$1\"}", + encodeBasicHeader("nagilum", "nagilum") + ).getBody(); assertThat(neg_first_body, not(containsString("negate_first_restored_index_foo"))); assertThat(neg_first_body, not(containsString("negate_first_restored_index_bar"))); assertThat(neg_first_body, containsString("negate_first_restored_index_baz")); @@ -333,52 +851,105 @@ public void testSnapshotRestoreSpecialIndicesPatterns() throws Exception { public void testNoSnapshotRestore() throws Exception { final Settings settings = Settings.builder() - .putList("path.repo", repositoryPath.getRoot().getAbsolutePath()) - .put("plugins.security.enable_snapshot_restore_privilege", false) - .build(); - - setup(Settings.EMPTY, new DynamicSecurityConfig().setSecurityActionGroups("action_groups_packaged.yml"), settings, true, currentClusterConfig); + .putList("path.repo", repositoryPath.getRoot().getAbsolutePath()) + .put("plugins.security.enable_snapshot_restore_privilege", false) + .build(); + + setup( + Settings.EMPTY, + new DynamicSecurityConfig().setSecurityActionGroups("action_groups_packaged.yml"), + settings, + true, + currentClusterConfig + ); try (Client tc = getClient()) { - tc.index(new IndexRequest("testsnap1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("testsnap2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("testsnap3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("testsnap4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("testsnap5").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("testsnap6").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.admin().cluster().putRepository(new PutRepositoryRequest("bckrepo").type("fs").settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/bckrepo"))).actionGet(); + tc.index(new IndexRequest("testsnap1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("testsnap2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("testsnap3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("testsnap4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("testsnap5").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("testsnap6").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.admin() + .cluster() + .putRepository( + new PutRepositoryRequest("bckrepo").type("fs") + .settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/bckrepo")) + ) + .actionGet(); } RestHelper rh = nonSslRestHelper(); - String putSnapshot = - "{"+ - "\"indices\": \"testsnap1\","+ - "\"ignore_unavailable\": false,"+ - "\"include_global_state\": false"+ - "}"; - - Assert.assertEquals(HttpStatus.SC_OK, rh.executePutRequest("_snapshot/bckrepo/"+putSnapshot.hashCode()+"?wait_for_completion=true&pretty", putSnapshot, encodeBasicHeader("snapresuser", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/bckrepo/"+putSnapshot.hashCode()+"/_restore?wait_for_completion=true&pretty","{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", encodeBasicHeader("snapresuser", "nagilum")).getStatusCode()); - - putSnapshot = - "{"+ - "\"indices\": \".opendistro_security\","+ - "\"ignore_unavailable\": false,"+ - "\"include_global_state\": false"+ - "}"; - - Assert.assertEquals(HttpStatus.SC_OK, rh.executePutRequest("_snapshot/bckrepo/"+putSnapshot.hashCode()+"?wait_for_completion=true&pretty", putSnapshot, encodeBasicHeader("snapresuser", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/bckrepo/"+putSnapshot.hashCode()+"/_restore?wait_for_completion=true&pretty","{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", encodeBasicHeader("snapresuser", "nagilum")).getStatusCode()); - - putSnapshot = - "{"+ - "\"indices\": \"testsnap2\","+ - "\"ignore_unavailable\": false,"+ - "\"include_global_state\": true"+ - "}"; - - Assert.assertEquals(HttpStatus.SC_OK, rh.executePutRequest("_snapshot/bckrepo/"+putSnapshot.hashCode()+"?wait_for_completion=true&pretty", putSnapshot, encodeBasicHeader("snapresuser", "nagilum")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("_snapshot/bckrepo/"+putSnapshot.hashCode()+"/_restore?wait_for_completion=true&pretty","{ \"include_global_state\": true, \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", encodeBasicHeader("snapresuser", "nagilum")).getStatusCode()); + String putSnapshot = "{" + + "\"indices\": \"testsnap1\"," + + "\"ignore_unavailable\": false," + + "\"include_global_state\": false" + + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePutRequest( + "_snapshot/bckrepo/" + putSnapshot.hashCode() + "?wait_for_completion=true&pretty", + putSnapshot, + encodeBasicHeader("snapresuser", "nagilum") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/bckrepo/" + putSnapshot.hashCode() + "/_restore?wait_for_completion=true&pretty", + "{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", + encodeBasicHeader("snapresuser", "nagilum") + ).getStatusCode() + ); + + putSnapshot = "{" + + "\"indices\": \".opendistro_security\"," + + "\"ignore_unavailable\": false," + + "\"include_global_state\": false" + + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePutRequest( + "_snapshot/bckrepo/" + putSnapshot.hashCode() + "?wait_for_completion=true&pretty", + putSnapshot, + encodeBasicHeader("snapresuser", "nagilum") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/bckrepo/" + putSnapshot.hashCode() + "/_restore?wait_for_completion=true&pretty", + "{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", + encodeBasicHeader("snapresuser", "nagilum") + ).getStatusCode() + ); + + putSnapshot = "{" + "\"indices\": \"testsnap2\"," + "\"ignore_unavailable\": false," + "\"include_global_state\": true" + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executePutRequest( + "_snapshot/bckrepo/" + putSnapshot.hashCode() + "?wait_for_completion=true&pretty", + putSnapshot, + encodeBasicHeader("snapresuser", "nagilum") + ).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + rh.executePostRequest( + "_snapshot/bckrepo/" + putSnapshot.hashCode() + "/_restore?wait_for_completion=true&pretty", + "{ \"include_global_state\": true, \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_$1\" }", + encodeBasicHeader("snapresuser", "nagilum") + ).getStatusCode() + ); } } diff --git a/src/test/java/org/opensearch/security/SystemIntegratorsTests.java b/src/test/java/org/opensearch/security/SystemIntegratorsTests.java index 4e647a6324..8d287dd8a3 100644 --- a/src/test/java/org/opensearch/security/SystemIntegratorsTests.java +++ b/src/test/java/org/opensearch/security/SystemIntegratorsTests.java @@ -40,81 +40,117 @@ import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; public class SystemIntegratorsTests extends SingleClusterTest { - + @Test public void testInjectedUserMalformed() throws Exception { - - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true) - .put("http.type", "org.opensearch.security.http.UserInjectingServerTransport") - .build(); - + + final Settings settings = Settings.builder() + .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true) + .put("http.type", "org.opensearch.security.http.UserInjectingServerTransport") + .build(); + setup(settings, ClusterConfiguration.USERINJECTOR); - + final RestHelper rh = nonSslRestHelper(); // username|role1,role2|remoteIP|attributes - + HttpResponse resc; - - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, null)); + + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, null) + ); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, resc.getStatusCode()); - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "|||")); + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "|||") + ); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, resc.getStatusCode()); - - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "||127.0.0:80|")); + + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "||127.0.0:80|") + ); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, resc.getStatusCode()); - - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "username||ip|")); + + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "username||ip|") + ); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, resc.getStatusCode()); - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "username||ip:port|")); + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "username||ip:port|") + ); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, resc.getStatusCode()); - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "username||ip:80|")); + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "username||ip:80|") + ); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, resc.getStatusCode()); - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "username||127.0.x:80|")); + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "username||127.0.x:80|") + ); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, resc.getStatusCode()); - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "username||127.0.0:80|key1,value1,key2")); + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "username||127.0.0:80|key1,value1,key2") + ); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, resc.getStatusCode()); - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "||127.0.0:80|key1,value1,key2,value2")); + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "||127.0.0:80|key1,value1,key2,value2") + ); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, resc.getStatusCode()); - + } @Test public void testInjectedUser() throws Exception { - - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true) - .put("http.type", "org.opensearch.security.http.UserInjectingServerTransport") - .build(); - + + final Settings settings = Settings.builder() + .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true) + .put("http.type", "org.opensearch.security.http.UserInjectingServerTransport") + .build(); + setup(settings, ClusterConfiguration.USERINJECTOR); - + final RestHelper rh = nonSslRestHelper(); // username|role1,role2|remoteIP|attributes - + HttpResponse resc; - - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "admin||127.0.0:80|")); + + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "admin||127.0.0:80|") + ); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("User [name=admin, backend_roles=[], requestedTenant=null]")); Assert.assertTrue(resc.getBody().contains("\"remote_address\":\"127.0.0.0:80\"")); Assert.assertTrue(resc.getBody().contains("\"backend_roles\":[]")); Assert.assertTrue(resc.getBody().contains("\"custom_attribute_names\":[]")); - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "admin|role1|127.0.0:80|key1,value1")); + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "admin|role1|127.0.0:80|key1,value1") + ); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("User [name=admin, backend_roles=[role1], requestedTenant=null]")); Assert.assertTrue(resc.getBody().contains("\"remote_address\":\"127.0.0.0:80\"")); Assert.assertTrue(resc.getBody().contains("\"backend_roles\":[\"role1\"]")); Assert.assertTrue(resc.getBody().contains("\"custom_attribute_names\":[\"key1\"]")); - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "admin|role1,role2||key1,value1")); + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "admin|role1,role2||key1,value1") + ); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("User [name=admin, backend_roles=[role1, role2], requestedTenant=null]")); // remote IP is assigned by XFFResolver @@ -122,7 +158,10 @@ public void testInjectedUser() throws Exception { Assert.assertTrue(resc.getBody().contains("\"backend_roles\":[\"role1\",\"role2\"]")); Assert.assertTrue(resc.getBody().contains("\"custom_attribute_names\":[\"key1\"]")); - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "admin|role1,role2|8.8.8.8:8|key1,value1,key2,value2")); + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "admin|role1,role2|8.8.8.8:8|key1,value1,key2,value2") + ); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("User [name=admin, backend_roles=[role1, role2], requestedTenant=null]")); // remote IP is assigned by XFFResolver @@ -130,7 +169,10 @@ public void testInjectedUser() throws Exception { Assert.assertTrue(resc.getBody().contains("\"backend_roles\":[\"role1\",\"role2\"]")); Assert.assertTrue(resc.getBody().contains("\"custom_attribute_names\":[\"key1\",\"key2\"]")); - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "nagilum|role1,role2|8.8.8.8:8|key1,value1,key2,value2")); + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "nagilum|role1,role2|8.8.8.8:8|key1,value1,key2,value2") + ); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("User [name=nagilum, backend_roles=[role1, role2], requestedTenant=null]")); // remote IP is assigned by XFFResolver @@ -139,8 +181,11 @@ public void testInjectedUser() throws Exception { // mapped by username Assert.assertTrue(resc.getBody().contains("\"roles\":[\"opendistro_security_all_access\"")); Assert.assertTrue(resc.getBody().contains("\"custom_attribute_names\":[\"key1\",\"key2\"]")); - - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "myuser|role1,vulcanadmin|8.8.8.8:8|key1,value1,key2,value2")); + + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "myuser|role1,vulcanadmin|8.8.8.8:8|key1,value1,key2,value2") + ); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("User [name=myuser, backend_roles=[role1, vulcanadmin], requestedTenant=null]")); // remote IP is assigned by XFFResolver @@ -149,9 +194,15 @@ public void testInjectedUser() throws Exception { // mapped by backend role "twitter" Assert.assertTrue(resc.getBody().contains("\"roles\":[\"public\",\"role_vulcans_admin\"]")); Assert.assertTrue(resc.getBody().contains("\"custom_attribute_names\":[\"key1\",\"key2\"]")); - + // add requested tenant - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "myuser|role1,vulcanadmin|8.8.8.8:8|key1,value1,key2,value2|")); + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader( + ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, + "myuser|role1,vulcanadmin|8.8.8.8:8|key1,value1,key2,value2|" + ) + ); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("User [name=myuser, backend_roles=[role1, vulcanadmin], requestedTenant=null]")); // remote IP is assigned by XFFResolver @@ -161,7 +212,13 @@ public void testInjectedUser() throws Exception { Assert.assertTrue(resc.getBody(), resc.getBody().contains("\"roles\":[\"public\",\"role_vulcans_admin\"]")); Assert.assertTrue(resc.getBody().contains("\"custom_attribute_names\":[\"key1\",\"key2\"]")); - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "myuser|role1,vulcanadmin|8.8.8.8:8|key1,value1,key2,value2|mytenant")); + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader( + ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, + "myuser|role1,vulcanadmin|8.8.8.8:8|key1,value1,key2,value2|mytenant" + ) + ); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("User [name=myuser, backend_roles=[role1, vulcanadmin], requestedTenant=mytenant]")); // remote IP is assigned by XFFResolver @@ -171,87 +228,110 @@ public void testInjectedUser() throws Exception { Assert.assertTrue(resc.getBody().contains("\"roles\":[\"public\",\"role_vulcans_admin\"]")); Assert.assertTrue(resc.getBody().contains("\"custom_attribute_names\":[\"key1\",\"key2\"]")); - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "myuser|role1,vulcanadmin|8.8.8.8:8||mytenant with whitespace")); + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader( + ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, + "myuser|role1,vulcanadmin|8.8.8.8:8||mytenant with whitespace" + ) + ); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - Assert.assertTrue(resc.getBody().contains("User [name=myuser, backend_roles=[role1, vulcanadmin], requestedTenant=mytenant with whitespace]")); + Assert.assertTrue( + resc.getBody().contains("User [name=myuser, backend_roles=[role1, vulcanadmin], requestedTenant=mytenant with whitespace]") + ); // remote IP is assigned by XFFResolver Assert.assertTrue(resc.getBody().contains("\"remote_address\":\"8.8.8.8:8\"")); Assert.assertTrue(resc.getBody().contains("\"backend_roles\":[\"role1\",\"vulcanadmin\"]")); // mapped by backend role "twitter" Assert.assertTrue(resc.getBody().contains("\"roles\":[\"public\",\"role_vulcans_admin\"]")); - - } + } @Test public void testInjectedUserDisabled() throws Exception { - - final Settings settings = Settings.builder() - .put("http.type", "org.opensearch.security.http.UserInjectingServerTransport") - .build(); - + + final Settings settings = Settings.builder().put("http.type", "org.opensearch.security.http.UserInjectingServerTransport").build(); + setup(settings, ClusterConfiguration.USERINJECTOR); - + final RestHelper rh = nonSslRestHelper(); // username|role1,role2|remoteIP|attributes - + HttpResponse resc; - - resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "admin|role1|127.0.0:80|key1,value1")); + + resc = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "admin|role1|127.0.0:80|key1,value1") + ); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, resc.getStatusCode()); } - @Test - public void testInjectedAdminUser() throws Exception { - - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true) - .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_ADMIN_USER_ENABLED, true) - .putList(ConfigConstants.SECURITY_AUTHCZ_ADMIN_DN, Lists.newArrayList("CN=kirk,OU=client,O=client,L=Test,C=DE","injectedadmin")) - .put("http.type", "org.opensearch.security.http.UserInjectingServerTransport") - .build(); - - setup(settings, ClusterConfiguration.USERINJECTOR); - - final RestHelper rh = nonSslRestHelper(); - HttpResponse resc; - - // injected user is admin, access to Security index must be allowed - resc = rh.executeGetRequest(".opendistro_security/_search?pretty", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "injectedadmin|role1|127.0.0:80|key1,value1")); - Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - Assert.assertTrue(resc.getBody().contains("\"_id\" : \"config\"")); - Assert.assertTrue(resc.getBody().contains("\"_id\" : \"roles\"")); - Assert.assertTrue(resc.getBody().contains("\"_id\" : \"internalusers\"")); - Assert.assertTrue(resc.getBody().contains("\"total\" : 5")); - - resc = rh.executeGetRequest(".opendistro_security/_search?pretty", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "wrongadmin|role1|127.0.0:80|key1,value1")); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - - } + @Test + public void testInjectedAdminUser() throws Exception { + + final Settings settings = Settings.builder() + .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true) + .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_ADMIN_USER_ENABLED, true) + .putList( + ConfigConstants.SECURITY_AUTHCZ_ADMIN_DN, + Lists.newArrayList("CN=kirk,OU=client,O=client,L=Test,C=DE", "injectedadmin") + ) + .put("http.type", "org.opensearch.security.http.UserInjectingServerTransport") + .build(); + + setup(settings, ClusterConfiguration.USERINJECTOR); + + final RestHelper rh = nonSslRestHelper(); + HttpResponse resc; + + // injected user is admin, access to Security index must be allowed + resc = rh.executeGetRequest( + ".opendistro_security/_search?pretty", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "injectedadmin|role1|127.0.0:80|key1,value1") + ); + Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); + Assert.assertTrue(resc.getBody().contains("\"_id\" : \"config\"")); + Assert.assertTrue(resc.getBody().contains("\"_id\" : \"roles\"")); + Assert.assertTrue(resc.getBody().contains("\"_id\" : \"internalusers\"")); + Assert.assertTrue(resc.getBody().contains("\"total\" : 5")); + + resc = rh.executeGetRequest( + ".opendistro_security/_search?pretty", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "wrongadmin|role1|127.0.0:80|key1,value1") + ); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); + + } @Test public void testInjectedAdminUserAdminInjectionDisabled() throws Exception { - - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true) - .putList(ConfigConstants.SECURITY_AUTHCZ_ADMIN_DN, Lists.newArrayList("CN=kirk,OU=client,O=client,L=Test,C=DE","injectedadmin")) - .put("http.type", "org.opensearch.security.http.UserInjectingServerTransport") - .build(); - + + final Settings settings = Settings.builder() + .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true) + .putList( + ConfigConstants.SECURITY_AUTHCZ_ADMIN_DN, + Lists.newArrayList("CN=kirk,OU=client,O=client,L=Test,C=DE", "injectedadmin") + ) + .put("http.type", "org.opensearch.security.http.UserInjectingServerTransport") + .build(); + setup(settings, ClusterConfiguration.USERINJECTOR); - + final RestHelper rh = nonSslRestHelper(); HttpResponse resc; - + // injected user is admin, access to Security index must be allowed - resc = rh.executeGetRequest(".opendistro_security/_search?pretty", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "injectedadmin|role1|127.0.0:80|key1,value1")); + resc = rh.executeGetRequest( + ".opendistro_security/_search?pretty", + new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "injectedadmin|role1|127.0.0:80|key1,value1") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); Assert.assertFalse(resc.getBody().contains("\"_id\" : \"config\"")); Assert.assertFalse(resc.getBody().contains("\"_id\" : \"roles\"")); Assert.assertFalse(resc.getBody().contains("\"_id\" : \"internalusers\"")); Assert.assertFalse(resc.getBody().contains("\"_id\" : \"tattr\"")); Assert.assertFalse(resc.getBody(), resc.getBody().contains("\"total\" : 6")); - - } + + } } diff --git a/src/test/java/org/opensearch/security/TaskTests.java b/src/test/java/org/opensearch/security/TaskTests.java index 0ec671af27..784f5c7418 100644 --- a/src/test/java/org/opensearch/security/TaskTests.java +++ b/src/test/java/org/opensearch/security/TaskTests.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security; @@ -30,16 +30,21 @@ import org.opensearch.tasks.Task; public class TaskTests extends SingleClusterTest { - + @Test public void testXOpaqueIdHeader() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig(), Settings.EMPTY); - + RestHelper rh = nonSslRestHelper(); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_tasks?group_by=parents&pretty" - , encodeBasicHeader("nagilum", "nagilum") - , new BasicHeader(Task.X_OPAQUE_ID, "myOpaqueId12"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest( + "_tasks?group_by=parents&pretty", + encodeBasicHeader("nagilum", "nagilum"), + new BasicHeader(Task.X_OPAQUE_ID, "myOpaqueId12") + )).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().split("X-Opaque-Id").length > 2); Assert.assertTrue(!res.getBody().contains("failures")); diff --git a/src/test/java/org/opensearch/security/TracingTests.java b/src/test/java/org/opensearch/security/TracingTests.java index 10372cf73b..2fefd33155 100644 --- a/src/test/java/org/opensearch/security/TracingTests.java +++ b/src/test/java/org/opensearch/security/TracingTests.java @@ -56,10 +56,22 @@ public void testAdvancedMapping() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig(), Settings.EMPTY, true, ClusterConfiguration.DEFAULT); try (Client tc = getClient()) { - tc.admin().indices().create(new CreateIndexRequest("myindex1").mapping(FileHelper.loadFile("mapping1.json"), XContentType.JSON)).actionGet(); - tc.admin().indices().create(new CreateIndexRequest("myindex2").mapping(FileHelper.loadFile("mapping2.json"), XContentType.JSON)).actionGet(); - tc.admin().indices().create(new CreateIndexRequest("myindex3").mapping(FileHelper.loadFile("mapping3.json"), XContentType.JSON)).actionGet(); - tc.admin().indices().create(new CreateIndexRequest("myindex4").mapping(FileHelper.loadFile("mapping4.json"), XContentType.JSON)).actionGet(); + tc.admin() + .indices() + .create(new CreateIndexRequest("myindex1").mapping(FileHelper.loadFile("mapping1.json"), XContentType.JSON)) + .actionGet(); + tc.admin() + .indices() + .create(new CreateIndexRequest("myindex2").mapping(FileHelper.loadFile("mapping2.json"), XContentType.JSON)) + .actionGet(); + tc.admin() + .indices() + .create(new CreateIndexRequest("myindex3").mapping(FileHelper.loadFile("mapping3.json"), XContentType.JSON)) + .actionGet(); + tc.admin() + .indices() + .create(new CreateIndexRequest("myindex4").mapping(FileHelper.loadFile("mapping4.json"), XContentType.JSON)) + .actionGet(); } RestHelper rh = nonSslRestHelper(); @@ -94,69 +106,154 @@ public void testHTTPTraceNoSource() throws Exception { tc.admin().indices().create(new CreateIndexRequest("test")).actionGet(); tc.admin().indices().create(new CreateIndexRequest("u")).actionGet(); - tc.admin().indices().putMapping(new PutMappingRequest("a") - .source("_source","enabled=false","content","store=true,type=text","field1","store=true,type=text", "field2","store=true,type=text", "a","store=true,type=text", "b","store=true,type=text", "my.nested.field","store=true,type=text") - ).actionGet(); - - tc.admin().indices().putMapping(new PutMappingRequest("c") - .source("_source","enabled=false","content","store=true,type=text","field1","store=true,type=text", "field2","store=true,type=text", "a","store=true,type=text", "b","store=true,type=text", "my.nested.field","store=true,type=text") - ).actionGet(); - - tc.admin().indices().putMapping(new PutMappingRequest("test") - .source("_source","enabled=false","content","store=true,type=text","field1","store=true,type=text", "field2","store=true,type=text", "a","store=true,type=text", "b","store=true,type=text", "my.nested.field","store=true,type=text") - ).actionGet(); - - tc.admin().indices().putMapping(new PutMappingRequest("u") - .source("_source","enabled=false","content","store=true,type=text","field1","store=true,type=text", "field2","store=true,type=text", "a","store=true,type=text", "b","store=true,type=text", "my.nested.field","store=true,type=text") - ).actionGet(); - - for(int i=0; i<50;i++) { - tc.index(new IndexRequest("a").id(i+"").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":"+i+"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("c").id(i+"").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":"+i+"}", XContentType.JSON)).actionGet(); + tc.admin() + .indices() + .putMapping( + new PutMappingRequest("a").source( + "_source", + "enabled=false", + "content", + "store=true,type=text", + "field1", + "store=true,type=text", + "field2", + "store=true,type=text", + "a", + "store=true,type=text", + "b", + "store=true,type=text", + "my.nested.field", + "store=true,type=text" + ) + ) + .actionGet(); + + tc.admin() + .indices() + .putMapping( + new PutMappingRequest("c").source( + "_source", + "enabled=false", + "content", + "store=true,type=text", + "field1", + "store=true,type=text", + "field2", + "store=true,type=text", + "a", + "store=true,type=text", + "b", + "store=true,type=text", + "my.nested.field", + "store=true,type=text" + ) + ) + .actionGet(); + + tc.admin() + .indices() + .putMapping( + new PutMappingRequest("test").source( + "_source", + "enabled=false", + "content", + "store=true,type=text", + "field1", + "store=true,type=text", + "field2", + "store=true,type=text", + "a", + "store=true,type=text", + "b", + "store=true,type=text", + "my.nested.field", + "store=true,type=text" + ) + ) + .actionGet(); + + tc.admin() + .indices() + .putMapping( + new PutMappingRequest("u").source( + "_source", + "enabled=false", + "content", + "store=true,type=text", + "field1", + "store=true,type=text", + "field2", + "store=true,type=text", + "a", + "store=true,type=text", + "b", + "store=true,type=text", + "my.nested.field", + "store=true,type=text" + ) + ) + .actionGet(); + + for (int i = 0; i < 50; i++) { + tc.index( + new IndexRequest("a").id(i + "") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":" + i + "}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("c").id(i + "") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":" + i + "}", XContentType.JSON) + ).actionGet(); } } - //setup complex mapping with parent child and nested fields - + // setup complex mapping with parent child and nested fields RestHelper rh = nonSslRestHelper(); System.out.println("############ check shards"); System.out.println(rh.executeGetRequest("_cat/shards?v", encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ _bulk"); - String bulkBody = - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"field1\" : \"value1\" }" +System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ - "{ \"delete\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }"+System.lineSeparator(); + String bulkBody = "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"field1\" : \"value1\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator() + + "{ \"delete\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }" + + System.lineSeparator(); System.out.println(rh.executePostRequest("_bulk?refresh=true", bulkBody, encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ _bulk"); - bulkBody = - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"field1\" : \"value1\" }" +System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ - "{ \"delete\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }"+System.lineSeparator(); + bulkBody = "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"field1\" : \"value1\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator() + + "{ \"delete\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }" + + System.lineSeparator(); System.out.println(rh.executePostRequest("_bulk?refresh=true", bulkBody, encodeBasicHeader("nagilum", "nagilum"))); - System.out.println("############ cat indices"); - //cluster:monitor/state - //cluster:monitor/health - //indices:monitor/stats + // cluster:monitor/state + // cluster:monitor/health + // indices:monitor/stats System.out.println(rh.executeGetRequest("_cat/indices", encodeBasicHeader("nagilum", "nagilum"))); - System.out.println("############ _search"); - //indices:data/read/search + // indices:data/read/search System.out.println(rh.executeGetRequest("_search", encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ get 1"); - //indices:data/read/get + // indices:data/read/get System.out.println(rh.executeGetRequest("a/b/1", encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ get 5"); System.out.println(rh.executeGetRequest("a/b/5", encodeBasicHeader("nagilum", "nagilum"))); @@ -164,71 +261,68 @@ public void testHTTPTraceNoSource() throws Exception { System.out.println(rh.executeGetRequest("a/b/17", encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ index (+create index)"); - //indices:data/write/index - //indices:data/write/bulk - //indices:admin/create - //indices:data/write/bulk[s] - System.out.println(rh.executePostRequest("u/b/1?refresh=true", "{}",encodeBasicHeader("nagilum", "nagilum"))); + // indices:data/write/index + // indices:data/write/bulk + // indices:admin/create + // indices:data/write/bulk[s] + System.out.println(rh.executePostRequest("u/b/1?refresh=true", "{}", encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ index only"); - //indices:data/write/index - //indices:data/write/bulk - //indices:admin/create - //indices:data/write/bulk[s] - System.out.println(rh.executePostRequest("u/b/2?refresh=true", "{}",encodeBasicHeader("nagilum", "nagilum"))); - + // indices:data/write/index + // indices:data/write/bulk + // indices:admin/create + // indices:data/write/bulk[s] + System.out.println(rh.executePostRequest("u/b/2?refresh=true", "{}", encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ delete"); - //indices:data/write/index - //indices:data/write/bulk - //indices:admin/create - //indices:data/write/bulk[s] - System.out.println(rh.executeDeleteRequest("u/b/2?refresh=true",encodeBasicHeader("nagilum", "nagilum"))); + // indices:data/write/index + // indices:data/write/bulk + // indices:admin/create + // indices:data/write/bulk[s] + System.out.println(rh.executeDeleteRequest("u/b/2?refresh=true", encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ msearch"); - String msearchBody = - "{\"index\":\"a\", \"type\":\"b\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ - "{\"index\":\"a\", \"type\":\"b\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ - "{\"index\":\"public\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); - + String msearchBody = "{\"index\":\"a\", \"type\":\"b\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator() + + "{\"index\":\"a\", \"type\":\"b\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator() + + "{\"index\":\"public\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); System.out.println(rh.executePostRequest("_msearch", msearchBody, encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ mget"); - String mgetBody = "{"+ - "\"docs\" : ["+ - "{"+ - "\"_index\" : \"a\","+ - "\"_id\" : \"1\""+ - " },"+ - " {"+ - "\"_index\" : \"a\","+ - " \"_id\" : \"12\""+ - "},"+ - " {"+ - "\"_index\" : \"a\","+ - " \"_id\" : \"13\""+ - "},"+" {"+ - "\"_index\" : \"a\","+ - " \"_id\" : \"14\""+ - "}"+ - "]"+ - "}"; + String mgetBody = "{" + + "\"docs\" : [" + + "{" + + "\"_index\" : \"a\"," + + "\"_id\" : \"1\"" + + " }," + + " {" + + "\"_index\" : \"a\"," + + " \"_id\" : \"12\"" + + "}," + + " {" + + "\"_index\" : \"a\"," + + " \"_id\" : \"13\"" + + "}," + + " {" + + "\"_index\" : \"a\"," + + " \"_id\" : \"14\"" + + "}" + + "]" + + "}"; System.out.println(rh.executePostRequest("_mget?refresh=true", mgetBody, encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ delete by query"); - String dbqBody = "{"+ - ""+ - " \"query\": { "+ - " \"match\": {"+ - " \"content\": 12"+ - " }"+ - " }"+ - "}"; + String dbqBody = "{" + "" + " \"query\": { " + " \"match\": {" + " \"content\": 12" + " }" + " }" + "}"; System.out.println(rh.executePostRequest("a/b/_delete_by_query", dbqBody, encodeBasicHeader("nagilum", "nagilum"))); @@ -237,28 +331,56 @@ public void testHTTPTraceNoSource() throws Exception { @Test public void testHTTPSingle() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS+".worf", "knuddel","nonexists") + final Settings settings = Settings.builder() + .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS + ".worf", "knuddel", "nonexists") .build(); - setup(settings); - final RestHelper rh = nonSslRestHelper(); + setup(settings); + final RestHelper rh = nonSslRestHelper(); try (Client tc = getClient()) { tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); + tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("starfleet","starfleet_academy","starfleet_library").alias("sf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire","vulcangov").alias("nonsf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))).actionGet(); + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction( + AliasActions.add().indices("starfleet", "starfleet_academy", "starfleet_library").alias("sf") + ) + ) + .actionGet(); + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire", "vulcangov").alias("nonsf")) + ) + .actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))) + .actionGet(); } @@ -275,16 +397,24 @@ public void testHTTPSingle() throws Exception { System.out.println("########end pause2"); System.out.println("############ _bulk"); - String bulkBody = - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"field1\" : \"value1\" }" +System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ - "{ \"delete\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }"+System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"myindex\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"field1\" : \"value1\" }" +System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"myindex\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"field1\" : \"value1\" }" +System.lineSeparator(); + String bulkBody = "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"field1\" : \"value1\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator() + + "{ \"delete\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"myindex\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"field1\" : \"value1\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"myindex\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"field1\" : \"value1\" }" + + System.lineSeparator(); System.out.println(rh.executePostRequest("_bulk?refresh=true", bulkBody, encodeBasicHeader("nagilum", "nagilum")).getBody()); System.out.println("############ _end"); @@ -293,33 +423,42 @@ public void testHTTPSingle() throws Exception { @Test public void testSearchScroll() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS+".worf", "knuddel","nonexists") + final Settings settings = Settings.builder() + .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS + ".worf", "knuddel", "nonexists") .build(); - setup(settings); - final RestHelper rh = nonSslRestHelper(); + setup(settings); + final RestHelper rh = nonSslRestHelper(); try (Client tc = getClient()) { - for(int i=0; i<3; i++) - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); + for (int i = 0; i < 3; i++) + tc.index( + new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); } - System.out.println("########search"); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res=rh.executeGetRequest("vulcangov/_search?scroll=1m&pretty=true", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("vulcangov/_search?scroll=1m&pretty=true", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode() + ); System.out.println(res.getBody()); int start = res.getBody().indexOf("_scroll_id") + 15; - String scrollid = res.getBody().substring(start, res.getBody().indexOf("\"", start+1)); + String scrollid = res.getBody().substring(start, res.getBody().indexOf("\"", start + 1)); System.out.println(scrollid); System.out.println("########search scroll"); - Assert.assertEquals(HttpStatus.SC_OK, (res=rh.executePostRequest("/_search/scroll?pretty=true", "{\"scroll_id\" : \""+scrollid+"\"}", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); - + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest( + "/_search/scroll?pretty=true", + "{\"scroll_id\" : \"" + scrollid + "\"}", + encodeBasicHeader("nagilum", "nagilum") + )).getStatusCode() + ); System.out.println("########search done"); - } @Test @@ -329,53 +468,64 @@ public void testHTTPTrace() throws Exception { try (Client tc = getClient()) { - for(int i=0; i<50;i++) { - tc.index(new IndexRequest("a").id(i+"").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":"+i+"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("c").id(i+"").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":"+i+"}", XContentType.JSON)).actionGet(); + for (int i = 0; i < 50; i++) { + tc.index( + new IndexRequest("a").id(i + "") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":" + i + "}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("c").id(i + "") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":" + i + "}", XContentType.JSON) + ).actionGet(); } } - - - RestHelper rh = nonSslRestHelper(); System.out.println("############ check shards"); System.out.println(rh.executeGetRequest("_cat/shards?v", encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ _bulk"); - String bulkBody = - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"field1\" : \"value1\" }" +System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ - "{ \"delete\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }"+System.lineSeparator(); + String bulkBody = "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"field1\" : \"value1\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator() + + "{ \"delete\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }" + + System.lineSeparator(); System.out.println(rh.executePostRequest("_bulk?refresh=true", bulkBody, encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ _bulk"); - bulkBody = - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"field1\" : \"value1\" }" +System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ - "{ \"delete\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }"+System.lineSeparator(); + bulkBody = "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"field1\" : \"value1\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator() + + "{ \"delete\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }" + + System.lineSeparator(); System.out.println(rh.executePostRequest("_bulk?refresh=true", bulkBody, encodeBasicHeader("nagilum", "nagilum"))); - System.out.println("############ cat indices"); - //cluster:monitor/state - //cluster:monitor/health - //indices:monitor/stats + // cluster:monitor/state + // cluster:monitor/health + // indices:monitor/stats System.out.println(rh.executeGetRequest("_cat/indices", encodeBasicHeader("nagilum", "nagilum"))); - System.out.println("############ _search"); - //indices:data/read/search + // indices:data/read/search System.out.println(rh.executeGetRequest("_search", encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ get 1"); - //indices:data/read/get + // indices:data/read/get System.out.println(rh.executeGetRequest("a/b/1", encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ get 5"); System.out.println(rh.executeGetRequest("a/b/5", encodeBasicHeader("nagilum", "nagilum"))); @@ -383,106 +533,107 @@ public void testHTTPTrace() throws Exception { System.out.println(rh.executeGetRequest("a/b/17", encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ index (+create index)"); - //indices:data/write/index - //indices:data/write/bulk - //indices:admin/create - //indices:data/write/bulk[s] - System.out.println(rh.executePostRequest("u/b/1?refresh=true", "{}",encodeBasicHeader("nagilum", "nagilum"))); + // indices:data/write/index + // indices:data/write/bulk + // indices:admin/create + // indices:data/write/bulk[s] + System.out.println(rh.executePostRequest("u/b/1?refresh=true", "{}", encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ index only"); - //indices:data/write/index - //indices:data/write/bulk - //indices:admin/create - //indices:data/write/bulk[s] - System.out.println(rh.executePostRequest("u/b/2?refresh=true", "{}",encodeBasicHeader("nagilum", "nagilum"))); + // indices:data/write/index + // indices:data/write/bulk + // indices:admin/create + // indices:data/write/bulk[s] + System.out.println(rh.executePostRequest("u/b/2?refresh=true", "{}", encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ update"); - //indices:data/write/index - //indices:data/write/bulk - //indices:admin/create - //indices:data/write/bulk[s] - System.out.println(rh.executePostRequest("u/b/2/_update?refresh=true", "{\"doc\" : {\"a\":1}}",encodeBasicHeader("nagilum", "nagilum"))); + // indices:data/write/index + // indices:data/write/bulk + // indices:admin/create + // indices:data/write/bulk[s] + System.out.println( + rh.executePostRequest("u/b/2/_update?refresh=true", "{\"doc\" : {\"a\":1}}", encodeBasicHeader("nagilum", "nagilum")) + ); System.out.println("############ update2"); - //indices:data/write/index - //indices:data/write/bulk - //indices:admin/create - //indices:data/write/bulk[s] - System.out.println(rh.executePostRequest("u/b/2/_update?refresh=true", "{\"doc\" : {\"a\":44, \"b\":55}}",encodeBasicHeader("nagilum", "nagilum"))); + // indices:data/write/index + // indices:data/write/bulk + // indices:admin/create + // indices:data/write/bulk[s] + System.out.println( + rh.executePostRequest("u/b/2/_update?refresh=true", "{\"doc\" : {\"a\":44, \"b\":55}}", encodeBasicHeader("nagilum", "nagilum")) + ); System.out.println("############ update3"); - //indices:data/write/index - //indices:data/write/bulk - //indices:admin/create - //indices:data/write/bulk[s] - System.out.println(rh.executePostRequest("u/b/2/_update?refresh=true", "{\"doc\" : {\"b\":66}}",encodeBasicHeader("nagilum", "nagilum"))); - + // indices:data/write/index + // indices:data/write/bulk + // indices:admin/create + // indices:data/write/bulk[s] + System.out.println( + rh.executePostRequest("u/b/2/_update?refresh=true", "{\"doc\" : {\"b\":66}}", encodeBasicHeader("nagilum", "nagilum")) + ); System.out.println("############ delete"); - //indices:data/write/index - //indices:data/write/bulk - //indices:admin/create - //indices:data/write/bulk[s] - System.out.println(rh.executeDeleteRequest("u/b/2?refresh=true",encodeBasicHeader("nagilum", "nagilum"))); + // indices:data/write/index + // indices:data/write/bulk + // indices:admin/create + // indices:data/write/bulk[s] + System.out.println(rh.executeDeleteRequest("u/b/2?refresh=true", encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ reindex"); - String reindex = - "{"+ - " \"source\": {"+ - " \"index\": \"a\""+ - " },"+ - " \"dest\": {"+ - " \"index\": \"new_a\""+ - " }"+ - "}"; + String reindex = "{" + + " \"source\": {" + + " \"index\": \"a\"" + + " }," + + " \"dest\": {" + + " \"index\": \"new_a\"" + + " }" + + "}"; System.out.println(rh.executePostRequest("_reindex", reindex, encodeBasicHeader("nagilum", "nagilum"))); - System.out.println("############ msearch"); - String msearchBody = - "{\"index\":\"a\", \"type\":\"b\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ - "{\"index\":\"a\", \"type\":\"b\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ - "{\"index\":\"public\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); - + String msearchBody = "{\"index\":\"a\", \"type\":\"b\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator() + + "{\"index\":\"a\", \"type\":\"b\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator() + + "{\"index\":\"public\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); System.out.println(rh.executePostRequest("_msearch", msearchBody, encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ mget"); - String mgetBody = "{"+ - "\"docs\" : ["+ - "{"+ - "\"_index\" : \"a\","+ - "\"_id\" : \"1\""+ - " },"+ - " {"+ - "\"_index\" : \"a\","+ - " \"_id\" : \"12\""+ - "},"+ - " {"+ - "\"_index\" : \"a\","+ - " \"_id\" : \"13\""+ - "},"+" {"+ - "\"_index\" : \"a\","+ - " \"_id\" : \"14\""+ - "}"+ - "]"+ - "}"; + String mgetBody = "{" + + "\"docs\" : [" + + "{" + + "\"_index\" : \"a\"," + + "\"_id\" : \"1\"" + + " }," + + " {" + + "\"_index\" : \"a\"," + + " \"_id\" : \"12\"" + + "}," + + " {" + + "\"_index\" : \"a\"," + + " \"_id\" : \"13\"" + + "}," + + " {" + + "\"_index\" : \"a\"," + + " \"_id\" : \"14\"" + + "}" + + "]" + + "}"; System.out.println(rh.executePostRequest("_mget?refresh=true", mgetBody, encodeBasicHeader("nagilum", "nagilum"))); System.out.println("############ delete by query"); - String dbqBody = "{"+ - ""+ - " \"query\": { "+ - " \"match\": {"+ - " \"content\": 12"+ - " }"+ - " }"+ - "}"; + String dbqBody = "{" + "" + " \"query\": { " + " \"match\": {" + " \"content\": 12" + " }" + " }" + "}"; System.out.println(rh.executePostRequest("a/b/_delete_by_query", dbqBody, encodeBasicHeader("nagilum", "nagilum"))); diff --git a/src/test/java/org/opensearch/security/TransportUserInjectorIntegTest.java b/src/test/java/org/opensearch/security/TransportUserInjectorIntegTest.java index fc61a3f127..8b5259eb81 100644 --- a/src/test/java/org/opensearch/security/TransportUserInjectorIntegTest.java +++ b/src/test/java/org/opensearch/security/TransportUserInjectorIntegTest.java @@ -55,52 +55,69 @@ public UserInjectorPlugin(final Settings settings, final Path configPath) { } @Override - public Collection createComponents(Client client, ClusterService clusterService, ThreadPool threadPool, - ResourceWatcherService resourceWatcherService, ScriptService scriptService, - NamedXContentRegistry xContentRegistry, Environment environment, - NodeEnvironment nodeEnvironment, NamedWriteableRegistry namedWriteableRegistry, - IndexNameExpressionResolver indexNameExpressionResolver, - Supplier repositoriesServiceSupplier) { - if(injectedUser != null) - threadPool.getThreadContext().putTransient(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, injectedUser); + public Collection createComponents( + Client client, + ClusterService clusterService, + ThreadPool threadPool, + ResourceWatcherService resourceWatcherService, + ScriptService scriptService, + NamedXContentRegistry xContentRegistry, + Environment environment, + NodeEnvironment nodeEnvironment, + NamedWriteableRegistry namedWriteableRegistry, + IndexNameExpressionResolver indexNameExpressionResolver, + Supplier repositoriesServiceSupplier + ) { + if (injectedUser != null) threadPool.getThreadContext() + .putTransient(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, injectedUser); return new ArrayList<>(); } } @Test public void testSecurityUserInjection() throws Exception { - final Settings clusterNodeSettings = Settings.builder() - .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true) - .build(); + final Settings clusterNodeSettings = Settings.builder().put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true).build(); setup(clusterNodeSettings, new DynamicSecurityConfig().setSecurityRolesMapping("roles_transport_inject_user.yml"), Settings.EMPTY); final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) - .put(minimumSecuritySettings(Settings.EMPTY).get(0)) - .put("cluster.name", clusterInfo.clustername) - .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") - .put("path.logs", "./target/data/" + clusterInfo.clustername + "/cert/logs") - .put("path.home", "./target") - .put("node.name", "testclient") - .put("discovery.initial_state_timeout", "8s") - .put("plugins.security.allow_default_init_securityindex", "true") - .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true) - .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost + ":" + clusterInfo.nodePort) - .build(); - + .put(minimumSecuritySettings(Settings.EMPTY).get(0)) + .put("cluster.name", clusterInfo.clustername) + .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") + .put("path.logs", "./target/data/" + clusterInfo.clustername + "/cert/logs") + .put("path.home", "./target") + .put("node.name", "testclient") + .put("discovery.initial_state_timeout", "8s") + .put("plugins.security.allow_default_init_securityindex", "true") + .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true) + .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost + ":" + clusterInfo.nodePort) + .build(); // 1. without user injection - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, - OpenSearchSecurityPlugin.class, UserInjectorPlugin.class).start()) { + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + UserInjectorPlugin.class + ).start() + ) { waitForInit(node.client()); CreateIndexResponse cir = node.client().admin().indices().create(new CreateIndexRequest("captain-logs-1")).actionGet(); Assert.assertTrue(cir.isAcknowledged()); } - // 2. with invalid backend roles UserInjectorPlugin.injectedUser = "ttt|kkk"; Exception exception = null; - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, - OpenSearchSecurityPlugin.class, UserInjectorPlugin.class).start()) { + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + UserInjectorPlugin.class + ).start() + ) { waitForInit(node.client()); CreateIndexResponse cir = node.client().admin().indices().create(new CreateIndexRequest("captain-logs-2")).actionGet(); Assert.fail("Expecting exception"); @@ -111,11 +128,17 @@ public void testSecurityUserInjection() throws Exception { Assert.assertTrue(exception.getMessage().toString().contains("no permissions for [indices:admin/create]")); } - // 3. with valid backend roles for injected user UserInjectorPlugin.injectedUser = "injectedadmin|injecttest"; - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, - OpenSearchSecurityPlugin.class, UserInjectorPlugin.class).start()) { + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + UserInjectorPlugin.class + ).start() + ) { waitForInit(node.client()); CreateIndexResponse cir = node.client().admin().indices().create(new CreateIndexRequest("captain-logs-2")).actionGet(); Assert.assertTrue(cir.isAcknowledged()); @@ -125,25 +148,32 @@ public void testSecurityUserInjection() throws Exception { @Test public void testSecurityUserInjectionWithConfigDisabled() throws Exception { final Settings clusterNodeSettings = Settings.builder() - .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, false) - .build(); + .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, false) + .build(); setup(clusterNodeSettings, new DynamicSecurityConfig().setSecurityRolesMapping("roles_transport_inject_user.yml"), Settings.EMPTY); final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) - .put(minimumSecuritySettings(Settings.EMPTY).get(0)) - .put("cluster.name", clusterInfo.clustername) - .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") - .put("path.logs", "./target/data/" + clusterInfo.clustername + "/cert/logs") - .put("path.home", "./target") - .put("node.name", "testclient") - .put("discovery.initial_state_timeout", "8s") - .put("plugins.security.allow_default_init_securityindex", "true") - .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, false) - .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost + ":" + clusterInfo.nodePort) - .build(); + .put(minimumSecuritySettings(Settings.EMPTY).get(0)) + .put("cluster.name", clusterInfo.clustername) + .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") + .put("path.logs", "./target/data/" + clusterInfo.clustername + "/cert/logs") + .put("path.home", "./target") + .put("node.name", "testclient") + .put("discovery.initial_state_timeout", "8s") + .put("plugins.security.allow_default_init_securityindex", "true") + .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, false) + .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost + ":" + clusterInfo.nodePort) + .build(); // 1. without user injection - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, - OpenSearchSecurityPlugin.class, UserInjectorPlugin.class).start()) { + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + UserInjectorPlugin.class + ).start() + ) { waitForInit(node.client()); CreateIndexResponse cir = node.client().admin().indices().create(new CreateIndexRequest("captain-logs-1")).actionGet(); Assert.assertTrue(cir.isAcknowledged()); @@ -151,8 +181,15 @@ public void testSecurityUserInjectionWithConfigDisabled() throws Exception { // with invalid backend roles UserInjectorPlugin.injectedUser = "ttt|kkk"; - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, - OpenSearchSecurityPlugin.class, UserInjectorPlugin.class).start()) { + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + UserInjectorPlugin.class + ).start() + ) { waitForInit(node.client()); CreateIndexResponse cir = node.client().admin().indices().create(new CreateIndexRequest("captain-logs-2")).actionGet(); // Should pass as the user injection is disabled diff --git a/src/test/java/org/opensearch/security/UtilTests.java b/src/test/java/org/opensearch/security/UtilTests.java index 16baf932cc..2127ada55f 100644 --- a/src/test/java/org/opensearch/security/UtilTests.java +++ b/src/test/java/org/opensearch/security/UtilTests.java @@ -86,109 +86,124 @@ public void testWildcardMatcherClassesCaseInsensitive() { @Test public void testWildcardMatchers() { - assertTrue(!WildcardMatcher.from("a*?").test( "a")); - assertTrue(WildcardMatcher.from("a*?").test( "aa")); - assertTrue(WildcardMatcher.from("a*?").test( "ab")); - //assertTrue(WildcardMatcher.pattern("a*?").test( "abb")); - assertTrue(WildcardMatcher.from("*my*index").test( "myindex")); - assertTrue(!WildcardMatcher.from("*my*index").test( "myindex1")); - assertTrue(WildcardMatcher.from("*my*index?").test( "myindex1")); - assertTrue(WildcardMatcher.from("*my*index").test( "this_is_my_great_index")); - assertTrue(!WildcardMatcher.from("*my*index").test( "MYindex")); - assertTrue(!WildcardMatcher.from("?kibana").test( "kibana")); - assertTrue(WildcardMatcher.from("?kibana").test( ".kibana")); - assertTrue(!WildcardMatcher.from("?kibana").test( "kibana.")); - assertTrue(WildcardMatcher.from("?kibana?").test( "?kibana.")); - assertTrue(WildcardMatcher.from("/(\\d{3}-?\\d{2}-?\\d{4})/").test( "123-45-6789")); - assertTrue(!WildcardMatcher.from("(\\d{3}-?\\d{2}-?\\d{4})").test( "123-45-6789")); - assertTrue(WildcardMatcher.from("/\\S*/").test( "abc")); - assertTrue(WildcardMatcher.from("abc").test( "abc")); - assertTrue(!WildcardMatcher.from("ABC").test( "abc")); + assertTrue(!WildcardMatcher.from("a*?").test("a")); + assertTrue(WildcardMatcher.from("a*?").test("aa")); + assertTrue(WildcardMatcher.from("a*?").test("ab")); + // assertTrue(WildcardMatcher.pattern("a*?").test( "abb")); + assertTrue(WildcardMatcher.from("*my*index").test("myindex")); + assertTrue(!WildcardMatcher.from("*my*index").test("myindex1")); + assertTrue(WildcardMatcher.from("*my*index?").test("myindex1")); + assertTrue(WildcardMatcher.from("*my*index").test("this_is_my_great_index")); + assertTrue(!WildcardMatcher.from("*my*index").test("MYindex")); + assertTrue(!WildcardMatcher.from("?kibana").test("kibana")); + assertTrue(WildcardMatcher.from("?kibana").test(".kibana")); + assertTrue(!WildcardMatcher.from("?kibana").test("kibana.")); + assertTrue(WildcardMatcher.from("?kibana?").test("?kibana.")); + assertTrue(WildcardMatcher.from("/(\\d{3}-?\\d{2}-?\\d{4})/").test("123-45-6789")); + assertTrue(!WildcardMatcher.from("(\\d{3}-?\\d{2}-?\\d{4})").test("123-45-6789")); + assertTrue(WildcardMatcher.from("/\\S*/").test("abc")); + assertTrue(WildcardMatcher.from("abc").test("abc")); + assertTrue(!WildcardMatcher.from("ABC").test("abc")); } @Test public void testMapFromArray() { - Map map = SecurityUtils.mapFromArray((Object)null); + Map map = SecurityUtils.mapFromArray((Object) null); assertTrue(map == null); - + map = SecurityUtils.mapFromArray("key"); assertTrue(map == null); map = SecurityUtils.mapFromArray("key", "value", "otherkey"); assertTrue(map == null); - + map = SecurityUtils.mapFromArray("key", "value"); - assertNotNull(map); + assertNotNull(map); assertEquals(1, map.size()); assertEquals("value", map.get("key")); map = SecurityUtils.mapFromArray("key", "value", "key", "value"); - assertNotNull(map); + assertNotNull(map); assertEquals(1, map.size()); assertEquals("value", map.get("key")); map = SecurityUtils.mapFromArray("key1", "value1", "key2", "value2"); - assertNotNull(map); + assertNotNull(map); assertEquals(2, map.size()); assertEquals("value1", map.get("key1")); assertEquals("value2", map.get("key2")); } - + @Test public void testEnvReplace() { Settings settings = Settings.EMPTY; - assertEquals("abv${env.MYENV}xyz", SecurityUtils.replaceEnvVars("abv${env.MYENV}xyz",settings)); - assertEquals("abv${envbc.MYENV}xyz", SecurityUtils.replaceEnvVars("abv${envbc.MYENV}xyz",settings)); - assertEquals("abvtTtxyz", SecurityUtils.replaceEnvVars("abv${env.MYENV:-tTt}xyz",settings)); - assertTrue(OpenBSDBCrypt.checkPassword(SecurityUtils.replaceEnvVars("${envbc.MYENV:-tTt}",settings), "tTt".toCharArray())); - assertEquals("abvtTtxyzxxx", SecurityUtils.replaceEnvVars("abv${env.MYENV:-tTt}xyz${env.MYENV:-xxx}",settings)); - assertTrue(SecurityUtils.replaceEnvVars("abv${env.MYENV:-tTt}xyz${envbc.MYENV:-xxx}",settings).startsWith("abvtTtxyz$2y$")); - assertEquals("abv${env.MYENV:tTt}xyz", SecurityUtils.replaceEnvVars("abv${env.MYENV:tTt}xyz",settings)); - assertEquals("abv${env.MYENV-tTt}xyz", SecurityUtils.replaceEnvVars("abv${env.MYENV-tTt}xyz",settings)); - //assertEquals("abvabcdefgxyz", SecurityUtils.replaceEnvVars("abv${envbase64.B64TEST}xyz",settings)); + assertEquals("abv${env.MYENV}xyz", SecurityUtils.replaceEnvVars("abv${env.MYENV}xyz", settings)); + assertEquals("abv${envbc.MYENV}xyz", SecurityUtils.replaceEnvVars("abv${envbc.MYENV}xyz", settings)); + assertEquals("abvtTtxyz", SecurityUtils.replaceEnvVars("abv${env.MYENV:-tTt}xyz", settings)); + assertTrue(OpenBSDBCrypt.checkPassword(SecurityUtils.replaceEnvVars("${envbc.MYENV:-tTt}", settings), "tTt".toCharArray())); + assertEquals("abvtTtxyzxxx", SecurityUtils.replaceEnvVars("abv${env.MYENV:-tTt}xyz${env.MYENV:-xxx}", settings)); + assertTrue(SecurityUtils.replaceEnvVars("abv${env.MYENV:-tTt}xyz${envbc.MYENV:-xxx}", settings).startsWith("abvtTtxyz$2y$")); + assertEquals("abv${env.MYENV:tTt}xyz", SecurityUtils.replaceEnvVars("abv${env.MYENV:tTt}xyz", settings)); + assertEquals("abv${env.MYENV-tTt}xyz", SecurityUtils.replaceEnvVars("abv${env.MYENV-tTt}xyz", settings)); + // assertEquals("abvabcdefgxyz", SecurityUtils.replaceEnvVars("abv${envbase64.B64TEST}xyz",settings)); Map env = System.getenv(); assertTrue(env.size() > 0); - + boolean checked = false; - for(String k: env.keySet()) { - String val=System.getenv().get(k); - if(val == null || val.isEmpty()) { + for (String k : env.keySet()) { + String val = System.getenv().get(k); + if (val == null || val.isEmpty()) { continue; } - assertEquals("abv"+val+"xyz", SecurityUtils.replaceEnvVars("abv${env."+k+"}xyz",settings)); - assertEquals("abv${"+k+"}xyz", SecurityUtils.replaceEnvVars("abv${"+k+"}xyz",settings)); - assertEquals("abv"+val+"xyz", SecurityUtils.replaceEnvVars("abv${env."+k+":-k182765ggh}xyz",settings)); - assertEquals("abv"+val+"xyzabv"+val+"xyz", SecurityUtils.replaceEnvVars("abv${env."+k+"}xyzabv${env."+k+"}xyz",settings)); - assertEquals("abv"+val+"xyz", SecurityUtils.replaceEnvVars("abv${env."+k+":-k182765ggh}xyz",settings)); - assertTrue(OpenBSDBCrypt.checkPassword(SecurityUtils.replaceEnvVars("${envbc."+k+"}",settings), val.toCharArray())); + assertEquals("abv" + val + "xyz", SecurityUtils.replaceEnvVars("abv${env." + k + "}xyz", settings)); + assertEquals("abv${" + k + "}xyz", SecurityUtils.replaceEnvVars("abv${" + k + "}xyz", settings)); + assertEquals("abv" + val + "xyz", SecurityUtils.replaceEnvVars("abv${env." + k + ":-k182765ggh}xyz", settings)); + assertEquals( + "abv" + val + "xyzabv" + val + "xyz", + SecurityUtils.replaceEnvVars("abv${env." + k + "}xyzabv${env." + k + "}xyz", settings) + ); + assertEquals("abv" + val + "xyz", SecurityUtils.replaceEnvVars("abv${env." + k + ":-k182765ggh}xyz", settings)); + assertTrue(OpenBSDBCrypt.checkPassword(SecurityUtils.replaceEnvVars("${envbc." + k + "}", settings), val.toCharArray())); checked = true; } - + assertTrue(checked); } - + @Test public void testNoEnvReplace() { Settings settings = Settings.builder().put(ConfigConstants.SECURITY_DISABLE_ENVVAR_REPLACEMENT, true).build(); - assertEquals("abv${env.MYENV}xyz", SecurityUtils.replaceEnvVars("abv${env.MYENV}xyz",settings)); - assertEquals("abv${envbc.MYENV}xyz", SecurityUtils.replaceEnvVars("abv${envbc.MYENV}xyz",settings)); - assertEquals("abv${env.MYENV:-tTt}xyz", SecurityUtils.replaceEnvVars("abv${env.MYENV:-tTt}xyz",settings)); - assertEquals("abv${env.MYENV:-tTt}xyz${env.MYENV:-xxx}", SecurityUtils.replaceEnvVars("abv${env.MYENV:-tTt}xyz${env.MYENV:-xxx}",settings)); - assertFalse(SecurityUtils.replaceEnvVars("abv${env.MYENV:-tTt}xyz${envbc.MYENV:-xxx}",settings).startsWith("abvtTtxyz$2y$")); - assertEquals("abv${env.MYENV:tTt}xyz", SecurityUtils.replaceEnvVars("abv${env.MYENV:tTt}xyz",settings)); - assertEquals("abv${env.MYENV-tTt}xyz", SecurityUtils.replaceEnvVars("abv${env.MYENV-tTt}xyz",settings)); + assertEquals("abv${env.MYENV}xyz", SecurityUtils.replaceEnvVars("abv${env.MYENV}xyz", settings)); + assertEquals("abv${envbc.MYENV}xyz", SecurityUtils.replaceEnvVars("abv${envbc.MYENV}xyz", settings)); + assertEquals("abv${env.MYENV:-tTt}xyz", SecurityUtils.replaceEnvVars("abv${env.MYENV:-tTt}xyz", settings)); + assertEquals( + "abv${env.MYENV:-tTt}xyz${env.MYENV:-xxx}", + SecurityUtils.replaceEnvVars("abv${env.MYENV:-tTt}xyz${env.MYENV:-xxx}", settings) + ); + assertFalse(SecurityUtils.replaceEnvVars("abv${env.MYENV:-tTt}xyz${envbc.MYENV:-xxx}", settings).startsWith("abvtTtxyz$2y$")); + assertEquals("abv${env.MYENV:tTt}xyz", SecurityUtils.replaceEnvVars("abv${env.MYENV:tTt}xyz", settings)); + assertEquals("abv${env.MYENV-tTt}xyz", SecurityUtils.replaceEnvVars("abv${env.MYENV-tTt}xyz", settings)); Map env = System.getenv(); assertTrue(env.size() > 0); - - for(String k: env.keySet()) { - assertEquals("abv${env."+k+"}xyz", SecurityUtils.replaceEnvVars("abv${env."+k+"}xyz",settings)); - assertEquals("abv${"+k+"}xyz", SecurityUtils.replaceEnvVars("abv${"+k+"}xyz",settings)); - assertEquals("abv${env."+k+":-k182765ggh}xyz", SecurityUtils.replaceEnvVars("abv${env."+k+":-k182765ggh}xyz",settings)); - assertEquals("abv${env."+k+"}xyzabv${env."+k+"}xyz", SecurityUtils.replaceEnvVars("abv${env."+k+"}xyzabv${env."+k+"}xyz",settings)); - assertEquals("abv${env."+k+":-k182765ggh}xyz", SecurityUtils.replaceEnvVars("abv${env."+k+":-k182765ggh}xyz",settings)); + + for (String k : env.keySet()) { + assertEquals("abv${env." + k + "}xyz", SecurityUtils.replaceEnvVars("abv${env." + k + "}xyz", settings)); + assertEquals("abv${" + k + "}xyz", SecurityUtils.replaceEnvVars("abv${" + k + "}xyz", settings)); + assertEquals( + "abv${env." + k + ":-k182765ggh}xyz", + SecurityUtils.replaceEnvVars("abv${env." + k + ":-k182765ggh}xyz", settings) + ); + assertEquals( + "abv${env." + k + "}xyzabv${env." + k + "}xyz", + SecurityUtils.replaceEnvVars("abv${env." + k + "}xyzabv${env." + k + "}xyz", settings) + ); + assertEquals( + "abv${env." + k + ":-k182765ggh}xyz", + SecurityUtils.replaceEnvVars("abv${env." + k + ":-k182765ggh}xyz", settings) + ); } } } diff --git a/src/test/java/org/opensearch/security/auditlog/AbstractAuditlogiUnitTest.java b/src/test/java/org/opensearch/security/auditlog/AbstractAuditlogiUnitTest.java index 14ae6aa81e..f567a90ec8 100644 --- a/src/test/java/org/opensearch/security/auditlog/AbstractAuditlogiUnitTest.java +++ b/src/test/java/org/opensearch/security/auditlog/AbstractAuditlogiUnitTest.java @@ -45,8 +45,10 @@ protected final void setup(Settings settings) throws Exception { // Separate the cluster defaults from audit settings that will be applied after the cluster is up settings.keySet().forEach(key -> { final boolean moveToAuditConfig = Arrays.stream(AuditConfig.Filter.FilterEntries.values()) - .anyMatch(entry -> entry.getKeyWithNamespace().equalsIgnoreCase(key) || entry.getLegacyKeyWithNamespace().equalsIgnoreCase(key)) - || DEPRECATED_KEYS.stream().anyMatch(key::equalsIgnoreCase); + .anyMatch( + entry -> entry.getKeyWithNamespace().equalsIgnoreCase(key) || entry.getLegacyKeyWithNamespace().equalsIgnoreCase(key) + ) + || DEPRECATED_KEYS.stream().anyMatch(key::equalsIgnoreCase); if (moveToAuditConfig) { auditConfigSettings.put(key, settings.get(key)); } else { @@ -64,10 +66,8 @@ protected Settings defaultNodeSettings(Settings additionalSettings) { Settings.Builder builder = Settings.builder(); builder.put("plugins.security.ssl.http.enabled", true) - .put("plugins.security.ssl.http.keystore_filepath", - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")); + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")); return builder.put(additionalSettings).build(); } @@ -87,7 +87,7 @@ protected void setupStarfleetIndex() throws Exception { protected boolean validateMsgs(final Collection msgs) { boolean valid = true; - for(AuditMessage msg: msgs) { + for (AuditMessage msg : msgs) { valid = validateMsg(msg) && valid; } return valid; @@ -99,15 +99,15 @@ protected boolean validateMsg(final AuditMessage msg) { protected boolean validateJson(final String json) { - if(json == null || json.isEmpty()) { + if (json == null || json.isEmpty()) { return false; } try { JsonNode node = DefaultObjectMapper.objectMapper.readTree(json); - if(node.get("audit_request_body") != null) { - System.out.println(" Check audit_request_body for validity: "+node.get("audit_request_body").asText()); + if (node.get("audit_request_body") != null) { + System.out.println(" Check audit_request_body for validity: " + node.get("audit_request_body").asText()); DefaultObjectMapper.objectMapper.readTree(node.get("audit_request_body").asText()); } diff --git a/src/test/java/org/opensearch/security/auditlog/AuditTestUtils.java b/src/test/java/org/opensearch/security/auditlog/AuditTestUtils.java index 507ebc1409..98f5fab88e 100644 --- a/src/test/java/org/opensearch/security/auditlog/AuditTestUtils.java +++ b/src/test/java/org/opensearch/security/auditlog/AuditTestUtils.java @@ -62,7 +62,8 @@ public static AbstractAuditLog createAuditLog( final Client clientProvider, final ThreadPool threadPool, final IndexNameExpressionResolver resolver, - final ClusterService clusterService) { + final ClusterService clusterService + ) { AuditLogImpl auditLog = new AuditLogImpl(settings, configPath, clientProvider, threadPool, resolver, clusterService); AuditConfig auditConfig = AuditConfig.from(settings); auditLog.setConfig(auditConfig); 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 dd53cd16a8..361c3cc313 100644 --- a/src/test/java/org/opensearch/security/auditlog/compliance/ComplianceAuditlogTest.java +++ b/src/test/java/org/opensearch/security/auditlog/compliance/ComplianceAuditlogTest.java @@ -54,14 +54,14 @@ public class ComplianceAuditlogTest extends AbstractAuditlogiUnitTest { @Test public void testSourceFilter() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_WATCHED_FIELDS, "emp") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_WATCHED_FIELDS, "emp") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .build(); setup(additionalSettings); final boolean sendAdminCertificate = rh.sendAdminCertificate; @@ -74,18 +74,18 @@ public void testSourceFilter() throws Exception { rh.sendAdminCertificate = sendAdminCertificate; rh.keystore = keystore; - String search = "{" + - " \"_source\":[" + - " \"Gender\""+ - " ]," + - " \"from\":0," + - " \"size\":3," + - " \"query\":{" + - " \"term\":{" + - " \"Salary\": 300" + - " }" + - " }" + - "}"; + String search = "{" + + " \"_source\":[" + + " \"Gender\"" + + " ]," + + " \"from\":0," + + " \"size\":3," + + " \"query\":{" + + " \"term\":{" + + " \"Salary\": 300" + + " }" + + " }" + + "}"; final AuditMessage message = TestAuditlogImpl.doThenWaitForMessage(() -> { final HttpResponse response = rh.executePostRequest("_search?pretty", search, encodeBasicHeader("admin", "admin")); @@ -102,9 +102,7 @@ public void testSourceFilter() throws Exception { @Test public void testComplianceEnable() throws Exception { - Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .build(); + Settings additionalSettings = Settings.builder().put("plugins.security.audit.type", TestAuditlogImpl.class.getName()).build(); setup(additionalSettings); @@ -112,7 +110,14 @@ public void testComplianceEnable() throws Exception { rh.keystore = "auditlog/kirk-keystore.jks"; // watch emp for write - AuditConfig auditConfig = new AuditConfig(true, AuditConfig.Filter.DEFAULT , ComplianceConfig.from(ImmutableMap.of("enabled", true, "write_watched_indices", Collections.singletonList("emp")), additionalSettings)); + AuditConfig auditConfig = new AuditConfig( + true, + AuditConfig.Filter.DEFAULT, + ComplianceConfig.from( + ImmutableMap.of("enabled", true, "write_watched_indices", Collections.singletonList("emp")), + additionalSettings + ) + ); updateAuditConfig(AuditTestUtils.createAuditPayload(auditConfig)); // make an event happen @@ -122,23 +127,36 @@ public void testComplianceEnable() throws Exception { rh.executePutRequest("emp/_doc/0?refresh", "{\"Designation\" : \"CEO\", \"Gender\" : \"female\", \"Salary\" : 100}"); System.out.println(rh.executeGetRequest("_cat/shards?v")); }, 7); - } catch (final MessagesNotFoundException ex) { + } catch (final MessagesNotFoundException ex) { // indices:admin/mapping/auto_put can be logged twice, this handles if they were not found assertThat("Too many missing audit log messages", ex.getMissingCount(), equalTo(2)); messages = ex.getFoundMessages(); } - messages.stream().filter(msg -> msg.getCategory().equals(AuditCategory.COMPLIANCE_DOC_WRITE)) - .findFirst().orElseThrow(() -> new RuntimeException("Missing COMPLIANCE message")); + messages.stream() + .filter(msg -> msg.getCategory().equals(AuditCategory.COMPLIANCE_DOC_WRITE)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Missing COMPLIANCE message")); - final List indexCreation = messages.stream().filter(msg -> "indices:admin/auto_create".equals(msg.getPrivilege())).collect(Collectors.toList()); + final List indexCreation = messages.stream() + .filter(msg -> "indices:admin/auto_create".equals(msg.getPrivilege())) + .collect(Collectors.toList()); assertThat(indexCreation.size(), equalTo(2)); - final List mappingCreation = messages.stream().filter(msg -> "indices:admin/mapping/auto_put".equals(msg.getPrivilege())).collect(Collectors.toList()); + final List mappingCreation = messages.stream() + .filter(msg -> "indices:admin/mapping/auto_put".equals(msg.getPrivilege())) + .collect(Collectors.toList()); assertThat(mappingCreation.size(), anyOf(equalTo(4), equalTo(2))); - + // disable compliance - auditConfig = new AuditConfig(true, AuditConfig.Filter.DEFAULT , ComplianceConfig.from(ImmutableMap.of("enabled", false, "write_watched_indices", Collections.singletonList("emp")), additionalSettings)); + auditConfig = new AuditConfig( + true, + AuditConfig.Filter.DEFAULT, + ComplianceConfig.from( + ImmutableMap.of("enabled", false, "write_watched_indices", Collections.singletonList("emp")), + additionalSettings + ) + ); updateAuditConfig(AuditTestUtils.createAuditPayload(auditConfig)); // trigger an event that it not captured by the audit log @@ -154,15 +172,15 @@ public void testComplianceEnable() throws Exception { public void testSourceFilterMsearch() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) - //.put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_WATCHED_INDICES, "emp") - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_WATCHED_FIELDS, "emp") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) + // .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_WATCHED_INDICES, "emp") + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_WATCHED_FIELDS, "emp") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .build(); setup(additionalSettings); final boolean sendAdminCertificate = rh.sendAdminCertificate; @@ -175,33 +193,38 @@ public void testSourceFilterMsearch() throws Exception { rh.sendAdminCertificate = sendAdminCertificate; rh.keystore = keystore; - String search = "{}"+System.lineSeparator() - + "{" + - " \"_source\":[" + - " \"Gender\""+ - " ]," + - " \"from\":0," + - " \"size\":3," + - " \"query\":{" + - " \"term\":{" + - " \"Salary\": 300" + - " }" + - " }" + - "}"+System.lineSeparator()+ - - "{}"+System.lineSeparator() - + "{" + - " \"_source\":[" + - " \"Designation\""+ - " ]," + - " \"from\":0," + - " \"size\":3," + - " \"query\":{" + - " \"term\":{" + - " \"Salary\": 200" + - " }" + - " }" + - "}"+System.lineSeparator(); + String search = "{}" + + System.lineSeparator() + + "{" + + " \"_source\":[" + + " \"Gender\"" + + " ]," + + " \"from\":0," + + " \"size\":3," + + " \"query\":{" + + " \"term\":{" + + " \"Salary\": 300" + + " }" + + " }" + + "}" + + System.lineSeparator() + + + + "{}" + + System.lineSeparator() + + "{" + + " \"_source\":[" + + " \"Designation\"" + + " ]," + + " \"from\":0," + + " \"size\":3," + + " \"query\":{" + + " \"term\":{" + + " \"Salary\": 200" + + " }" + + " }" + + "}" + + System.lineSeparator(); final List messages = TestAuditlogImpl.doThenWaitForMessages(() -> { HttpResponse response = rh.executePostRequest("_msearch?pretty", search, encodeBasicHeader("admin", "admin")); @@ -209,8 +232,10 @@ public void testSourceFilterMsearch() throws Exception { Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); }, 2); - - final AuditMessage desginationMsg = messages.stream().filter(msg -> msg.getRequestBody().contains("Designation")).findFirst().orElseThrow(); + final AuditMessage desginationMsg = messages.stream() + .filter(msg -> msg.getRequestBody().contains("Designation")) + .findFirst() + .orElseThrow(); assertThat(desginationMsg.getCategory(), equalTo(AuditCategory.COMPLIANCE_DOC_READ)); assertThat(desginationMsg.getRequestBody(), containsString("Designation")); assertThat(desginationMsg.getRequestBody(), not(containsString("Salary"))); @@ -227,23 +252,31 @@ public void testSourceFilterMsearch() throws Exception { public void testInternalConfig() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_LOG_DIFFS, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) - .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_LOG_DIFFS, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) + .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .build(); setup(additionalSettings); - final List expectedDocumentsTypes = List.of("config", "actiongroups", "internalusers", "roles", "rolesmapping", "tenants", "audit"); + final List expectedDocumentsTypes = List.of( + "config", + "actiongroups", + "internalusers", + "roles", + "rolesmapping", + "tenants", + "audit" + ); final List messages = TestAuditlogImpl.doThenWaitForMessages(() -> { try (RestHighLevelClient restHighLevelClient = getRestClient(clusterInfo, "kirk-keystore.jks", "truststore.jks")) { - for (IndexRequest ir: new DynamicSecurityConfig().setSecurityRoles("roles_2.yml").getDynamicConfig(getResourceFolder())) { + for (IndexRequest ir : new DynamicSecurityConfig().setSecurityRoles("roles_2.yml").getDynamicConfig(getResourceFolder())) { restHighLevelClient.index(ir, RequestOptions.DEFAULT); GetResponse getDocumentResponse = restHighLevelClient.get(new GetRequest(ir.index(), ir.id()), RequestOptions.DEFAULT); assertThat(getDocumentResponse.isExists(), equalTo(true)); @@ -262,7 +295,8 @@ public void testInternalConfig() throws Exception { messages.stream().collect(Collectors.groupingBy(AuditMessage::getDocId)).entrySet().forEach((e) -> { final String docId = e.getKey(); final List messagesByDocId = e.getValue(); - assertThat("Doc " + docId + " should have a read/write config message", + assertThat( + "Doc " + docId + " should have a read/write config message", messagesByDocId.stream().map(AuditMessage::getCategory).collect(Collectors.toList()), equalTo(List.of(AuditCategory.COMPLIANCE_INTERNAL_CONFIG_WRITE, AuditCategory.COMPLIANCE_INTERNAL_CONFIG_READ)) ); @@ -275,15 +309,15 @@ public void testInternalConfig() throws Exception { public void testExternalConfig() throws Exception { final Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, true) - .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, true) + .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .build(); final List messages = TestAuditlogImpl.doThenWaitForMessages(() -> { try { @@ -293,7 +327,7 @@ public void testExternalConfig() throws Exception { } try (Client tc = getClient()) { - for(IndexRequest ir: new DynamicSecurityConfig().setSecurityRoles("roles_2.yml").getDynamicConfig(getResourceFolder())) { + for (IndexRequest ir : new DynamicSecurityConfig().setSecurityRoles("roles_2.yml").getDynamicConfig(getResourceFolder())) { tc.index(ir).actionGet(); } } @@ -319,41 +353,46 @@ public void testExternalConfig() throws Exception { public void testUpdate() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) - .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_WATCHED_INDICES, "finance") - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_WATCHED_FIELDS, "humanresources,Designation,FirstName,LastName") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) + .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_WATCHED_INDICES, "finance") + .put( + ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_WATCHED_FIELDS, + "humanresources,Designation,FirstName,LastName" + ) + .build(); setup(additionalSettings); - try (Client tc = getClient()) { - tc.prepareIndex("humanresources") - .setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .setSource("Age", 456) - .execute() - .actionGet(); + tc.prepareIndex("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE).setSource("Age", 456).execute().actionGet(); } final MessagesNotFoundException ex1 = assertThrows(MessagesNotFoundException.class, () -> { TestAuditlogImpl.doThenWaitForMessage(() -> { final String body = "{\"doc\": {\"Age\":123}}"; - final HttpResponse response = rh.executePostRequest("humanresources/_doc/100?pretty", body, encodeBasicHeader("admin", "admin")); + final HttpResponse response = rh.executePostRequest( + "humanresources/_doc/100?pretty", + body, + encodeBasicHeader("admin", "admin") + ); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); }); }); assertThat(ex1.getMissingCount(), equalTo(1)); - final MessagesNotFoundException ex2 = assertThrows(MessagesNotFoundException.class, () -> { TestAuditlogImpl.doThenWaitForMessage(() -> { final String body = "{\"doc\": {\"Age\":456}}"; - final HttpResponse response = rh.executePostRequest("humanresources/_update/100?pretty", body, encodeBasicHeader("admin", "admin")); + final HttpResponse response = rh.executePostRequest( + "humanresources/_update/100?pretty", + body, + encodeBasicHeader("admin", "admin") + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); }); }); @@ -367,34 +406,38 @@ public void testUpdate() throws Exception { public void testWriteHistory() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_LOG_DIFFS, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_WATCHED_INDICES, "humanresources") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_LOG_DIFFS, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_WATCHED_INDICES, "humanresources") + .build(); setup(additionalSettings); try (Client tc = getClient()) { - tc.prepareIndex("humanresources") - .setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .setSource("Age", 456) - .execute() - .actionGet(); + tc.prepareIndex("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE).setSource("Age", 456).execute().actionGet(); } TestAuditlogImpl.doThenWaitForMessage(() -> { final String body = "{\"doc\": {\"Age\":123}}"; - final HttpResponse response = rh.executePostRequest("humanresources/_doc/100?pretty", body, encodeBasicHeader("admin", "admin")); + final HttpResponse response = rh.executePostRequest( + "humanresources/_doc/100?pretty", + body, + encodeBasicHeader("admin", "admin") + ); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); }); Assert.assertTrue(TestAuditlogImpl.sb.toString().split(".*audit_compliance_diff_content.*replace.*").length == 1); TestAuditlogImpl.doThenWaitForMessage(() -> { final String body = "{\"doc\": {\"Age\":555}}"; - final HttpResponse response = rh.executePostRequest("humanresources/_update/100?pretty", body, encodeBasicHeader("admin", "admin")); + final HttpResponse response = rh.executePostRequest( + "humanresources/_update/100?pretty", + body, + encodeBasicHeader("admin", "admin") + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); }); Assert.assertTrue(TestAuditlogImpl.sb.toString().split(".*audit_compliance_diff_content.*replace.*").length == 1); 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 a40e94ad28..467475212b 100644 --- a/src/test/java/org/opensearch/security/auditlog/compliance/ComplianceConfigTest.java +++ b/src/test/java/org/opensearch/security/auditlog/compliance/ComplianceConfigTest.java @@ -50,19 +50,21 @@ public void testConfig() { // arrange final String testSalt = "abcdefghijklmnop"; final Settings settings = Settings.builder() - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, true) - .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_METADATA_ONLY, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_METADATA_ONLY, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_LOG_DIFFS, true) - .put(ConfigConstants.SECURITY_COMPLIANCE_SALT, testSalt) - .putList(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_WATCHED_INDICES, "write_index1", "write_index_pattern*") - .putList(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_WATCHED_FIELDS, "read_index1,field1,field2", "read_index_pattern*,field1,field_pattern*") - .putList(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_IGNORE_USERS, - "test-user-1", "test-user-2") - .putList(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_IGNORE_USERS, - "test-user-3", "test-user-4") - .build(); + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, true) + .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_METADATA_ONLY, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_METADATA_ONLY, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_LOG_DIFFS, true) + .put(ConfigConstants.SECURITY_COMPLIANCE_SALT, testSalt) + .putList(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_WATCHED_INDICES, "write_index1", "write_index_pattern*") + .putList( + ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_WATCHED_FIELDS, + "read_index1,field1,field2", + "read_index_pattern*,field1,field_pattern*" + ) + .putList(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_IGNORE_USERS, "test-user-1", "test-user-2") + .putList(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_IGNORE_USERS, "test-user-3", "test-user-4") + .build(); // act final ComplianceConfig complianceConfig = ComplianceConfig.from(settings); @@ -74,8 +76,14 @@ public void testConfig() { assertTrue(complianceConfig.shouldLogReadMetadataOnly()); assertTrue(complianceConfig.shouldLogWriteMetadataOnly()); assertFalse(complianceConfig.shouldLogDiffsForWrite()); - assertEquals(WildcardMatcher.from(ImmutableSet.of("test-user-1", "test-user-2")), complianceConfig.getIgnoredComplianceUsersForReadMatcher()); - assertEquals(WildcardMatcher.from(ImmutableSet.of("test-user-3", "test-user-4")), complianceConfig.getIgnoredComplianceUsersForWriteMatcher()); + assertEquals( + WildcardMatcher.from(ImmutableSet.of("test-user-1", "test-user-2")), + complianceConfig.getIgnoredComplianceUsersForReadMatcher() + ); + assertEquals( + WildcardMatcher.from(ImmutableSet.of("test-user-3", "test-user-4")), + complianceConfig.getIgnoredComplianceUsersForWriteMatcher() + ); // test write history assertTrue(complianceConfig.writeHistoryEnabledForIndex(".opendistro_security")); @@ -105,11 +113,9 @@ public void testConfig() { public void testNone() { // arrange final Settings settings = Settings.builder() - .putList(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_IGNORE_USERS, - "NONE") - .putList(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_IGNORE_USERS, - "NONE") - .build(); + .putList(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_IGNORE_USERS, "NONE") + .putList(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_IGNORE_USERS, "NONE") + .build(); // act final ComplianceConfig complianceConfig = ComplianceConfig.from(settings); // assert @@ -121,11 +127,9 @@ public void testNone() { public void testEmpty() { // arrange final Settings settings = Settings.builder() - .putList(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_IGNORE_USERS, - Collections.emptyList()) - .putList(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_IGNORE_USERS, - Collections.emptyList()) - .build(); + .putList(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_READ_IGNORE_USERS, Collections.emptyList()) + .putList(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_IGNORE_USERS, Collections.emptyList()) + .build(); // act final ComplianceConfig complianceConfig = ComplianceConfig.from(settings); // assert 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 37ef283ccb..519237bd8e 100644 --- a/src/test/java/org/opensearch/security/auditlog/compliance/RestApiComplianceAuditlogTest.java +++ b/src/test/java/org/opensearch/security/auditlog/compliance/RestApiComplianceAuditlogTest.java @@ -29,25 +29,29 @@ public class RestApiComplianceAuditlogTest extends AbstractAuditlogiUnitTest { public void testRestApiRolesEnabled() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED, "opendistro_security_all_access") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) - .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED, "opendistro_security_all_access") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) + .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .build(); setup(additionalSettings); TestAuditlogImpl.clear(); String body = "{ \"password\":\"some new password\",\"backend_roles\":[\"role1\",\"role2\"] }"; - HttpResponse response = rh.executePutRequest("_opendistro/_security/api/internalusers/compuser?pretty", body, encodeBasicHeader("admin", "admin")); + HttpResponse response = rh.executePutRequest( + "_opendistro/_security/api/internalusers/compuser?pretty", + body, + encodeBasicHeader("admin", "admin") + ); Thread.sleep(1500); System.out.println(TestAuditlogImpl.sb.toString()); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); - Assert.assertTrue(TestAuditlogImpl.messages.size()+"",TestAuditlogImpl.messages.size() == 1); + Assert.assertTrue(TestAuditlogImpl.messages.size() + "", TestAuditlogImpl.messages.size() == 1); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("audit_request_effective_user")); Assert.assertFalse(TestAuditlogImpl.sb.toString().contains("COMPLIANCE_INTERNAL_CONFIG_READ")); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("COMPLIANCE_INTERNAL_CONFIG_WRITE")); @@ -59,15 +63,15 @@ public void testRestApiRolesEnabled() throws Exception { public void testRestApiRolesDisabled() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) - .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) + .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .build(); setup(additionalSettings); TestAuditlogImpl.clear(); @@ -82,7 +86,7 @@ public void testRestApiRolesDisabled() throws Exception { Thread.sleep(1500); System.out.println(TestAuditlogImpl.sb.toString()); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); - Assert.assertTrue(TestAuditlogImpl.messages.size()+"",TestAuditlogImpl.messages.size() == 1); + Assert.assertTrue(TestAuditlogImpl.messages.size() + "", TestAuditlogImpl.messages.size() == 1); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("audit_request_effective_user")); Assert.assertFalse(TestAuditlogImpl.sb.toString().contains("COMPLIANCE_INTERNAL_CONFIG_READ")); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("COMPLIANCE_INTERNAL_CONFIG_WRITE")); @@ -95,15 +99,15 @@ public void testRestApiRolesDisabled() throws Exception { public void testRestApiRolesDisabledGet() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) - .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) + .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .build(); setup(additionalSettings); TestAuditlogImpl.clear(); @@ -125,21 +129,19 @@ public void testRestApiRolesDisabledGet() throws Exception { Assert.assertTrue(validateMsgs(TestAuditlogImpl.messages)); } - - @Test public void testAutoInit() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, true) - .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, true) + .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .build(); setup(additionalSettings); @@ -157,42 +159,45 @@ public void testAutoInit() throws Exception { public void testRestApiNewUser() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED, "opendistro_security_all_access") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) - .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_IGNORE_USERS, "admin") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED, "opendistro_security_all_access") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) + .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_IGNORE_USERS, "admin") + .build(); setup(additionalSettings); TestAuditlogImpl.clear(); String body = "{ \"password\":\"some new password\",\"backend_roles\":[\"role1\",\"role2\"] }"; System.out.println("exec"); - HttpResponse response = rh.executePutRequest("_opendistro/_security/api/internalusers/compuser?pretty", - body, encodeBasicHeader("admin", "admin")); + HttpResponse response = rh.executePutRequest( + "_opendistro/_security/api/internalusers/compuser?pretty", + body, + encodeBasicHeader("admin", "admin") + ); Thread.sleep(1500); System.out.println(TestAuditlogImpl.sb.toString()); Assert.assertEquals(response.getBody(), HttpStatus.SC_CREATED, response.getStatusCode()); - Assert.assertTrue(TestAuditlogImpl.messages.size()+"", TestAuditlogImpl.messages.isEmpty()); + Assert.assertTrue(TestAuditlogImpl.messages.size() + "", TestAuditlogImpl.messages.isEmpty()); } @Test public void testRestInternalConfigRead() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED, "opendistro_security_all_access") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) - .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED, "opendistro_security_all_access") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) + .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .build(); setup(additionalSettings); TestAuditlogImpl.clear(); @@ -206,7 +211,7 @@ public void testRestInternalConfigRead() throws Exception { Thread.sleep(1500); System.out.println(TestAuditlogImpl.sb.toString()); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - Assert.assertTrue(TestAuditlogImpl.messages.size()+"",TestAuditlogImpl.messages.size() == 1); + Assert.assertTrue(TestAuditlogImpl.messages.size() + "", TestAuditlogImpl.messages.size() == 1); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("audit_request_effective_user")); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("COMPLIANCE_INTERNAL_CONFIG_READ")); Assert.assertFalse(TestAuditlogImpl.sb.toString().contains("COMPLIANCE_INTERNAL_CONFIG_WRITE")); @@ -217,13 +222,13 @@ public void testRestInternalConfigRead() throws Exception { @Test public void testBCryptHashRedaction() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED, "opendistro_security_all_access") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) - .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_LOG_DIFFS, true) - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED, "opendistro_security_all_access") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) + .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_LOG_DIFFS, true) + .build(); setup(settings); rh.sendAdminCertificate = true; rh.keystore = "kirk-keystore.jks"; @@ -242,7 +247,7 @@ public void testBCryptHashRedaction() throws Exception { // create internal user and verify no BCrypt hash is present in audit logs TestAuditlogImpl.clear(); - rh.executePutRequest("/_opendistro/_security/api/internalusers/test", "{ \"password\":\"some new user password\"}"); + rh.executePutRequest("/_opendistro/_security/api/internalusers/test", "{ \"password\":\"some new user password\"}"); Assert.assertEquals(1, TestAuditlogImpl.messages.size()); Assert.assertFalse(AuditMessage.BCRYPT_HASH.matcher(TestAuditlogImpl.sb.toString()).matches()); } 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 4b4676d852..fad4cabbc5 100644 --- a/src/test/java/org/opensearch/security/auditlog/config/AuditConfigFilterTest.java +++ b/src/test/java/org/opensearch/security/auditlog/config/AuditConfigFilterTest.java @@ -65,19 +65,25 @@ public void testDefault() { public void testConfig() { // arrange final Settings settings = Settings.builder() - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_LOG_REQUEST_BODY, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_INDICES, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_EXCLUDE_SENSITIVE_HEADERS, false) - .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_IGNORE_REQUESTS, "test-request") - .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_IGNORE_USERS, "test-user") - .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, - BAD_HEADERS.toString(), SSL_EXCEPTION.toString()) - .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, - FAILED_LOGIN.toString(), MISSING_PRIVILEGES.toString()) - .build(); + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_LOG_REQUEST_BODY, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_INDICES, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_EXCLUDE_SENSITIVE_HEADERS, false) + .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_IGNORE_REQUESTS, "test-request") + .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_IGNORE_USERS, "test-user") + .putList( + ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, + BAD_HEADERS.toString(), + SSL_EXCEPTION.toString() + ) + .putList( + ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, + FAILED_LOGIN.toString(), + MISSING_PRIVILEGES.toString() + ) + .build(); // act final AuditConfig.Filter auditConfigFilter = AuditConfig.Filter.from(settings); // assert @@ -97,12 +103,10 @@ public void testConfig() { public void testNone() { // arrange final Settings settings = Settings.builder() - .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_IGNORE_USERS, "NONE") - .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, - "None") - .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, - "none") - .build(); + .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_IGNORE_USERS, "NONE") + .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "None") + .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "none") + .build(); // act final AuditConfig.Filter auditConfigFilter = AuditConfig.Filter.from(settings); // assert @@ -115,13 +119,11 @@ public void testNone() { public void testEmpty() { // arrange final Settings settings = Settings.builder() - .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_IGNORE_USERS, Collections.emptyList()) - .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_IGNORE_REQUESTS, Collections.emptyList()) - .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, - Collections.emptyList()) - .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, - Collections.emptyList()) - .build(); + .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_IGNORE_USERS, Collections.emptyList()) + .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_IGNORE_REQUESTS, Collections.emptyList()) + .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, Collections.emptyList()) + .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, Collections.emptyList()) + .build(); // act final AuditConfig.Filter auditConfigFilter = AuditConfig.Filter.from(settings); // assert @@ -130,7 +132,6 @@ public void testEmpty() { assertTrue(auditConfigFilter.getDisabledTransportCategories().isEmpty()); } - @Test public void testFilterEntries() { assertThat(FilterEntries.ENABLE_REST.getKey(), equalTo("enable_rest")); @@ -147,16 +148,14 @@ public void fromSettingBoolean() { .put(entry.getKeyWithNamespace(), false) .put(entry.getLegacyKeyWithNamespace(), true) .build(); - assertThat(AuditConfig.Filter.fromSettingBoolean(settings1, entry, true), equalTo(false)); + assertThat(AuditConfig.Filter.fromSettingBoolean(settings1, entry, true), equalTo(false)); // Use fallback key - final Settings settings2 = Settings.builder() - .put(entry.getLegacyKeyWithNamespace(), false) - .build(); - assertThat(AuditConfig.Filter.fromSettingBoolean(settings2, entry, true), equalTo(false)); + final Settings settings2 = Settings.builder().put(entry.getLegacyKeyWithNamespace(), false).build(); + assertThat(AuditConfig.Filter.fromSettingBoolean(settings2, entry, true), equalTo(false)); // Use default - assertThat(AuditConfig.Filter.fromSettingBoolean(Settings.builder().build(), entry, true), equalTo(true)); + assertThat(AuditConfig.Filter.fromSettingBoolean(Settings.builder().build(), entry, true), equalTo(true)); } @Test @@ -165,67 +164,65 @@ public void fromSettingStringSet() { // Use primary key final Settings settings1 = Settings.builder() - .putList(entry.getKeyWithNamespace(), "abc") - .putList(entry.getLegacyKeyWithNamespace(), "def") - .build(); + .putList(entry.getKeyWithNamespace(), "abc") + .putList(entry.getLegacyKeyWithNamespace(), "def") + .build(); assertThat(AuditConfig.Filter.fromSettingStringSet(settings1, entry, List.of("xyz")), equalTo(ImmutableSet.of("abc"))); // Use fallback key - final Settings settings2 = Settings.builder() - .putList(entry.getLegacyKeyWithNamespace(), "def") - .build(); + final Settings settings2 = Settings.builder().putList(entry.getLegacyKeyWithNamespace(), "def").build(); assertThat(AuditConfig.Filter.fromSettingStringSet(settings2, entry, List.of("xyz")), equalTo(ImmutableSet.of("def"))); // Use default - assertThat(AuditConfig.Filter.fromSettingStringSet(Settings.builder().build(), entry, List.of("xyz")), equalTo(ImmutableSet.of("xyz"))); + assertThat( + AuditConfig.Filter.fromSettingStringSet(Settings.builder().build(), entry, List.of("xyz")), + equalTo(ImmutableSet.of("xyz")) + ); } @Test public void fromSettingParseAuditCategory() { final FilterEntries entry = FilterEntries.DISABLE_REST_CATEGORIES; - final Function> parse = (settings) -> - AuditCategory.parse(AuditConfig.Filter.fromSettingStringSet(settings, entry, ConfigConstants.OPENDISTRO_SECURITY_AUDIT_DISABLED_CATEGORIES_DEFAULT)); + final Function> parse = (settings) -> AuditCategory.parse( + AuditConfig.Filter.fromSettingStringSet(settings, entry, ConfigConstants.OPENDISTRO_SECURITY_AUDIT_DISABLED_CATEGORIES_DEFAULT) + ); final Settings noValues = Settings.builder().build(); assertThat(parse.apply(noValues), equalTo(ImmutableSet.of(AUTHENTICATED, GRANTED_PRIVILEGES))); - final Settings legacySettingNone = Settings.builder() - .put(entry.getLegacyKeyWithNamespace(), "NONE") - .build(); + final Settings legacySettingNone = Settings.builder().put(entry.getLegacyKeyWithNamespace(), "NONE").build(); assertThat(parse.apply(legacySettingNone), equalTo(ImmutableSet.of())); - final Settings legacySettingValue = Settings.builder() - .put(entry.getLegacyKeyWithNamespace(), AUTHENTICATED.name()) - .build(); + final Settings legacySettingValue = Settings.builder().put(entry.getLegacyKeyWithNamespace(), AUTHENTICATED.name()).build(); assertThat(parse.apply(legacySettingValue), equalTo(ImmutableSet.of(AUTHENTICATED))); final Settings legacySettingMultipleValues = Settings.builder() - .putList(entry.getLegacyKeyWithNamespace(), AUTHENTICATED.name(), BAD_HEADERS.name()) - .build(); + .putList(entry.getLegacyKeyWithNamespace(), AUTHENTICATED.name(), BAD_HEADERS.name()) + .build(); assertThat(parse.apply(legacySettingMultipleValues), equalTo(ImmutableSet.of(AUTHENTICATED, BAD_HEADERS))); final Settings settingNone = Settings.builder() - .put(entry.getKeyWithNamespace(), "NONE") - .put(entry.getLegacyKeyWithNamespace(), FAILED_LOGIN.name()) - .build(); + .put(entry.getKeyWithNamespace(), "NONE") + .put(entry.getLegacyKeyWithNamespace(), FAILED_LOGIN.name()) + .build(); assertThat(parse.apply(settingNone), equalTo(ImmutableSet.of())); final Settings settingValue = Settings.builder() - .put(entry.getKeyWithNamespace(), AUTHENTICATED.name()) - .put(entry.getLegacyKeyWithNamespace(), FAILED_LOGIN.name()) - .build(); + .put(entry.getKeyWithNamespace(), AUTHENTICATED.name()) + .put(entry.getLegacyKeyWithNamespace(), FAILED_LOGIN.name()) + .build(); assertThat(parse.apply(settingValue), equalTo(ImmutableSet.of(AUTHENTICATED))); final Settings settingMultipleValues = Settings.builder() - .putList(entry.getKeyWithNamespace(), AUTHENTICATED.name(), BAD_HEADERS.name()) - .put(entry.getLegacyKeyWithNamespace(), FAILED_LOGIN.name()) - .build(); + .putList(entry.getKeyWithNamespace(), AUTHENTICATED.name(), BAD_HEADERS.name()) + .put(entry.getLegacyKeyWithNamespace(), FAILED_LOGIN.name()) + .build(); assertThat(parse.apply(settingMultipleValues), equalTo(ImmutableSet.of(AUTHENTICATED, BAD_HEADERS))); final Settings settingMultipleValuesString = Settings.builder() - .put(entry.getKeyWithNamespace(), AUTHENTICATED.name() + "," + BAD_HEADERS.name()) - .put(entry.getLegacyKeyWithNamespace(), FAILED_LOGIN.name()) - .build(); + .put(entry.getKeyWithNamespace(), AUTHENTICATED.name() + "," + BAD_HEADERS.name()) + .put(entry.getLegacyKeyWithNamespace(), FAILED_LOGIN.name()) + .build(); assertThat(parse.apply(settingMultipleValues), equalTo(ImmutableSet.of(AUTHENTICATED, BAD_HEADERS))); } } 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 d7ba321ea9..8cc19fa0f5 100644 --- a/src/test/java/org/opensearch/security/auditlog/config/AuditConfigSerializeTest.java +++ b/src/test/java/org/opensearch/security/auditlog/config/AuditConfigSerializeTest.java @@ -60,33 +60,33 @@ public void testDefaultSerialize() throws IOException { final String json = objectMapper.writeValueAsString(audit); final XContentBuilder jsonBuilder = XContentFactory.jsonBuilder() - .startObject() - .field("enabled", true) - .startObject("audit") - .field("enable_rest", true) - .field("disabled_rest_categories", ImmutableList.of( "AUTHENTICATED", "GRANTED_PRIVILEGES")) - .field("enable_transport", true) - .field("disabled_transport_categories", ImmutableList.of( "AUTHENTICATED", "GRANTED_PRIVILEGES")) - .field("resolve_bulk_requests", false) - .field("log_request_body", true) - .field("resolve_indices", true) - .field("exclude_sensitive_headers", true) - .field("ignore_users", Collections.singletonList("kibanaserver")) - .field("ignore_requests", Collections.emptyList()) - .endObject() - .startObject("compliance") - .field("enabled", true) - .field("external_config", false) - .field("internal_config", false) - .field("read_metadata_only", false) - .field("read_watched_fields", Collections.emptyMap()) - .field("read_ignore_users", Collections.singletonList("kibanaserver")) - .field("write_metadata_only", false) - .field("write_log_diffs", false) - .field("write_watched_indices", Collections.emptyList()) - .field("write_ignore_users", Collections.singletonList("kibanaserver")) - .endObject() - .endObject(); + .startObject() + .field("enabled", true) + .startObject("audit") + .field("enable_rest", true) + .field("disabled_rest_categories", ImmutableList.of("AUTHENTICATED", "GRANTED_PRIVILEGES")) + .field("enable_transport", true) + .field("disabled_transport_categories", ImmutableList.of("AUTHENTICATED", "GRANTED_PRIVILEGES")) + .field("resolve_bulk_requests", false) + .field("log_request_body", true) + .field("resolve_indices", true) + .field("exclude_sensitive_headers", true) + .field("ignore_users", Collections.singletonList("kibanaserver")) + .field("ignore_requests", Collections.emptyList()) + .endObject() + .startObject("compliance") + .field("enabled", true) + .field("external_config", false) + .field("internal_config", false) + .field("read_metadata_only", false) + .field("read_watched_fields", Collections.emptyMap()) + .field("read_ignore_users", Collections.singletonList("kibanaserver")) + .field("write_metadata_only", false) + .field("write_log_diffs", false) + .field("write_watched_indices", Collections.emptyList()) + .field("write_ignore_users", Collections.singletonList("kibanaserver")) + .endObject() + .endObject(); assertTrue(compareJson(Strings.toString(jsonBuilder), json)); } @@ -121,33 +121,33 @@ public void testDefaultDeserialize() throws IOException { public void testDeserialize() throws IOException { // arrange final XContentBuilder jsonBuilder = XContentFactory.jsonBuilder() - .startObject() - .field("enabled", true) - .startObject("audit") - .field("enable_rest", true) - .field("disabled_rest_categories", Collections.singletonList("AUTHENTICATED")) - .field("enable_transport", true) - .field("disabled_transport_categories", Collections.singletonList("SSL_EXCEPTION")) - .field("resolve_bulk_requests", true) - .field("log_request_body", true) - .field("resolve_indices", true) - .field("exclude_sensitive_headers", true) - .field("ignore_users", Collections.singletonList("test-user-1")) - .field("ignore_requests", Collections.singletonList("test-request")) - .endObject() - .startObject("compliance") - .field("enabled", true) - .field("external_config", true) - .field("internal_config", true) - .field("read_metadata_only", true) - .field("read_watched_fields", Collections.singletonMap("test-read-watch-field", Collections.singleton("test-field-1"))) - .field("read_ignore_users", Collections.singletonList("test-user-2")) - .field("write_metadata_only", true) - .field("write_log_diffs", false) - .field("write_watched_indices", Collections.singletonList("test-write-watch-index")) - .field("write_ignore_users", Collections.singletonList("test-user-3")) - .endObject() - .endObject(); + .startObject() + .field("enabled", true) + .startObject("audit") + .field("enable_rest", true) + .field("disabled_rest_categories", Collections.singletonList("AUTHENTICATED")) + .field("enable_transport", true) + .field("disabled_transport_categories", Collections.singletonList("SSL_EXCEPTION")) + .field("resolve_bulk_requests", true) + .field("log_request_body", true) + .field("resolve_indices", true) + .field("exclude_sensitive_headers", true) + .field("ignore_users", Collections.singletonList("test-user-1")) + .field("ignore_requests", Collections.singletonList("test-request")) + .endObject() + .startObject("compliance") + .field("enabled", true) + .field("external_config", true) + .field("internal_config", true) + .field("read_metadata_only", true) + .field("read_watched_fields", Collections.singletonMap("test-read-watch-field", Collections.singleton("test-field-1"))) + .field("read_ignore_users", Collections.singletonList("test-user-2")) + .field("write_metadata_only", true) + .field("write_log_diffs", false) + .field("write_watched_indices", Collections.singletonList("test-write-watch-index")) + .field("write_ignore_users", Collections.singletonList("test-user-3")) + .endObject() + .endObject(); final String json = Strings.toString(jsonBuilder); // act @@ -168,48 +168,80 @@ public void testDeserialize() throws IOException { assertEquals(WildcardMatcher.from(Collections.singleton("test-user-1")), audit.getIgnoredAuditUsersMatcher()); assertEquals(WildcardMatcher.from(Collections.singleton("test-request")), audit.getIgnoredAuditRequestsMatcher()); assertTrue(configCompliance.shouldLogReadMetadataOnly()); - assertEquals(WildcardMatcher.from(Collections.singleton("test-user-2")), configCompliance.getIgnoredComplianceUsersForReadMatcher()); - assertEquals(Collections.singletonMap(WildcardMatcher.from("test-read-watch-field"), Collections.singleton("test-field-1")), configCompliance.getReadEnabledFields()); + assertEquals( + WildcardMatcher.from(Collections.singleton("test-user-2")), + configCompliance.getIgnoredComplianceUsersForReadMatcher() + ); + assertEquals( + Collections.singletonMap(WildcardMatcher.from("test-read-watch-field"), Collections.singleton("test-field-1")), + configCompliance.getReadEnabledFields() + ); assertTrue(configCompliance.shouldLogWriteMetadataOnly()); assertFalse(configCompliance.shouldLogDiffsForWrite()); - assertEquals(WildcardMatcher.from(Collections.singleton("test-user-3")), configCompliance.getIgnoredComplianceUsersForWriteMatcher()); + assertEquals( + WildcardMatcher.from(Collections.singleton("test-user-3")), + configCompliance.getIgnoredComplianceUsersForWriteMatcher() + ); assertEquals(WildcardMatcher.from("test-write-watch-index"), configCompliance.getWatchedWriteIndicesMatcher()); } @Test public void testSerialize() throws IOException { // arrange - final AuditConfig.Filter audit = new AuditConfig.Filter(true, true, true, true, true, true, ImmutableSet.of("ignore-user-1", "ignore-user-2"), ImmutableSet.of("ignore-request-1"), EnumSet.of(AuditCategory.FAILED_LOGIN, AuditCategory.GRANTED_PRIVILEGES), EnumSet.of(AUTHENTICATED)); - final ComplianceConfig compliance = new ComplianceConfig(true, true, true, true, Collections.singletonMap("test-read-watch-field-1", Collections.emptyList()), Collections.singleton("test-user-1"), true, false,Collections.singletonList("test-write-watch-index"), Collections.singleton("test-user-2"), Settings.EMPTY); + final AuditConfig.Filter audit = new AuditConfig.Filter( + true, + true, + true, + true, + true, + true, + ImmutableSet.of("ignore-user-1", "ignore-user-2"), + ImmutableSet.of("ignore-request-1"), + EnumSet.of(AuditCategory.FAILED_LOGIN, AuditCategory.GRANTED_PRIVILEGES), + EnumSet.of(AUTHENTICATED) + ); + final ComplianceConfig compliance = new ComplianceConfig( + true, + true, + true, + true, + Collections.singletonMap("test-read-watch-field-1", Collections.emptyList()), + Collections.singleton("test-user-1"), + true, + false, + Collections.singletonList("test-write-watch-index"), + Collections.singleton("test-user-2"), + Settings.EMPTY + ); final AuditConfig auditConfig = new AuditConfig(true, audit, compliance); final XContentBuilder jsonBuilder = XContentFactory.jsonBuilder() - .startObject() - .field("enabled", true) - .startObject("audit") - .field("enable_rest", true) - .field("disabled_rest_categories", ImmutableList.of("FAILED_LOGIN", "GRANTED_PRIVILEGES")) - .field("enable_transport", true) - .field("disabled_transport_categories", Collections.singletonList("AUTHENTICATED")) - .field("resolve_bulk_requests", true) - .field("log_request_body", true) - .field("resolve_indices", true) - .field("exclude_sensitive_headers", true) - .field("ignore_users", ImmutableList.of("ignore-user-1", "ignore-user-2")) - .field("ignore_requests", Collections.singletonList("ignore-request-1")) - .endObject() - .startObject("compliance") - .field("enabled", true) - .field("external_config", true) - .field("internal_config", true) - .field("read_metadata_only", true) - .field("read_watched_fields", Collections.singletonMap("test-read-watch-field-1", Collections.emptyList())) - .field("read_ignore_users", Collections.singletonList("test-user-1")) - .field("write_metadata_only", true) - .field("write_log_diffs", false) - .field("write_watched_indices", Collections.singletonList("test-write-watch-index")) - .field("write_ignore_users", Collections.singletonList("test-user-2")) - .endObject() - .endObject(); + .startObject() + .field("enabled", true) + .startObject("audit") + .field("enable_rest", true) + .field("disabled_rest_categories", ImmutableList.of("FAILED_LOGIN", "GRANTED_PRIVILEGES")) + .field("enable_transport", true) + .field("disabled_transport_categories", Collections.singletonList("AUTHENTICATED")) + .field("resolve_bulk_requests", true) + .field("log_request_body", true) + .field("resolve_indices", true) + .field("exclude_sensitive_headers", true) + .field("ignore_users", ImmutableList.of("ignore-user-1", "ignore-user-2")) + .field("ignore_requests", Collections.singletonList("ignore-request-1")) + .endObject() + .startObject("compliance") + .field("enabled", true) + .field("external_config", true) + .field("internal_config", true) + .field("read_metadata_only", true) + .field("read_watched_fields", Collections.singletonMap("test-read-watch-field-1", Collections.emptyList())) + .field("read_ignore_users", Collections.singletonList("test-user-1")) + .field("write_metadata_only", true) + .field("write_log_diffs", false) + .field("write_watched_indices", Collections.singletonList("test-write-watch-index")) + .field("write_ignore_users", Collections.singletonList("test-user-2")) + .endObject() + .endObject(); // act final String json = objectMapper.writeValueAsString(auditConfig); @@ -225,33 +257,33 @@ public void testNullSerialize() throws IOException { final ComplianceConfig compliance = ComplianceConfig.from(Collections.emptyMap(), Settings.EMPTY); final AuditConfig auditConfig = new AuditConfig(true, audit, compliance); final XContentBuilder jsonBuilder = XContentFactory.jsonBuilder() - .startObject() - .field("enabled", true) - .startObject("audit") - .field("enable_rest", true) - .field("disabled_rest_categories", ImmutableList.of("AUTHENTICATED", "GRANTED_PRIVILEGES")) - .field("enable_transport", true) - .field("disabled_transport_categories", ImmutableList.of("AUTHENTICATED", "GRANTED_PRIVILEGES")) - .field("resolve_bulk_requests", false) - .field("log_request_body", true) - .field("resolve_indices", true) - .field("exclude_sensitive_headers", true) - .field("ignore_users", ImmutableList.of("kibanaserver")) - .field("ignore_requests", Collections.emptyList()) - .endObject() - .startObject("compliance") - .field("enabled", true) - .field("external_config", false) - .field("internal_config", false) - .field("read_metadata_only", false) - .field("read_watched_fields", Collections.emptyMap()) - .field("read_ignore_users", Collections.singletonList("kibanaserver")) - .field("write_metadata_only", false) - .field("write_log_diffs", false) - .field("write_watched_indices", Collections.emptyList()) - .field("write_ignore_users", Collections.singletonList("kibanaserver")) - .endObject() - .endObject(); + .startObject() + .field("enabled", true) + .startObject("audit") + .field("enable_rest", true) + .field("disabled_rest_categories", ImmutableList.of("AUTHENTICATED", "GRANTED_PRIVILEGES")) + .field("enable_transport", true) + .field("disabled_transport_categories", ImmutableList.of("AUTHENTICATED", "GRANTED_PRIVILEGES")) + .field("resolve_bulk_requests", false) + .field("log_request_body", true) + .field("resolve_indices", true) + .field("exclude_sensitive_headers", true) + .field("ignore_users", ImmutableList.of("kibanaserver")) + .field("ignore_requests", Collections.emptyList()) + .endObject() + .startObject("compliance") + .field("enabled", true) + .field("external_config", false) + .field("internal_config", false) + .field("read_metadata_only", false) + .field("read_watched_fields", Collections.emptyMap()) + .field("read_ignore_users", Collections.singletonList("kibanaserver")) + .field("write_metadata_only", false) + .field("write_log_diffs", false) + .field("write_watched_indices", Collections.emptyList()) + .field("write_ignore_users", Collections.singletonList("kibanaserver")) + .endObject() + .endObject(); // act final String json = objectMapper.writeValueAsString(auditConfig); @@ -262,10 +294,7 @@ public void testNullSerialize() throws IOException { @Test public void testNullDeSerialize() throws IOException { // arrange - final String json = "{" + - "\"audit\":{}," + - "\"compliance\":{}" + - "}"; + final String json = "{" + "\"audit\":{}," + "\"compliance\":{}" + "}"; // act final AuditConfig auditConfig = objectMapper.readValue(json, AuditConfig.class); @@ -287,36 +316,38 @@ public void testNullDeSerialize() throws IOException { public void testCustomSettings() throws IOException { // arrange final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_CONFIG_INDEX_NAME, "test-security-index") - .put(ConfigConstants.SECURITY_AUDIT_TYPE_DEFAULT, "internal_opensearch") - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_OPENSEARCH_INDEX, - "test-auditlog-index") - .build(); + .put(ConfigConstants.SECURITY_CONFIG_INDEX_NAME, "test-security-index") + .put(ConfigConstants.SECURITY_AUDIT_TYPE_DEFAULT, "internal_opensearch") + .put( + ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_OPENSEARCH_INDEX, + "test-auditlog-index" + ) + .build(); final ObjectMapper customObjectMapper = new ObjectMapper(); InjectableValues.Std iv = new InjectableValues.Std(); iv.addValue(Settings.class, settings); customObjectMapper.setInjectableValues(iv); final XContentBuilder jsonBuilder = XContentFactory.jsonBuilder() - .startObject() - .field("enabled", true) - .startObject("audit") - .field("enable_rest", true) - .field("enable_transport", true) - .field("resolve_bulk_requests", true) - .field("log_request_body", true) - .field("resolve_indices", true) - .field("exclude_sensitive_headers", true) - .endObject() - .startObject("compliance") - .field("enabled", true) - .field("external_config", true) - .field("internal_config", true) - .field("read_metadata_only", true) - .field("write_metadata_only", true) - .field("write_log_diffs", false) - .endObject() - .endObject(); + .startObject() + .field("enabled", true) + .startObject("audit") + .field("enable_rest", true) + .field("enable_transport", true) + .field("resolve_bulk_requests", true) + .field("log_request_body", true) + .field("resolve_indices", true) + .field("exclude_sensitive_headers", true) + .endObject() + .startObject("compliance") + .field("enabled", true) + .field("external_config", true) + .field("internal_config", true) + .field("read_metadata_only", true) + .field("write_metadata_only", true) + .field("write_log_diffs", false) + .endObject() + .endObject(); final String json = Strings.toString(jsonBuilder); // act diff --git a/src/test/java/org/opensearch/security/auditlog/config/ThreadPoolConfigTest.java b/src/test/java/org/opensearch/security/auditlog/config/ThreadPoolConfigTest.java index 914163a7f3..83c5e9ae2a 100644 --- a/src/test/java/org/opensearch/security/auditlog/config/ThreadPoolConfigTest.java +++ b/src/test/java/org/opensearch/security/auditlog/config/ThreadPoolConfigTest.java @@ -74,9 +74,9 @@ public void testConfig() { public void testGenerationFromSettings() { // arrange Settings settings = Settings.builder() - .put("plugins.security.audit.threadpool.size", "8") - .put("plugins.security.audit.threadpool.max_queue_len", "50") - .build(); + .put("plugins.security.audit.threadpool.size", "8") + .put("plugins.security.audit.threadpool.max_queue_len", "50") + .build(); // assert ThreadPoolConfig config = ThreadPoolConfig.getConfig(settings); diff --git a/src/test/java/org/opensearch/security/auditlog/helper/ErroneousHttpHandler.java b/src/test/java/org/opensearch/security/auditlog/helper/ErroneousHttpHandler.java index 120232825b..4ba106ddd9 100644 --- a/src/test/java/org/opensearch/security/auditlog/helper/ErroneousHttpHandler.java +++ b/src/test/java/org/opensearch/security/auditlog/helper/ErroneousHttpHandler.java @@ -17,8 +17,8 @@ import org.apache.hc.core5.http.protocol.HttpContext; public class ErroneousHttpHandler implements HttpRequestHandler { - @Override - public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) { - response.setCode(404); - } + @Override + public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) { + response.setCode(404); + } } diff --git a/src/test/java/org/opensearch/security/auditlog/helper/FailingSink.java b/src/test/java/org/opensearch/security/auditlog/helper/FailingSink.java index 8557314ab1..0c915810e1 100644 --- a/src/test/java/org/opensearch/security/auditlog/helper/FailingSink.java +++ b/src/test/java/org/opensearch/security/auditlog/helper/FailingSink.java @@ -21,10 +21,10 @@ public FailingSink(String name, Settings settings, String sinkPrefix, AuditLogSi super(name, settings, null, fallbackSink); } - @Override - protected boolean doStore(AuditMessage msg) { - return false; - } + @Override + protected boolean doStore(AuditMessage msg) { + return false; + } @Override public boolean isHandlingBackpressure() { diff --git a/src/test/java/org/opensearch/security/auditlog/helper/LoggingSink.java b/src/test/java/org/opensearch/security/auditlog/helper/LoggingSink.java index 63b4e71958..8125acd8c4 100644 --- a/src/test/java/org/opensearch/security/auditlog/helper/LoggingSink.java +++ b/src/test/java/org/opensearch/security/auditlog/helper/LoggingSink.java @@ -20,16 +20,15 @@ public class LoggingSink extends AuditLogSink { - public List messages = new ArrayList(100); + public List messages = new ArrayList(100); public StringBuffer sb = new StringBuffer(); public LoggingSink(String name, Settings settings, String settingsPrefix, AuditLogSink fallbackSink) { super(name, settings, null, fallbackSink); } - public boolean doStore(AuditMessage msg) { - sb.append(msg.toPrettyString()+System.lineSeparator()); + sb.append(msg.toPrettyString() + System.lineSeparator()); messages.add(msg); return true; } 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 c0c24107ef..7e67fc374c 100644 --- a/src/test/java/org/opensearch/security/auditlog/helper/MockAuditMessageFactory.java +++ b/src/test/java/org/opensearch/security/auditlog/helper/MockAuditMessageFactory.java @@ -26,14 +26,14 @@ public class MockAuditMessageFactory { - public static AuditMessage validAuditMessage() { - return validAuditMessage(AuditCategory.FAILED_LOGIN); - } + public static AuditMessage validAuditMessage() { + return validAuditMessage(AuditCategory.FAILED_LOGIN); + } - public static AuditMessage validAuditMessage(AuditCategory category) { + public static AuditMessage validAuditMessage(AuditCategory category) { - ClusterService cs = mock(ClusterService.class); - DiscoveryNode dn = mock(DiscoveryNode.class); + ClusterService cs = mock(ClusterService.class); + DiscoveryNode dn = mock(DiscoveryNode.class); when(dn.getHostAddress()).thenReturn("hostaddress"); when(dn.getId()).thenReturn("hostaddress"); @@ -41,13 +41,13 @@ public static AuditMessage validAuditMessage(AuditCategory category) { when(cs.localNode()).thenReturn(dn); when(cs.getClusterName()).thenReturn(new ClusterName("testcluster")); - TransportAddress ta = new TransportAddress(new InetSocketAddress("8.8.8.8",80)); + TransportAddress ta = new TransportAddress(new InetSocketAddress("8.8.8.8", 80)); - AuditMessage msg = new AuditMessage(category, cs, Origin.TRANSPORT, Origin.TRANSPORT); - msg.addEffectiveUser("John Doe"); - msg.addRemoteAddress(ta); - msg.addRequestType("IndexRequest"); - return msg; - } + AuditMessage msg = new AuditMessage(category, cs, Origin.TRANSPORT, Origin.TRANSPORT); + msg.addEffectiveUser("John Doe"); + msg.addRemoteAddress(ta); + msg.addRequestType("IndexRequest"); + return msg; + } } diff --git a/src/test/java/org/opensearch/security/auditlog/helper/MockRestRequest.java b/src/test/java/org/opensearch/security/auditlog/helper/MockRestRequest.java index 6328c94352..d2b15750ff 100644 --- a/src/test/java/org/opensearch/security/auditlog/helper/MockRestRequest.java +++ b/src/test/java/org/opensearch/security/auditlog/helper/MockRestRequest.java @@ -20,8 +20,8 @@ public class MockRestRequest extends RestRequest { public MockRestRequest() { - //NamedXContentRegistry xContentRegistry, Map params, String path, - //Map> headers, HttpRequest httpRequest, HttpChannel httpChannel + // NamedXContentRegistry xContentRegistry, Map params, String path, + // Map> headers, HttpRequest httpRequest, HttpChannel httpChannel super(NamedXContentRegistry.EMPTY, Collections.emptyMap(), "", Collections.emptyMap(), null, null); } diff --git a/src/test/java/org/opensearch/security/auditlog/helper/MyOwnAuditLog.java b/src/test/java/org/opensearch/security/auditlog/helper/MyOwnAuditLog.java index d1138c7c9b..8df27f0d1d 100644 --- a/src/test/java/org/opensearch/security/auditlog/helper/MyOwnAuditLog.java +++ b/src/test/java/org/opensearch/security/auditlog/helper/MyOwnAuditLog.java @@ -23,19 +23,26 @@ public class MyOwnAuditLog extends AuditLogSink { - public MyOwnAuditLog(final String name, final Settings settings, final String settingsPrefix, final Path configPath, final ThreadPool threadPool, - final IndexNameExpressionResolver resolver, final ClusterService clusterService, AuditLogSink fallbackSink) { + public MyOwnAuditLog( + final String name, + final Settings settings, + final String settingsPrefix, + final Path configPath, + final ThreadPool threadPool, + final IndexNameExpressionResolver resolver, + final ClusterService clusterService, + AuditLogSink fallbackSink + ) { super(name, settings, settingsPrefix, fallbackSink); } @Override - public void close() throws IOException { - - } + public void close() throws IOException { + } - public boolean doStore(AuditMessage msg) { - return true; - } + public boolean doStore(AuditMessage msg) { + return true; + } } diff --git a/src/test/java/org/opensearch/security/auditlog/helper/RetrySink.java b/src/test/java/org/opensearch/security/auditlog/helper/RetrySink.java index f26188bed7..0d41111f25 100644 --- a/src/test/java/org/opensearch/security/auditlog/helper/RetrySink.java +++ b/src/test/java/org/opensearch/security/auditlog/helper/RetrySink.java @@ -28,8 +28,8 @@ public RetrySink(String name, Settings settings, String sinkPrefix, AuditLogSink @Override protected synchronized boolean doStore(AuditMessage msg) { - if(failCount++ < 5) { - log.debug("Fail "+failCount); + if (failCount++ < 5) { + log.debug("Fail " + failCount); return false; } log.debug("doStore ok"); diff --git a/src/test/java/org/opensearch/security/auditlog/helper/SlowSink.java b/src/test/java/org/opensearch/security/auditlog/helper/SlowSink.java index f291b76cda..376c29cf80 100644 --- a/src/test/java/org/opensearch/security/auditlog/helper/SlowSink.java +++ b/src/test/java/org/opensearch/security/auditlog/helper/SlowSink.java @@ -21,13 +21,12 @@ public SlowSink(String name, Settings settings, Settings sinkSetting, AuditLogSi super(name, settings, null, fallbackSink); } - public boolean doStore(AuditMessage msg) { - try { - Thread.sleep(3000); - } catch (InterruptedException e) { - e.printStackTrace(); - } + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + e.printStackTrace(); + } return true; } diff --git a/src/test/java/org/opensearch/security/auditlog/helper/TestHttpHandler.java b/src/test/java/org/opensearch/security/auditlog/helper/TestHttpHandler.java index d888949e46..d4f68e8291 100644 --- a/src/test/java/org/opensearch/security/auditlog/helper/TestHttpHandler.java +++ b/src/test/java/org/opensearch/security/auditlog/helper/TestHttpHandler.java @@ -23,22 +23,22 @@ import org.apache.hc.core5.http.protocol.HttpContext; public class TestHttpHandler implements HttpRequestHandler { - public String method; - public String uri; - public String body; + public String method; + public String uri; + public String body; - @Override - public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) throws HttpException, IOException { - this.method = request.getMethod(); - this.uri = request.getRequestUri(); + @Override + public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) throws HttpException, IOException { + this.method = request.getMethod(); + this.uri = request.getRequestUri(); - HttpEntity entity = request.getEntity(); - body = EntityUtils.toString(entity, StandardCharsets.UTF_8); - } + HttpEntity entity = request.getEntity(); + body = EntityUtils.toString(entity, StandardCharsets.UTF_8); + } - public void reset() { - this.body = null; - this.uri = null; - this.method = null; - } + public void reset() { + this.body = null; + this.uri = null; + this.method = null; + } } 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 abd8260fa7..18670f42cf 100644 --- a/src/test/java/org/opensearch/security/auditlog/impl/AuditCategoryTest.java +++ b/src/test/java/org/opensearch/security/auditlog/impl/AuditCategoryTest.java @@ -42,19 +42,32 @@ public AuditCategoryParseTest(List input, EnumSet expecte @Parameterized.Parameters public static Collection data() { - return Arrays.asList(new Object[][]{ - {Arrays.asList(), EnumSet.noneOf(AuditCategory.class)}, - {Arrays.asList("BAD_HEADERS"), EnumSet.of(BAD_HEADERS)}, - {Arrays.asList("bad_headers"), EnumSet.of(BAD_HEADERS)}, - {Arrays.asList("bAd_HeAdErS"), EnumSet.of(BAD_HEADERS)}, - {Arrays.asList("bAd_HeAdErS"), EnumSet.of(BAD_HEADERS)}, - {Arrays.asList("BAD_HEADERS", "AUTHENTICATED"), EnumSet.of(BAD_HEADERS, AUTHENTICATED)}, - {Arrays.asList("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" - ), EnumSet.allOf(AuditCategory.class)}, - }); + return Arrays.asList( + new Object[][] { + { Arrays.asList(), EnumSet.noneOf(AuditCategory.class) }, + { Arrays.asList("BAD_HEADERS"), EnumSet.of(BAD_HEADERS) }, + { Arrays.asList("bad_headers"), EnumSet.of(BAD_HEADERS) }, + { Arrays.asList("bAd_HeAdErS"), EnumSet.of(BAD_HEADERS) }, + { Arrays.asList("bAd_HeAdErS"), EnumSet.of(BAD_HEADERS) }, + { Arrays.asList("BAD_HEADERS", "AUTHENTICATED"), EnumSet.of(BAD_HEADERS, AUTHENTICATED) }, + { + Arrays.asList( + "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" + ), + EnumSet.allOf(AuditCategory.class) }, } + ); } @Test @@ -75,10 +88,9 @@ public AuditCategoryExceptionTest(List input) { @Parameterized.Parameters public static Collection data() { - return Arrays.asList(new Object[][]{ - {Arrays.asList("BAD_INPUT")}, - {Arrays.asList("BAD_HEADERS", "bad_category", "AUTHENTICATED")}, - }); + return Arrays.asList( + new Object[][] { { Arrays.asList("BAD_INPUT") }, { Arrays.asList("BAD_HEADERS", "bad_category", "AUTHENTICATED") }, } + ); } @Test(expected = IllegalArgumentException.class) 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 da408f1000..6bfaf32816 100644 --- a/src/test/java/org/opensearch/security/auditlog/impl/AuditMessageTest.java +++ b/src/test/java/org/opensearch/security/auditlog/impl/AuditMessageTest.java @@ -38,17 +38,25 @@ public class AuditMessageTest { private static final Map> TEST_REST_HEADERS = ImmutableMap.of( - "authorization", ImmutableList.of("test-1"), - "Authorization", ImmutableList.of("test-2"), - "AuThOrIzAtIoN", ImmutableList.of("test-3"), - "test-header", ImmutableList.of("test-4") + "authorization", + ImmutableList.of("test-1"), + "Authorization", + ImmutableList.of("test-2"), + "AuThOrIzAtIoN", + ImmutableList.of("test-3"), + "test-header", + ImmutableList.of("test-4") ); private static final Map TEST_TRANSPORT_HEADERS = ImmutableMap.of( - "authorization", "test-1", - "Authorization", "test-2", - "AuThOrIzAtIoN","test-3", - "test-header", "test-4" + "authorization", + "test-1", + "Authorization", + "test-2", + "AuThOrIzAtIoN", + "test-3", + "test-header", + "test-4" ); private AuditMessage message; @@ -58,10 +66,7 @@ public void setUp() { final ClusterService clusterServiceMock = mock(ClusterService.class); when(clusterServiceMock.localNode()).thenReturn(mock(DiscoveryNode.class)); when(clusterServiceMock.getClusterName()).thenReturn(mock(ClusterName.class)); - message = new AuditMessage(AuditCategory.AUTHENTICATED, - clusterServiceMock, - AuditLog.Origin.REST, - AuditLog.Origin.REST); + message = new AuditMessage(AuditCategory.AUTHENTICATED, clusterServiceMock, AuditLog.Origin.REST, AuditLog.Origin.REST); } @Test @@ -131,7 +136,7 @@ public void testBCryptHashIsRedacted() { assertEquals("Diff is __HASH__", message.getAsMap().get(AuditMessage.COMPLIANCE_DIFF_CONTENT)); // test tuple redaction - final ByteBuffer[] byteBuffers = new ByteBuffer[]{ ByteBuffer.wrap(("Hash in tuple is " + hash1).getBytes()) }; + final ByteBuffer[] byteBuffers = new ByteBuffer[] { ByteBuffer.wrap(("Hash in tuple is " + hash1).getBytes()) }; BytesReference ref = BytesReference.fromByteBuffers(byteBuffers); message.addSecurityConfigTupleToRequestBody(new Tuple<>(XContentType.JSON, ref), internalUsersDocId); assertEquals("Hash in tuple is __HASH__", message.getAsMap().get(AuditMessage.REQUEST_BODY)); 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 e72b85694f..cd4ced3523 100644 --- a/src/test/java/org/opensearch/security/auditlog/impl/AuditlogTest.java +++ b/src/test/java/org/opensearch/security/auditlog/impl/AuditlogTest.java @@ -49,9 +49,9 @@ public void setup() { @Test public void testClusterHealthRequest() { Settings settings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .build(); AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); TestAuditlogImpl.clear(); al.logGrantedPrivileges("indices:data/read/search", new ClusterHealthRequest(), null); @@ -62,13 +62,13 @@ public void testClusterHealthRequest() { public void testSearchRequest() { SearchRequest sr = new SearchRequest(); - sr.indices("index1","logstash*"); + sr.indices("index1", "logstash*"); Settings settings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .build(); - AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .build(); + AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); TestAuditlogImpl.clear(); al.logGrantedPrivileges("indices:data/read/search", sr, null); Assert.assertEquals(1, TestAuditlogImpl.messages.size()); @@ -78,12 +78,12 @@ public void testSearchRequest() { public void testSslException() { Settings settings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .build(); - AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .build(); + AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); TestAuditlogImpl.clear(); al.logSSLException(null, new Exception("test rest")); al.logSSLException(null, new Exception("test rest"), null, null); @@ -97,14 +97,14 @@ public void testRetry() { RetrySink.init(); Settings settings = Settings.builder() - .put("plugins.security.audit.type", RetrySink.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .put(ConfigConstants.SECURITY_AUDIT_RETRY_COUNT, 10) - .put(ConfigConstants.SECURITY_AUDIT_RETRY_DELAY_MS, 500) - .build(); - AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); + .put("plugins.security.audit.type", RetrySink.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .put(ConfigConstants.SECURITY_AUDIT_RETRY_COUNT, 10) + .put(ConfigConstants.SECURITY_AUDIT_RETRY_DELAY_MS, 500) + .build(); + AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); al.logSSLException(null, new Exception("test retry")); Assert.assertNotNull(RetrySink.getMsg()); Assert.assertTrue(RetrySink.getMsg().toJson().contains("test retry")); @@ -116,36 +116,32 @@ public void testNoRetry() { RetrySink.init(); Settings settings = Settings.builder() - .put("plugins.security.audit.type", RetrySink.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .put(ConfigConstants.SECURITY_AUDIT_RETRY_COUNT, 0) - .put(ConfigConstants.SECURITY_AUDIT_RETRY_DELAY_MS, 500) - .build(); - AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); + .put("plugins.security.audit.type", RetrySink.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .put(ConfigConstants.SECURITY_AUDIT_RETRY_COUNT, 0) + .put(ConfigConstants.SECURITY_AUDIT_RETRY_DELAY_MS, 500) + .build(); + AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); al.logSSLException(null, new Exception("test retry")); Assert.assertNull(RetrySink.getMsg()); } @Test public void testRestFilterEnabledCheck() { - final Settings settings = Settings.builder() - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) - .build(); - final AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); - for (AuditCategory category: AuditCategory.values()) { + final Settings settings = Settings.builder().put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false).build(); + final AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); + for (AuditCategory category : AuditCategory.values()) { Assert.assertFalse(al.checkRestFilter(category, "user", mock(RestRequest.class))); } } @Test public void testTransportFilterEnabledCheck() { - final Settings settings = Settings.builder() - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) - .build(); - final AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); - for (AuditCategory category: AuditCategory.values()) { + final Settings settings = Settings.builder().put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false).build(); + final AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); + for (AuditCategory category : AuditCategory.values()) { Assert.assertFalse(al.checkTransportFilter(category, "action", "user", mock(TransportRequest.class))); } } @@ -153,11 +149,11 @@ public void testTransportFilterEnabledCheck() { @Test public void testTransportFilterMonitorActionsCheck() { final Settings settings = Settings.builder() - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .build(); - final AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); - for (AuditCategory category: AuditCategory.values()) { + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .build(); + final AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); + for (AuditCategory category : AuditCategory.values()) { Assert.assertTrue(al.checkTransportFilter(category, "cluster:monitor/any", "user", mock(TransportRequest.class))); Assert.assertTrue(al.checkTransportFilter(category, "indices:data/any", "user", mock(TransportRequest.class))); Assert.assertFalse(al.checkTransportFilter(category, "internal:any", "user", mock(TransportRequest.class))); diff --git a/src/test/java/org/opensearch/security/auditlog/impl/DelegateTest.java b/src/test/java/org/opensearch/security/auditlog/impl/DelegateTest.java index a88c73e3bf..fa176a2011 100644 --- a/src/test/java/org/opensearch/security/auditlog/impl/DelegateTest.java +++ b/src/test/java/org/opensearch/security/auditlog/impl/DelegateTest.java @@ -22,28 +22,28 @@ import org.opensearch.security.auditlog.sink.InternalOpenSearchSink; public class DelegateTest { - @Test - public void auditLogTypeTest() throws Exception{ - testAuditType("DeBUg", DebugSink.class); - testAuditType("intERnal_OpenSearch", InternalOpenSearchSink.class); - testAuditType("EXTERnal_OpenSearch", ExternalOpenSearchSink.class); - testAuditType("org.opensearch.security.auditlog.sink.MyOwnAuditLog", MyOwnAuditLog.class); - testAuditType("org.opensearch.security.auditlog.sink.MyOwnAuditLog", null); - testAuditType("idonotexist", null); - } + @Test + public void auditLogTypeTest() throws Exception { + testAuditType("DeBUg", DebugSink.class); + testAuditType("intERnal_OpenSearch", InternalOpenSearchSink.class); + testAuditType("EXTERnal_OpenSearch", ExternalOpenSearchSink.class); + testAuditType("org.opensearch.security.auditlog.sink.MyOwnAuditLog", MyOwnAuditLog.class); + testAuditType("org.opensearch.security.auditlog.sink.MyOwnAuditLog", null); + testAuditType("idonotexist", null); + } - private void testAuditType(String type, Class expectedClass) throws Exception { - Builder settingsBuilder = Settings.builder(); - settingsBuilder.put("plugins.security.audit.type", type); - settingsBuilder.put("path.home", "."); - AuditLogImpl auditLog = new AuditLogImpl(settingsBuilder.build(), null, null, null, null, null); - auditLog.close(); -// if (expectedClass != null) { -// Assert.assertNotNull("delegate is null for type: "+type,auditLog.delegate); -// Assert.assertEquals(expectedClass, auditLog.delegate.getClass()); -// } else { -// Assert.assertNull(auditLog.delegate); -// } + private void testAuditType(String type, Class expectedClass) throws Exception { + Builder settingsBuilder = Settings.builder(); + settingsBuilder.put("plugins.security.audit.type", type); + settingsBuilder.put("path.home", "."); + AuditLogImpl auditLog = new AuditLogImpl(settingsBuilder.build(), null, null, null, null, null); + auditLog.close(); + // if (expectedClass != null) { + // Assert.assertNotNull("delegate is null for type: "+type,auditLog.delegate); + // Assert.assertEquals(expectedClass, auditLog.delegate.getClass()); + // } else { + // Assert.assertNull(auditLog.delegate); + // } - } + } } 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 db7d3da0fb..2a37749fbe 100644 --- a/src/test/java/org/opensearch/security/auditlog/impl/DisabledCategoriesTest.java +++ b/src/test/java/org/opensearch/security/auditlog/impl/DisabledCategoriesTest.java @@ -45,8 +45,8 @@ public class DisabledCategoriesTest { ClusterService cs = mock(ClusterService.class); DiscoveryNode dn = mock(DiscoveryNode.class); - @Rule - public ExpectedException thrown = ExpectedException.none(); + @Rule + public ExpectedException thrown = ExpectedException.none(); @Before public void setup() { @@ -58,195 +58,220 @@ public void setup() { TestAuditlogImpl.clear(); } - @Test - public void invalidRestCategoryConfigurationTest() { - thrown.expect(IllegalArgumentException.class); + @Test + public void invalidRestCategoryConfigurationTest() { + thrown.expect(IllegalArgumentException.class); - Builder settingsBuilder = Settings.builder(); - settingsBuilder.put("plugins.security.audit.type", TestAuditlogImpl.class.getName()); + Builder settingsBuilder = Settings.builder(); + settingsBuilder.put("plugins.security.audit.type", TestAuditlogImpl.class.getName()); settingsBuilder.put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "nonexistent"); - AuditTestUtils.createAuditLog(settingsBuilder.build(), null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); - } - - @Test - public void invalidTransportCategoryConfigurationTest() { - thrown.expect(IllegalArgumentException.class); - - Builder settingsBuilder = Settings.builder(); - settingsBuilder.put("plugins.security.audit.type", TestAuditlogImpl.class.getName()); - settingsBuilder.put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "nonexistent"); - AuditTestUtils.createAuditLog(settingsBuilder.build(), null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); - } - - @Test - public void invalidConfigurationTest() { - Builder settingsBuilder = Settings.builder(); - settingsBuilder.put("plugins.security.audit.type", "debug"); - settingsBuilder.put("plugins.security.audit.config.disabled_categories", "nonexistant, bad_headers"); - AbstractAuditLog auditLog = AuditTestUtils.createAuditLog(settingsBuilder.build(), null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); - logAll(auditLog); - String result = TestAuditlogImpl.sb.toString(); - Assert.assertFalse(categoriesPresentInLog(result, AuditCategory.BAD_HEADERS)); - } - - @Test - public void enableAllCategoryTest() throws Exception { - final Builder settingsBuilder = Settings.builder(); - - settingsBuilder.put("plugins.security.audit.type", TestAuditlogImpl.class.getName()); - settingsBuilder.put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE"); + AuditTestUtils.createAuditLog(settingsBuilder.build(), null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); + } + + @Test + public void invalidTransportCategoryConfigurationTest() { + thrown.expect(IllegalArgumentException.class); + + Builder settingsBuilder = Settings.builder(); + settingsBuilder.put("plugins.security.audit.type", TestAuditlogImpl.class.getName()); + settingsBuilder.put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "nonexistent"); + AuditTestUtils.createAuditLog(settingsBuilder.build(), null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); + } + + @Test + public void invalidConfigurationTest() { + Builder settingsBuilder = Settings.builder(); + settingsBuilder.put("plugins.security.audit.type", "debug"); + settingsBuilder.put("plugins.security.audit.config.disabled_categories", "nonexistant, bad_headers"); + AbstractAuditLog auditLog = AuditTestUtils.createAuditLog( + settingsBuilder.build(), + null, + null, + AbstractSecurityUnitTest.MOCK_POOL, + null, + cs + ); + logAll(auditLog); + String result = TestAuditlogImpl.sb.toString(); + Assert.assertFalse(categoriesPresentInLog(result, AuditCategory.BAD_HEADERS)); + } + + @Test + public void enableAllCategoryTest() throws Exception { + final Builder settingsBuilder = Settings.builder(); + + settingsBuilder.put("plugins.security.audit.type", TestAuditlogImpl.class.getName()); + settingsBuilder.put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE"); settingsBuilder.put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE"); - // we use the debug output, no OpenSearch client is needed. Also, we - // do not need to close. - AbstractAuditLog auditLog = AuditTestUtils.createAuditLog(settingsBuilder.build(), null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); - logAll(auditLog); - - // we're using the ExecutorService in AuditLogImpl, so we need to wait - // until all tasks are finished before we can check the result - auditLog.close(); - - String result = TestAuditlogImpl.sb.toString(); - - Assert.assertTrue(AuditCategory.values()+"#"+result, categoriesPresentInLog(result, filterComplianceCategories(AuditCategory.values()))); - - Assert.assertThat(result, containsString("testuser.rest.succeededlogin")); - Assert.assertThat(result, containsString("testuser.rest.failedlogin")); - Assert.assertThat(result, containsString("privilege.missing")); - Assert.assertThat(result, containsString("action.indexattempt")); - Assert.assertThat(result, containsString("action.transport.ssl")); - Assert.assertThat(result, containsString("action.success")); - Assert.assertThat(result, containsString("Empty")); - } - - @Test - public void disableSingleCategoryTest() throws Exception { - for (AuditCategory category : AuditCategory.values()) { - TestAuditlogImpl.clear(); - checkCategoriesDisabled(category); - } - } - - @Test - public void disableAllCategoryTest() throws Exception{ - checkCategoriesDisabled(AuditCategory.values()); - } - - @Test - public void disableSomeCategoryTest() throws Exception{ - checkCategoriesDisabled(AuditCategory.AUTHENTICATED, AuditCategory.BAD_HEADERS, AuditCategory.FAILED_LOGIN); - } - - /*@After - public void restoreOut() { - System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); - }*/ - - protected void checkCategoriesDisabled(AuditCategory... disabledCategories) throws Exception { - - List categoryNames = new LinkedList<>(); - for (AuditCategory category : disabledCategories) { - categoryNames.add(category.name().toLowerCase()); - } - String disabledCategoriesString = Joiner.on(",").join(categoryNames); - - Builder settingsBuilder = Settings.builder(); - settingsBuilder.put("plugins.security.audit.type", TestAuditlogImpl.class.getName()); - settingsBuilder.put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, disabledCategoriesString); - settingsBuilder.put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, disabledCategoriesString); + // we use the debug output, no OpenSearch client is needed. Also, we + // do not need to close. + AbstractAuditLog auditLog = AuditTestUtils.createAuditLog( + settingsBuilder.build(), + null, + null, + AbstractSecurityUnitTest.MOCK_POOL, + null, + cs + ); + logAll(auditLog); + + // we're using the ExecutorService in AuditLogImpl, so we need to wait + // until all tasks are finished before we can check the result + auditLog.close(); + + String result = TestAuditlogImpl.sb.toString(); + + Assert.assertTrue( + AuditCategory.values() + "#" + result, + categoriesPresentInLog(result, filterComplianceCategories(AuditCategory.values())) + ); + + Assert.assertThat(result, containsString("testuser.rest.succeededlogin")); + Assert.assertThat(result, containsString("testuser.rest.failedlogin")); + Assert.assertThat(result, containsString("privilege.missing")); + Assert.assertThat(result, containsString("action.indexattempt")); + Assert.assertThat(result, containsString("action.transport.ssl")); + Assert.assertThat(result, containsString("action.success")); + Assert.assertThat(result, containsString("Empty")); + } + + @Test + public void disableSingleCategoryTest() throws Exception { + for (AuditCategory category : AuditCategory.values()) { + TestAuditlogImpl.clear(); + checkCategoriesDisabled(category); + } + } + + @Test + public void disableAllCategoryTest() throws Exception { + checkCategoriesDisabled(AuditCategory.values()); + } + @Test + public void disableSomeCategoryTest() throws Exception { + checkCategoriesDisabled(AuditCategory.AUTHENTICATED, AuditCategory.BAD_HEADERS, AuditCategory.FAILED_LOGIN); + } - // we use the debug output, no OpenSearch client is needed. Also, we - // do not need to close. - AbstractAuditLog auditLog = AuditTestUtils.createAuditLog(settingsBuilder.build(), null, null, AbstractSecurityUnitTest.MOCK_POOL, null, cs); - logAll(auditLog); + /*@After + public void restoreOut() { + System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); + }*/ - auditLog.close(); + protected void checkCategoriesDisabled(AuditCategory... disabledCategories) throws Exception { - String result = TestAuditlogImpl.sb.toString(); + List categoryNames = new LinkedList<>(); + for (AuditCategory category : disabledCategories) { + categoryNames.add(category.name().toLowerCase()); + } + String disabledCategoriesString = Joiner.on(",").join(categoryNames); - List allButDisablesCategories = new LinkedList<>(Arrays.asList(AuditCategory.values())); - allButDisablesCategories.removeAll(Arrays.asList(disabledCategories)); + Builder settingsBuilder = Settings.builder(); + settingsBuilder.put("plugins.security.audit.type", TestAuditlogImpl.class.getName()); + settingsBuilder.put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, disabledCategoriesString); + settingsBuilder.put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, disabledCategoriesString); - System.out.println(result+"###"+disabledCategoriesString); - Assert.assertFalse(categoriesPresentInLog(result, disabledCategories)); - Assert.assertTrue(categoriesPresentInLog(result, filterComplianceCategories(allButDisablesCategories.toArray(new AuditCategory[] {})))); - } + // we use the debug output, no OpenSearch client is needed. Also, we + // do not need to close. + AbstractAuditLog auditLog = AuditTestUtils.createAuditLog( + settingsBuilder.build(), + null, + null, + AbstractSecurityUnitTest.MOCK_POOL, + null, + cs + ); + logAll(auditLog); + + auditLog.close(); + + String result = TestAuditlogImpl.sb.toString(); + + List allButDisablesCategories = new LinkedList<>(Arrays.asList(AuditCategory.values())); + allButDisablesCategories.removeAll(Arrays.asList(disabledCategories)); + + System.out.println(result + "###" + disabledCategoriesString); + Assert.assertFalse(categoriesPresentInLog(result, disabledCategories)); + Assert.assertTrue( + categoriesPresentInLog(result, filterComplianceCategories(allButDisablesCategories.toArray(new AuditCategory[] {}))) + ); + } - protected boolean categoriesPresentInLog(String result, AuditCategory... categories) { - // since we're logging a JSON structure, whitespaces between keys and - // values must not matter - result = result.replaceAll(" ", ""); - for (AuditCategory category : categories) { - if(!result.contains("\""+AuditMessage.CATEGORY+"\":\""+category.name()+"\"")) { - System.out.println("MISSING: "+category.name()); - return false; - } - } - return true; - } + protected boolean categoriesPresentInLog(String result, AuditCategory... categories) { + // since we're logging a JSON structure, whitespaces between keys and + // values must not matter + result = result.replaceAll(" ", ""); + for (AuditCategory category : categories) { + if (!result.contains("\"" + AuditMessage.CATEGORY + "\":\"" + category.name() + "\"")) { + System.out.println("MISSING: " + category.name()); + return false; + } + } + return true; + } - protected void logAll(AuditLog auditLog) { - logRestFailedLogin(auditLog); - logRestBadHeaders(auditLog); - logRestSSLException(auditLog); - logRestSucceededLogin(auditLog); + protected void logAll(AuditLog auditLog) { + logRestFailedLogin(auditLog); + logRestBadHeaders(auditLog); + logRestSSLException(auditLog); + logRestSucceededLogin(auditLog); - logMissingPrivileges(auditLog); - logSecurityIndexAttempt(auditLog); - logAuthenticatedRequest(auditLog); + logMissingPrivileges(auditLog); + logSecurityIndexAttempt(auditLog); + logAuthenticatedRequest(auditLog); - logTransportSSLException(auditLog); - logTransportBadHeaders(auditLog); + logTransportSSLException(auditLog); + logTransportBadHeaders(auditLog); - logIndexEvent(auditLog); + logIndexEvent(auditLog); } - protected void logRestSucceededLogin(AuditLog auditLog) { - auditLog.logSucceededLogin("testuser.rest.succeededlogin", false, "testuser.rest.succeededlogin", new MockRestRequest()); - } + protected void logRestSucceededLogin(AuditLog auditLog) { + auditLog.logSucceededLogin("testuser.rest.succeededlogin", false, "testuser.rest.succeededlogin", new MockRestRequest()); + } protected void logRestFailedLogin(AuditLog auditLog) { - auditLog.logFailedLogin("testuser.rest.failedlogin", false, "testuser.rest.failedlogin", new MockRestRequest()); + auditLog.logFailedLogin("testuser.rest.failedlogin", false, "testuser.rest.failedlogin", new MockRestRequest()); } protected void logMissingPrivileges(AuditLog auditLog) { - auditLog.logMissingPrivileges("privilege.missing", new TransportRequest.Empty(), null); + auditLog.logMissingPrivileges("privilege.missing", new TransportRequest.Empty(), null); } protected void logTransportBadHeaders(AuditLog auditLog) { - auditLog.logBadHeaders(new TransportRequest.Empty(),"action", null); + auditLog.logBadHeaders(new TransportRequest.Empty(), "action", null); } protected void logRestBadHeaders(AuditLog auditLog) { - auditLog.logBadHeaders(new MockRestRequest()); + auditLog.logBadHeaders(new MockRestRequest()); } protected void logSecurityIndexAttempt(AuditLog auditLog) { - auditLog.logSecurityIndexAttempt(new TransportRequest.Empty(), "action.indexattempt", null); + auditLog.logSecurityIndexAttempt(new TransportRequest.Empty(), "action.indexattempt", null); } protected void logRestSSLException(AuditLog auditLog) { - auditLog.logSSLException(new MockRestRequest(), new Exception()); + auditLog.logSSLException(new MockRestRequest(), new Exception()); } protected void logTransportSSLException(AuditLog auditLog) { - auditLog.logSSLException(new TransportRequest.Empty(), new Exception(), "action.transport.ssl", null); + auditLog.logSSLException(new TransportRequest.Empty(), new Exception(), "action.transport.ssl", null); } protected void logAuthenticatedRequest(AuditLog auditLog) { - auditLog.logGrantedPrivileges("action.success", new TransportRequest.Empty(), null); + auditLog.logGrantedPrivileges("action.success", new TransportRequest.Empty(), null); } - protected void logIndexEvent(AuditLog auditLog) { - auditLog.logIndexEvent("indices:admin/test/action", new TransportRequest.Empty(), null); - } + protected void logIndexEvent(AuditLog auditLog) { + auditLog.logIndexEvent("indices:admin/test/action", new TransportRequest.Empty(), null); + } private static final AuditCategory[] filterComplianceCategories(AuditCategory[] cats) { List retval = new ArrayList(); - for(AuditCategory c: cats) { - if(!c.toString().startsWith("COMPLIANCE")) { + for (AuditCategory c : cats) { + if (!c.toString().startsWith("COMPLIANCE")) { retval.add(c); } } 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 9939db53d8..036482e8f3 100644 --- a/src/test/java/org/opensearch/security/auditlog/impl/IgnoreAuditUsersTest.java +++ b/src/test/java/org/opensearch/security/auditlog/impl/IgnoreAuditUsersTest.java @@ -61,16 +61,21 @@ public static void initSearchRequest() { sr.indices("index1", "logstash*"); } - - @Test public void testConfiguredIgnoreUser() { Settings settings = Settings.builder() - .put("opendistro_security.audit.ignore_users", ignoreUser) - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .build(); - AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, newThreadPool(ConfigConstants.OPENDISTRO_SECURITY_USER, ignoreUserObj), null, cs); + .put("opendistro_security.audit.ignore_users", ignoreUser) + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .build(); + AbstractAuditLog al = AuditTestUtils.createAuditLog( + settings, + null, + null, + newThreadPool(ConfigConstants.OPENDISTRO_SECURITY_USER, ignoreUserObj), + null, + cs + ); TestAuditlogImpl.clear(); al.logGrantedPrivileges("indices:data/read/search", sr, null); Assert.assertEquals(0, TestAuditlogImpl.messages.size()); @@ -79,12 +84,19 @@ public void testConfiguredIgnoreUser() { @Test public void testNonConfiguredIgnoreUser() { Settings settings = Settings.builder() - .put("opendistro_security.audit.ignore_users", nonIgnoreUser) - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .build(); - AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, newThreadPool(ConfigConstants.OPENDISTRO_SECURITY_USER, ignoreUserObj), null, cs); + .put("opendistro_security.audit.ignore_users", nonIgnoreUser) + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .build(); + AbstractAuditLog al = AuditTestUtils.createAuditLog( + settings, + null, + null, + newThreadPool(ConfigConstants.OPENDISTRO_SECURITY_USER, ignoreUserObj), + null, + cs + ); TestAuditlogImpl.clear(); al.logGrantedPrivileges("indices:data/read/search", sr, null); Assert.assertEquals(1, TestAuditlogImpl.messages.size()); @@ -93,11 +105,18 @@ public void testNonConfiguredIgnoreUser() { @Test public void testNonExistingIgnoreUser() { Settings settings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .build(); - AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, newThreadPool(ConfigConstants.OPENDISTRO_SECURITY_USER, ignoreUserObj), null, cs); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .build(); + AbstractAuditLog al = AuditTestUtils.createAuditLog( + settings, + null, + null, + newThreadPool(ConfigConstants.OPENDISTRO_SECURITY_USER, ignoreUserObj), + null, + cs + ); TestAuditlogImpl.clear(); al.logGrantedPrivileges("indices:data/read/search", sr, null); Assert.assertEquals(1, TestAuditlogImpl.messages.size()); @@ -108,78 +127,122 @@ public void testWildcards() { SearchRequest sr = new SearchRequest(); User user = new User("John Doe"); - //sr.putInContext(ConfigConstants.OPENDISTRO_SECURITY_USER, user); - //sr.putInContext(ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS, "8.8.8.8"); - //sr.putInContext(ConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PRINCIPAL, "CN=kirk,OU=client,O=client,L=test,C=DE"); - //sr.putHeader("myheader", "hval"); - sr.indices("index1","logstash*"); - //sr.source("{\"query\": false}"); + // sr.putInContext(ConfigConstants.OPENDISTRO_SECURITY_USER, user); + // sr.putInContext(ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS, "8.8.8.8"); + // sr.putInContext(ConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PRINCIPAL, "CN=kirk,OU=client,O=client,L=test,C=DE"); + // sr.putHeader("myheader", "hval"); + sr.indices("index1", "logstash*"); + // sr.source("{\"query\": false}"); Settings settings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .putList("opendistro_security.audit.ignore_users", "*") - .build(); - - TransportAddress ta = new TransportAddress(new InetSocketAddress("8.8.8.8",80)); - - AbstractAuditLog al = AuditTestUtils.createAuditLog(settings, null, null, newThreadPool(ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS, ta, - ConfigConstants.OPENDISTRO_SECURITY_USER, new User("John Doe"), - ConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PRINCIPAL, "CN=kirk,OU=client,O=client,L=test,C=DE" - ), null, cs); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .putList("opendistro_security.audit.ignore_users", "*") + .build(); + + TransportAddress ta = new TransportAddress(new InetSocketAddress("8.8.8.8", 80)); + + AbstractAuditLog al = AuditTestUtils.createAuditLog( + settings, + null, + null, + newThreadPool( + ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS, + ta, + ConfigConstants.OPENDISTRO_SECURITY_USER, + new User("John Doe"), + ConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PRINCIPAL, + "CN=kirk,OU=client,O=client,L=test,C=DE" + ), + null, + cs + ); TestAuditlogImpl.clear(); al.logGrantedPrivileges("indices:data/read/search", sr, null); Assert.assertEquals(0, TestAuditlogImpl.messages.size()); settings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .putList("opendistro_security.audit.ignore_users", "xxx") - .build(); - al = AuditTestUtils.createAuditLog(settings, null, null, newThreadPool(ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS, ta, - ConfigConstants.OPENDISTRO_SECURITY_USER, new User("John Doe"), - ConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PRINCIPAL, "CN=kirk,OU=client,O=client,L=test,C=DE" - ), null, cs); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .putList("opendistro_security.audit.ignore_users", "xxx") + .build(); + al = AuditTestUtils.createAuditLog( + settings, + null, + null, + newThreadPool( + ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS, + ta, + ConfigConstants.OPENDISTRO_SECURITY_USER, + new User("John Doe"), + ConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PRINCIPAL, + "CN=kirk,OU=client,O=client,L=test,C=DE" + ), + null, + cs + ); TestAuditlogImpl.clear(); al.logGrantedPrivileges("indices:data/read/search", sr, null); Assert.assertEquals(1, TestAuditlogImpl.messages.size()); settings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .putList("opendistro_security.audit.ignore_users", "John Doe","Capatin Kirk") - .build(); - al = AuditTestUtils.createAuditLog(settings, null, null, newThreadPool(ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS, ta, - ConfigConstants.OPENDISTRO_SECURITY_USER, new User("John Doe"), - ConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PRINCIPAL, "CN=kirk,OU=client,O=client,L=test,C=DE" - ), null, cs); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .putList("opendistro_security.audit.ignore_users", "John Doe", "Capatin Kirk") + .build(); + al = AuditTestUtils.createAuditLog( + settings, + null, + null, + newThreadPool( + ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS, + ta, + ConfigConstants.OPENDISTRO_SECURITY_USER, + new User("John Doe"), + ConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PRINCIPAL, + "CN=kirk,OU=client,O=client,L=test,C=DE" + ), + null, + cs + ); TestAuditlogImpl.clear(); al.logGrantedPrivileges("indices:data/read/search", sr, null); al.logSecurityIndexAttempt(sr, "indices:data/read/search", null); - al.logMissingPrivileges("indices:data/read/search",sr, null); + al.logMissingPrivileges("indices:data/read/search", sr, null); Assert.assertEquals(TestAuditlogImpl.messages.toString(), 0, TestAuditlogImpl.messages.size()); settings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .putList("opendistro_security.audit.ignore_users", "Wil Riker","Capatin Kirk") - .build(); - al = AuditTestUtils.createAuditLog(settings, null, null, newThreadPool(ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS, ta, - ConfigConstants.OPENDISTRO_SECURITY_USER, new User("John Doe"), - ConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PRINCIPAL, "CN=kirk,OU=client,O=client,L=test,C=DE" - ), null, cs); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .putList("opendistro_security.audit.ignore_users", "Wil Riker", "Capatin Kirk") + .build(); + al = AuditTestUtils.createAuditLog( + settings, + null, + null, + newThreadPool( + ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS, + ta, + ConfigConstants.OPENDISTRO_SECURITY_USER, + new User("John Doe"), + ConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_PRINCIPAL, + "CN=kirk,OU=client,O=client,L=test,C=DE" + ), + null, + cs + ); TestAuditlogImpl.clear(); al.logGrantedPrivileges("indices:data/read/search", sr, null); Assert.assertEquals(1, TestAuditlogImpl.messages.size()); } private static ThreadPool newThreadPool(Object... transients) { - ThreadPool tp = new ThreadPool(Settings.builder().put("node.name", "mock").build()); - for(int i=0;i 0); // disable - auditConfig = new AuditConfig(false, AuditConfig.Filter.from(ImmutableMap.of("disabled_rest_categories", Collections.emptySet(), "disabled_transport_categories", Collections.emptySet())) , ComplianceConfig.DEFAULT); + auditConfig = new AuditConfig( + false, + AuditConfig.Filter.from( + ImmutableMap.of("disabled_rest_categories", Collections.emptySet(), "disabled_transport_categories", Collections.emptySet()) + ), + ComplianceConfig.DEFAULT + ); updateAuditConfig(AuditTestUtils.createAuditPayload(auditConfig)); // assert no auditing @@ -83,7 +93,7 @@ public void testSimpleAuthenticatedSetting() throws Exception { final Settings settings = Settings.builder() .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) .put(FilterEntries.DISABLE_TRANSPORT_CATEGORIES.getKeyWithNamespace(), "NONE") - .build(); + .build(); verifyAuthenticated(settings); } @@ -99,13 +109,10 @@ public void testSimpleAuthenticatedLegacySetting() throws Exception { private void verifyAuthenticated(final Settings settings) throws Exception { setup(settings); - - final List messages = TestAuditlogImpl.doThenWaitForMessages( - () -> { - final HttpResponse response = rh.executeGetRequest("_search", encodeBasicHeader("admin", "admin")); - assertThat(response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - }, - /* expectedCount*/ 1); + final List messages = TestAuditlogImpl.doThenWaitForMessages(() -> { + final HttpResponse response = rh.executeGetRequest("_search", encodeBasicHeader("admin", "admin")); + assertThat(response.getStatusCode(), equalTo(HttpStatus.SC_OK)); + }, /* expectedCount*/ 1); assertThat(messages.size(), equalTo(1)); @@ -116,30 +123,32 @@ private void verifyAuthenticated(final Settings settings) throws Exception { @Test public void testSSLPlainText() throws Exception { - //if this fails permanently look in the logs for an abstract method error or method not found error. - //needs proper ssl plugin version + // if this fails permanently look in the logs for an abstract method error or method not found error. + // needs proper ssl plugin version Settings additionalSettings = Settings.builder() - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .build(); + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .build(); setup(additionalSettings); final List messages = TestAuditlogImpl.doThenWaitForMessages(() -> { - final RuntimeException ex = Assert.assertThrows(RuntimeException.class, - () -> nonSslRestHelper().executeGetRequest("_search", encodeBasicHeader("admin", "admin"))); + final RuntimeException ex = Assert.assertThrows( + RuntimeException.class, + () -> nonSslRestHelper().executeGetRequest("_search", encodeBasicHeader("admin", "admin")) + ); Assert.assertEquals("org.apache.hc.core5.http.NoHttpResponseException", ex.getCause().getClass().getName()); - }, 1); /* no retry on NotSslRecordException exceptions */ + }, 1); /* no retry on NotSslRecordException exceptions */ // All of the messages should be the same as the http client is attempting multiple times. messages.stream().forEach((message) -> { Assert.assertEquals(AuditCategory.SSL_EXCEPTION, message.getCategory()); Assert.assertTrue(message.getExceptionStackTrace().contains("not an SSL/TLS record")); - }); + }); Assert.assertTrue(validateMsgs(messages)); } @@ -147,10 +156,10 @@ public void testSSLPlainText() throws Exception { public void testTaskId() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .build(); setup(additionalSettings); setupStarfleetIndex(); @@ -169,8 +178,10 @@ public void testTaskId() throws Exception { Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("\"audit_request_effective_user\" : \"admin\"")); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("REST")); Assert.assertFalse(TestAuditlogImpl.sb.toString().toLowerCase().contains("authorization")); - Assert.assertEquals(TestAuditlogImpl.messages.get(1).getAsMap().get(AuditMessage.TASK_ID), - TestAuditlogImpl.messages.get(1).getAsMap().get(AuditMessage.TASK_ID)); + Assert.assertEquals( + TestAuditlogImpl.messages.get(1).getAsMap().get(AuditMessage.TASK_ID), + TestAuditlogImpl.messages.get(1).getAsMap().get(AuditMessage.TASK_ID) + ); Assert.assertTrue(validateMsgs(TestAuditlogImpl.messages)); } @@ -178,10 +189,10 @@ public void testTaskId() throws Exception { public void testDefaultsRest() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .build(); setup(additionalSettings); setupStarfleetIndex(); @@ -206,11 +217,11 @@ public void testDefaultsRest() throws Exception { @Test public void testGrantedPrivilegesRest() throws Exception { final Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED, "opendistro_security_all_access") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "AUTHENTICATED") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED, "opendistro_security_all_access") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "AUTHENTICATED") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .build(); setup(additionalSettings); setupStarfleetIndex(); @@ -221,10 +232,10 @@ public void testGrantedPrivilegesRest() throws Exception { @Test public void testMissingPrivilegesRest() throws Exception { final Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "AUTHENTICATED") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "AUTHENTICATED") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .build(); setup(additionalSettings); setupStarfleetIndex(); @@ -237,7 +248,7 @@ private void testPrivilegeRest(final int expectedStatus, final String endpoint, Assert.assertEquals(expectedStatus, response.getStatusCode()); final String auditlog = TestAuditlogImpl.sb.toString(); Assert.assertEquals(1, TestAuditlogImpl.messages.size()); - Assert.assertTrue(auditlog.contains("\"audit_category\" : \"" + category +"\"")); + Assert.assertTrue(auditlog.contains("\"audit_category\" : \"" + category + "\"")); Assert.assertTrue(auditlog.contains("\"audit_rest_request_path\" : \"" + endpoint + "\"")); Assert.assertTrue(auditlog.contains("\"audit_request_effective_user\" : \"admin\"")); } @@ -246,12 +257,12 @@ private void testPrivilegeRest(final int expectedStatus, final String endpoint, public void testAuthenticated() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .build(); setup(additionalSettings); setupStarfleetIndex(); @@ -273,9 +284,7 @@ public void testAuthenticated() throws Exception { @Test public void testNonAuthenticated() throws Exception { - Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .build(); + Settings additionalSettings = Settings.builder().put("plugins.security.audit.type", TestAuditlogImpl.class.getName()).build(); setup(additionalSettings); setupStarfleetIndex(); @@ -303,28 +312,26 @@ public void testWrongUser() throws Exception { HttpResponse response = rh.executeGetRequest("", encodeBasicHeader("wronguser", "admin")); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusCode()); Thread.sleep(500); - Assert.assertTrue(TestAuditlogImpl.sb.toString(),TestAuditlogImpl.sb.toString().contains("FAILED_LOGIN")); - Assert.assertTrue(TestAuditlogImpl.sb.toString(),TestAuditlogImpl.sb.toString().contains("wronguser")); - Assert.assertTrue(TestAuditlogImpl.sb.toString(),TestAuditlogImpl.sb.toString().contains(AuditMessage.UTC_TIMESTAMP)); - Assert.assertFalse(TestAuditlogImpl.sb.toString(),TestAuditlogImpl.sb.toString().contains("AUTHENTICATED")); + Assert.assertTrue(TestAuditlogImpl.sb.toString(), TestAuditlogImpl.sb.toString().contains("FAILED_LOGIN")); + Assert.assertTrue(TestAuditlogImpl.sb.toString(), TestAuditlogImpl.sb.toString().contains("wronguser")); + Assert.assertTrue(TestAuditlogImpl.sb.toString(), TestAuditlogImpl.sb.toString().contains(AuditMessage.UTC_TIMESTAMP)); + Assert.assertFalse(TestAuditlogImpl.sb.toString(), TestAuditlogImpl.sb.toString().contains("AUTHENTICATED")); Assert.assertEquals(1, TestAuditlogImpl.messages.size()); Assert.assertTrue(validateMsgs(TestAuditlogImpl.messages)); } - public void testUnknownAuthorization() throws Exception { HttpResponse response = rh.executeGetRequest("", encodeBasicHeader("unknown", "unknown")); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusCode()); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("FAILED_LOGIN")); - Assert.assertFalse(TestAuditlogImpl.sb.toString(),TestAuditlogImpl.sb.toString().contains("Basic dW5rbm93bjp1bmtub3du")); + Assert.assertFalse(TestAuditlogImpl.sb.toString(), TestAuditlogImpl.sb.toString().contains("Basic dW5rbm93bjp1bmtub3du")); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains(AuditMessage.UTC_TIMESTAMP)); Assert.assertFalse(TestAuditlogImpl.sb.toString().contains("AUTHENTICATED")); Assert.assertEquals(1, TestAuditlogImpl.messages.size()); Assert.assertTrue(validateMsgs(TestAuditlogImpl.messages)); } - public void testUnauthenticated() throws Exception { System.out.println("#### testUnauthenticated"); @@ -349,7 +356,6 @@ public void testJustAuthenticated() throws Exception { Assert.assertTrue(validateMsgs(TestAuditlogImpl.messages)); } - public void testSecurityIndexAttempt() throws Exception { HttpResponse response = rh.executePutRequest(".opendistro_security/_doc/0", "{}", encodeBasicHeader("admin", "admin")); @@ -363,10 +369,13 @@ public void testSecurityIndexAttempt() throws Exception { Assert.assertTrue(validateMsgs(TestAuditlogImpl.messages)); } - public void testBadHeader() throws Exception { - HttpResponse response = rh.executeGetRequest("", new BasicHeader("_opendistro_security_bad", "bad"), encodeBasicHeader("admin", "admin")); + HttpResponse response = rh.executeGetRequest( + "", + new BasicHeader("_opendistro_security_bad", "bad"), + encodeBasicHeader("admin", "admin") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); Assert.assertFalse(TestAuditlogImpl.sb.toString(), TestAuditlogImpl.sb.toString().contains("AUTHENTICATED")); Assert.assertTrue(TestAuditlogImpl.sb.toString(), TestAuditlogImpl.sb.toString().contains("BAD_HEADERS")); @@ -375,7 +384,6 @@ public void testBadHeader() throws Exception { Assert.assertTrue(validateMsgs(TestAuditlogImpl.messages)); } - public void testMissingPriv() throws Exception { HttpResponse response = rh.executeGetRequest("sf/_search", encodeBasicHeader("worf", "worf")); @@ -390,13 +398,16 @@ public void testMissingPriv() throws Exception { Assert.assertTrue(validateMsgs(TestAuditlogImpl.messages)); } - public void testMsearch() throws Exception { + public void testMsearch() throws Exception { - String msearch = - "{\"index\":\"sf\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":0,\"query\":{\"match_all\":{}}}"+System.lineSeparator()+ - "{\"index\":\"sf\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":0,\"query\":{\"match_all\":{}}}"+System.lineSeparator(); + String msearch = "{\"index\":\"sf\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":0,\"query\":{\"match_all\":{}}}" + + System.lineSeparator() + + "{\"index\":\"sf\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":0,\"query\":{\"match_all\":{}}}" + + System.lineSeparator(); System.out.println("##### msaerch"); HttpResponse response = rh.executePostRequest("_msearch?pretty", msearch, encodeBasicHeader("admin", "admin")); @@ -409,24 +420,31 @@ public void testMsearch() throws Exception { Assert.assertEquals(TestAuditlogImpl.sb.toString(), 4, TestAuditlogImpl.messages.size()); Assert.assertFalse(TestAuditlogImpl.sb.toString().toLowerCase().contains("authorization")); Assert.assertTrue(validateMsgs(TestAuditlogImpl.messages)); - } - + } public void testBulkAuth() throws Exception { System.out.println("#### testBulkAuth"); - String bulkBody = - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"field1\" : \"value1\" }" +System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"worf\", \"_id\" : \"2\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ - - "{ \"update\" : {\"_id\" : \"1\", \"_index\" : \"test\"} }"+System.lineSeparator()+ - "{ \"doc\" : {\"field\" : \"valuex\"} }"+System.lineSeparator()+ - "{ \"delete\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"create\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"field1\" : \"value3x\" }"+System.lineSeparator(); - + String bulkBody = "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"field1\" : \"value1\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"worf\", \"_id\" : \"2\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator() + + + + "{ \"update\" : {\"_id\" : \"1\", \"_index\" : \"test\"} }" + + System.lineSeparator() + + "{ \"doc\" : {\"field\" : \"valuex\"} }" + + System.lineSeparator() + + "{ \"delete\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"create\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"field1\" : \"value3x\" }" + + System.lineSeparator(); HttpResponse response = rh.executePostRequest("_bulk", bulkBody, encodeBasicHeader("admin", "admin")); System.out.println(TestAuditlogImpl.sb.toString()); @@ -438,24 +456,33 @@ public void testBulkAuth() throws Exception { Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("IndexRequest")); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("audit_trace_task_parent_id")); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("audit_trace_task_id")); - //may vary because we log shardrequests which are not predictable here + // may vary because we log shardrequests which are not predictable here Assert.assertTrue(TestAuditlogImpl.messages.size() >= 17); Assert.assertTrue(validateMsgs(TestAuditlogImpl.messages)); } public void testBulkNonAuth() throws Exception { - String bulkBody = - "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"field1\" : \"value1\" }" +System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \"worf\", \"_id\" : \"2\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ - - "{ \"update\" : {\"_id\" : \"1\", \"_index\" : \"test\"} }"+System.lineSeparator()+ - "{ \"doc\" : {\"field\" : \"valuex\"} }"+System.lineSeparator()+ - "{ \"delete\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"create\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ - "{ \"field1\" : \"value3x\" }"+System.lineSeparator(); + String bulkBody = "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"field1\" : \"value1\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \"worf\", \"_id\" : \"2\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator() + + + + "{ \"update\" : {\"_id\" : \"1\", \"_index\" : \"test\"} }" + + System.lineSeparator() + + "{ \"doc\" : {\"field\" : \"valuex\"} }" + + System.lineSeparator() + + "{ \"delete\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"create\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }" + + System.lineSeparator() + + "{ \"field1\" : \"value3x\" }" + + System.lineSeparator(); HttpResponse response = rh.executePostRequest("_bulk", bulkBody, encodeBasicHeader("worf", "worf")); System.out.println(response.getBody()); @@ -468,22 +495,21 @@ public void testBulkNonAuth() throws Exception { Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("MISSING_PRIVILEGES")); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("indices:data/write/bulk[s]")); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("IndexRequest")); - //may vary because we log shardrequests which are not predictable here + // may vary because we log shardrequests which are not predictable here Assert.assertTrue(TestAuditlogImpl.messages.size() >= 7); Assert.assertTrue(validateMsgs(TestAuditlogImpl.messages)); } public void testUpdateSettings() throws Exception { - String json = - "{"+ - "\"persistent\" : {"+ - "\"indices.recovery.*\" : null"+ - "},"+ - "\"transient\" : {"+ - "\"indices.recovery.*\" : null"+ - "}"+ - "}"; + String json = "{" + + "\"persistent\" : {" + + "\"indices.recovery.*\" : null" + + "}," + + "\"transient\" : {" + + "\"indices.recovery.*\" : null" + + "}" + + "}"; HttpResponse response = rh.executePutRequest("_cluster/settings", json, encodeBasicHeader("admin", "admin")); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); @@ -491,7 +517,7 @@ public void testUpdateSettings() throws Exception { Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("AUTHENTICATED")); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("cluster:admin/settings/update")); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("indices.recovery.*")); - //may vary because we log may hit cluster manager directly or not + // may vary because we log may hit cluster manager directly or not Assert.assertTrue(TestAuditlogImpl.messages.size() > 1); Assert.assertTrue(validateMsgs(TestAuditlogImpl.messages)); } @@ -500,14 +526,14 @@ public void testUpdateSettings() throws Exception { public void testIndexPattern() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", "internal_opensearch") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_LOG_REQUEST_BODY, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_INDICES, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .put("plugins.security.audit.threadpool.size", 10) //must be greater 0 - .put("plugins.security.audit.config.index", "'auditlog-'YYYY.MM.dd.ss") - .build(); + .put("plugins.security.audit.type", "internal_opensearch") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_LOG_REQUEST_BODY, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_INDICES, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .put("plugins.security.audit.threadpool.size", 10) // must be greater 0 + .put("plugins.security.audit.config.index", "'auditlog-'YYYY.MM.dd.ss") + .build(); setup(additionalSettings); setupStarfleetIndex(); @@ -527,31 +553,59 @@ public void testIndexPattern() throws Exception { public void testAliases() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .build(); setup(additionalSettings); try (Client tc = getClient()) { tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("starfleet","starfleet_academy","starfleet_library").alias("sf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire","vulcangov").alias("nonsf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))).actionGet(); + tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction( + AliasActions.add().indices("starfleet", "starfleet_academy", "starfleet_library").alias("sf") + ) + ) + .actionGet(); + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire", "vulcangov").alias("nonsf")) + ) + .actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))) + .actionGet(); } TestAuditlogImpl.clear(); @@ -571,34 +625,56 @@ public void testAliases() throws Exception { public void testScroll() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .build(); setup(additionalSettings); try (Client tc = getClient()) { - for(int i=0; i<3; i++) - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); + for (int i = 0; i < 3; i++) + tc.index( + new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); } TestAuditlogImpl.clear(); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res=rh.executeGetRequest("vulcangov/_search?scroll=1m&pretty=true", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("vulcangov/_search?scroll=1m&pretty=true", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); int start = res.getBody().indexOf("_scroll_id") + 15; - String scrollid = res.getBody().substring(start, res.getBody().indexOf("\"", start+1)); - Assert.assertEquals(HttpStatus.SC_OK, (res=rh.executePostRequest("/_search/scroll?pretty=true", "{\"scroll_id\" : \""+scrollid+"\"}", encodeBasicHeader("admin", "admin"))).getStatusCode()); + String scrollid = res.getBody().substring(start, res.getBody().indexOf("\"", start + 1)); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest( + "/_search/scroll?pretty=true", + "{\"scroll_id\" : \"" + scrollid + "\"}", + encodeBasicHeader("admin", "admin") + )).getStatusCode() + ); Assert.assertEquals(4, TestAuditlogImpl.messages.size()); - Assert.assertEquals(HttpStatus.SC_OK, (res=rh.executeGetRequest("vulcangov/_search?scroll=1m&pretty=true", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("vulcangov/_search?scroll=1m&pretty=true", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); start = res.getBody().indexOf("_scroll_id") + 15; - scrollid = res.getBody().substring(start, res.getBody().indexOf("\"", start+1)); - TestAuditlogImpl.clear(); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res=rh.executePostRequest("/_search/scroll?pretty=true", "{\"scroll_id\" : \""+scrollid+"\"}", encodeBasicHeader("admin2", "admin"))).getStatusCode()); + scrollid = res.getBody().substring(start, res.getBody().indexOf("\"", start + 1)); + TestAuditlogImpl.clear(); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executePostRequest( + "/_search/scroll?pretty=true", + "{\"scroll_id\" : \"" + scrollid + "\"}", + encodeBasicHeader("admin2", "admin") + )).getStatusCode() + ); Thread.sleep(1000); System.out.println(TestAuditlogImpl.sb.toString()); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("InternalScrollSearchRequest")); @@ -611,21 +687,25 @@ public void testScroll() throws Exception { public void testAliasResolution() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .build(); setup(additionalSettings); - try (Client tc = getClient()) { - for(int i=0; i<3; i++) - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().alias("thealias").index("vulcangov"))).actionGet(); + for (int i = 0; i < 3; i++) + tc.index( + new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().alias("thealias").index("vulcangov"))) + .actionGet(); } TestAuditlogImpl.clear(); @@ -644,17 +724,21 @@ public void testAliasResolution() throws Exception { public void testAliasBadHeaders() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .build(); setup(additionalSettings); TestAuditlogImpl.clear(); - HttpResponse response = rh.executeGetRequest("_search?pretty", new BasicHeader("_opendistro_security_user", "xxx"), encodeBasicHeader("admin", "admin")); + HttpResponse response = rh.executeGetRequest( + "_search?pretty", + new BasicHeader("_opendistro_security_user", "xxx"), + encodeBasicHeader("admin", "admin") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); System.out.println(TestAuditlogImpl.sb.toString()); Assert.assertFalse(TestAuditlogImpl.sb.toString().contains("YWRtaW46YWRtaW4")); @@ -669,13 +753,13 @@ public void testAliasBadHeaders() throws Exception { public void testIndexCloseDelete() throws Exception { Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .build(); setup(additionalSettings); @@ -701,24 +785,33 @@ public void testIndexCloseDelete() throws Exception { public void testDeleteByQuery() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .build(); setup(settings); try (Client tc = getClient()) { - for(int i=0; i<3; i++) - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); + for (int i = 0; i < 3; i++) + tc.index( + new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); } TestAuditlogImpl.clear(); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res=rh.executePostRequest("/vulcango*/_delete_by_query?refresh=true&wait_for_completion=true&pretty=true", "{\"query\" : {\"match_all\" : {}}}", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest( + "/vulcango*/_delete_by_query?refresh=true&wait_for_completion=true&pretty=true", + "{\"query\" : {\"match_all\" : {}}}", + encodeBasicHeader("admin", "admin") + )).getStatusCode() + ); assertContains(res, "*\"deleted\" : 3,*"); String auditlogContents = TestAuditlogImpl.sb.toString(); Assert.assertTrue(auditlogContents.contains("indices:data/write/delete/byquery")); @@ -729,21 +822,29 @@ public void testDeleteByQuery() throws Exception { @Test public void testIndexRequests() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "AUTHENTICATED,GRANTED_PRIVILEGES") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_LOG_REQUEST_BODY, true) - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "AUTHENTICATED,GRANTED_PRIVILEGES") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_LOG_REQUEST_BODY, true) + .build(); setup(settings); // test create index TestAuditlogImpl.clear(); - rh.executePutRequest("/twitter", "{\"settings\":{\"index\":{\"number_of_shards\":3,\"number_of_replicas\":2}}}", encodeBasicHeader("admin", "admin")); + rh.executePutRequest( + "/twitter", + "{\"settings\":{\"index\":{\"number_of_shards\":3,\"number_of_replicas\":2}}}", + encodeBasicHeader("admin", "admin") + ); String auditlogs = TestAuditlogImpl.sb.toString(); Assert.assertTrue(auditlogs.contains("\"audit_category\" : \"INDEX_EVENT\"")); Assert.assertTrue(auditlogs.contains("\"audit_transport_request_type\" : \"CreateIndexRequest\",")); - Assert.assertTrue(auditlogs.contains("\"audit_request_body\" : \"{\\\"index\\\":{\\\"number_of_shards\\\":\\\"3\\\",\\\"number_of_replicas\\\":\\\"2\\\"}}\"")); + Assert.assertTrue( + auditlogs.contains( + "\"audit_request_body\" : \"{\\\"index\\\":{\\\"number_of_shards\\\":\\\"3\\\",\\\"number_of_replicas\\\":\\\"2\\\"}}\"" + ) + ); // test update index TestAuditlogImpl.clear(); @@ -755,7 +856,11 @@ public void testIndexRequests() throws Exception { // test put mapping TestAuditlogImpl.clear(); - rh.executePutRequest("/twitter/_mapping", "{\"properties\":{\"message\":{\"type\":\"keyword\"}}}", encodeBasicHeader("admin", "admin")); + rh.executePutRequest( + "/twitter/_mapping", + "{\"properties\":{\"message\":{\"type\":\"keyword\"}}}", + encodeBasicHeader("admin", "admin") + ); auditlogs = TestAuditlogImpl.sb.toString(); Assert.assertTrue(auditlogs.contains("\"audit_category\" : \"INDEX_EVENT\"")); Assert.assertTrue(auditlogs.contains("\"audit_transport_request_type\" : \"PutMappingRequest\",")); @@ -776,50 +881,41 @@ private String messageRestRequestMethod(AuditMessage msg) { @Test public void testRestMethod() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) + .build(); setup(settings); final Header adminHeader = encodeBasicHeader("admin", "admin"); List messages; // test GET - messages = TestAuditlogImpl.doThenWaitForMessages(() -> { - rh.executeGetRequest("test", adminHeader); - }, 1); + messages = TestAuditlogImpl.doThenWaitForMessages(() -> { rh.executeGetRequest("test", adminHeader); }, 1); Assert.assertEquals(GET, messages.get(0).getRequestMethod()); // test PUT - messages = TestAuditlogImpl.doThenWaitForMessages(() -> { - rh.executePutRequest("test/_doc/0", "{}", adminHeader); - }, 1); + messages = TestAuditlogImpl.doThenWaitForMessages(() -> { rh.executePutRequest("test/_doc/0", "{}", adminHeader); }, 1); Assert.assertEquals(PUT, messages.get(0).getRequestMethod()); // test DELETE - messages = TestAuditlogImpl.doThenWaitForMessages(() -> { - rh.executeDeleteRequest("test", adminHeader); - }, 1); + messages = TestAuditlogImpl.doThenWaitForMessages(() -> { rh.executeDeleteRequest("test", adminHeader); }, 1); Assert.assertEquals(DELETE, messages.get(0).getRequestMethod()); // test POST - messages = TestAuditlogImpl.doThenWaitForMessages(() -> { - rh.executePostRequest("test/_doc", "{}", adminHeader); - }, 1); + messages = TestAuditlogImpl.doThenWaitForMessages(() -> { rh.executePostRequest("test/_doc", "{}", adminHeader); }, 1); Assert.assertEquals(POST, messages.get(0).getRequestMethod()); // test PATCH - messages = TestAuditlogImpl.doThenWaitForMessages(() -> { - rh.executePatchRequest("/_opendistro/_security/api/audit", "[]"); - }, 1); + messages = TestAuditlogImpl.doThenWaitForMessages(() -> { rh.executePatchRequest("/_opendistro/_security/api/audit", "[]"); }, 1); Assert.assertEquals(PATCH, messages.get(0).getRequestMethod()); // test MISSING_PRIVILEGES // admin does not have REST role here - messages = TestAuditlogImpl.doThenWaitForMessages(() -> { - rh.executePatchRequest("/_opendistro/_security/api/audit", "[]", adminHeader); - }, 2); + messages = TestAuditlogImpl.doThenWaitForMessages( + () -> { rh.executePatchRequest("/_opendistro/_security/api/audit", "[]", adminHeader); }, + 2 + ); // The intital request is authenicated Assert.assertEquals(PATCH, messages.get(0).getRequestMethod()); Assert.assertEquals(AuditCategory.AUTHENTICATED, messages.get(0).getCategory()); @@ -828,16 +924,15 @@ public void testRestMethod() throws Exception { Assert.assertEquals(AuditCategory.MISSING_PRIVILEGES, messages.get(1).getCategory()); // test AUTHENTICATED - messages = TestAuditlogImpl.doThenWaitForMessages(() -> { - rh.executeGetRequest("test", adminHeader); - }, 1); + messages = TestAuditlogImpl.doThenWaitForMessages(() -> { rh.executeGetRequest("test", adminHeader); }, 1); Assert.assertEquals(AuditCategory.AUTHENTICATED, messages.get(0).getCategory()); Assert.assertEquals(GET, messages.get(0).getRequestMethod()); // test FAILED_LOGIN - messages = TestAuditlogImpl.doThenWaitForMessages(() -> { - rh.executeGetRequest("test", encodeBasicHeader("random", "random")); - }, 1); + messages = TestAuditlogImpl.doThenWaitForMessages( + () -> { rh.executeGetRequest("test", encodeBasicHeader("random", "random")); }, + 1 + ); Assert.assertEquals(AuditCategory.FAILED_LOGIN, messages.get(0).getCategory()); Assert.assertEquals(GET, messages.get(0).getRequestMethod()); @@ -852,11 +947,11 @@ public void testRestMethod() throws Exception { @Test public void testSensitiveMethodRedaction() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "AUTHENTICATED") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "AUTHENTICATED") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) + .build(); setup(settings); rh.sendAdminCertificate = true; final String expectedRequestBody = "\"audit_request_body\" : \"__SENSITIVE__\""; @@ -869,19 +964,28 @@ public void testSensitiveMethodRedaction() throws Exception { // test PUT internal users API TestAuditlogImpl.clear(); - rh.executePutRequest("/_opendistro/_security/api/internalusers/test1", "{\"password\":\"new-pass\", \"backend_roles\":[], \"attributes\": {}}"); + rh.executePutRequest( + "/_opendistro/_security/api/internalusers/test1", + "{\"password\":\"new-pass\", \"backend_roles\":[], \"attributes\": {}}" + ); Assert.assertEquals(1, TestAuditlogImpl.messages.size()); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains(expectedRequestBody)); // test PATCH internal users API TestAuditlogImpl.clear(); - rh.executePatchRequest("/_opendistro/_security/api/internalusers/test1", "[{\"op\":\"add\", \"path\":\"/password\", \"value\": \"test-pass\"}]"); + rh.executePatchRequest( + "/_opendistro/_security/api/internalusers/test1", + "[{\"op\":\"add\", \"path\":\"/password\", \"value\": \"test-pass\"}]" + ); Assert.assertEquals(1, TestAuditlogImpl.messages.size()); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains(expectedRequestBody)); // test PUT users API TestAuditlogImpl.clear(); - rh.executePutRequest("/_opendistro/_security/api/user/test2", "{\"password\":\"new-pass\", \"backend_roles\":[], \"attributes\": {}}"); + rh.executePutRequest( + "/_opendistro/_security/api/user/test2", + "{\"password\":\"new-pass\", \"backend_roles\":[], \"attributes\": {}}" + ); Assert.assertEquals(1, TestAuditlogImpl.messages.size()); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains(expectedRequestBody)); } 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 56fd17ddff..3eb49dc794 100644 --- a/src/test/java/org/opensearch/security/auditlog/integration/SSLAuditlogTest.java +++ b/src/test/java/org/opensearch/security/auditlog/integration/SSLAuditlogTest.java @@ -31,7 +31,9 @@ public class SSLAuditlogTest extends AbstractAuditlogiUnitTest { private ClusterInfo monitoringClusterInfo; private RestHelper rhMon; - private final ClusterHelper monitoringCluster = new ClusterHelper("mon_n"+num.incrementAndGet()+"_f"+System.getProperty("forkno")+"_t"+System.nanoTime()); + private final ClusterHelper monitoringCluster = new ClusterHelper( + "mon_n" + num.incrementAndGet() + "_f" + System.getProperty("forkno") + "_t" + System.nanoTime() + ); @After @Override @@ -48,36 +50,53 @@ public void tearDown() { private void setupMonitoring() throws Exception { Assert.assertNull("No monitoring cluster", monitoringClusterInfo); - monitoringClusterInfo = monitoringCluster.startCluster(minimumSecuritySettings(defaultNodeSettings(Settings.EMPTY)), ClusterConfiguration.DEFAULT); + monitoringClusterInfo = monitoringCluster.startCluster( + minimumSecuritySettings(defaultNodeSettings(Settings.EMPTY)), + ClusterConfiguration.DEFAULT + ); initialize(monitoringCluster, monitoringClusterInfo, new DynamicSecurityConfig()); rhMon = new RestHelper(monitoringClusterInfo, getResourceFolder()); } - @Test public void testExternalPemUserPass() throws Exception { setupMonitoring(); Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", "external_opensearch") - .put("plugins.security.audit.config.http_endpoints", monitoringClusterInfo.httpHost+":"+monitoringClusterInfo.httpPort) - .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_IGNORE_USERS, "*spock*","admin", "CN=kirk,OU=client,O=client,L=Test,C=DE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLE_SSL, true) - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLE_SSL_CLIENT_AUTH, false) - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMTRUSTEDCAS_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/chain-ca.pem")) - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMCERT_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/spock.crtfull.pem")) - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMKEY_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/spock.key.pem")) - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_USERNAME, - "admin") - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PASSWORD, - "admin") - .build(); + .put("plugins.security.audit.type", "external_opensearch") + .put("plugins.security.audit.config.http_endpoints", monitoringClusterInfo.httpHost + ":" + monitoringClusterInfo.httpPort) + .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_IGNORE_USERS, "*spock*", "admin", "CN=kirk,OU=client,O=client,L=Test,C=DE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLE_SSL, true) + .put( + ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLE_SSL_CLIENT_AUTH, + false + ) + .put( + ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/chain-ca.pem") + ) + .put( + ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMCERT_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/spock.crtfull.pem") + ) + .put( + ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMKEY_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/spock.key.pem") + ) + .put( + ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_USERNAME, + "admin" + ) + .put( + ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PASSWORD, + "admin" + ) + .build(); setup(additionalSettings); HttpResponse response = rh.executeGetRequest("_search"); @@ -99,20 +118,31 @@ public void testExternalPemClientAuth() throws Exception { setupMonitoring(); Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", "external_opensearch") - .put("plugins.security.audit.config.http_endpoints", monitoringClusterInfo.httpHost+":"+monitoringClusterInfo.httpPort) - .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_IGNORE_USERS, "*spock*","admin", "CN=kirk,OU=client,O=client,L=Test,C=DE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLE_SSL, true) - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLE_SSL_CLIENT_AUTH, true) - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMTRUSTEDCAS_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/chain-ca.pem")) - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMCERT_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/kirk.crtfull.pem")) - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMKEY_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/kirk.key.pem")) - .build(); + .put("plugins.security.audit.type", "external_opensearch") + .put("plugins.security.audit.config.http_endpoints", monitoringClusterInfo.httpHost + ":" + monitoringClusterInfo.httpPort) + .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_IGNORE_USERS, "*spock*", "admin", "CN=kirk,OU=client,O=client,L=Test,C=DE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLE_SSL, true) + .put( + ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLE_SSL_CLIENT_AUTH, + true + ) + .put( + ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/chain-ca.pem") + ) + .put( + ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMCERT_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/kirk.crtfull.pem") + ) + .put( + ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMKEY_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/kirk.key.pem") + ) + .build(); setup(additionalSettings); HttpResponse response = rh.executeGetRequest("_search"); @@ -133,19 +163,26 @@ public void testExternalPemUserPassTp() throws Exception { setupMonitoring(); Settings additionalSettings = Settings.builder() - .put("plugins.security.audit.type", "external_opensearch") - .put("plugins.security.audit.config.http_endpoints", monitoringClusterInfo.httpHost+":"+monitoringClusterInfo.httpPort) - .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_IGNORE_USERS, "*spock*","admin", "CN=kirk,OU=client,O=client,L=Test,C=DE") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLE_SSL, true) - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMTRUSTEDCAS_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/chain-ca.pem")) - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_USERNAME, - "admin") - .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PASSWORD, - "admin") - .build(); + .put("plugins.security.audit.type", "external_opensearch") + .put("plugins.security.audit.config.http_endpoints", monitoringClusterInfo.httpHost + ":" + monitoringClusterInfo.httpPort) + .putList(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_IGNORE_USERS, "*spock*", "admin", "CN=kirk,OU=client,O=client,L=Test,C=DE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, true) + .put(ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLE_SSL, true) + .put( + ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/chain-ca.pem") + ) + .put( + ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_USERNAME, + "admin" + ) + .put( + ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX + ConfigConstants.SECURITY_AUDIT_EXTERNAL_OPENSEARCH_PASSWORD, + "admin" + ) + .build(); setup(additionalSettings); HttpResponse response = rh.executeGetRequest("_search"); diff --git a/src/test/java/org/opensearch/security/auditlog/integration/TestAuditlogImpl.java b/src/test/java/org/opensearch/security/auditlog/integration/TestAuditlogImpl.java index ba094e23a1..7a3cd45f5b 100644 --- a/src/test/java/org/opensearch/security/auditlog/integration/TestAuditlogImpl.java +++ b/src/test/java/org/opensearch/security/auditlog/integration/TestAuditlogImpl.java @@ -42,7 +42,7 @@ public synchronized boolean doStore(AuditMessage msg) { // Ignore any messages that are sent before TestAuditlogImpl is waiting. return true; } - sb.append(msg.toPrettyString()+System.lineSeparator()); + sb.append(msg.toPrettyString() + System.lineSeparator()); messagesRef.get().add(msg); countDownRef.get().countDown(); return true; @@ -81,14 +81,11 @@ public static List doThenWaitForMessages(final Runnable action, fi try { Thread.sleep(100); if (missedMessages.size() != 0) { - final String missedMessagesErrorMessage = new StringBuilder() - .append("Audit messages were missed! ") - .append("Found " + (missedMessages.size()) + " messages.") - .append("Messages found during this time: \n\n") - .append(missedMessages.stream() - .map(AuditMessage::toString) - .collect(Collectors.joining("\n"))) - .toString(); + final String missedMessagesErrorMessage = new StringBuilder().append("Audit messages were missed! ") + .append("Found " + (missedMessages.size()) + " messages.") + .append("Messages found during this time: \n\n") + .append(missedMessages.stream().map(AuditMessage::toString).collect(Collectors.joining("\n"))) + .toString(); throw new RuntimeException(missedMessagesErrorMessage); } @@ -134,6 +131,7 @@ public static class MessagesNotFoundException extends RuntimeException { private final int expectedCount; private final int missingCount; private final List foundMessages; + public MessagesNotFoundException(final int expectedCount, List foundMessages) { super(MessagesNotFoundException.createDetailMessage(expectedCount, foundMessages)); this.expectedCount = expectedCount; @@ -154,14 +152,11 @@ public List getFoundMessages() { } private static String createDetailMessage(final int expectedCount, final List foundMessages) { - return new StringBuilder() - .append("Did not receive all " + expectedCount + " audit messages after a short wait. ") - .append("Missing " + (expectedCount - foundMessages.size()) + " messages.") - .append("Messages found during this time: \n\n") - .append(foundMessages.stream() - .map(AuditMessage::toString) - .collect(Collectors.joining("\n"))) - .toString(); + return new StringBuilder().append("Did not receive all " + expectedCount + " audit messages after a short wait. ") + .append("Missing " + (expectedCount - foundMessages.size()) + " messages.") + .append("Messages found during this time: \n\n") + .append(foundMessages.stream().map(AuditMessage::toString).collect(Collectors.joining("\n"))) + .toString(); } } } 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 0cd48f6009..cf76dbc343 100644 --- a/src/test/java/org/opensearch/security/auditlog/routing/FallbackTest.java +++ b/src/test/java/org/opensearch/security/auditlog/routing/FallbackTest.java @@ -32,96 +32,99 @@ public class FallbackTest extends AbstractAuditlogiUnitTest { - @Test - public void testFallback() throws Exception { - Settings.Builder settingsBuilder = Settings.builder().loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/fallback.yml")); - - Settings settings = settingsBuilder.put("path.home", ".").put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE").build(); - - AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); - - AuditMessage msg = MockAuditMessageFactory.validAuditMessage(AuditCategory.MISSING_PRIVILEGES); - router.route(msg); - - // endpoint 1 is failing, endoint2 and default work - List sinks = router.categorySinks.get(AuditCategory.MISSING_PRIVILEGES); - Assert.assertEquals(3, sinks.size()); - // this sink has failed, message must be logged to fallback sink - AuditLogSink sink = sinks.get(0); - Assert.assertEquals("endpoint1", sink.getName()); - Assert.assertEquals(FailingSink.class, sink.getClass()); - sink = sink.getFallbackSink(); - Assert.assertEquals("fallback", sink.getName()); - Assert.assertEquals(LoggingSink.class, sink.getClass()); - LoggingSink loggingSkin = (LoggingSink) sink; - Assert.assertEquals(msg, loggingSkin.messages.get(0)); - // this sink succeeds - sink = sinks.get(1); - Assert.assertEquals("endpoint2", sink.getName()); - Assert.assertEquals(LoggingSink.class, sink.getClass()); - loggingSkin = (LoggingSink) sink; - Assert.assertEquals(msg, loggingSkin.messages.get(0)); - // default sink also succeeds - sink = sinks.get(2); - Assert.assertEquals("default", sink.getName()); - Assert.assertEquals(LoggingSink.class, sink.getClass()); - loggingSkin = (LoggingSink) sink; - Assert.assertEquals(msg, loggingSkin.messages.get(0)); - - // has only one end point which fails - router = createMessageRouterComplianceEnabled(settings); - msg = MockAuditMessageFactory.validAuditMessage(AuditCategory.COMPLIANCE_DOC_READ); - router.route(msg); - sinks = router.categorySinks.get(AuditCategory.COMPLIANCE_DOC_READ); - sink = sinks.get(0); - Assert.assertEquals("endpoint3", sink.getName()); - Assert.assertEquals(FailingSink.class, sink.getClass()); - sink = sink.getFallbackSink(); - Assert.assertEquals("fallback", sink.getName()); - Assert.assertEquals(LoggingSink.class, sink.getClass()); - loggingSkin = (LoggingSink) sink; - Assert.assertEquals(msg, loggingSkin.messages.get(0)); - - // has only default which succeeds - router = createMessageRouterComplianceEnabled(settings); - msg = MockAuditMessageFactory.validAuditMessage(AuditCategory.COMPLIANCE_DOC_WRITE); - router.route(msg); - sinks = router.categorySinks.get(AuditCategory.COMPLIANCE_DOC_WRITE); - sink = sinks.get(0); - Assert.assertEquals("default", sink.getName()); - Assert.assertEquals(LoggingSink.class, sink.getClass()); - loggingSkin = (LoggingSink) sink; - Assert.assertEquals(1, loggingSkin.messages.size()); - Assert.assertEquals(msg, loggingSkin.messages.get(0)); - // fallback must be empty - sink = sink.getFallbackSink(); - Assert.assertEquals("fallback", sink.getName()); - Assert.assertEquals(LoggingSink.class, sink.getClass()); - loggingSkin = (LoggingSink) sink; - Assert.assertEquals(0, loggingSkin.messages.size()); - - // test non configured categories, must be logged to default only - router = createMessageRouterComplianceEnabled(settings); - msg = MockAuditMessageFactory.validAuditMessage(AuditCategory.FAILED_LOGIN); - router.route(msg); - Assert.assertNull(router.categorySinks.get(AuditCategory.FAILED_LOGIN)); - loggingSkin = (LoggingSink) router.defaultSink; - Assert.assertEquals(1, loggingSkin.messages.size()); - Assert.assertEquals(msg, loggingSkin.messages.get(0)); - // all others must be empty - assertLoggingSinksEmpty(router); - - } - - private void assertLoggingSinksEmpty(AuditMessageRouter router) { - // get all sinks - List allSinks = router.categorySinks.values().stream().flatMap(Collection::stream).collect(Collectors.toList()); - allSinks = allSinks.stream().filter(sink -> (sink instanceof LoggingSink)).collect(Collectors.toList()); - allSinks.removeAll(Collections.singleton(router.defaultSink)); - for(AuditLogSink sink : allSinks) { - LoggingSink loggingSink = (LoggingSink)sink; - Assert.assertEquals(0, loggingSink.messages.size()); - } - } + @Test + public void testFallback() throws Exception { + Settings.Builder settingsBuilder = Settings.builder() + .loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/fallback.yml")); + + Settings settings = settingsBuilder.put("path.home", ".") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .build(); + + AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); + + AuditMessage msg = MockAuditMessageFactory.validAuditMessage(AuditCategory.MISSING_PRIVILEGES); + router.route(msg); + + // endpoint 1 is failing, endoint2 and default work + List sinks = router.categorySinks.get(AuditCategory.MISSING_PRIVILEGES); + Assert.assertEquals(3, sinks.size()); + // this sink has failed, message must be logged to fallback sink + AuditLogSink sink = sinks.get(0); + Assert.assertEquals("endpoint1", sink.getName()); + Assert.assertEquals(FailingSink.class, sink.getClass()); + sink = sink.getFallbackSink(); + Assert.assertEquals("fallback", sink.getName()); + Assert.assertEquals(LoggingSink.class, sink.getClass()); + LoggingSink loggingSkin = (LoggingSink) sink; + Assert.assertEquals(msg, loggingSkin.messages.get(0)); + // this sink succeeds + sink = sinks.get(1); + Assert.assertEquals("endpoint2", sink.getName()); + Assert.assertEquals(LoggingSink.class, sink.getClass()); + loggingSkin = (LoggingSink) sink; + Assert.assertEquals(msg, loggingSkin.messages.get(0)); + // default sink also succeeds + sink = sinks.get(2); + Assert.assertEquals("default", sink.getName()); + Assert.assertEquals(LoggingSink.class, sink.getClass()); + loggingSkin = (LoggingSink) sink; + Assert.assertEquals(msg, loggingSkin.messages.get(0)); + + // has only one end point which fails + router = createMessageRouterComplianceEnabled(settings); + msg = MockAuditMessageFactory.validAuditMessage(AuditCategory.COMPLIANCE_DOC_READ); + router.route(msg); + sinks = router.categorySinks.get(AuditCategory.COMPLIANCE_DOC_READ); + sink = sinks.get(0); + Assert.assertEquals("endpoint3", sink.getName()); + Assert.assertEquals(FailingSink.class, sink.getClass()); + sink = sink.getFallbackSink(); + Assert.assertEquals("fallback", sink.getName()); + Assert.assertEquals(LoggingSink.class, sink.getClass()); + loggingSkin = (LoggingSink) sink; + Assert.assertEquals(msg, loggingSkin.messages.get(0)); + + // has only default which succeeds + router = createMessageRouterComplianceEnabled(settings); + msg = MockAuditMessageFactory.validAuditMessage(AuditCategory.COMPLIANCE_DOC_WRITE); + router.route(msg); + sinks = router.categorySinks.get(AuditCategory.COMPLIANCE_DOC_WRITE); + sink = sinks.get(0); + Assert.assertEquals("default", sink.getName()); + Assert.assertEquals(LoggingSink.class, sink.getClass()); + loggingSkin = (LoggingSink) sink; + Assert.assertEquals(1, loggingSkin.messages.size()); + Assert.assertEquals(msg, loggingSkin.messages.get(0)); + // fallback must be empty + sink = sink.getFallbackSink(); + Assert.assertEquals("fallback", sink.getName()); + Assert.assertEquals(LoggingSink.class, sink.getClass()); + loggingSkin = (LoggingSink) sink; + Assert.assertEquals(0, loggingSkin.messages.size()); + + // test non configured categories, must be logged to default only + router = createMessageRouterComplianceEnabled(settings); + msg = MockAuditMessageFactory.validAuditMessage(AuditCategory.FAILED_LOGIN); + router.route(msg); + Assert.assertNull(router.categorySinks.get(AuditCategory.FAILED_LOGIN)); + loggingSkin = (LoggingSink) router.defaultSink; + Assert.assertEquals(1, loggingSkin.messages.size()); + Assert.assertEquals(msg, loggingSkin.messages.get(0)); + // all others must be empty + assertLoggingSinksEmpty(router); + + } + + private void assertLoggingSinksEmpty(AuditMessageRouter router) { + // get all sinks + List allSinks = router.categorySinks.values().stream().flatMap(Collection::stream).collect(Collectors.toList()); + allSinks = allSinks.stream().filter(sink -> (sink instanceof LoggingSink)).collect(Collectors.toList()); + allSinks.removeAll(Collections.singleton(router.defaultSink)); + for (AuditLogSink sink : allSinks) { + LoggingSink loggingSink = (LoggingSink) sink; + Assert.assertEquals(0, loggingSink.messages.size()); + } + } } 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 c71a4dc951..f308db21fc 100644 --- a/src/test/java/org/opensearch/security/auditlog/routing/PerfTest.java +++ b/src/test/java/org/opensearch/security/auditlog/routing/PerfTest.java @@ -24,28 +24,28 @@ import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.helper.file.FileHelper; - public class PerfTest extends AbstractAuditlogiUnitTest { - @Test - @Ignore(value="jvm crash on cci") - public void testPerf() throws Exception { - Settings.Builder settingsBuilder = Settings.builder().loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/perftest.yml")); - - Settings settings = settingsBuilder.put("path.home", ".") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .build(); - - AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); - int limit = 150000; - while(limit > 0) { - AuditMessage msg = MockAuditMessageFactory.validAuditMessage(AuditCategory.MISSING_PRIVILEGES); - router.route(msg); - limit--; - } - LoggingSink loggingSink = (LoggingSink)router.defaultSink.getFallbackSink(); - int currentSize = loggingSink.messages.size(); - Assert.assertTrue(currentSize > 0); - } + @Test + @Ignore(value = "jvm crash on cci") + public void testPerf() throws Exception { + Settings.Builder settingsBuilder = Settings.builder() + .loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/perftest.yml")); + + Settings settings = settingsBuilder.put("path.home", ".") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .build(); + + AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); + int limit = 150000; + while (limit > 0) { + AuditMessage msg = MockAuditMessageFactory.validAuditMessage(AuditCategory.MISSING_PRIVILEGES); + router.route(msg); + limit--; + } + LoggingSink loggingSink = (LoggingSink) router.defaultSink.getFallbackSink(); + int currentSize = loggingSink.messages.size(); + Assert.assertTrue(currentSize > 0); + } } 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 49d603884f..9ab7c0f93c 100644 --- a/src/test/java/org/opensearch/security/auditlog/routing/RouterTest.java +++ b/src/test/java/org/opensearch/security/auditlog/routing/RouterTest.java @@ -31,45 +31,46 @@ import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.helper.file.FileHelper; -public class RouterTest extends AbstractAuditlogiUnitTest{ - - - @Test - public void testValidConfiguration() throws Exception { - Settings settings = Settings.builder().loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/configuration_valid.yml")).build(); - AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); - // default - Assert.assertEquals("default", router.defaultSink.getName()); - Assert.assertEquals(ExternalOpenSearchSink.class, router.defaultSink.getClass()); - // test category sinks - List sinks = router.categorySinks.get(AuditCategory.MISSING_PRIVILEGES); - Assert.assertNotNull(sinks); - // 3, since we include default as well - Assert.assertEquals(3, sinks.size()); - Assert.assertEquals("endpoint1", sinks.get(0).getName()); - Assert.assertEquals(InternalOpenSearchSink.class, sinks.get(0).getClass()); - Assert.assertEquals("endpoint2", sinks.get(1).getName()); - Assert.assertEquals(ExternalOpenSearchSink.class, sinks.get(1).getClass()); - Assert.assertEquals("default", sinks.get(2).getName()); - Assert.assertEquals(ExternalOpenSearchSink.class, sinks.get(2).getClass()); - sinks = router.categorySinks.get(AuditCategory.COMPLIANCE_DOC_READ); - // 1, since we do not include default - Assert.assertEquals(1, sinks.size()); - Assert.assertEquals("endpoint3", sinks.get(0).getName()); - Assert.assertEquals(DebugSink.class, sinks.get(0).getClass()); - } +public class RouterTest extends AbstractAuditlogiUnitTest { + + @Test + public void testValidConfiguration() throws Exception { + Settings settings = Settings.builder() + .loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/configuration_valid.yml")) + .build(); + AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); + // default + Assert.assertEquals("default", router.defaultSink.getName()); + Assert.assertEquals(ExternalOpenSearchSink.class, router.defaultSink.getClass()); + // test category sinks + List sinks = router.categorySinks.get(AuditCategory.MISSING_PRIVILEGES); + Assert.assertNotNull(sinks); + // 3, since we include default as well + Assert.assertEquals(3, sinks.size()); + Assert.assertEquals("endpoint1", sinks.get(0).getName()); + Assert.assertEquals(InternalOpenSearchSink.class, sinks.get(0).getClass()); + Assert.assertEquals("endpoint2", sinks.get(1).getName()); + Assert.assertEquals(ExternalOpenSearchSink.class, sinks.get(1).getClass()); + Assert.assertEquals("default", sinks.get(2).getName()); + Assert.assertEquals(ExternalOpenSearchSink.class, sinks.get(2).getClass()); + sinks = router.categorySinks.get(AuditCategory.COMPLIANCE_DOC_READ); + // 1, since we do not include default + Assert.assertEquals(1, sinks.size()); + Assert.assertEquals("endpoint3", sinks.get(0).getName()); + Assert.assertEquals(DebugSink.class, sinks.get(0).getClass()); + } @Test public void testMessageRouting() throws Exception { - Settings.Builder settingsBuilder = Settings.builder().loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/routing.yml")); + Settings.Builder settingsBuilder = Settings.builder() + .loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/routing.yml")); - Settings settings = settingsBuilder - .put("path.home", ".") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") - .build(); + Settings settings = settingsBuilder.put("path.home", ".") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .build(); - AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); + AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); AuditMessage msg = MockAuditMessageFactory.validAuditMessage(AuditCategory.MISSING_PRIVILEGES); router.route(msg); testMessageDeliveredForCategory(router, msg, AuditCategory.MISSING_PRIVILEGES, "endpoint1", "endpoint2", "default"); @@ -96,35 +97,40 @@ public void testMessageRouting() throws Exception { } - private void testMessageDeliveredForCategory(AuditMessageRouter router, AuditMessage msg, AuditCategory categoryToCheck, String ... sinkNames) { - Map> sinksForCategory = router.categorySinks; - for(AuditCategory category : AuditCategory.values()) { - List sinks = sinksForCategory.get(category); - if (sinks == null) { - continue; - } - if (category.equals(categoryToCheck)) { - // each sink must contain our message - for(AuditLogSink sink : sinks) { - LoggingSink logSink = (LoggingSink)sink; - Assert.assertEquals(1, logSink.messages.size()); - Assert.assertEquals(msg, logSink.messages.get(0)); - Assert.assertTrue(logSink.sb.length() > 0); - Assert.assertTrue(Arrays.stream(sinkNames).anyMatch(sink.getName()::equals)); - } - } else { - // make sure sinks are empty for all other categories, exclude default - for(AuditLogSink sink : sinks) { - // default is configured for multiple categories, skip - if (sink.getName().equals("default")) { - continue; - } - LoggingSink logSink = (LoggingSink)sink; - Assert.assertEquals(0, logSink.messages.size()); - Assert.assertTrue(logSink.sb.length() == 0); - } - } - } + private void testMessageDeliveredForCategory( + AuditMessageRouter router, + AuditMessage msg, + AuditCategory categoryToCheck, + String... sinkNames + ) { + Map> sinksForCategory = router.categorySinks; + for (AuditCategory category : AuditCategory.values()) { + List sinks = sinksForCategory.get(category); + if (sinks == null) { + continue; + } + if (category.equals(categoryToCheck)) { + // each sink must contain our message + for (AuditLogSink sink : sinks) { + LoggingSink logSink = (LoggingSink) sink; + Assert.assertEquals(1, logSink.messages.size()); + Assert.assertEquals(msg, logSink.messages.get(0)); + Assert.assertTrue(logSink.sb.length() > 0); + Assert.assertTrue(Arrays.stream(sinkNames).anyMatch(sink.getName()::equals)); + } + } else { + // make sure sinks are empty for all other categories, exclude default + for (AuditLogSink sink : sinks) { + // default is configured for multiple categories, skip + if (sink.getName().equals("default")) { + continue; + } + LoggingSink logSink = (LoggingSink) sink; + Assert.assertEquals(0, logSink.messages.size()); + Assert.assertTrue(logSink.sb.length() == 0); + } + } + } } } 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 f33d52c663..8ddb79bcba 100644 --- a/src/test/java/org/opensearch/security/auditlog/routing/RoutingConfigurationTest.java +++ b/src/test/java/org/opensearch/security/auditlog/routing/RoutingConfigurationTest.java @@ -28,139 +28,155 @@ import org.opensearch.security.auditlog.sink.InternalOpenSearchSink; import org.opensearch.security.test.helper.file.FileHelper; -public class RoutingConfigurationTest extends AbstractAuditlogiUnitTest{ - - @Test - public void testValidConfiguration() throws Exception { - Settings settings = Settings.builder().loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/configuration_valid.yml")).build(); - AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); - // default - Assert.assertEquals("default", router.defaultSink.getName()); - Assert.assertEquals(ExternalOpenSearchSink.class, router.defaultSink.getClass()); - // test category sinks - List sinks = router.categorySinks.get(AuditCategory.MISSING_PRIVILEGES); - Assert.assertNotNull(sinks); - // 3, since we include default as well - Assert.assertEquals(3, sinks.size()); - Assert.assertEquals("endpoint1", sinks.get(0).getName()); - Assert.assertEquals(InternalOpenSearchSink.class, sinks.get(0).getClass()); - Assert.assertEquals("endpoint2", sinks.get(1).getName()); - Assert.assertEquals(ExternalOpenSearchSink.class, sinks.get(1).getClass()); - Assert.assertEquals("default", sinks.get(2).getName()); - Assert.assertEquals(ExternalOpenSearchSink.class, sinks.get(2).getClass()); - sinks = router.categorySinks.get(AuditCategory.COMPLIANCE_DOC_READ); - // 1, since we do not include default - Assert.assertEquals(1, sinks.size()); - Assert.assertEquals("endpoint3", sinks.get(0).getName()); - Assert.assertEquals(DebugSink.class, sinks.get(0).getClass()); - } - - @Test - public void testNoDefaultSink() throws Exception { - Settings settings = Settings.builder().loadFromPath(Objects.requireNonNull(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/configuration_no_default.yml"))).build(); - AuditMessageRouter router = new AuditMessageRouter(settings, null, null, null); - // no default sink, audit log not enabled - Assert.assertEquals(false, router.isEnabled()); - Assert.assertEquals(null, router.defaultSink); - Assert.assertEquals(null, router.categorySinks); - // make sure no exception is thrown - router.route(MockAuditMessageFactory.validAuditMessage()); - } - - @Test - public void testMissingEndpoints() throws Exception { - Settings settings = Settings.builder().loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/configuration_wrong_endpoint_names.yml")).build(); - AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); - // fallback to debug sink if no default is given - Assert.assertEquals(InternalOpenSearchSink.class, router.defaultSink.getClass()); - // missing configuration for endpoint2 / External ES. Fallback to - // localhost - List sinks = router.categorySinks.get(AuditCategory.MISSING_PRIVILEGES); - // 2 valid endpoints - Assert.assertEquals(2, sinks.size()); - Assert.assertEquals("endpoint1", sinks.get(0).getName()); - Assert.assertEquals(InternalOpenSearchSink.class, sinks.get(0).getClass()); - Assert.assertEquals("endpoint3", sinks.get(1).getName()); - Assert.assertEquals(DebugSink.class, sinks.get(1).getClass()); - sinks = router.categorySinks.get(AuditCategory.COMPLIANCE_DOC_WRITE); - Assert.assertEquals(1, sinks.size()); - Assert.assertEquals("default", sinks.get(0).getName()); - Assert.assertEquals(InternalOpenSearchSink.class, sinks.get(0).getClass()); - // no valid end points for category, must use default - Assert.assertNull(router.categorySinks.get(AuditCategory.COMPLIANCE_DOC_READ)); - } - - @Test - public void testWrongCategories() throws Exception { - Settings settings = Settings.builder().loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/configuration_wrong_categories.yml")).build(); - AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); - // no default sink, we fall back to debug sink - Assert.assertEquals(DebugSink.class, router.defaultSink.getClass()); - - List sinks = router.categorySinks.get(AuditCategory.MISSING_PRIVILEGES); - // 3, since default is not valid but replaced with Debug - Assert.assertEquals(3, sinks.size()); - Assert.assertEquals("default", sinks.get(0).getName()); - Assert.assertEquals(DebugSink.class, sinks.get(0).getClass()); - Assert.assertEquals("endpoint1", sinks.get(1).getName()); - Assert.assertEquals(InternalOpenSearchSink.class, sinks.get(1).getClass()); - Assert.assertEquals("endpoint2", sinks.get(2).getName()); - Assert.assertEquals(ExternalOpenSearchSink.class, sinks.get(2).getClass()); - - sinks = router.categorySinks.get(AuditCategory.GRANTED_PRIVILEGES); - Assert.assertEquals(3, sinks.size()); - Assert.assertEquals("endpoint1", sinks.get(0).getName()); - Assert.assertEquals(InternalOpenSearchSink.class, sinks.get(0).getClass()); - Assert.assertEquals("endpoint3", sinks.get(1).getName()); - Assert.assertEquals(DebugSink.class, sinks.get(1).getClass()); - Assert.assertEquals("default", sinks.get(2).getName()); - Assert.assertEquals(DebugSink.class, sinks.get(2).getClass()); - - sinks = router.categorySinks.get(AuditCategory.AUTHENTICATED); - Assert.assertEquals(1, sinks.size()); - Assert.assertEquals("endpoint1", sinks.get(0).getName()); - Assert.assertEquals(InternalOpenSearchSink.class, sinks.get(0).getClass()); - - // bad headers has no valid endpoint, so we use default - Assert.assertNull(router.categorySinks.get(AuditCategory.BAD_HEADERS)); - - // failed login has no endpoint configuration, so we use default - Assert.assertNull(router.categorySinks.get(AuditCategory.FAILED_LOGIN)); - - } - - @Test - public void testWrongEndpointTypes() throws Exception { - Settings settings = Settings.builder().loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/configuration_wrong_endpoint_types.yml")).build(); - AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); - // debug sink not valid, fallback to debug - Assert.assertEquals(DebugSink.class, router.defaultSink.getClass()); - - List sinks = router.categorySinks.get(AuditCategory.MISSING_PRIVILEGES); - // 2 valid endpoints in config, default falls back to debug - Assert.assertEquals(3, sinks.size()); - Assert.assertEquals("endpoint2", sinks.get(0).getName()); - Assert.assertEquals(ExternalOpenSearchSink.class, sinks.get(0).getClass()); - Assert.assertEquals("endpoint3", sinks.get(1).getName()); - Assert.assertEquals(DebugSink.class, sinks.get(1).getClass()); - Assert.assertEquals("default", sinks.get(2).getName()); - Assert.assertEquals(DebugSink.class, sinks.get(2).getClass()); - - sinks = router.categorySinks.get(AuditCategory.COMPLIANCE_DOC_WRITE); - Assert.assertEquals(1, sinks.size()); - Assert.assertEquals("default", sinks.get(0).getName()); - Assert.assertEquals(DebugSink.class, sinks.get(0).getClass()); - - // no valid endpoints for category, must fallback to default - Assert.assertNull(router.categorySinks.get(AuditCategory.COMPLIANCE_DOC_READ)); - } - - @Test - public void testNoMultipleEndpointsConfiguration() throws Exception { - Settings settings = Settings.builder().loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/sink/configuration_no_multiple_endpoints.yml")).build(); - AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); - ThreadPoolConfig config = router.storagePool.getConfig(); - Assert.assertEquals(5, config.getThreadPoolSize()); - Assert.assertEquals(200000, config.getThreadPoolMaxQueueLen()); - } +public class RoutingConfigurationTest extends AbstractAuditlogiUnitTest { + + @Test + public void testValidConfiguration() throws Exception { + Settings settings = Settings.builder() + .loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/configuration_valid.yml")) + .build(); + AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); + // default + Assert.assertEquals("default", router.defaultSink.getName()); + Assert.assertEquals(ExternalOpenSearchSink.class, router.defaultSink.getClass()); + // test category sinks + List sinks = router.categorySinks.get(AuditCategory.MISSING_PRIVILEGES); + Assert.assertNotNull(sinks); + // 3, since we include default as well + Assert.assertEquals(3, sinks.size()); + Assert.assertEquals("endpoint1", sinks.get(0).getName()); + Assert.assertEquals(InternalOpenSearchSink.class, sinks.get(0).getClass()); + Assert.assertEquals("endpoint2", sinks.get(1).getName()); + Assert.assertEquals(ExternalOpenSearchSink.class, sinks.get(1).getClass()); + Assert.assertEquals("default", sinks.get(2).getName()); + Assert.assertEquals(ExternalOpenSearchSink.class, sinks.get(2).getClass()); + sinks = router.categorySinks.get(AuditCategory.COMPLIANCE_DOC_READ); + // 1, since we do not include default + Assert.assertEquals(1, sinks.size()); + Assert.assertEquals("endpoint3", sinks.get(0).getName()); + Assert.assertEquals(DebugSink.class, sinks.get(0).getClass()); + } + + @Test + public void testNoDefaultSink() throws Exception { + Settings settings = Settings.builder() + .loadFromPath( + Objects.requireNonNull( + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/configuration_no_default.yml") + ) + ) + .build(); + AuditMessageRouter router = new AuditMessageRouter(settings, null, null, null); + // no default sink, audit log not enabled + Assert.assertEquals(false, router.isEnabled()); + Assert.assertEquals(null, router.defaultSink); + Assert.assertEquals(null, router.categorySinks); + // make sure no exception is thrown + router.route(MockAuditMessageFactory.validAuditMessage()); + } + + @Test + public void testMissingEndpoints() throws Exception { + Settings settings = Settings.builder() + .loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/configuration_wrong_endpoint_names.yml")) + .build(); + AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); + // fallback to debug sink if no default is given + Assert.assertEquals(InternalOpenSearchSink.class, router.defaultSink.getClass()); + // missing configuration for endpoint2 / External ES. Fallback to + // localhost + List sinks = router.categorySinks.get(AuditCategory.MISSING_PRIVILEGES); + // 2 valid endpoints + Assert.assertEquals(2, sinks.size()); + Assert.assertEquals("endpoint1", sinks.get(0).getName()); + Assert.assertEquals(InternalOpenSearchSink.class, sinks.get(0).getClass()); + Assert.assertEquals("endpoint3", sinks.get(1).getName()); + Assert.assertEquals(DebugSink.class, sinks.get(1).getClass()); + sinks = router.categorySinks.get(AuditCategory.COMPLIANCE_DOC_WRITE); + Assert.assertEquals(1, sinks.size()); + Assert.assertEquals("default", sinks.get(0).getName()); + Assert.assertEquals(InternalOpenSearchSink.class, sinks.get(0).getClass()); + // no valid end points for category, must use default + Assert.assertNull(router.categorySinks.get(AuditCategory.COMPLIANCE_DOC_READ)); + } + + @Test + public void testWrongCategories() throws Exception { + Settings settings = Settings.builder() + .loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/configuration_wrong_categories.yml")) + .build(); + AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); + // no default sink, we fall back to debug sink + Assert.assertEquals(DebugSink.class, router.defaultSink.getClass()); + + List sinks = router.categorySinks.get(AuditCategory.MISSING_PRIVILEGES); + // 3, since default is not valid but replaced with Debug + Assert.assertEquals(3, sinks.size()); + Assert.assertEquals("default", sinks.get(0).getName()); + Assert.assertEquals(DebugSink.class, sinks.get(0).getClass()); + Assert.assertEquals("endpoint1", sinks.get(1).getName()); + Assert.assertEquals(InternalOpenSearchSink.class, sinks.get(1).getClass()); + Assert.assertEquals("endpoint2", sinks.get(2).getName()); + Assert.assertEquals(ExternalOpenSearchSink.class, sinks.get(2).getClass()); + + sinks = router.categorySinks.get(AuditCategory.GRANTED_PRIVILEGES); + Assert.assertEquals(3, sinks.size()); + Assert.assertEquals("endpoint1", sinks.get(0).getName()); + Assert.assertEquals(InternalOpenSearchSink.class, sinks.get(0).getClass()); + Assert.assertEquals("endpoint3", sinks.get(1).getName()); + Assert.assertEquals(DebugSink.class, sinks.get(1).getClass()); + Assert.assertEquals("default", sinks.get(2).getName()); + Assert.assertEquals(DebugSink.class, sinks.get(2).getClass()); + + sinks = router.categorySinks.get(AuditCategory.AUTHENTICATED); + Assert.assertEquals(1, sinks.size()); + Assert.assertEquals("endpoint1", sinks.get(0).getName()); + Assert.assertEquals(InternalOpenSearchSink.class, sinks.get(0).getClass()); + + // bad headers has no valid endpoint, so we use default + Assert.assertNull(router.categorySinks.get(AuditCategory.BAD_HEADERS)); + + // failed login has no endpoint configuration, so we use default + Assert.assertNull(router.categorySinks.get(AuditCategory.FAILED_LOGIN)); + + } + + @Test + public void testWrongEndpointTypes() throws Exception { + Settings settings = Settings.builder() + .loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/routing/configuration_wrong_endpoint_types.yml")) + .build(); + AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); + // debug sink not valid, fallback to debug + Assert.assertEquals(DebugSink.class, router.defaultSink.getClass()); + + List sinks = router.categorySinks.get(AuditCategory.MISSING_PRIVILEGES); + // 2 valid endpoints in config, default falls back to debug + Assert.assertEquals(3, sinks.size()); + Assert.assertEquals("endpoint2", sinks.get(0).getName()); + Assert.assertEquals(ExternalOpenSearchSink.class, sinks.get(0).getClass()); + Assert.assertEquals("endpoint3", sinks.get(1).getName()); + Assert.assertEquals(DebugSink.class, sinks.get(1).getClass()); + Assert.assertEquals("default", sinks.get(2).getName()); + Assert.assertEquals(DebugSink.class, sinks.get(2).getClass()); + + sinks = router.categorySinks.get(AuditCategory.COMPLIANCE_DOC_WRITE); + Assert.assertEquals(1, sinks.size()); + Assert.assertEquals("default", sinks.get(0).getName()); + Assert.assertEquals(DebugSink.class, sinks.get(0).getClass()); + + // no valid endpoints for category, must fallback to default + Assert.assertNull(router.categorySinks.get(AuditCategory.COMPLIANCE_DOC_READ)); + } + + @Test + public void testNoMultipleEndpointsConfiguration() throws Exception { + Settings settings = Settings.builder() + .loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/sink/configuration_no_multiple_endpoints.yml")) + .build(); + AuditMessageRouter router = createMessageRouterComplianceEnabled(settings); + ThreadPoolConfig config = router.storagePool.getConfig(); + Assert.assertEquals(5, config.getThreadPoolSize()); + Assert.assertEquals(200000, config.getThreadPoolMaxQueueLen()); + } } 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 b074dd2b62..bf567c6ebe 100644 --- a/src/test/java/org/opensearch/security/auditlog/sink/KafkaSinkTest.java +++ b/src/test/java/org/opensearch/security/auditlog/sink/KafkaSinkTest.java @@ -37,6 +37,7 @@ public class KafkaSinkTest extends AbstractAuditlogiUnitTest { public static EmbeddedKafkaRule embeddedKafka = new EmbeddedKafkaRule(1, true, 1, "compliance") { // Prevents test exceptions from randomized runner, see https://bit.ly/3y17IkI private UncaughtExceptionHandler currentHandler; + @Override public void before() { currentHandler = Thread.getDefaultUncaughtExceptionHandler(); @@ -53,9 +54,9 @@ public void after() { @Test public void testKafka() throws Exception { String configYml = FileHelper.loadFile("auditlog/endpoints/sink/configuration_kafka.yml"); - configYml = configYml.replace("_RPLC_BOOTSTRAP_SERVERS_",embeddedKafka.getEmbeddedKafka().getBrokersAsString()); + configYml = configYml.replace("_RPLC_BOOTSTRAP_SERVERS_", embeddedKafka.getEmbeddedKafka().getBrokersAsString()); Settings.Builder settingsBuilder = Settings.builder().loadFromSource(configYml, YamlXContent.yamlXContent.mediaType()); - try(KafkaConsumer consumer = createConsumer()) { + try (KafkaConsumer consumer = createConsumer()) { consumer.subscribe(Arrays.asList("compliance")); Settings settings = settingsBuilder.put("path.home", ".").build(); @@ -78,7 +79,7 @@ private KafkaConsumer createConsumer() { Properties props = new Properties(); props.put("bootstrap.servers", embeddedKafka.getEmbeddedKafka().getBrokersAsString()); props.put("auto.offset.reset", "earliest"); - props.put("group.id", "mygroup"+System.currentTimeMillis()+"_"+new Random().nextDouble()); + props.put("group.id", "mygroup" + System.currentTimeMillis() + "_" + new Random().nextDouble()); props.put("key.deserializer", "org.apache.kafka.common.serialization.LongDeserializer"); props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); return new KafkaConsumer<>(props); diff --git a/src/test/java/org/opensearch/security/auditlog/sink/MockWebhookAuditLog.java b/src/test/java/org/opensearch/security/auditlog/sink/MockWebhookAuditLog.java index b93904574e..6dd019e733 100644 --- a/src/test/java/org/opensearch/security/auditlog/sink/MockWebhookAuditLog.java +++ b/src/test/java/org/opensearch/security/auditlog/sink/MockWebhookAuditLog.java @@ -15,23 +15,22 @@ public class MockWebhookAuditLog extends WebhookSink { - public String payload = null; - public String url = null; - - public MockWebhookAuditLog(Settings settings, String settingsPrefix, AuditLogSink fallback) throws Exception { - super("test", settings, settingsPrefix, null, fallback); - } - - @Override - protected boolean doPost(String url, String payload) { - this.payload = payload; - return true; - } - - - @Override - protected boolean doGet(String url) { - this.url = url; - return true; - } + public String payload = null; + public String url = null; + + public MockWebhookAuditLog(Settings settings, String settingsPrefix, AuditLogSink fallback) throws Exception { + super("test", settings, settingsPrefix, null, fallback); + } + + @Override + protected boolean doPost(String url, String payload) { + this.payload = payload; + return true; + } + + @Override + protected boolean doGet(String url) { + this.url = url; + return true; + } } 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 fb0f665b16..467cce5fe9 100644 --- a/src/test/java/org/opensearch/security/auditlog/sink/SinkProviderTLSTest.java +++ b/src/test/java/org/opensearch/security/auditlog/sink/SinkProviderTLSTest.java @@ -39,119 +39,132 @@ public class SinkProviderTLSTest { - protected HttpServer server = null; - - @Before - @After - public void tearDown() { - if (server != null) { - try { - server.stop(); - } catch (Exception e) { - // ignore - } - } - } - - @Test - public void testTlsConfigurationNoFallback() throws Exception { - - TestHttpHandler handler = new TestHttpHandler(); - - int port = findFreePort(); - server = ServerBootstrap.bootstrap().setListenerPort(port).setHttpProcessor(HttpProcessors.server("Test/1.1")).setSslContext(createSSLContext()).register("*", handler).create(); - - server.start(); - - Builder builder = Settings.builder().loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/sink/configuration_tls.yml")); - builder.put("path.home", "/"); - - // replace some values with absolute paths for unit tests - builder.put("plugins.security.audit.config.webhook.ssl.pemtrustedcas_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/root-ca.pem")); - builder.put("plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.pemtrustedcas_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/root-ca.pem")); - builder.put("plugins.security.audit.endpoints.endpoint2.config.webhook.ssl.pemtrustedcas_content", FileHelper.loadFile("auditlog/root-ca.pem")); - - builder.put("plugins.security.audit.config.webhook.url", "https://localhost:" + port); - builder.put("plugins.security.audit.endpoints.endpoint1.config.webhook.url", "https://localhost:" + port); - builder.put("plugins.security.audit.endpoints.endpoint2.config.webhook.url", "https://localhost:" + port); - - - SinkProvider provider = new SinkProvider(builder.build(), null, null, null); - WebhookSink defaultSink = (WebhookSink) provider.defaultSink; - Assert.assertEquals(true, defaultSink.verifySSL); - - AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); - provider.allSinks.get("endpoint1").store(msg); - - Assert.assertTrue(handler.method.equals("POST")); + protected HttpServer server = null; + + @Before + @After + public void tearDown() { + if (server != null) { + try { + server.stop(); + } catch (Exception e) { + // ignore + } + } + } + + @Test + public void testTlsConfigurationNoFallback() throws Exception { + + TestHttpHandler handler = new TestHttpHandler(); + + int port = findFreePort(); + server = ServerBootstrap.bootstrap() + .setListenerPort(port) + .setHttpProcessor(HttpProcessors.server("Test/1.1")) + .setSslContext(createSSLContext()) + .register("*", handler) + .create(); + + server.start(); + + Builder builder = Settings.builder() + .loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/sink/configuration_tls.yml")); + builder.put("path.home", "/"); + + // replace some values with absolute paths for unit tests + builder.put( + "plugins.security.audit.config.webhook.ssl.pemtrustedcas_filepath", + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/root-ca.pem") + ); + builder.put( + "plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.pemtrustedcas_filepath", + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/root-ca.pem") + ); + builder.put( + "plugins.security.audit.endpoints.endpoint2.config.webhook.ssl.pemtrustedcas_content", + FileHelper.loadFile("auditlog/root-ca.pem") + ); + + builder.put("plugins.security.audit.config.webhook.url", "https://localhost:" + port); + builder.put("plugins.security.audit.endpoints.endpoint1.config.webhook.url", "https://localhost:" + port); + builder.put("plugins.security.audit.endpoints.endpoint2.config.webhook.url", "https://localhost:" + port); + + SinkProvider provider = new SinkProvider(builder.build(), null, null, null); + WebhookSink defaultSink = (WebhookSink) provider.defaultSink; + Assert.assertEquals(true, defaultSink.verifySSL); + + AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); + provider.allSinks.get("endpoint1").store(msg); + + Assert.assertTrue(handler.method.equals("POST")); Assert.assertTrue(handler.body != null); Assert.assertTrue(handler.body.contains("{")); assertStringContainsAllKeysAndValues(handler.body); - handler.reset(); + handler.reset(); - provider.allSinks.get("endpoint2").store(msg); + provider.allSinks.get("endpoint2").store(msg); - Assert.assertTrue(handler.method.equals("POST")); + Assert.assertTrue(handler.method.equals("POST")); Assert.assertTrue(handler.body != null); Assert.assertTrue(handler.body.contains("{")); assertStringContainsAllKeysAndValues(handler.body); - handler.reset(); + handler.reset(); - provider.defaultSink.store(msg); + provider.defaultSink.store(msg); - Assert.assertTrue(handler.method.equals("POST")); + Assert.assertTrue(handler.method.equals("POST")); Assert.assertTrue(handler.body != null); Assert.assertTrue(handler.body.contains("{")); assertStringContainsAllKeysAndValues(handler.body); server.stop(); - } - - // for TLS support on our in-memory server - private SSLContext createSSLContext() throws Exception { - final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory - .getDefaultAlgorithm()); - final KeyStore trustStore = KeyStore.getInstance("JKS"); - InputStream trustStream = new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks").toFile()); - trustStore.load(trustStream, "changeit".toCharArray()); - tmf.init(trustStore); - - final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - final KeyStore keyStore = KeyStore.getInstance("JKS"); - InputStream keyStream = new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/node-0-keystore.jks").toFile()); - - keyStore.load(keyStream, "changeit".toCharArray()); - kmf.init(keyStore, "changeit".toCharArray()); - - SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); - sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); - return sslContext; - } - - private void assertStringContainsAllKeysAndValues(String in) { - System.out.println(in); - Assert.assertTrue(in, in.contains(AuditMessage.FORMAT_VERSION)); - Assert.assertTrue(in, in.contains(AuditMessage.CATEGORY)); - Assert.assertTrue(in, in.contains(AuditMessage.FORMAT_VERSION)); - Assert.assertTrue(in, in.contains(AuditMessage.REMOTE_ADDRESS)); - Assert.assertTrue(in, in.contains(AuditMessage.ORIGIN)); - Assert.assertTrue(in, in.contains(AuditMessage.REQUEST_LAYER)); - Assert.assertTrue(in, in.contains(AuditMessage.TRANSPORT_REQUEST_TYPE)); - Assert.assertTrue(in, in.contains(AuditMessage.UTC_TIMESTAMP)); - Assert.assertTrue(in, in.contains(AuditCategory.FAILED_LOGIN.name())); - Assert.assertTrue(in, in.contains("FAILED_LOGIN")); - Assert.assertTrue(in, in.contains("John Doe")); - Assert.assertTrue(in, in.contains("8.8.8.8")); - //Assert.assertTrue(in, in.contains("CN=kirk,OU=client,O=client,L=test,C=DE")); - } - - private int findFreePort() { - try (ServerSocket serverSocket = new ServerSocket(0)) { - return serverSocket.getLocalPort(); - } catch (IOException e) { - throw new RuntimeException("Failed to find free port", e); - } - } + } + + // for TLS support on our in-memory server + private SSLContext createSSLContext() throws Exception { + final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + final KeyStore trustStore = KeyStore.getInstance("JKS"); + InputStream trustStream = new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks").toFile()); + trustStore.load(trustStream, "changeit".toCharArray()); + tmf.init(trustStore); + + final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + final KeyStore keyStore = KeyStore.getInstance("JKS"); + InputStream keyStream = new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/node-0-keystore.jks").toFile()); + + keyStore.load(keyStream, "changeit".toCharArray()); + kmf.init(keyStore, "changeit".toCharArray()); + + SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); + sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + return sslContext; + } + + private void assertStringContainsAllKeysAndValues(String in) { + System.out.println(in); + Assert.assertTrue(in, in.contains(AuditMessage.FORMAT_VERSION)); + Assert.assertTrue(in, in.contains(AuditMessage.CATEGORY)); + Assert.assertTrue(in, in.contains(AuditMessage.FORMAT_VERSION)); + Assert.assertTrue(in, in.contains(AuditMessage.REMOTE_ADDRESS)); + Assert.assertTrue(in, in.contains(AuditMessage.ORIGIN)); + Assert.assertTrue(in, in.contains(AuditMessage.REQUEST_LAYER)); + Assert.assertTrue(in, in.contains(AuditMessage.TRANSPORT_REQUEST_TYPE)); + Assert.assertTrue(in, in.contains(AuditMessage.UTC_TIMESTAMP)); + Assert.assertTrue(in, in.contains(AuditCategory.FAILED_LOGIN.name())); + Assert.assertTrue(in, in.contains("FAILED_LOGIN")); + Assert.assertTrue(in, in.contains("John Doe")); + Assert.assertTrue(in, in.contains("8.8.8.8")); + // Assert.assertTrue(in, in.contains("CN=kirk,OU=client,O=client,L=test,C=DE")); + } + + private int findFreePort() { + try (ServerSocket serverSocket = new ServerSocket(0)) { + return serverSocket.getLocalPort(); + } catch (IOException e) { + throw new RuntimeException("Failed to find free port", e); + } + } } diff --git a/src/test/java/org/opensearch/security/auditlog/sink/SinkProviderTest.java b/src/test/java/org/opensearch/security/auditlog/sink/SinkProviderTest.java index 029192e097..5e3203261f 100644 --- a/src/test/java/org/opensearch/security/auditlog/sink/SinkProviderTest.java +++ b/src/test/java/org/opensearch/security/auditlog/sink/SinkProviderTest.java @@ -20,82 +20,85 @@ public class SinkProviderTest { - @Test - public void testConfiguration() throws Exception { - - Settings settings = Settings.builder().loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/sink/configuration_all_variants.yml")).build(); - SinkProvider provider = new SinkProvider(settings, null, null, null); - - // make sure we have a debug sink as fallback - Assert.assertEquals(DebugSink.class, provider.fallbackSink.getClass() ); - - AuditLogSink sink = provider.getSink("DefaULT"); - Assert.assertEquals(sink.getClass(), DebugSink.class); - - sink = provider.getSink("endpoint1"); - Assert.assertEquals(InternalOpenSearchSink.class, sink.getClass()); - - sink = provider.getSink("endpoint2"); - Assert.assertEquals(ExternalOpenSearchSink.class, sink.getClass()); - // todo: sink does not work - - sink = provider.getSink("endpoinT3"); - Assert.assertEquals(DebugSink.class, sink.getClass()); - - // no valid type - sink = provider.getSink("endpoint4"); - Assert.assertEquals(null, sink); - - sink = provider.getSink("endpoint2"); - Assert.assertEquals(ExternalOpenSearchSink.class, sink.getClass()); - // todo: sink does not work, no valid config - - // no valid type - sink = provider.getSink("endpoint6"); - Assert.assertEquals(null, sink); - - // no valid type - sink = provider.getSink("endpoint7"); - Assert.assertEquals(null, sink); - - sink = provider.getSink("endpoint8"); - Assert.assertEquals(DebugSink.class, sink.getClass()); - - // wrong type in config - sink = provider.getSink("endpoint9"); - Assert.assertEquals(ExternalOpenSearchSink.class, sink.getClass()); - - // log4j, valid configuration - sink = provider.getSink("endpoint10"); - Assert.assertEquals(Log4JSink.class, sink.getClass()); - Log4JSink lsink = (Log4JSink)sink; - Assert.assertEquals("loggername", lsink.loggerName); - Assert.assertEquals(Level.WARN, lsink.logLevel); - - // log4j, no level, fallback to default - sink = provider.getSink("endpoint11"); - Assert.assertEquals(Log4JSink.class, sink.getClass()); - lsink = (Log4JSink)sink; - Assert.assertEquals("loggername", lsink.loggerName); - Assert.assertEquals(Level.INFO, lsink.logLevel); - - // log4j, wrong level, fallback to log4j default - sink = provider.getSink("endpoint12"); - Assert.assertEquals(Log4JSink.class, sink.getClass()); - lsink = (Log4JSink)sink; - Assert.assertEquals("loggername", lsink.loggerName); - Assert.assertEquals(Level.DEBUG, lsink.logLevel); - - } - - @Test - public void testNoMultipleEndpointsConfiguration() throws Exception { - Settings settings = Settings.builder().loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/sink/configuration_no_multiple_endpoints.yml")).build(); - SinkProvider provider = new SinkProvider(settings, null, null, null); - InternalOpenSearchSink sink = (InternalOpenSearchSink)provider.defaultSink; - Assert.assertEquals("myownindex", sink.index); - Assert.assertEquals("auditevents", sink.type); - } - + @Test + public void testConfiguration() throws Exception { + + Settings settings = Settings.builder() + .loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/sink/configuration_all_variants.yml")) + .build(); + SinkProvider provider = new SinkProvider(settings, null, null, null); + + // make sure we have a debug sink as fallback + Assert.assertEquals(DebugSink.class, provider.fallbackSink.getClass()); + + AuditLogSink sink = provider.getSink("DefaULT"); + Assert.assertEquals(sink.getClass(), DebugSink.class); + + sink = provider.getSink("endpoint1"); + Assert.assertEquals(InternalOpenSearchSink.class, sink.getClass()); + + sink = provider.getSink("endpoint2"); + Assert.assertEquals(ExternalOpenSearchSink.class, sink.getClass()); + // todo: sink does not work + + sink = provider.getSink("endpoinT3"); + Assert.assertEquals(DebugSink.class, sink.getClass()); + + // no valid type + sink = provider.getSink("endpoint4"); + Assert.assertEquals(null, sink); + + sink = provider.getSink("endpoint2"); + Assert.assertEquals(ExternalOpenSearchSink.class, sink.getClass()); + // todo: sink does not work, no valid config + + // no valid type + sink = provider.getSink("endpoint6"); + Assert.assertEquals(null, sink); + + // no valid type + sink = provider.getSink("endpoint7"); + Assert.assertEquals(null, sink); + + sink = provider.getSink("endpoint8"); + Assert.assertEquals(DebugSink.class, sink.getClass()); + + // wrong type in config + sink = provider.getSink("endpoint9"); + Assert.assertEquals(ExternalOpenSearchSink.class, sink.getClass()); + + // log4j, valid configuration + sink = provider.getSink("endpoint10"); + Assert.assertEquals(Log4JSink.class, sink.getClass()); + Log4JSink lsink = (Log4JSink) sink; + Assert.assertEquals("loggername", lsink.loggerName); + Assert.assertEquals(Level.WARN, lsink.logLevel); + + // log4j, no level, fallback to default + sink = provider.getSink("endpoint11"); + Assert.assertEquals(Log4JSink.class, sink.getClass()); + lsink = (Log4JSink) sink; + Assert.assertEquals("loggername", lsink.loggerName); + Assert.assertEquals(Level.INFO, lsink.logLevel); + + // log4j, wrong level, fallback to log4j default + sink = provider.getSink("endpoint12"); + Assert.assertEquals(Log4JSink.class, sink.getClass()); + lsink = (Log4JSink) sink; + Assert.assertEquals("loggername", lsink.loggerName); + Assert.assertEquals(Level.DEBUG, lsink.logLevel); + + } + + @Test + public void testNoMultipleEndpointsConfiguration() throws Exception { + Settings settings = Settings.builder() + .loadFromPath(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/endpoints/sink/configuration_no_multiple_endpoints.yml")) + .build(); + SinkProvider provider = new SinkProvider(settings, null, null, null); + InternalOpenSearchSink sink = (InternalOpenSearchSink) provider.defaultSink; + Assert.assertEquals("myownindex", sink.index); + Assert.assertEquals("auditevents", sink.type); + } } 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 1e327750b6..2c2af154a0 100644 --- a/src/test/java/org/opensearch/security/auditlog/sink/WebhookAuditLogTest.java +++ b/src/test/java/org/opensearch/security/auditlog/sink/WebhookAuditLogTest.java @@ -51,326 +51,354 @@ public class WebhookAuditLogTest { @Before @After public void tearDown() { - if(server != null) { + if (server != null) { try { server.stop(); } catch (Exception e) { - //ignore + // ignore } } } - @Test - public void invalidConfFallbackTest() throws Exception { - AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); - - // provide no settings, fallback must be used - Settings settings = Settings.builder() - .put("path.home", ".") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .build(); - LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null); - MockWebhookAuditLog auditlog = new MockWebhookAuditLog(settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, fallback); - auditlog.store(msg); - // Webhook sink has failed ... - Assert.assertEquals(null, auditlog.webhookFormat); - // ... so message must be stored in fallback - Assert.assertEquals(1, fallback.messages.size()); - Assert.assertEquals(msg, fallback.messages.get(0)); - - } - - @Test - public void formatsTest() throws Exception { - - String url = "http://localhost"; - AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); - - // provide no format, defaults to TEXT - Settings settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("path.home", ".") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .put("plugins.security.ssl.transport.enforce_hostname_verification", false) - .build(); - - MockWebhookAuditLog auditlog = new MockWebhookAuditLog(settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null); - auditlog.store(msg); - Assert.assertEquals(WebhookFormat.TEXT, auditlog.webhookFormat); - Assert.assertEquals(ContentType.TEXT_PLAIN, auditlog.webhookFormat.getContentType()); - Assert.assertTrue(auditlog.payload, !auditlog.payload.startsWith("{\"text\":")); - - // provide faulty format, defaults to TEXT - settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "idonotexist") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .put("path.home", ".") - .build(); - auditlog = new MockWebhookAuditLog(settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null); - auditlog.store(msg); - Assert.assertEquals(WebhookFormat.TEXT, auditlog.webhookFormat); - Assert.assertEquals(ContentType.TEXT_PLAIN, auditlog.webhookFormat.getContentType()); - Assert.assertTrue(auditlog.payload, !auditlog.payload.startsWith("{\"text\":")); - auditlog.close(); - - // TEXT - settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "text") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .put("path.home", ".") - .build(); - auditlog = new MockWebhookAuditLog(settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null); - auditlog.store(msg); - Assert.assertEquals(WebhookFormat.TEXT, auditlog.webhookFormat); - Assert.assertEquals(ContentType.TEXT_PLAIN, auditlog.webhookFormat.getContentType()); - Assert.assertTrue(auditlog.payload, !auditlog.payload.startsWith("{\"text\":")); - Assert.assertTrue(auditlog.payload, auditlog.payload.contains(AuditMessage.UTC_TIMESTAMP)); - Assert.assertTrue(auditlog.payload, auditlog.payload.contains("audit_request_remote_address")); - - // JSON - settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "json") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .put("path.home", ".") - .build(); - auditlog = new MockWebhookAuditLog(settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null); - auditlog.store(msg); - System.out.println(auditlog.payload); - Assert.assertEquals(WebhookFormat.JSON, auditlog.webhookFormat); - Assert.assertEquals(ContentType.APPLICATION_JSON, auditlog.webhookFormat.getContentType()); - Assert.assertTrue(auditlog.payload, !auditlog.payload.startsWith("{\"text\":")); - Assert.assertTrue(auditlog.payload, auditlog.payload.contains(AuditMessage.UTC_TIMESTAMP)); + @Test + public void invalidConfFallbackTest() throws Exception { + AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); + + // provide no settings, fallback must be used + Settings settings = Settings.builder() + .put("path.home", ".") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .build(); + LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null); + MockWebhookAuditLog auditlog = new MockWebhookAuditLog(settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, fallback); + auditlog.store(msg); + // Webhook sink has failed ... + Assert.assertEquals(null, auditlog.webhookFormat); + // ... so message must be stored in fallback + Assert.assertEquals(1, fallback.messages.size()); + Assert.assertEquals(msg, fallback.messages.get(0)); + + } + + @Test + public void formatsTest() throws Exception { + + String url = "http://localhost"; + AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); + + // provide no format, defaults to TEXT + Settings settings = Settings.builder() + .put("plugins.security.audit.config.webhook.url", url) + .put("path.home", ".") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .put("plugins.security.ssl.transport.enforce_hostname_verification", false) + .build(); + + MockWebhookAuditLog auditlog = new MockWebhookAuditLog(settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null); + auditlog.store(msg); + Assert.assertEquals(WebhookFormat.TEXT, auditlog.webhookFormat); + Assert.assertEquals(ContentType.TEXT_PLAIN, auditlog.webhookFormat.getContentType()); + Assert.assertTrue(auditlog.payload, !auditlog.payload.startsWith("{\"text\":")); + + // provide faulty format, defaults to TEXT + settings = Settings.builder() + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "idonotexist") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .put("path.home", ".") + .build(); + auditlog = new MockWebhookAuditLog(settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null); + auditlog.store(msg); + Assert.assertEquals(WebhookFormat.TEXT, auditlog.webhookFormat); + Assert.assertEquals(ContentType.TEXT_PLAIN, auditlog.webhookFormat.getContentType()); + Assert.assertTrue(auditlog.payload, !auditlog.payload.startsWith("{\"text\":")); + auditlog.close(); + + // TEXT + settings = Settings.builder() + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "text") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .put("path.home", ".") + .build(); + auditlog = new MockWebhookAuditLog(settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null); + auditlog.store(msg); + Assert.assertEquals(WebhookFormat.TEXT, auditlog.webhookFormat); + Assert.assertEquals(ContentType.TEXT_PLAIN, auditlog.webhookFormat.getContentType()); + Assert.assertTrue(auditlog.payload, !auditlog.payload.startsWith("{\"text\":")); + Assert.assertTrue(auditlog.payload, auditlog.payload.contains(AuditMessage.UTC_TIMESTAMP)); + Assert.assertTrue(auditlog.payload, auditlog.payload.contains("audit_request_remote_address")); + + // JSON + settings = Settings.builder() + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "json") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .put("path.home", ".") + .build(); + auditlog = new MockWebhookAuditLog(settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null); + auditlog.store(msg); + System.out.println(auditlog.payload); + Assert.assertEquals(WebhookFormat.JSON, auditlog.webhookFormat); + Assert.assertEquals(ContentType.APPLICATION_JSON, auditlog.webhookFormat.getContentType()); + Assert.assertTrue(auditlog.payload, !auditlog.payload.startsWith("{\"text\":")); + Assert.assertTrue(auditlog.payload, auditlog.payload.contains(AuditMessage.UTC_TIMESTAMP)); Assert.assertTrue(auditlog.payload, auditlog.payload.contains("audit_request_remote_address")); - // SLACK - settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "slack") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .put("path.home", ".") - .build(); - auditlog = new MockWebhookAuditLog(settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null); - auditlog.store(msg); - Assert.assertEquals(WebhookFormat.SLACK, auditlog.webhookFormat); - Assert.assertEquals(ContentType.APPLICATION_JSON, auditlog.webhookFormat.getContentType()); - Assert.assertTrue(auditlog.payload, auditlog.payload.startsWith("{\"text\":")); - Assert.assertTrue(auditlog.payload, auditlog.payload.contains(AuditMessage.UTC_TIMESTAMP)); + // SLACK + settings = Settings.builder() + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "slack") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .put("path.home", ".") + .build(); + auditlog = new MockWebhookAuditLog(settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null); + auditlog.store(msg); + Assert.assertEquals(WebhookFormat.SLACK, auditlog.webhookFormat); + Assert.assertEquals(ContentType.APPLICATION_JSON, auditlog.webhookFormat.getContentType()); + Assert.assertTrue(auditlog.payload, auditlog.payload.startsWith("{\"text\":")); + Assert.assertTrue(auditlog.payload, auditlog.payload.contains(AuditMessage.UTC_TIMESTAMP)); Assert.assertTrue(auditlog.payload, auditlog.payload.contains("audit_request_remote_address")); - } - - - - @Test - public void invalidUrlTest() throws Exception { - - String url = "faultyurl"; - - final Settings settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "slack") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .put("path.home", ".") - .build(); - LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null);; - MockWebhookAuditLog auditlog = new MockWebhookAuditLog(settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, fallback); - AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); - auditlog.store(msg); - Assert.assertEquals(null, auditlog.url); - Assert.assertEquals(null, auditlog.payload); - Assert.assertEquals(null, auditlog.webhookUrl); - // message must be stored in fallback - Assert.assertEquals(1, fallback.messages.size()); - Assert.assertEquals(msg, fallback.messages.get(0)); - } - - @Test - public void noServerRunningHttpTest() throws Exception { - String url = "http://localhost:8080/endpoint"; - - Settings settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "slack") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .put("path.home", ".") - .build(); - - LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null);; - WebhookSink auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); - AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); - auditlog.store(msg); - // can't connect, no server running ... - Assert.assertEquals("http://localhost:8080/endpoint", auditlog.webhookUrl); - // ... message must be stored in fallback - Assert.assertEquals(1, fallback.messages.size()); - Assert.assertEquals(msg, fallback.messages.get(0)); - } - - - @Test - public void postGetHttpTest() throws Exception { - TestHttpHandler handler = new TestHttpHandler(); - - int port = findFreePort(); - server = ServerBootstrap.bootstrap() - .setListenerPort(port) - .setHttpProcessor(HttpProcessors.server("Test/1.1")) - .register("*", handler) - .create(); - - server.start(); - - String url = "http://localhost:" + port + "/endpoint"; - - // SLACK - Settings settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "slack") - .put("path.home", ".") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .build(); - - LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null);; - WebhookSink auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); - AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); - auditlog.store(msg); - Assert.assertTrue(handler.method.equals("POST")); - Assert.assertTrue(handler.body != null); - Assert.assertTrue(handler.body.startsWith("{\"text\":")); - assertStringContainsAllKeysAndValues(handler.body); - // no message stored on fallback - Assert.assertEquals(0, fallback.messages.size()); - handler.reset(); - - // TEXT - settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "texT") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .put("path.home", ".") - .build(); - - auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); - auditlog.store(msg); - Assert.assertTrue(handler.method.equals("POST")); - Assert.assertTrue(handler.body != null); - System.out.println(handler.body); - Assert.assertFalse(handler.body.contains("{")); - assertStringContainsAllKeysAndValues(handler.body); - handler.reset(); - - // JSON - settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "JSon") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .put("path.home", ".") - .build(); - - auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); - auditlog.store(msg); - Assert.assertTrue(handler.method.equals("POST")); - Assert.assertTrue(handler.body != null); - Assert.assertTrue(handler.body.contains("{")); - assertStringContainsAllKeysAndValues(handler.body); - handler.reset(); - - // URL POST - settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "URL_PARAMETER_POST") - .put("path.home", ".") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .build(); - - auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); - auditlog.store(msg); - Assert.assertTrue(handler.method.equals("POST")); - Assert.assertTrue(handler.body.equals("")); - Assert.assertTrue(!handler.body.contains("{")); - assertStringContainsAllKeysAndValues(URLDecoder.decode(handler.uri, StandardCharsets.UTF_8.displayName())); - handler.reset(); - - // URL GET - settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "URL_PARAMETER_GET") - .put("path.home", ".") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .build(); - - auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); - auditlog.store(msg); - Assert.assertTrue(handler.method.equals("GET")); - Assert.assertEquals(null, handler.body); - assertStringContainsAllKeysAndValues(URLDecoder.decode(handler.uri, StandardCharsets.UTF_8.displayName())); - server.awaitTermination(TimeValue.ofSeconds(3)); - } - - @Test - public void httpsTestWithoutTLSServer() throws Exception { - - TestHttpHandler handler = new TestHttpHandler(); - - int port = findFreePort(); - server = ServerBootstrap.bootstrap() - .setListenerPort(port) - .setHttpProcessor(HttpProcessors.server("Test/1.1")) - .register("*", handler) - .create(); - - server.start(); - - String url = "https://localhost:" + port + "/endpoint"; - - Settings settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "slack") - .put("path.home", ".") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .build(); - - LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null);; - WebhookSink auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); - AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); - auditlog.store(msg); - Assert.assertTrue(handler.method == null); - Assert.assertTrue(handler.body == null); - Assert.assertTrue(handler.uri == null); - // ... so message must be stored in fallback - Assert.assertEquals(1, fallback.messages.size()); - Assert.assertEquals(msg, fallback.messages.get(0)); - server.awaitTermination(TimeValue.ofSeconds(3)); - } - - - @Test + } + + @Test + public void invalidUrlTest() throws Exception { + + String url = "faultyurl"; + + final Settings settings = Settings.builder() + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "slack") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .put("path.home", ".") + .build(); + LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null); + ; + MockWebhookAuditLog auditlog = new MockWebhookAuditLog(settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, fallback); + AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); + auditlog.store(msg); + Assert.assertEquals(null, auditlog.url); + Assert.assertEquals(null, auditlog.payload); + Assert.assertEquals(null, auditlog.webhookUrl); + // message must be stored in fallback + Assert.assertEquals(1, fallback.messages.size()); + Assert.assertEquals(msg, fallback.messages.get(0)); + } + + @Test + public void noServerRunningHttpTest() throws Exception { + String url = "http://localhost:8080/endpoint"; + + Settings settings = Settings.builder() + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "slack") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .put("path.home", ".") + .build(); + + LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null); + ; + WebhookSink auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); + AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); + auditlog.store(msg); + // can't connect, no server running ... + Assert.assertEquals("http://localhost:8080/endpoint", auditlog.webhookUrl); + // ... message must be stored in fallback + Assert.assertEquals(1, fallback.messages.size()); + Assert.assertEquals(msg, fallback.messages.get(0)); + } + + @Test + public void postGetHttpTest() throws Exception { + TestHttpHandler handler = new TestHttpHandler(); + + int port = findFreePort(); + server = ServerBootstrap.bootstrap() + .setListenerPort(port) + .setHttpProcessor(HttpProcessors.server("Test/1.1")) + .register("*", handler) + .create(); + + server.start(); + + String url = "http://localhost:" + port + "/endpoint"; + + // SLACK + Settings settings = Settings.builder() + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "slack") + .put("path.home", ".") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .build(); + + LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null); + ; + WebhookSink auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); + AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); + auditlog.store(msg); + Assert.assertTrue(handler.method.equals("POST")); + Assert.assertTrue(handler.body != null); + Assert.assertTrue(handler.body.startsWith("{\"text\":")); + assertStringContainsAllKeysAndValues(handler.body); + // no message stored on fallback + Assert.assertEquals(0, fallback.messages.size()); + handler.reset(); + + // TEXT + settings = Settings.builder() + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "texT") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .put("path.home", ".") + .build(); + + auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); + auditlog.store(msg); + Assert.assertTrue(handler.method.equals("POST")); + Assert.assertTrue(handler.body != null); + System.out.println(handler.body); + Assert.assertFalse(handler.body.contains("{")); + assertStringContainsAllKeysAndValues(handler.body); + handler.reset(); + + // JSON + settings = Settings.builder() + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "JSon") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .put("path.home", ".") + .build(); + + auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); + auditlog.store(msg); + Assert.assertTrue(handler.method.equals("POST")); + Assert.assertTrue(handler.body != null); + Assert.assertTrue(handler.body.contains("{")); + assertStringContainsAllKeysAndValues(handler.body); + handler.reset(); + + // URL POST + settings = Settings.builder() + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "URL_PARAMETER_POST") + .put("path.home", ".") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .build(); + + auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); + auditlog.store(msg); + Assert.assertTrue(handler.method.equals("POST")); + Assert.assertTrue(handler.body.equals("")); + Assert.assertTrue(!handler.body.contains("{")); + assertStringContainsAllKeysAndValues(URLDecoder.decode(handler.uri, StandardCharsets.UTF_8.displayName())); + handler.reset(); + + // URL GET + settings = Settings.builder() + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "URL_PARAMETER_GET") + .put("path.home", ".") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .build(); + + auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); + auditlog.store(msg); + Assert.assertTrue(handler.method.equals("GET")); + Assert.assertEquals(null, handler.body); + assertStringContainsAllKeysAndValues(URLDecoder.decode(handler.uri, StandardCharsets.UTF_8.displayName())); + server.awaitTermination(TimeValue.ofSeconds(3)); + } + + @Test + public void httpsTestWithoutTLSServer() throws Exception { + + TestHttpHandler handler = new TestHttpHandler(); + + int port = findFreePort(); + server = ServerBootstrap.bootstrap() + .setListenerPort(port) + .setHttpProcessor(HttpProcessors.server("Test/1.1")) + .register("*", handler) + .create(); + + server.start(); + + String url = "https://localhost:" + port + "/endpoint"; + + Settings settings = Settings.builder() + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "slack") + .put("path.home", ".") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .build(); + + LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null); + ; + WebhookSink auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); + AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); + auditlog.store(msg); + Assert.assertTrue(handler.method == null); + Assert.assertTrue(handler.body == null); + Assert.assertTrue(handler.uri == null); + // ... so message must be stored in fallback + Assert.assertEquals(1, fallback.messages.size()); + Assert.assertEquals(msg, fallback.messages.get(0)); + server.awaitTermination(TimeValue.ofSeconds(3)); + } + + @Test public void httpsTest() throws Exception { TestHttpHandler handler = new TestHttpHandler(); - int port = findFreePort(); + int port = findFreePort(); server = ServerBootstrap.bootstrap() - .setListenerPort(port) - .setHttpProcessor(HttpProcessors.server("Test/1.1")) - .setSslContext(createSSLContext()) - .register("*", handler) - .create(); + .setListenerPort(port) + .setHttpProcessor(HttpProcessors.server("Test/1.1")) + .setSslContext(createSSLContext()) + .register("*", handler) + .create(); server.start(); AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); @@ -379,30 +407,30 @@ public void httpsTest() throws Exception { // try with ssl verification on, no trust ca, must fail Settings settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "slack") - .put("path.home", ".") - .put("plugins.security.audit.config.webhook.ssl.verify", true) - .build(); - - LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null); - WebhookSink auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "slack") + .put("path.home", ".") + .put("plugins.security.audit.config.webhook.ssl.verify", true) + .build(); + + LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null); + WebhookSink auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); auditlog.store(msg); Assert.assertNull(handler.method); Assert.assertNull(handler.body); Assert.assertNull(handler.body); - // message must be stored in fallback - Assert.assertEquals(1, fallback.messages.size()); - Assert.assertEquals(msg, fallback.messages.get(0)); + // message must be stored in fallback + Assert.assertEquals(1, fallback.messages.size()); + Assert.assertEquals(msg, fallback.messages.get(0)); // disable ssl verification, no ca, call must succeed handler.reset(); settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "jSoN") - .put("plugins.security.audit.config.webhook.ssl.verify", false) - .put("path.home", ".") - .build(); + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "jSoN") + .put("plugins.security.audit.config.webhook.ssl.verify", false) + .put("path.home", ".") + .build(); auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); auditlog.store(msg); Assert.assertTrue(handler.method.equals("POST")); @@ -413,12 +441,15 @@ public void httpsTest() throws Exception { // enable ssl verification, provide correct trust ca, call must succeed handler.reset(); settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "jSoN") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .put("plugins.security.audit.config.webhook.ssl.verify", true) - .put("path.home", ".") - .build(); + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "jSoN") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .put("plugins.security.audit.config.webhook.ssl.verify", true) + .put("path.home", ".") + .build(); auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); auditlog.store(msg); Assert.assertTrue(handler.method.equals("POST")); @@ -429,48 +460,54 @@ public void httpsTest() throws Exception { // enable ssl verification, provide wrong trust ca, call must succeed handler.reset(); settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "jSoN") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore_fail.jks")) - .put("plugins.security.audit.config.webhook.ssl.verify", true) - .put("path.home", ".") - .build(); + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "jSoN") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore_fail.jks") + ) + .put("plugins.security.audit.config.webhook.ssl.verify", true) + .put("path.home", ".") + .build(); auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); auditlog.store(msg); Assert.assertNull(handler.method); Assert.assertNull(handler.body); Assert.assertNull(handler.body); - server.awaitTermination(TimeValue.ofSeconds(3)); + server.awaitTermination(TimeValue.ofSeconds(3)); } - @Test + @Test public void httpsTestPemDefault() throws Exception { final int port = findFreePort(); - TestHttpHandler handler = new TestHttpHandler(); + TestHttpHandler handler = new TestHttpHandler(); server = ServerBootstrap.bootstrap() - .setListenerPort(port) - .setHttpProcessor(HttpProcessors.server("Test/1.1")) - .setSslContext(createSSLContext()) - .register("*", handler) - .create(); + .setListenerPort(port) + .setHttpProcessor(HttpProcessors.server("Test/1.1")) + .setSslContext(createSSLContext()) + .register("*", handler) + .create(); server.start(); AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); - LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null); + LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null); String url = "https://localhost:" + port + "/endpoint"; // test default with filepath handler.reset(); Settings settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "jSoN") - .put("plugins.security.audit.config.webhook.ssl.pemtrustedcas_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/root-ca.pem")) - .put("plugins.security.audit.config.webhook.ssl.verify", true) - .put("path.home", ".") - .build(); + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "jSoN") + .put( + "plugins.security.audit.config.webhook.ssl.pemtrustedcas_filepath", + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/root-ca.pem") + ) + .put("plugins.security.audit.config.webhook.ssl.verify", true) + .put("path.home", ".") + .build(); AuditLogSink auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); auditlog.store(msg); Assert.assertTrue(handler.method.equals("POST")); @@ -481,12 +518,15 @@ public void httpsTestPemDefault() throws Exception { // test default with missing filepath and fallback to correct Security settings handler.reset(); settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "jSoN") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .put("plugins.security.audit.config.webhook.ssl.verify", true) - .put("path.home", ".") - .build(); + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "jSoN") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .put("plugins.security.audit.config.webhook.ssl.verify", true) + .put("path.home", ".") + .build(); auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); auditlog.store(msg); Assert.assertTrue(handler.method.equals("POST")); @@ -497,13 +537,16 @@ public void httpsTestPemDefault() throws Exception { // test default with wrong filepath and fallback to wrong Security settings handler.reset(); settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "jSoN") - .put("plugins.security.audit.config.webhook.ssl.pemtrustedcas_filepath", "wrong") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore_fail.jks")) - .put("plugins.security.audit.config.webhook.ssl.verify", true) - .put("path.home", ".") - .build(); + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "jSoN") + .put("plugins.security.audit.config.webhook.ssl.pemtrustedcas_filepath", "wrong") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore_fail.jks") + ) + .put("plugins.security.audit.config.webhook.ssl.verify", true) + .put("path.home", ".") + .build(); auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); auditlog.store(msg); Assert.assertNull(handler.method); @@ -513,12 +556,12 @@ public void httpsTestPemDefault() throws Exception { // test default with wrong/no filepath and no fallback to Security settings, must fail handler.reset(); settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.ssl.pemtrustedcas_filepath", "wrong") - .put("plugins.security.audit.config.webhook.format", "jSoN") - .put("plugins.security.audit.config.webhook.ssl.verify", true) - .put("path.home", ".") - .build(); + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.ssl.pemtrustedcas_filepath", "wrong") + .put("plugins.security.audit.config.webhook.format", "jSoN") + .put("plugins.security.audit.config.webhook.ssl.verify", true) + .put("path.home", ".") + .build(); auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); auditlog.store(msg); Assert.assertNull(handler.method); @@ -528,12 +571,15 @@ public void httpsTestPemDefault() throws Exception { // test default with existing but wrong PEM, no fallback handler.reset(); settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "jSoN") - .put("plugins.security.audit.config.webhook.ssl.pemtrustedcas_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/spock.crt.pem")) - .put("plugins.security.audit.config.webhook.ssl.verify", true) - .put("path.home", ".") - .build(); + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "jSoN") + .put( + "plugins.security.audit.config.webhook.ssl.pemtrustedcas_filepath", + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/spock.crt.pem") + ) + .put("plugins.security.audit.config.webhook.ssl.verify", true) + .put("path.home", ".") + .build(); auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); auditlog.store(msg); Assert.assertNull(handler.method); @@ -543,49 +589,58 @@ public void httpsTestPemDefault() throws Exception { // test default with existing but wrong PEM, fallback present but pemtrustedcas_filepath takes precedence and must fail handler.reset(); settings = Settings.builder() - .put("plugins.security.audit.config.webhook.url", url) - .put("plugins.security.audit.config.webhook.format", "jSoN") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .put("plugins.security.audit.config.webhook.ssl.pemtrustedcas_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/spock.crt.pem")) - .put("plugins.security.audit.config.webhook.ssl.verify", true) - .put("path.home", ".") - .build(); + .put("plugins.security.audit.config.webhook.url", url) + .put("plugins.security.audit.config.webhook.format", "jSoN") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .put( + "plugins.security.audit.config.webhook.ssl.pemtrustedcas_filepath", + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/spock.crt.pem") + ) + .put("plugins.security.audit.config.webhook.ssl.verify", true) + .put("path.home", ".") + .build(); auditlog = new WebhookSink("name", settings, ConfigConstants.SECURITY_AUDIT_CONFIG_DEFAULT, null, fallback); auditlog.store(msg); Assert.assertNull(handler.method); Assert.assertNull(handler.body); Assert.assertNull(handler.body); - server.awaitTermination(TimeValue.ofSeconds(3)); - } + server.awaitTermination(TimeValue.ofSeconds(3)); + } - @Test + @Test public void httpsTestPemEndpoint() throws Exception { TestHttpHandler handler = new TestHttpHandler(); - int port = findFreePort(); + int port = findFreePort(); server = ServerBootstrap.bootstrap() - .setListenerPort(port) - .setHttpProcessor(HttpProcessors.server("Test/1.1")) - .setSslContext(createSSLContext()) - .register("*", handler) - .create(); + .setListenerPort(port) + .setHttpProcessor(HttpProcessors.server("Test/1.1")) + .setSslContext(createSSLContext()) + .register("*", handler) + .create(); server.start(); AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); - LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null); + LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null); String url = "https://localhost:" + port + "/endpoint"; // test default with filepath handler.reset(); Settings settings = Settings.builder() - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.url", url) - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.format", "jSoN") - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.pemtrustedcas_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/root-ca.pem")) - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.verify", true) - .put("path.home", ".") - .build(); + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.url", url) + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.format", "jSoN") + .put( + "plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.pemtrustedcas_filepath", + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/root-ca.pem") + ) + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.verify", true) + .put("path.home", ".") + .build(); AuditLogSink auditlog = new WebhookSink("name", settings, "plugins.security.audit.endpoints.endpoint1.config", null, fallback); auditlog.store(msg); Assert.assertTrue(handler.method.equals("POST")); @@ -596,12 +651,15 @@ public void httpsTestPemEndpoint() throws Exception { // test default with missing filepath and fallback to correct Security settings handler.reset(); settings = Settings.builder() - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.url", url) - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.format", "jSoN") - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.verify", true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .put("path.home", ".") - .build(); + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.url", url) + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.format", "jSoN") + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.verify", true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks") + ) + .put("path.home", ".") + .build(); auditlog = new WebhookSink("name", settings, "plugins.security.audit.endpoints.endpoint1.config", null, fallback); auditlog.store(msg); Assert.assertTrue(handler.method.equals("POST")); @@ -612,12 +670,15 @@ public void httpsTestPemEndpoint() throws Exception { // test default with wrong filepath and fallback to wrong Security settings handler.reset(); settings = Settings.builder() - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.url", url) - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.format", "jSoN") - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.verify", true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore_fail.jks")) - .put("path.home", ".") - .build(); + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.url", url) + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.format", "jSoN") + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.verify", true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore_fail.jks") + ) + .put("path.home", ".") + .build(); auditlog = new WebhookSink("name", settings, "plugins.security.audit.endpoints.endpoint1.config", null, fallback); auditlog.store(msg); Assert.assertNull(handler.method); @@ -627,11 +688,11 @@ public void httpsTestPemEndpoint() throws Exception { // test default with wrong/no filepath and no fallback to Security settings, must fail handler.reset(); settings = Settings.builder() - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.url", url) - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.format", "jSoN") - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.verify", true) - .put("path.home", ".") - .build(); + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.url", url) + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.format", "jSoN") + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.verify", true) + .put("path.home", ".") + .build(); auditlog = new WebhookSink("name", settings, "plugins.security.audit.endpoints.endpoint1.config", null, fallback); auditlog.store(msg); Assert.assertNull(handler.method); @@ -641,49 +702,55 @@ public void httpsTestPemEndpoint() throws Exception { // test default with existing but wrong PEM, no fallback handler.reset(); settings = Settings.builder() - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.url", url) - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.format", "jSoN") - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.verify", true) - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.pemtrustedcas_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/spock.crt.pem")) - .put("path.home", ".") - .build(); + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.url", url) + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.format", "jSoN") + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.verify", true) + .put( + "plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.pemtrustedcas_filepath", + FileHelper.getAbsoluteFilePathFromClassPath("auditlog/spock.crt.pem") + ) + .put("path.home", ".") + .build(); auditlog = new WebhookSink("name", settings, "plugins.security.audit.endpoints.endpoint1.config", null, fallback); auditlog.store(msg); Assert.assertNull(handler.method); Assert.assertNull(handler.body); Assert.assertNull(handler.body); - server.awaitTermination(TimeValue.ofSeconds(3)); - } + server.awaitTermination(TimeValue.ofSeconds(3)); + } - @Test + @Test public void httpsTestPemContentEndpoint() throws Exception { TestHttpHandler handler = new TestHttpHandler(); - int port = findFreePort(); + int port = findFreePort(); server = ServerBootstrap.bootstrap() - .setListenerPort(port) - .setHttpProcessor(HttpProcessors.server("Test/1.1")) - .setSslContext(createSSLContext()) - .register("*", handler) - .create(); + .setListenerPort(port) + .setHttpProcessor(HttpProcessors.server("Test/1.1")) + .setSslContext(createSSLContext()) + .register("*", handler) + .create(); server.start(); AuditMessage msg = MockAuditMessageFactory.validAuditMessage(); - LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null); + LoggingSink fallback = new LoggingSink("test", Settings.EMPTY, null, null); String url = "https://localhost:" + port + "/endpoint"; - // test with filecontent + // test with filecontent handler.reset(); Settings settings = Settings.builder() - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.url", url) - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.format", "jSoN") - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.pemtrustedcas_content", FileHelper.loadFile("auditlog/root-ca.pem")) - .put("plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.verify", true) - .put("path.home", ".") - .build(); + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.url", url) + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.format", "jSoN") + .put( + "plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.pemtrustedcas_content", + FileHelper.loadFile("auditlog/root-ca.pem") + ) + .put("plugins.security.audit.endpoints.endpoint1.config.webhook.ssl.verify", true) + .put("path.home", ".") + .build(); AuditLogSink auditlog = new WebhookSink("name", settings, "plugins.security.audit.endpoints.endpoint1.config", null, fallback); auditlog.store(msg); @@ -692,52 +759,51 @@ public void httpsTestPemContentEndpoint() throws Exception { Assert.assertTrue(handler.body.contains("{")); assertStringContainsAllKeysAndValues(handler.body); - server.awaitTermination(TimeValue.ofSeconds(3)); - } - - // for TLS support on our in-memory server - private SSLContext createSSLContext() throws Exception { - final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory - .getDefaultAlgorithm()); - final KeyStore trustStore = KeyStore.getInstance("JKS"); - InputStream trustStream = new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks").toFile()); - trustStore.load(trustStream, "changeit".toCharArray()); - tmf.init(trustStore); - - final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - final KeyStore keyStore = KeyStore.getInstance("JKS"); - InputStream keyStream = new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/node-0-keystore.jks").toFile()); - - keyStore.load(keyStream, "changeit".toCharArray()); - kmf.init(keyStore, "changeit".toCharArray()); - - SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); - sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); - return sslContext; - } - - private void assertStringContainsAllKeysAndValues(String in) { - System.out.println(in); - Assert.assertTrue(in, in.contains(AuditMessage.FORMAT_VERSION)); - Assert.assertTrue(in, in.contains(AuditMessage.CATEGORY)); - Assert.assertTrue(in, in.contains(AuditMessage.FORMAT_VERSION)); - Assert.assertTrue(in, in.contains(AuditMessage.REMOTE_ADDRESS)); - Assert.assertTrue(in, in.contains(AuditMessage.ORIGIN)); - Assert.assertTrue(in, in.contains(AuditMessage.REQUEST_LAYER)); - Assert.assertTrue(in, in.contains(AuditMessage.TRANSPORT_REQUEST_TYPE)); - Assert.assertTrue(in, in.contains(AuditMessage.UTC_TIMESTAMP)); - Assert.assertTrue(in, in.contains(AuditCategory.FAILED_LOGIN.name())); - Assert.assertTrue(in, in.contains("FAILED_LOGIN")); - Assert.assertTrue(in, in.contains("John Doe")); - Assert.assertTrue(in, in.contains("8.8.8.8")); - //Assert.assertTrue(in, in.contains("CN=kirk,OU=client,O=client,L=test,C=DE")); - } - - private int findFreePort() { - try (ServerSocket serverSocket = new ServerSocket(0)) { - return serverSocket.getLocalPort(); - } catch (IOException e) { - throw new RuntimeException("Failed to find free port", e); - } - } + server.awaitTermination(TimeValue.ofSeconds(3)); + } + + // for TLS support on our in-memory server + private SSLContext createSSLContext() throws Exception { + final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + final KeyStore trustStore = KeyStore.getInstance("JKS"); + InputStream trustStream = new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks").toFile()); + trustStore.load(trustStream, "changeit".toCharArray()); + tmf.init(trustStore); + + final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + final KeyStore keyStore = KeyStore.getInstance("JKS"); + InputStream keyStream = new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath("auditlog/node-0-keystore.jks").toFile()); + + keyStore.load(keyStream, "changeit".toCharArray()); + kmf.init(keyStore, "changeit".toCharArray()); + + SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); + sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + return sslContext; + } + + private void assertStringContainsAllKeysAndValues(String in) { + System.out.println(in); + Assert.assertTrue(in, in.contains(AuditMessage.FORMAT_VERSION)); + Assert.assertTrue(in, in.contains(AuditMessage.CATEGORY)); + Assert.assertTrue(in, in.contains(AuditMessage.FORMAT_VERSION)); + Assert.assertTrue(in, in.contains(AuditMessage.REMOTE_ADDRESS)); + Assert.assertTrue(in, in.contains(AuditMessage.ORIGIN)); + Assert.assertTrue(in, in.contains(AuditMessage.REQUEST_LAYER)); + Assert.assertTrue(in, in.contains(AuditMessage.TRANSPORT_REQUEST_TYPE)); + Assert.assertTrue(in, in.contains(AuditMessage.UTC_TIMESTAMP)); + Assert.assertTrue(in, in.contains(AuditCategory.FAILED_LOGIN.name())); + Assert.assertTrue(in, in.contains("FAILED_LOGIN")); + Assert.assertTrue(in, in.contains("John Doe")); + Assert.assertTrue(in, in.contains("8.8.8.8")); + // Assert.assertTrue(in, in.contains("CN=kirk,OU=client,O=client,L=test,C=DE")); + } + + private int findFreePort() { + try (ServerSocket serverSocket = new ServerSocket(0)) { + return serverSocket.getLocalPort(); + } catch (IOException e) { + throw new RuntimeException("Failed to find free port", e); + } + } } diff --git a/src/test/java/org/opensearch/security/auth/InternalAuthBackendTests.java b/src/test/java/org/opensearch/security/auth/InternalAuthBackendTests.java index 3821be7038..c059c890ab 100644 --- a/src/test/java/org/opensearch/security/auth/InternalAuthBackendTests.java +++ b/src/test/java/org/opensearch/security/auth/InternalAuthBackendTests.java @@ -51,7 +51,7 @@ private char[] createArrayFromPasswordBytes(byte[] password) { CharBuffer buf = StandardCharsets.UTF_8.decode(wrap); char[] array = new char[buf.limit()]; buf.get(array); - Arrays.fill(password, (byte)0); + Arrays.fill(password, (byte) 0); return array; } @@ -68,12 +68,11 @@ public void testHashActionWithValidUserValidPassword() { char[] array = createArrayFromPasswordBytes(validPasswordBytes); - when(internalUsersModel.getHash(validUsernameAuth.getUsername())).thenReturn(hash); when(internalUsersModel.exists(validUsernameAuth.getUsername())).thenReturn(true); doReturn(true).when(internalAuthenticationBackend).passwordMatchesHash(Mockito.any(String.class), Mockito.any(char[].class)); - //Act + // Act internalAuthenticationBackend.authenticate(validUsernameAuth); verify(internalAuthenticationBackend, times(1)).passwordMatchesHash(hash, array); @@ -95,9 +94,11 @@ public void testHashActionWithValidUserInvalidPassword() { when(internalUsersModel.getHash("admin")).thenReturn(hash); when(internalUsersModel.exists("admin")).thenReturn(true); - OpenSearchSecurityException ex = Assert.assertThrows(OpenSearchSecurityException.class, - () -> internalAuthenticationBackend.authenticate(validUsernameAuth)); - assert(ex.getMessage().contains("password does not match")); + OpenSearchSecurityException ex = Assert.assertThrows( + OpenSearchSecurityException.class, + () -> internalAuthenticationBackend.authenticate(validUsernameAuth) + ); + assert (ex.getMessage().contains("password does not match")); verify(internalAuthenticationBackend, times(1)).passwordMatchesHash(hash, array); } @@ -114,11 +115,13 @@ public void testHashActionWithInvalidUserValidPassword() { char[] array = createArrayFromPasswordBytes(validPasswordBytes); when(internalUsersModel.exists("ertyuiykgjjfguyifdghc")).thenReturn(false); - when(internalAuthenticationBackend.passwordMatchesHash(hash, array)).thenReturn(true); //Say that the password is correct + when(internalAuthenticationBackend.passwordMatchesHash(hash, array)).thenReturn(true); // Say that the password is correct - OpenSearchSecurityException ex = Assert.assertThrows(OpenSearchSecurityException.class, - () -> internalAuthenticationBackend.authenticate(invalidUsernameAuth)); - assert(ex.getMessage().contains("not found")); + OpenSearchSecurityException ex = Assert.assertThrows( + OpenSearchSecurityException.class, + () -> internalAuthenticationBackend.authenticate(invalidUsernameAuth) + ); + assert (ex.getMessage().contains("not found")); verify(internalAuthenticationBackend, times(1)).passwordMatchesHash(hash, array); } @@ -136,10 +139,11 @@ public void testHashActionWithInvalidUserInvalidPassword() { when(internalUsersModel.exists("ertyuiykgjjfguyifdghc")).thenReturn(false); - - OpenSearchSecurityException ex = Assert.assertThrows(OpenSearchSecurityException.class, - () -> internalAuthenticationBackend.authenticate(invalidUsernameAuth)); + OpenSearchSecurityException ex = Assert.assertThrows( + OpenSearchSecurityException.class, + () -> internalAuthenticationBackend.authenticate(invalidUsernameAuth) + ); verify(internalAuthenticationBackend, times(1)).passwordMatchesHash(hash, array); - assert(ex.getMessage().contains("not found")); + assert (ex.getMessage().contains("not found")); } } diff --git a/src/test/java/org/opensearch/security/auth/RolesInjectorTest.java b/src/test/java/org/opensearch/security/auth/RolesInjectorTest.java index 0656f9ccd1..63eb32f862 100644 --- a/src/test/java/org/opensearch/security/auth/RolesInjectorTest.java +++ b/src/test/java/org/opensearch/security/auth/RolesInjectorTest.java @@ -34,7 +34,6 @@ import static org.mockito.Mockito.mock; import static org.opensearch.security.support.ConfigConstants.OPENDISTRO_SECURITY_INJECTED_ROLES; - public class RolesInjectorTest { private TransportRequest transportRequest; @@ -76,13 +75,7 @@ public void testInjected() { @Test public void testCorruptedInjection() { - List corruptedStrs = Arrays.asList( - "invalid", - "role_1,role_2", - " | ", - " ", - "|" - ); + List corruptedStrs = Arrays.asList("invalid", "role_1,role_2", " | ", " ", "|"); corruptedStrs.forEach(name -> { ThreadContext threadContext = new ThreadContext(Settings.EMPTY); diff --git a/src/test/java/org/opensearch/security/auth/UserInjectorTest.java b/src/test/java/org/opensearch/security/auth/UserInjectorTest.java index 09bc1653a4..e9570b1455 100644 --- a/src/test/java/org/opensearch/security/auth/UserInjectorTest.java +++ b/src/test/java/org/opensearch/security/auth/UserInjectorTest.java @@ -43,9 +43,7 @@ public class UserInjectorTest { @Before public void setup() { threadPool = mock(ThreadPool.class); - Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true) - .build(); + Settings settings = Settings.builder().put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true).build(); threadContext = new ThreadContext(settings); Mockito.when(threadPool.getThreadContext()).thenReturn(threadContext); transportRequest = mock(TransportRequest.class); diff --git a/src/test/java/org/opensearch/security/auth/blocking/HeapBasedClientBlockRegistryTest.java b/src/test/java/org/opensearch/security/auth/blocking/HeapBasedClientBlockRegistryTest.java index 391b48ed70..3adc7a577f 100644 --- a/src/test/java/org/opensearch/security/auth/blocking/HeapBasedClientBlockRegistryTest.java +++ b/src/test/java/org/opensearch/security/auth/blocking/HeapBasedClientBlockRegistryTest.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.auth.blocking; @@ -23,33 +23,33 @@ import static org.junit.Assert.assertTrue; public class HeapBasedClientBlockRegistryTest { - + @Test - public void simpleTest() throws Exception { + public void simpleTest() throws Exception { HeapBasedClientBlockRegistry registry = new HeapBasedClientBlockRegistry<>(50, 3, String.class); - + assertFalse(registry.isBlocked("a")); registry.block("a"); assertTrue(registry.isBlocked("a")); - + registry.block("b"); assertTrue(registry.isBlocked("a")); assertTrue(registry.isBlocked("b")); - + registry.block("c"); assertTrue(registry.isBlocked("a")); assertTrue(registry.isBlocked("b")); assertTrue(registry.isBlocked("c")); - + registry.block("d"); assertFalse(registry.isBlocked("a")); assertTrue(registry.isBlocked("b")); assertTrue(registry.isBlocked("c")); assertTrue(registry.isBlocked("d")); } - + @Test - public void expiryTest() throws Exception { + public void expiryTest() throws Exception { HeapBasedClientBlockRegistry registry = new HeapBasedClientBlockRegistry<>(50, 3, String.class); assertFalse(registry.isBlocked("a")); diff --git a/src/test/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiterTest.java b/src/test/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiterTest.java index bd0cadfa6c..827bfa24b6 100644 --- a/src/test/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiterTest.java +++ b/src/test/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiterTest.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.auth.limiting; diff --git a/src/test/java/org/opensearch/security/auth/limiting/HeapBasedRateTrackerTest.java b/src/test/java/org/opensearch/security/auth/limiting/HeapBasedRateTrackerTest.java index d3383f2dbe..c92c328564 100644 --- a/src/test/java/org/opensearch/security/auth/limiting/HeapBasedRateTrackerTest.java +++ b/src/test/java/org/opensearch/security/auth/limiting/HeapBasedRateTrackerTest.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.auth.limiting; @@ -26,11 +26,11 @@ import static org.junit.Assert.assertTrue; public class HeapBasedRateTrackerTest { - + @Test - public void simpleTest() throws Exception { + public void simpleTest() throws Exception { HeapBasedRateTracker tracker = new HeapBasedRateTracker<>(100, 5, 100_000); - + assertFalse(tracker.track("a")); assertFalse(tracker.track("a")); assertFalse(tracker.track("a")); @@ -38,12 +38,12 @@ public void simpleTest() throws Exception { assertTrue(tracker.track("a")); } - + @Test @Ignore // https://github.com/opensearch-project/security/issues/2193 - public void expiryTest() throws Exception { + public void expiryTest() throws Exception { HeapBasedRateTracker tracker = new HeapBasedRateTracker<>(100, 5, 100_000); - + assertFalse(tracker.track("a")); assertFalse(tracker.track("a")); assertFalse(tracker.track("a")); @@ -55,38 +55,37 @@ public void expiryTest() throws Exception { assertFalse(tracker.track("b")); assertFalse(tracker.track("b")); assertTrue(tracker.track("b")); - - assertFalse(tracker.track("c")); - + + assertFalse(tracker.track("c")); + Thread.sleep(50); - - assertFalse(tracker.track("c")); - assertFalse(tracker.track("c")); - assertFalse(tracker.track("c")); - - Thread.sleep(55); - - assertFalse(tracker.track("c")); - assertTrue(tracker.track("c")); - - assertFalse(tracker.track("a")); - + + assertFalse(tracker.track("c")); + assertFalse(tracker.track("c")); + assertFalse(tracker.track("c")); + Thread.sleep(55); - assertFalse(tracker.track("c")); - assertFalse(tracker.track("c")); - assertTrue(tracker.track("c")); - + assertFalse(tracker.track("c")); + assertTrue(tracker.track("c")); + + assertFalse(tracker.track("a")); + + Thread.sleep(55); + assertFalse(tracker.track("c")); + assertFalse(tracker.track("c")); + assertTrue(tracker.track("c")); + } - + @Test @Ignore // https://github.com/opensearch-project/security/issues/2193 - public void maxTwoTriesTest() throws Exception { + public void maxTwoTriesTest() throws Exception { HeapBasedRateTracker tracker = new HeapBasedRateTracker<>(100, 2, 100_000); - + assertFalse(tracker.track("a")); assertTrue(tracker.track("a")); - + assertFalse(tracker.track("b")); Thread.sleep(50); assertTrue(tracker.track("b")); 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 9e7d95fd00..e42d2bd1b8 100644 --- a/src/test/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiterTest.java +++ b/src/test/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiterTest.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.auth.limiting; 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 3330477721..55ce10df65 100644 --- a/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java +++ b/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java @@ -27,8 +27,7 @@ public class JwtVendorTest { @Test public void testCreateJwkFromSettings() throws Exception { - Settings settings = Settings.builder() - .put("signing_key", "abc123").build(); + Settings settings = Settings.builder().put("signing_key", "abc123").build(); JsonWebKey jwk = JwtVendor.createJwkFromSettings(settings); Assert.assertEquals("HS512", jwk.getAlgorithm()); @@ -36,10 +35,9 @@ public void testCreateJwkFromSettings() throws Exception { Assert.assertEquals("abc123", jwk.getProperty("k")); } - @Test (expected = Exception.class) - public void testCreateJwkFromSettingsWithoutSigningKey() throws Exception{ - Settings settings = Settings.builder() - .put("jwt", "").build(); + @Test(expected = Exception.class) + public void testCreateJwkFromSettingsWithoutSigningKey() throws Exception { + Settings settings = Settings.builder().put("jwt", "").build(); JwtVendor.createJwkFromSettings(settings); } @@ -51,9 +49,9 @@ public void testCreateJwtWithRoles() throws Exception { List roles = List.of("IT", "HR"); String expectedRoles = "IT,HR"; Integer expirySeconds = 300; - LongSupplier currentTime = () -> (int)100; + LongSupplier currentTime = () -> (int) 100; String claimsEncryptionKey = RandomStringUtils.randomAlphanumeric(16); - Settings settings = Settings.builder().put("signing_key", "abc123").put("encryption_key", claimsEncryptionKey).build(); + Settings settings = Settings.builder().put("signing_key", "abc123").put("encryption_key", claimsEncryptionKey).build(); Long expectedExp = currentTime.getAsLong() + (expirySeconds * 1000); JwtVendor jwtVendor = new JwtVendor(settings, currentTime); @@ -72,45 +70,45 @@ public void testCreateJwtWithRoles() throws Exception { Assert.assertEquals(expectedRoles, EncryptionDecryptionUtil.decrypt(claimsEncryptionKey, jwt.getClaim("er").toString())); } - @Test (expected = Exception.class) + @Test(expected = Exception.class) public void testCreateJwtWithBadExpiry() throws Exception { String issuer = "cluster_0"; String subject = "admin"; String audience = "audience_0"; - List roles = List.of("admin"); + List roles = List.of("admin"); Integer expirySeconds = -300; String claimsEncryptionKey = RandomStringUtils.randomAlphanumeric(16); - Settings settings = Settings.builder().put("signing_key", "abc123").put("encryption_key", claimsEncryptionKey).build(); + Settings settings = Settings.builder().put("signing_key", "abc123").put("encryption_key", claimsEncryptionKey).build(); JwtVendor jwtVendor = new JwtVendor(settings); jwtVendor.createJwt(issuer, subject, audience, expirySeconds, roles); } - @Test (expected = Exception.class) + @Test(expected = Exception.class) public void testCreateJwtWithBadEncryptionKey() throws Exception { String issuer = "cluster_0"; String subject = "admin"; String audience = "audience_0"; - List roles = List.of("admin"); + List roles = List.of("admin"); Integer expirySeconds = 300; - Settings settings = Settings.builder().put("signing_key", "abc123").build(); + Settings settings = Settings.builder().put("signing_key", "abc123").build(); JwtVendor jwtVendor = new JwtVendor(settings); jwtVendor.createJwt(issuer, subject, audience, expirySeconds, roles); } - @Test (expected = Exception.class) + @Test(expected = Exception.class) public void testCreateJwtWithBadRoles() throws Exception { String issuer = "cluster_0"; String subject = "admin"; String audience = "audience_0"; - List roles = null; + List roles = null; Integer expirySecond = 300; String claimsEncryptionKey = RandomStringUtils.randomAlphanumeric(16); - Settings settings = Settings.builder().put("signing_key", "abc123").put("encryption_key", claimsEncryptionKey).build(); + Settings settings = Settings.builder().put("signing_key", "abc123").put("encryption_key", claimsEncryptionKey).build(); JwtVendor jwtVendor = new JwtVendor(settings); diff --git a/src/test/java/org/opensearch/security/cache/CachingTest.java b/src/test/java/org/opensearch/security/cache/CachingTest.java index 5276196856..4bff91a1f3 100644 --- a/src/test/java/org/opensearch/security/cache/CachingTest.java +++ b/src/test/java/org/opensearch/security/cache/CachingTest.java @@ -23,7 +23,7 @@ import org.opensearch.security.test.helper.rest.RestHelper; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class CachingTest extends SingleClusterTest{ +public class CachingTest extends SingleClusterTest { @Override protected String getResourceFolder() { @@ -84,16 +84,28 @@ public void testRestCachingWithImpersonation() throws Exception { final Settings settings = Settings.builder().putList("plugins.security.authcz.rest_impersonation_user.dummy", "*").build(); setup(Settings.EMPTY, new DynamicSecurityConfig(), settings); final RestHelper rh = nonSslRestHelper(); - HttpResponse res = rh.executeGetRequest("_opendistro/_security/authinfo?pretty", new BasicHeader("opendistro_security_impersonate_as", "impuser")); + HttpResponse res = rh.executeGetRequest( + "_opendistro/_security/authinfo?pretty", + new BasicHeader("opendistro_security_impersonate_as", "impuser") + ); System.out.println(res.getBody()); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - res = rh.executeGetRequest("_opendistro/_security/authinfo?pretty", new BasicHeader("opendistro_security_impersonate_as", "impuser")); + res = rh.executeGetRequest( + "_opendistro/_security/authinfo?pretty", + new BasicHeader("opendistro_security_impersonate_as", "impuser") + ); System.out.println(res.getBody()); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - res = rh.executeGetRequest("_opendistro/_security/authinfo?pretty", new BasicHeader("opendistro_security_impersonate_as", "impuser")); + res = rh.executeGetRequest( + "_opendistro/_security/authinfo?pretty", + new BasicHeader("opendistro_security_impersonate_as", "impuser") + ); System.out.println(res.getBody()); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - res = rh.executeGetRequest("_opendistro/_security/authinfo?pretty", new BasicHeader("opendistro_security_impersonate_as", "impuser2")); + res = rh.executeGetRequest( + "_opendistro/_security/authinfo?pretty", + new BasicHeader("opendistro_security_impersonate_as", "impuser2") + ); System.out.println(res.getBody()); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); diff --git a/src/test/java/org/opensearch/security/cache/DummyAuthenticationBackend.java b/src/test/java/org/opensearch/security/cache/DummyAuthenticationBackend.java index f41ddade65..5e7980f431 100644 --- a/src/test/java/org/opensearch/security/cache/DummyAuthenticationBackend.java +++ b/src/test/java/org/opensearch/security/cache/DummyAuthenticationBackend.java @@ -19,14 +19,12 @@ import org.opensearch.security.user.AuthCredentials; import org.opensearch.security.user.User; - public class DummyAuthenticationBackend implements AuthenticationBackend { private static volatile long authCount; private static volatile long existsCount; - public DummyAuthenticationBackend(final Settings settings, final Path configPath) { - } + public DummyAuthenticationBackend(final Settings settings, final Path configPath) {} @Override public String getType() { @@ -54,7 +52,7 @@ public static long getExistsCount() { } public static void reset() { - authCount=0; - existsCount=0; + authCount = 0; + existsCount = 0; } } diff --git a/src/test/java/org/opensearch/security/cache/DummyAuthorizer.java b/src/test/java/org/opensearch/security/cache/DummyAuthorizer.java index 4c489f0c00..8f8a507cb8 100644 --- a/src/test/java/org/opensearch/security/cache/DummyAuthorizer.java +++ b/src/test/java/org/opensearch/security/cache/DummyAuthorizer.java @@ -19,13 +19,11 @@ import org.opensearch.security.user.AuthCredentials; import org.opensearch.security.user.User; - public class DummyAuthorizer implements AuthorizationBackend { private static volatile long count; - public DummyAuthorizer(final Settings settings, final Path configPath) { - } + public DummyAuthorizer(final Settings settings, final Path configPath) {} @Override public String getType() { @@ -44,7 +42,7 @@ public static long getCount() { } public static void reset() { - count=0; + count = 0; } } diff --git a/src/test/java/org/opensearch/security/cache/DummyHTTPAuthenticator.java b/src/test/java/org/opensearch/security/cache/DummyHTTPAuthenticator.java index 48bead257b..55c2e789c6 100644 --- a/src/test/java/org/opensearch/security/cache/DummyHTTPAuthenticator.java +++ b/src/test/java/org/opensearch/security/cache/DummyHTTPAuthenticator.java @@ -25,8 +25,7 @@ public class DummyHTTPAuthenticator implements HTTPAuthenticator { private static volatile long count; - public DummyHTTPAuthenticator(final Settings settings, final Path configPath) { - } + public DummyHTTPAuthenticator(final Settings settings, final Path configPath) {} @Override public String getType() { @@ -49,6 +48,6 @@ public static long getCount() { } public static void reset() { - count=0; + count = 0; } } diff --git a/src/test/java/org/opensearch/security/ccstest/CrossClusterMinimalRoundtripSearchTests.java b/src/test/java/org/opensearch/security/ccstest/CrossClusterMinimalRoundtripSearchTests.java index 292a0d38d8..db948b77df 100644 --- a/src/test/java/org/opensearch/security/ccstest/CrossClusterMinimalRoundtripSearchTests.java +++ b/src/test/java/org/opensearch/security/ccstest/CrossClusterMinimalRoundtripSearchTests.java @@ -13,5 +13,7 @@ public class CrossClusterMinimalRoundtripSearchTests extends CrossClusterSearchTests { @Override - protected boolean ccsMinimizeRoundtrips() { return true; } + protected boolean ccsMinimizeRoundtrips() { + return true; + } } diff --git a/src/test/java/org/opensearch/security/ccstest/CrossClusterSearchTests.java b/src/test/java/org/opensearch/security/ccstest/CrossClusterSearchTests.java index 64e73202c7..fad6c77a1a 100644 --- a/src/test/java/org/opensearch/security/ccstest/CrossClusterSearchTests.java +++ b/src/test/java/org/opensearch/security/ccstest/CrossClusterSearchTests.java @@ -67,15 +67,21 @@ import static org.hamcrest.Matchers.not; public class CrossClusterSearchTests extends AbstractSecurityUnitTest { - - private final ClusterHelper cl1 = new ClusterHelper("crl1_n"+num.incrementAndGet()+"_f"+System.getProperty("forkno")+"_t"+System.nanoTime()); - private final ClusterHelper cl2 = new ClusterHelper("crl2_n"+num.incrementAndGet()+"_f"+System.getProperty("forkno")+"_t"+System.nanoTime()); + + private final ClusterHelper cl1 = new ClusterHelper( + "crl1_n" + num.incrementAndGet() + "_f" + System.getProperty("forkno") + "_t" + System.nanoTime() + ); + private final ClusterHelper cl2 = new ClusterHelper( + "crl2_n" + num.incrementAndGet() + "_f" + System.getProperty("forkno") + "_t" + System.nanoTime() + ); private ClusterInfo cl1Info; private ClusterInfo cl2Info; private RestHelper rh1; private RestHelper rh2; - protected boolean ccsMinimizeRoundtrips() { return false; }; + protected boolean ccsMinimizeRoundtrips() { + return false; + }; private static class ClusterTransportClientSettings extends Tuple { @@ -84,9 +90,7 @@ public ClusterTransportClientSettings() { } public ClusterTransportClientSettings(Settings clusterSettings, Settings transportSettings) { - super(Settings.builder() - .put(clusterSettings) - .putList("node.roles", "remote_cluster_client").build(), transportSettings); + super(Settings.builder().put(clusterSettings).putList("node.roles", "remote_cluster_client").build(), transportSettings); } public Settings clusterSettings() { @@ -106,10 +110,13 @@ private void setupCcs(DynamicSecurityConfig dynamicSecurityConfig) throws Except setupCcs(dynamicSecurityConfig, new ClusterTransportClientSettings(), new ClusterTransportClientSettings()); } - private void setupCcs(DynamicSecurityConfig dynamicSecurityConfig, - ClusterTransportClientSettings cluster1Settings, ClusterTransportClientSettings cluster2Settings) throws Exception { + private void setupCcs( + DynamicSecurityConfig dynamicSecurityConfig, + ClusterTransportClientSettings cluster1Settings, + ClusterTransportClientSettings cluster2Settings + ) throws Exception { - System.setProperty("security.display_lic_none","true"); + System.setProperty("security.display_lic_none", "true"); Tuple cluster2 = setupCluster(cl2, cluster2Settings, dynamicSecurityConfig); cl2Info = cluster2.v1(); @@ -120,19 +127,17 @@ private void setupCcs(DynamicSecurityConfig dynamicSecurityConfig, rh1 = cluster1.v2(); final String seed = cl2Info.nodeHost + ":" + cl2Info.nodePort; - String json = - "{" + - "\"persistent\" : {" + - "\"cluster.remote.cross_cluster_two.seeds\" : [\"" + seed + "\"]" + - "}" + - "}"; - + String json = "{" + "\"persistent\" : {" + "\"cluster.remote.cross_cluster_two.seeds\" : [\"" + seed + "\"]" + "}" + "}"; HttpResponse response = rh1.executePutRequest("_cluster/settings", json, encodeBasicHeader("sarek", "sarek")); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); } - private Tuple setupCluster(ClusterHelper ch, ClusterTransportClientSettings cluster, DynamicSecurityConfig dynamicSecurityConfig) throws Exception { + private Tuple setupCluster( + ClusterHelper ch, + ClusterTransportClientSettings cluster, + DynamicSecurityConfig dynamicSecurityConfig + ) throws Exception { NodeSettingsSupplier settings = minimumSecuritySettings(cluster.clusterSettings()); ClusterInfo clusterInfo = ch.startCluster(settings, ClusterConfiguration.DEFAULT); initialize(ch, clusterInfo, dynamicSecurityConfig); @@ -143,63 +148,93 @@ private Tuple setupCluster(ClusterHelper ch, ClusterTra System.out.println("### " + ch.getClusterName() + " complete ###"); return new Tuple<>(clusterInfo, rh); } - + @After public void tearDown() throws Exception { cl1.stopCluster(); cl2.stopCluster(); } - + @Test public void testCcs() throws Exception { setupCcs(); - final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("nagilum","nagilum")).getBody(); + final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("nagilum", "nagilum") + ).getBody(); Assert.assertTrue(cl1BodyMain.contains("crl1")); try (Client tc = cl1.nodeClient()) { - tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } - final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("nagilum","nagilum")).getBody(); + final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("nagilum", "nagilum") + ).getBody(); Assert.assertTrue(cl2BodyMain.contains("crl2")); try (Client tc = cl2.nodeClient()) { - tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } HttpResponse ccs = null; System.out.println("###################### query 1"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:*/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:*/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("nagilum", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("crl1")); Assert.assertTrue(ccs.getBody().contains("crl2")); Assert.assertTrue(ccs.getBody().contains("twitter")); - System.out.println("###################### query 4"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:xx,xx/xx/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:xx,xx/xx/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("nagilum", "nagilum") + ); System.out.println(ccs.getBody()); - //TODO fix exception nesting - //Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, ccs.getStatusCode()); - //Assert.assertTrue(ccs.getBody().contains("Can not filter indices; index cross_cluster_two:xx exists but there is also a remote cluster named: cross_cluster_two")); + // TODO fix exception nesting + // Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, ccs.getStatusCode()); + // Assert.assertTrue(ccs.getBody().contains("Can not filter indices; index cross_cluster_two:xx exists but there is also a remote + // cluster named: cross_cluster_two")); System.out.println("###################### query 5"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:abcnonext/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:abcnonext/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("nagilum", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, ccs.getStatusCode()); Assert.assertTrue(ccs.getBody().contains("index_not_found_exception")); System.out.println("###################### query 6"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:twitter,twutter/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:twitter,twutter/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("nagilum", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); @@ -213,168 +248,279 @@ public void testCcs() throws Exception { public void testCcsNonadmin() throws Exception { setupCcs(); - final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("twitter","nagilum")).getBody(); + final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("twitter", "nagilum") + ).getBody(); Assert.assertTrue(cl1BodyMain.contains("crl1")); try (Client tc = cl1.nodeClient()) { - tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("twitter").alias("coordalias"))).actionGet(); + tc.index( + new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("twitter").alias("coordalias"))) + .actionGet(); } - final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("twitter","nagilum")).getBody(); + final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("twitter", "nagilum") + ).getBody(); Assert.assertTrue(cl2BodyMain.contains("crl2")); try (Client tc = cl2.nodeClient()) { - tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("twitter").alias("remotealias"))).actionGet(); + tc.index( + new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("twitter").alias("remotealias"))) + .actionGet(); } HttpResponse ccs = null; System.out.println("###################### query 1"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:*/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:*/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); System.out.println("###################### query 2"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:twit*/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:twit*/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:twitter/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:twitter/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - System.out.println("###################### query 3"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:twitter,twitter,twutter/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:twitter,twitter,twutter/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); System.out.println("###################### query 4"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:twitter,twitter/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:twitter,twitter/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertTrue(ccs.getBody().contains("crl1_")); Assert.assertTrue(ccs.getBody().contains("crl2_")); System.out.println("###################### query 5"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:twutter,twitter/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:twutter,twitter/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); System.out.println("###################### query 6"); - String msearchBody = - "{}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); + String msearchBody = "{}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:twitter,twitter/_msearch?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), msearchBody, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:twitter,twitter/_msearch?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + msearchBody, + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); System.out.println("###################### query 7"); - msearchBody = - "{}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); + msearchBody = "{}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:twitter/_msearch?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), msearchBody, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:twitter/_msearch?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + msearchBody, + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("_all/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "_all/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("*/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "*/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:twitter,twitter/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:twitter,twitter/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:*/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:*/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("*:*/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "*:*/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("hfghgtdhfhuth/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "hfghgtdhfhuth/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("hfghgtdhfhuth*/_search", encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "hfghgtdhfhuth*/_search", + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - Assert.assertTrue(ccs.getBody().contains("\"hits\":[]")); //TODO: Change for 25.0 to be forbidden (Indices options) + Assert.assertTrue(ccs.getBody().contains("\"hits\":[]")); // TODO: Change for 25.0 to be forbidden (Indices options) - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest(":*/_search", encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest(":*/_search", encodeBasicHeader("worf", "worf")); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - Assert.assertTrue(ccs.getBody().contains("\"hits\":[]")); //TODO: Change for 25.0 to be forbidden (Indices options) + Assert.assertTrue(ccs.getBody().contains("\"hits\":[]")); // TODO: Change for 25.0 to be forbidden (Indices options) - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("*:/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "*:/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("%3Clogstash-%7Bnow%2Fd%7D%3E/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "%3Clogstash-%7Bnow%2Fd%7D%3E/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:%3Clogstash-%7Bnow%2Fd%7D%3E/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:%3Clogstash-%7Bnow%2Fd%7D%3E/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:%3Clogstash-%7Bnow%2Fd%7D%3E,%3Clogstash-%7Bnow%2Fd%7D%3E/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:%3Clogstash-%7Bnow%2Fd%7D%3E,%3Clogstash-%7Bnow%2Fd%7D%3E/_search?pretty&ccs_minimize_roundtrips=" + + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:remotealias/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:remotealias/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("coordalias/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "coordalias/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:remotealias,coordalias/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:remotealias,coordalias/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:remotealias/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:remotealias/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("coordalias/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "coordalias/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); System.out.println("#### Alias both"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:remotealias,coordalias/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:remotealias,coordalias/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("notexist,coordalias/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "notexist,coordalias/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - //TODO Fix for 25.0 to resolve coordalias (Indices options) + // TODO Fix for 25.0 to resolve coordalias (Indices options) - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:twitter/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("crusherw","crusherw")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:twitter/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("crusherw", "crusherw") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); @@ -384,176 +530,291 @@ public void testCcsNonadmin() throws Exception { public void testCcsNonadminDnfof() throws Exception { setupCcs(new DynamicSecurityConfig().setConfig("config_dnfof.yml")); - final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("twitter","nagilum")).getBody(); + final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("twitter", "nagilum") + ).getBody(); Assert.assertTrue(cl1BodyMain.contains("crl1")); try (Client tc = cl1.nodeClient()) { - tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("twitter").alias("coordalias"))).actionGet(); + tc.index( + new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("twitter").alias("coordalias"))) + .actionGet(); } - final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("twitter","nagilum")).getBody(); + final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("twitter", "nagilum") + ).getBody(); Assert.assertTrue(cl2BodyMain.contains("crl2")); try (Client tc = cl2.nodeClient()) { - tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("twitter").alias("remotealias"))).actionGet(); + tc.index( + new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("twitter").alias("remotealias"))) + .actionGet(); } HttpResponse ccs = null; System.out.println("###################### query 1"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:*/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:*/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("crl1_")); Assert.assertTrue(ccs.getBody().contains("crl2_")); System.out.println("###################### query 2"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:twit*/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:twit*/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - System.out.println("###################### query 3"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:twitter,twitter,twutter/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:twitter,twitter,twutter/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("twutter")); System.out.println("###################### query 4"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:twitter,twitter/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:twitter,twitter/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertTrue(ccs.getBody().contains("crl1_")); Assert.assertTrue(ccs.getBody().contains("crl2_")); System.out.println("###################### query 5"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:twutter,twitter/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:twutter,twitter/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); System.out.println("###################### query 6"); - String msearchBody = - "{}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); + String msearchBody = "{}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:twitter,twitter/_msearch?pretty", msearchBody, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:twitter,twitter/_msearch?pretty", + msearchBody, + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); System.out.println("###################### query 7"); - msearchBody = - "{}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); + msearchBody = "{}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:twitter/_msearch?pretty", msearchBody, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:twitter/_msearch?pretty", + msearchBody, + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("_all/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "_all/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("*/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "*/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:twitter,twitter/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:twitter,twitter/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:*/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:*/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); System.out.println("#####*"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:*,*/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:*,*/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertTrue(ccs.getBody().contains("crl1_")); Assert.assertTrue(ccs.getBody().contains("crl2_")); - //wildcard in remote cluster names - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("*cross*:*twit*,*/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + // wildcard in remote cluster names + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "*cross*:*twit*,*/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:twitter,t*/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:twitter,t*/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("*:*/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "*:*/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("hfghgtdhfhuth/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "hfghgtdhfhuth/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("hfghgtdhfhuth*/_search", encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "hfghgtdhfhuth*/_search", + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - Assert.assertTrue(ccs.getBody().contains("\"hits\":[]")); //TODO: Change for 25.0 to be forbidden (Indices options) + Assert.assertTrue(ccs.getBody().contains("\"hits\":[]")); // TODO: Change for 25.0 to be forbidden (Indices options) - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest(":*/_search", encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest(":*/_search", encodeBasicHeader("worf", "worf")); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - Assert.assertTrue(ccs.getBody().contains("\"hits\":[]")); //TODO: Change for 25.0 to be forbidden (Indices options) + Assert.assertTrue(ccs.getBody().contains("\"hits\":[]")); // TODO: Change for 25.0 to be forbidden (Indices options) - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("*:/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "*:/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("%3Clogstash-%7Bnow%2Fd%7D%3E/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "%3Clogstash-%7Bnow%2Fd%7D%3E/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:%3Clogstash-%7Bnow%2Fd%7D%3E/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:%3Clogstash-%7Bnow%2Fd%7D%3E/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:%3Clogstash-%7Bnow%2Fd%7D%3E,%3Clogstash-%7Bnow%2Fd%7D%3E/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:%3Clogstash-%7Bnow%2Fd%7D%3E,%3Clogstash-%7Bnow%2Fd%7D%3E/_search?pretty&ccs_minimize_roundtrips=" + + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:remotealias/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:remotealias/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("coordalias/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "coordalias/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:remotealias,coordalias/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("worf","worf")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:remotealias,coordalias/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("worf", "worf") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:remotealias/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:remotealias/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("coordalias/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "coordalias/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:remotealias,coordalias/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:remotealias,coordalias/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:twitter/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("crusherw","crusherw")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:twitter/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("crusherw", "crusherw") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); } @@ -562,21 +823,33 @@ public void testCcsNonadminDnfof() throws Exception { public void testCcsEmptyCoord() throws Exception { setupCcs(); - final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("twitter","nagilum")).getBody(); + final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("twitter", "nagilum") + ).getBody(); Assert.assertTrue(cl1BodyMain.contains("crl1")); - final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("twitter","nagilum")).getBody(); + final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("twitter", "nagilum") + ).getBody(); Assert.assertTrue(cl2BodyMain.contains("crl2")); try (Client tc = cl2.nodeClient()) { - tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } HttpResponse ccs = null; System.out.println("###################### query 1"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:twitter/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:twitter/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("twitter", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); @@ -590,74 +863,120 @@ public void testCcsEmptyCoord() throws Exception { public void testCcsDashboardsAggregations() throws Exception { setupCcs(); - final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("twitter","nagilum")).getBody(); + final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("twitter", "nagilum") + ).getBody(); Assert.assertTrue(cl1BodyMain.contains("crl1")); - final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("twitter","nagilum")).getBody(); + final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("twitter", "nagilum") + ).getBody(); Assert.assertTrue(cl2BodyMain.contains("crl2")); try (Client tc = cl1.nodeClient()) { - tc.index(new IndexRequest("coordinating").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("abc").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("coordinating").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("abc").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } - try (Client tc = cl2.nodeClient()) { - tc.index(new IndexRequest("remote").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("remote").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } HttpResponse ccs = null; System.out.println("###################### kibana indices agg"); String dashboardsIndicesAgg = "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":100}}}}"; - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("*/_search?pretty", dashboardsIndicesAgg, encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "*/_search?pretty", + dashboardsIndicesAgg, + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertFalse(ccs.getBody().contains("cross_cluster_two")); Assert.assertTrue(ccs.getBody().contains("coordinating")); Assert.assertTrue(ccs.getBody().contains("abc")); Assert.assertFalse(ccs.getBody().contains("remote")); - ccs = new RestHelper(cl2Info, false, false, getResourceFolder()).executePostRequest("*/_search?pretty", dashboardsIndicesAgg, encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl2Info, false, false, getResourceFolder()).executePostRequest( + "*/_search?pretty", + dashboardsIndicesAgg, + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertFalse(ccs.getBody().contains("cross_cluster_two")); Assert.assertFalse(ccs.getBody().contains("coordinating")); Assert.assertFalse(ccs.getBody().contains("abc")); Assert.assertTrue(ccs.getBody().contains("remote")); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:/_search?pretty", dashboardsIndicesAgg, encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:/_search?pretty", + dashboardsIndicesAgg, + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:remo*,coo*/_search?pretty", dashboardsIndicesAgg, encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:remo*,coo*/_search?pretty", + dashboardsIndicesAgg, + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertTrue(ccs.getBody().contains("cross_cluster_two")); Assert.assertTrue(ccs.getBody().contains("remote")); Assert.assertTrue(ccs.getBody().contains("coordinating")); Assert.assertFalse(ccs.getBody().contains("abc")); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:remote/_search?pretty", dashboardsIndicesAgg, encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:remote/_search?pretty", + dashboardsIndicesAgg, + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertTrue(ccs.getBody().contains("cross_cluster_two")); Assert.assertTrue(ccs.getBody().contains("remote")); Assert.assertFalse(ccs.getBody().contains("coordinating")); Assert.assertFalse(ccs.getBody().contains("abc")); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:*/_search?pretty", dashboardsIndicesAgg, encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:*/_search?pretty", + dashboardsIndicesAgg, + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertTrue(ccs.getBody().contains("cross_cluster_two")); Assert.assertTrue(ccs.getBody().contains("remote")); Assert.assertFalse(ccs.getBody().contains("coordinating")); Assert.assertFalse(ccs.getBody().contains("abc")); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:*,*/_search?pretty", dashboardsIndicesAgg, encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:*,*/_search?pretty", + dashboardsIndicesAgg, + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertTrue(ccs.getBody().contains("cross_cluster_two")); Assert.assertTrue(ccs.getBody().contains("remote")); Assert.assertTrue(ccs.getBody().contains("coordinating")); Assert.assertTrue(ccs.getBody().contains("abc")); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:remo*,ab*/_search?pretty", dashboardsIndicesAgg, encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:remo*,ab*/_search?pretty", + dashboardsIndicesAgg, + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertTrue(ccs.getBody().contains("cross_cluster_two")); @@ -670,35 +989,59 @@ public void testCcsDashboardsAggregations() throws Exception { public void testCcsDashboardsAggregationsNonAdminDnfof() throws Exception { setupCcs(new DynamicSecurityConfig().setConfig("config_dnfof.yml")); - final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("twitter","nagilum")).getBody(); + final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("twitter", "nagilum") + ).getBody(); Assert.assertTrue(cl1BodyMain.contains("crl1")); - final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("twitter","nagilum")).getBody(); + final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("twitter", "nagilum") + ).getBody(); Assert.assertTrue(cl2BodyMain.contains("crl2")); try (Client tc = cl1.nodeClient()) { - tc.index(new IndexRequest("coordinating").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("abc").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("coordinating").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("abc").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } - try (Client tc = cl2.nodeClient()) { - tc.index(new IndexRequest("remote").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("analytics").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("remote").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + + tc.index( + new IndexRequest("analytics").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } HttpResponse ccs = null; System.out.println("###################### kibana indices agg"); String dashboardsIndicesAgg = "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":100}}}}"; - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("*/_search?pretty", dashboardsIndicesAgg, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "*/_search?pretty", + dashboardsIndicesAgg, + encodeBasicHeader("twitter", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertFalse(ccs.getBody().contains("cross_cluster_two")); @@ -708,7 +1051,11 @@ public void testCcsDashboardsAggregationsNonAdminDnfof() throws Exception { Assert.assertFalse(ccs.getBody().contains("coordinating")); Assert.assertFalse(ccs.getBody().contains("abc")); Assert.assertFalse(ccs.getBody().contains("remote")); - ccs = new RestHelper(cl2Info, false, false, getResourceFolder()).executePostRequest("*/_search?pretty", dashboardsIndicesAgg, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl2Info, false, false, getResourceFolder()).executePostRequest( + "*/_search?pretty", + dashboardsIndicesAgg, + encodeBasicHeader("twitter", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertFalse(ccs.getBody().contains("cross_cluster_two")); @@ -718,7 +1065,11 @@ public void testCcsDashboardsAggregationsNonAdminDnfof() throws Exception { Assert.assertFalse(ccs.getBody().contains("coordinating")); Assert.assertFalse(ccs.getBody().contains("abc")); Assert.assertFalse(ccs.getBody().contains("remote")); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:*,*/_search?pretty", dashboardsIndicesAgg, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:*,*/_search?pretty", + dashboardsIndicesAgg, + encodeBasicHeader("twitter", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertTrue(ccs.getBody().contains("cross_cluster_two:analytics")); @@ -726,9 +1077,17 @@ public void testCcsDashboardsAggregationsNonAdminDnfof() throws Exception { Assert.assertFalse(ccs.getBody().contains("coordinating")); Assert.assertFalse(ccs.getBody().contains("abc")); Assert.assertFalse(ccs.getBody().contains("remote")); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:remo*,coo*/_search?pretty", dashboardsIndicesAgg, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:remo*,coo*/_search?pretty", + dashboardsIndicesAgg, + encodeBasicHeader("twitter", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:ana*,twi*/_search?pretty", dashboardsIndicesAgg, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:ana*,twi*/_search?pretty", + dashboardsIndicesAgg, + encodeBasicHeader("twitter", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertTrue(ccs.getBody().contains("cross_cluster_two:analytics")); @@ -736,7 +1095,11 @@ public void testCcsDashboardsAggregationsNonAdminDnfof() throws Exception { Assert.assertFalse(ccs.getBody().contains("coordinating")); Assert.assertFalse(ccs.getBody().contains("abc")); Assert.assertFalse(ccs.getBody().contains("remote")); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:ana*,xyz*/_search?pretty", dashboardsIndicesAgg, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:ana*,xyz*/_search?pretty", + dashboardsIndicesAgg, + encodeBasicHeader("twitter", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertTrue(ccs.getBody().contains("cross_cluster_two:analytics")); @@ -744,9 +1107,17 @@ public void testCcsDashboardsAggregationsNonAdminDnfof() throws Exception { Assert.assertFalse(ccs.getBody().contains("coordinating")); Assert.assertFalse(ccs.getBody().contains("abc")); Assert.assertFalse(ccs.getBody().contains("remote")); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:ana*,xyz/_search?pretty", dashboardsIndicesAgg, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:ana*,xyz/_search?pretty", + dashboardsIndicesAgg, + encodeBasicHeader("twitter", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:*/_search?pretty", dashboardsIndicesAgg, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:*/_search?pretty", + dashboardsIndicesAgg, + encodeBasicHeader("twitter", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertTrue(ccs.getBody().contains("cross_cluster_two:analytics")); @@ -760,30 +1131,48 @@ public void testCcsDashboardsAggregationsNonAdminDnfof() throws Exception { public void testCcsAggregations() throws Exception { setupCcs(); - final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("twitter","nagilum")).getBody(); + final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("twitter", "nagilum") + ).getBody(); Assert.assertTrue(cl1BodyMain.contains("crl1")); - final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("twitter","nagilum")).getBody(); + final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("twitter", "nagilum") + ).getBody(); Assert.assertTrue(cl2BodyMain.contains("crl2")); try (Client tc = cl1.nodeClient()) { - tc.index(new IndexRequest("coordinating").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("abc").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("coordinating").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("abc").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } - try (Client tc = cl2.nodeClient()) { - tc.index(new IndexRequest("remote").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("remote").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } HttpResponse ccs = null; System.out.println("###################### aggs"); final String agg = "{\"size\":0,\"aggs\":{\"clusteragg\":{\"terms\":{\"field\":\"cluster.keyword\",\"size\":100}}}}"; - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("*:*,*/_search?pretty", agg, encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "*:*,*/_search?pretty", + agg, + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertTrue(ccs.getBody().contains("\"timed_out\" : false")); @@ -791,7 +1180,11 @@ public void testCcsAggregations() throws Exception { Assert.assertTrue(ccs.getBody().contains("crl2")); Assert.assertTrue(ccs.getBody().contains("\"doc_count\" : 2")); Assert.assertTrue(ccs.getBody().contains("\"doc_count\" : 1")); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("coordin*/_search?pretty", agg, encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "coordin*/_search?pretty", + agg, + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertTrue(ccs.getBody().contains("\"timed_out\" : false")); @@ -799,7 +1192,11 @@ public void testCcsAggregations() throws Exception { Assert.assertFalse(ccs.getBody().contains("crl2")); Assert.assertFalse(ccs.getBody().contains("\"doc_count\" : 2")); Assert.assertTrue(ccs.getBody().contains("\"doc_count\" : 1")); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:remo*/_search?pretty", agg, encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:remo*/_search?pretty", + agg, + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertTrue(ccs.getBody().contains("\"timed_out\" : false")); @@ -807,55 +1204,107 @@ public void testCcsAggregations() throws Exception { Assert.assertTrue(ccs.getBody().contains("crl2")); Assert.assertFalse(ccs.getBody().contains("\"doc_count\" : 2")); Assert.assertTrue(ccs.getBody().contains("\"doc_count\" : 1")); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:notfound,*/_search?pretty", agg, encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:notfound,*/_search?pretty", + agg, + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:*,notfound/_search?pretty", agg, encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:*,notfound/_search?pretty", + agg, + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:notfound,notfound/_search?pretty", agg, encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:notfound,notfound/_search?pretty", + agg, + encodeBasicHeader("nagilum", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:notfou*,*/_search?pretty", agg, encodeBasicHeader("nagilum","nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode());//TODO: Change for 25.0 to be forbidden (Indices options) - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:*,notfou*/_search?pretty", agg, encodeBasicHeader("nagilum","nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode());//TODO: Change for 25.0 to be forbidden (Indices options) - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:not*,notf*/_search?pretty", agg, encodeBasicHeader("nagilum","nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode());//TODO: Change for 25.0 to be forbidden (Indices options) + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:notfou*,*/_search?pretty", + agg, + encodeBasicHeader("nagilum", "nagilum") + ); + Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode());// TODO: Change for 25.0 to be forbidden (Indices options) + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:*,notfou*/_search?pretty", + agg, + encodeBasicHeader("nagilum", "nagilum") + ); + Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode());// TODO: Change for 25.0 to be forbidden (Indices options) + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:not*,notf*/_search?pretty", + agg, + encodeBasicHeader("nagilum", "nagilum") + ); + Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode());// TODO: Change for 25.0 to be forbidden (Indices options) } @Test public void testCcsAggregationsDnfof() throws Exception { setupCcs(new DynamicSecurityConfig().setConfig("config_dnfof.yml")); - final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("twitter","nagilum")).getBody(); + final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("twitter", "nagilum") + ).getBody(); Assert.assertTrue(cl1BodyMain.contains("crl1")); - final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("twitter","nagilum")).getBody(); + final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("twitter", "nagilum") + ).getBody(); Assert.assertTrue(cl2BodyMain.contains("crl2")); try (Client tc = cl1.nodeClient()) { - tc.index(new IndexRequest("coordinating").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("abc").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("coordinating").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("abc").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } - try (Client tc = cl2.nodeClient()) { - tc.index(new IndexRequest("remote").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("analytics").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("remote").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + + tc.index( + new IndexRequest("analytics").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } HttpResponse ccs = null; System.out.println("###################### aggs"); final String agg = "{\"size\":0,\"aggs\":{\"clusteragg\":{\"terms\":{\"field\":\"cluster.keyword\",\"size\":100}}}}"; - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:notfound,*/_search?pretty", agg, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:notfound,*/_search?pretty", + agg, + encodeBasicHeader("twitter", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:notfound*,*/_search?pretty", agg, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:notfound*,*/_search?pretty", + agg, + encodeBasicHeader("twitter", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("security_exception")); Assert.assertTrue(ccs.getBody().contains("\"timed_out\" : false")); @@ -863,58 +1312,97 @@ public void testCcsAggregationsDnfof() throws Exception { Assert.assertFalse(ccs.getBody().contains("crl2")); Assert.assertFalse(ccs.getBody().contains("\"doc_count\" : 2")); Assert.assertTrue(ccs.getBody().contains("\"doc_count\" : 1")); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:*,notfound/_search?pretty", agg, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:*,notfound/_search?pretty", + agg, + encodeBasicHeader("twitter", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:notfound,notfound/_search?pretty", agg, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:notfound,notfound/_search?pretty", + agg, + encodeBasicHeader("twitter", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:notfou*,*/_search?pretty", agg, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:notfou*,*/_search?pretty", + agg, + encodeBasicHeader("twitter", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:*,notfou*/_search?pretty", agg, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:*,notfou*/_search?pretty", + agg, + encodeBasicHeader("twitter", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("cross_cluster_two:not*,notf*/_search?pretty", agg, encodeBasicHeader("twitter","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "cross_cluster_two:not*,notf*/_search?pretty", + agg, + encodeBasicHeader("twitter", "nagilum") + ); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); } - private ClusterTransportClientSettings getBaseSettingsWithDifferentCert() { Settings cluster = Settings.builder() .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("restapi/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("restapi/truststore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("node-untspec5-keystore.p12")) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("restapi/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("restapi/truststore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("node-untspec5-keystore.p12") + ) .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "1") .put(ConfigConstants.SECURITY_NODES_DN_DYNAMIC_CONFIG_ENABLED, true) .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE, "PKCS12") - .putList(ConfigConstants.SECURITY_NODES_DN, - "EMAILADDRESS=unt@tst.com,CN=node-untspec5.example.com,OU=SSL,O=Te\\, st,L=Test,C=DE")//, "CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE") - .putList(ConfigConstants.SECURITY_AUTHCZ_ADMIN_DN, + .putList( + ConfigConstants.SECURITY_NODES_DN, + "EMAILADDRESS=unt@tst.com,CN=node-untspec5.example.com,OU=SSL,O=Te\\, st,L=Test,C=DE" + )// , "CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE") + .putList( + ConfigConstants.SECURITY_AUTHCZ_ADMIN_DN, "EMAILADDRESS=unt@xxx.com,CN=node-untspec6.example.com,OU=SSL,O=Te\\, st,L=Test,C=DE", - "CN=kirk,OU=client,O=client,l=tEst, C=De") - .put(ConfigConstants.SECURITY_CERT_OID,"1.2.3.4.5.6") + "CN=kirk,OU=client,O=client,l=tEst, C=De" + ) + .put(ConfigConstants.SECURITY_CERT_OID, "1.2.3.4.5.6") .build(); Settings transport = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("node-untspec6-keystore.p12")) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("node-untspec6-keystore.p12") + ) .build(); return new ClusterTransportClientSettings(cluster, transport); } private void populateBaseData(ClusterTransportClientSettings cluster1, ClusterTransportClientSettings cluster2) throws Exception { - final String cl1BodyMain = rh1.executeGetRequest("", encodeBasicHeader("twitter","nagilum")).getBody(); + final String cl1BodyMain = rh1.executeGetRequest("", encodeBasicHeader("twitter", "nagilum")).getBody(); Assert.assertTrue(cl1BodyMain, cl1BodyMain.contains("crl1")); - final String cl2BodyMain = rh2.executeGetRequest("", encodeBasicHeader("twitter","nagilum")).getBody(); + final String cl2BodyMain = rh2.executeGetRequest("", encodeBasicHeader("twitter", "nagilum")).getBody(); Assert.assertTrue(cl2BodyMain.contains("crl2")); try (Client tc = cl1.nodeClient()) { - tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } try (Client tc = cl2.nodeClient()) { - tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } } @@ -939,9 +1427,11 @@ public void testCcsWithDiffCertsWithNodesDnStaticallyAdded() throws Exception { ClusterTransportClientSettings cluster2 = getBaseSettingsWithDifferentCert(); Settings updatedCluster2 = Settings.builder() .put(cluster2.clusterSettings()) - .putList(ConfigConstants.SECURITY_NODES_DN, + .putList( + ConfigConstants.SECURITY_NODES_DN, "EMAILADDRESS=unt@tst.com,CN=node-untspec5.example.com,OU=SSL,O=Te\\, st,L=Test,C=DE", - "CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE") + "CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE" + ) .build(); cluster2 = new ClusterTransportClientSettings(updatedCluster2, cluster2.transportClientSettings()); @@ -966,9 +1456,11 @@ public void testCcsWithDiffCertsWithNodesDnDynamicallyAdded() throws Exception { setupCcs(new DynamicSecurityConfig().setSecurityNodesDn("nodes_dn_empty.yml"), cluster1, cluster2); - HttpResponse response = rh2.executePutRequest("_opendistro/_security/api/nodesdn/connection1", + HttpResponse response = rh2.executePutRequest( + "_opendistro/_security/api/nodesdn/connection1", "{\"nodes_dn\": [\"CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE\"]}", - encodeBasicHeader("sarek", "sarek")); + encodeBasicHeader("sarek", "sarek") + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_CREATED)); populateBaseData(cluster1, cluster2); @@ -988,41 +1480,59 @@ public void testCcsWithDiffCertsWithNodesDnDynamicallyAdded() throws Exception { public void testCcsWithRoleInjection() throws Exception { setupCcs(new DynamicSecurityConfig().setSecurityRoles("roles.yml")); - Assert.assertEquals(cl1Info.numNodes, cl1.nodeClient().admin().cluster().health( - new ClusterHealthRequest().waitForGreenStatus()).actionGet().getNumberOfNodes()); - Assert.assertEquals(ClusterHealthStatus.GREEN, cl1.nodeClient().admin().cluster(). - health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus()); - - Assert.assertEquals(cl2Info.numNodes, cl2.nodeClient().admin().cluster().health( - new ClusterHealthRequest().waitForGreenStatus()).actionGet().getNumberOfNodes()); - Assert.assertEquals(ClusterHealthStatus.GREEN, cl2.nodeClient().admin().cluster(). - health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus()); + Assert.assertEquals( + cl1Info.numNodes, + cl1.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getNumberOfNodes() + ); + Assert.assertEquals( + ClusterHealthStatus.GREEN, + cl1.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus() + ); + + Assert.assertEquals( + cl2Info.numNodes, + cl2.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getNumberOfNodes() + ); + Assert.assertEquals( + ClusterHealthStatus.GREEN, + cl2.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus() + ); try (Client tc = cl2.nodeClient()) { - tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } final Settings.Builder clusterClientSettings = Settings.builder().putList("node.roles", "remote_cluster_client"); - final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(clusterClientSettings, false, false) - .put(minimumSecuritySettings(Settings.EMPTY).get(0)) - .put("cluster.name", cl1Info.clustername) - .put("path.data", "./target/data/" + cl1Info.clustername + "/cert/data") - .put("path.logs", "./target/data/" + cl1Info.clustername + "/cert/logs") - .put("path.home", "./target") - .put("node.name", "testclient") - .put("discovery.initial_state_timeout", "8s") - .put("plugins.security.allow_default_init_securityindex", "true") - .putList("discovery.zen.ping.unicast.hosts", cl1Info.nodeHost + ":" + cl1Info.nodePort) - .build(); + final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(clusterClientSettings, false, false) + .put(minimumSecuritySettings(Settings.EMPTY).get(0)) + .put("cluster.name", cl1Info.clustername) + .put("path.data", "./target/data/" + cl1Info.clustername + "/cert/data") + .put("path.logs", "./target/data/" + cl1Info.clustername + "/cert/logs") + .put("path.home", "./target") + .put("node.name", "testclient") + .put("discovery.initial_state_timeout", "8s") + .put("plugins.security.allow_default_init_securityindex", "true") + .putList("discovery.zen.ping.unicast.hosts", cl1Info.nodeHost + ":" + cl1Info.nodePort) + .build(); OpenSearchSecurityException exception = null; System.out.println("###################### with invalid role injection"); - //1. With invalid roles injection + // 1. With invalid roles injection RolesInjectorIntegTest.RolesInjectorPlugin.injectedRoles = "invalid_user|invalid_role"; - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, - OpenSearchSecurityPlugin.class, RolesInjectorIntegTest.RolesInjectorPlugin.class).start()) { + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + RolesInjectorIntegTest.RolesInjectorPlugin.class + ).start() + ) { waitForInit(node.client()); Client remoteClient = node.client().getRemoteClusterClient("cross_cluster_two"); GetRequest getReq = new GetRequest("twitter", "0"); @@ -1039,10 +1549,17 @@ public void testCcsWithRoleInjection() throws Exception { Assert.assertTrue(exception.getMessage().contains("no permissions for")); System.out.println("###################### with valid role injection"); - //2. With valid roles injection + // 2. With valid roles injection RolesInjectorIntegTest.RolesInjectorPlugin.injectedRoles = "valid_user|opendistro_security_all_access"; - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, - OpenSearchSecurityPlugin.class, RolesInjectorIntegTest.RolesInjectorPlugin.class).start()) { + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + RolesInjectorIntegTest.RolesInjectorPlugin.class + ).start() + ) { waitForInit(node.client()); Client remoteClient = node.client().getRemoteClusterClient("cross_cluster_two"); GetRequest getReq = new GetRequest("twitter", "0"); diff --git a/src/test/java/org/opensearch/security/ccstest/RemoteReindexTests.java b/src/test/java/org/opensearch/security/ccstest/RemoteReindexTests.java index 0d6efe1bb9..3c49548cf3 100644 --- a/src/test/java/org/opensearch/security/ccstest/RemoteReindexTests.java +++ b/src/test/java/org/opensearch/security/ccstest/RemoteReindexTests.java @@ -45,78 +45,98 @@ import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; public class RemoteReindexTests extends AbstractSecurityUnitTest { - - private final ClusterHelper cl1 = new ClusterHelper("crl1_n"+num.incrementAndGet()+"_f"+System.getProperty("forkno")+"_t"+System.nanoTime()); - private final ClusterHelper cl2 = new ClusterHelper("crl2_n"+num.incrementAndGet()+"_f"+System.getProperty("forkno")+"_t"+System.nanoTime()); + + private final ClusterHelper cl1 = new ClusterHelper( + "crl1_n" + num.incrementAndGet() + "_f" + System.getProperty("forkno") + "_t" + System.nanoTime() + ); + private final ClusterHelper cl2 = new ClusterHelper( + "crl2_n" + num.incrementAndGet() + "_f" + System.getProperty("forkno") + "_t" + System.nanoTime() + ); private ClusterInfo cl1Info; private ClusterInfo cl2Info; - - private void setupReindex() throws Exception { - - System.setProperty("security.display_lic_none","true"); - + + private void setupReindex() throws Exception { + + System.setProperty("security.display_lic_none", "true"); + cl2Info = cl2.startCluster(minimumSecuritySettings(Settings.EMPTY), ClusterConfiguration.DEFAULT); initialize(cl2, cl2Info); - + cl1Info = cl1.startCluster(minimumSecuritySettings(crossClusterNodeSettings(cl2Info)), ClusterConfiguration.DEFAULT); initialize(cl1, cl1Info); } - + @After public void tearDown() throws Exception { cl1.stopCluster(); cl2.stopCluster(); } - + private Settings crossClusterNodeSettings(ClusterInfo remote) { - Settings.Builder builder = Settings.builder() - .putList("reindex.remote.whitelist", remote.httpHost+":"+remote.httpPort); + Settings.Builder builder = Settings.builder().putList("reindex.remote.whitelist", remote.httpHost + ":" + remote.httpPort); return builder.build(); } - - //TODO add ssl tests - //https://github.com/elastic/elasticsearch/issues/27267 - + + // TODO add ssl tests + // https://github.com/elastic/elasticsearch/issues/27267 + @Test public void testNonSSLReindex() throws Exception { setupReindex(); - - final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("nagilum","nagilum")).getBody(); + + final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("nagilum", "nagilum") + ).getBody(); Assert.assertTrue(cl1BodyMain.contains("crl1")); - + try (Client tc = cl1.nodeClient()) { tc.admin().indices().create(new CreateIndexRequest("twutter")).actionGet(); } - - final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("nagilum","nagilum")).getBody(); + + final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest( + "", + encodeBasicHeader("nagilum", "nagilum") + ).getBody(); Assert.assertTrue(cl2BodyMain.contains("crl2")); - + try (Client tc = cl2.nodeClient()) { - tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } - - String reindex = "{"+ - "\"source\": {"+ - "\"remote\": {"+ - "\"host\": \"http://"+cl2Info.httpHost+":"+cl2Info.httpPort+"\","+ - "\"username\": \"nagilum\","+ - "\"password\": \"nagilum\""+ - "},"+ - "\"index\": \"twitter\","+ - "\"size\": 10"+ - "},"+ - "\"dest\": {"+ - "\"index\": \"twutter\""+ - "}"+ - "}"; - + + String reindex = "{" + + "\"source\": {" + + "\"remote\": {" + + "\"host\": \"http://" + + cl2Info.httpHost + + ":" + + cl2Info.httpPort + + "\"," + + "\"username\": \"nagilum\"," + + "\"password\": \"nagilum\"" + + "}," + + "\"index\": \"twitter\"," + + "\"size\": 10" + + "}," + + "\"dest\": {" + + "\"index\": \"twutter\"" + + "}" + + "}"; + System.out.println(reindex); - + HttpResponse ccs = null; - + System.out.println("###################### reindex"); - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("_reindex?pretty", reindex, encodeBasicHeader("nagilum","nagilum")); + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest( + "_reindex?pretty", + reindex, + encodeBasicHeader("nagilum", "nagilum") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertTrue(ccs.getBody().contains("created\" : 1")); diff --git a/src/test/java/org/opensearch/security/configuration/SaltTest.java b/src/test/java/org/opensearch/security/configuration/SaltTest.java index 01ddf3de56..8af7501810 100644 --- a/src/test/java/org/opensearch/security/configuration/SaltTest.java +++ b/src/test/java/org/opensearch/security/configuration/SaltTest.java @@ -44,9 +44,7 @@ public void testDefault() { public void testConfig() { // arrange final String testSalt = "abcdefghijklmnop"; - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_COMPLIANCE_SALT, testSalt) - .build(); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_COMPLIANCE_SALT, testSalt).build(); // act final Salt salt = Salt.from(settings); @@ -60,9 +58,7 @@ public void testConfig() { public void testSaltUsesOnlyFirst16Bytes() { // arrange final String testSalt = "abcdefghijklmnopqrstuvwxyz"; - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_COMPLIANCE_SALT, testSalt) - .build(); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_COMPLIANCE_SALT, testSalt).build(); // act final Salt salt = Salt.from(settings); @@ -79,9 +75,7 @@ public void testSaltThrowsExceptionWhenInsufficientBytesProvided() { // arrange final String testSalt = "abcd"; - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_COMPLIANCE_SALT, testSalt) - .build(); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_COMPLIANCE_SALT, testSalt).build(); // act final Salt salt = Salt.from(settings); } @@ -93,7 +87,7 @@ public void testSaltThrowsExceptionWhenInsufficientBytesArrayProvided() { thrown.expectMessage("Provided compliance salt must contain 16 bytes"); // act - new Salt(new byte[]{1, 2, 3, 4, 5}); + new Salt(new byte[] { 1, 2, 3, 4, 5 }); } @Test @@ -103,12 +97,12 @@ public void testSaltThrowsExceptionWhenExcessBytesArrayProvided() { thrown.expectMessage("Provided compliance salt must contain 16 bytes"); // act - new Salt(new byte[]{1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5}); + new Salt(new byte[] { 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5 }); } @Test public void testSaltThrowsNoExceptionWhenCorrectBytesArrayProvided() { // act - new Salt(new byte[]{1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1}); + new Salt(new byte[] { 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1 }); } } 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 06d428a483..dfe96bb55d 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/AbstractDlsFlsTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/AbstractDlsFlsTest.java @@ -58,58 +58,56 @@ protected final void setup(Settings override, DynamicSecurityConfig dynamicSecur Settings settings = Settings.builder().put(ConfigConstants.SECURITY_AUDIT_TYPE_DEFAULT, "debug").put(override).build(); setup(Settings.EMPTY, dynamicSecurityConfig, settings, true); - try(Client tc = getClient()) { + try (Client tc = getClient()) { populateData(tc); } rh = nonSslRestHelper(); } - + protected SearchResponse executeSearch(String indexName, String user, String password) throws Exception { - HttpResponse response = rh.executeGetRequest("/"+indexName+"/_search?from=0&size=50&pretty", - encodeBasicHeader(user, password)); - Assert.assertEquals(200, response.getStatusCode()); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, - LoggingDeprecationHandler.INSTANCE, response.getBody()); - return SearchResponse.fromXContent(xcp); + HttpResponse response = rh.executeGetRequest("/" + indexName + "/_search?from=0&size=50&pretty", encodeBasicHeader(user, password)); + Assert.assertEquals(200, response.getStatusCode()); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + return SearchResponse.fromXContent(xcp); } protected GetResponse executeGet(String indexName, String id, String user, String password) throws Exception { - HttpResponse response = rh.executeGetRequest("/"+indexName+"/_doc/"+id, encodeBasicHeader(user, password)); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, - LoggingDeprecationHandler.INSTANCE, response.getBody()); - return GetResponse.fromXContent(xcp); + HttpResponse response = rh.executeGetRequest("/" + indexName + "/_doc/" + id, encodeBasicHeader(user, password)); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + return GetResponse.fromXContent(xcp); } - - protected MultiSearchResponse executeMSearchMatchAll(String user, String password, String ... indexName) throws Exception { - StringBuilder body = new StringBuilder(); - - for (String index : indexName) { - body.append("{\"index\": \"").append(index).append("\"}\n"); - body.append("{\"query\" : {\"match_all\" : {}}}\n"); - } - - HttpResponse response = rh.executePostRequest("/_msearch?pretty", body.toString(), - encodeBasicHeader(user, password)); - Assert.assertEquals(200, response.getStatusCode()); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, - LoggingDeprecationHandler.INSTANCE, response.getBody()); - return MultiSearchResponse.fromXContext(xcp); + + protected MultiSearchResponse executeMSearchMatchAll(String user, String password, String... indexName) throws Exception { + StringBuilder body = new StringBuilder(); + + for (String index : indexName) { + body.append("{\"index\": \"").append(index).append("\"}\n"); + body.append("{\"query\" : {\"match_all\" : {}}}\n"); + } + + HttpResponse response = rh.executePostRequest("/_msearch?pretty", body.toString(), encodeBasicHeader(user, password)); + Assert.assertEquals(200, response.getStatusCode()); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + return MultiSearchResponse.fromXContext(xcp); } protected MultiGetResponse executeMGet(String user, String password, Map indicesAndIds) throws Exception { - - Set indexAndIdJson = new HashSet<>(); - for (Map.Entry indexAndId : indicesAndIds.entrySet()) { - indexAndIdJson.add("{ \"_index\": \""+indexAndId.getKey()+"\", \"_id\": \""+indexAndId.getValue()+"\" }"); - } - String body = "{ \"docs\": ["+ String.join(",", indexAndIdJson) +"] }"; - - HttpResponse response = rh.executePostRequest("/_mget?pretty", body,encodeBasicHeader(user, password)); - Assert.assertEquals(200, response.getStatusCode()); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, - LoggingDeprecationHandler.INSTANCE, response.getBody()); - return MultiGetResponse.fromXContent(xcp); + + Set indexAndIdJson = new HashSet<>(); + for (Map.Entry indexAndId : indicesAndIds.entrySet()) { + indexAndIdJson.add("{ \"_index\": \"" + indexAndId.getKey() + "\", \"_id\": \"" + indexAndId.getValue() + "\" }"); + } + String body = "{ \"docs\": [" + String.join(",", indexAndIdJson) + "] }"; + + HttpResponse response = rh.executePostRequest("/_mget?pretty", body, encodeBasicHeader(user, password)); + Assert.assertEquals(200, response.getStatusCode()); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + return MultiGetResponse.fromXContent(xcp); } abstract void populateData(Client tc); 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 4cd6987b5a..079afa65bd 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/CCReplicationTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/CCReplicationTest.java @@ -73,18 +73,24 @@ public class CCReplicationTest extends AbstractDlsFlsTest { public static class MockReplicationPlugin extends Plugin implements ActionPlugin { public static String injectedRoles = null; - public MockReplicationPlugin() { - } + public MockReplicationPlugin() {} @Override - public Collection createComponents(Client client, ClusterService clusterService, ThreadPool threadPool, - ResourceWatcherService resourceWatcherService, ScriptService scriptService, - NamedXContentRegistry xContentRegistry, Environment environment, - NodeEnvironment nodeEnvironment, NamedWriteableRegistry namedWriteableRegistry, + public Collection createComponents( + Client client, + ClusterService clusterService, + ThreadPool threadPool, + ResourceWatcherService resourceWatcherService, + ScriptService scriptService, + NamedXContentRegistry xContentRegistry, + Environment environment, + NodeEnvironment nodeEnvironment, + NamedWriteableRegistry namedWriteableRegistry, IndexNameExpressionResolver indexNameExpressionResolver, - Supplier repositoriesServiceSupplier) { - if(injectedRoles != null) - threadPool.getThreadContext().putTransient(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_ROLES, injectedRoles); + Supplier repositoriesServiceSupplier + ) { + if (injectedRoles != null) threadPool.getThreadContext() + .putTransient(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_ROLES, injectedRoles); return new ArrayList<>(); } @@ -97,6 +103,7 @@ public Collection createComponents(Client client, ClusterService cluster public static class MockReplicationAction extends ActionType { public static final MockReplicationAction INSTANCE = new MockReplicationAction(); public static final String NAME = "indices:admin/plugins/replication/file_chunk"; + private MockReplicationAction() { super(NAME, AcknowledgedResponse::new); } @@ -104,6 +111,7 @@ private MockReplicationAction() { public static class MockReplicationRequest extends AcknowledgedRequest implements Replaceable { private String index; + public MockReplicationRequest(String index) { this.index = index; } @@ -131,7 +139,7 @@ public IndicesRequest indices(String... strings) { @Override public String[] indices() { - return new String[]{index}; + return new String[] { index }; } @Override @@ -148,8 +156,7 @@ public boolean includeDataStreams() { public static class TransportMockReplicationAction extends HandledTransportAction { @Inject - public TransportMockReplicationAction(TransportService transportService, - ActionFilters actionFilters) { + public TransportMockReplicationAction(TransportService transportService, ActionFilters actionFilters) { super(MockReplicationAction.NAME, transportService, actionFilters, MockReplicationRequest::new); } @@ -159,33 +166,54 @@ protected void doExecute(Task task, MockReplicationRequest request, ActionListen } } - //Wait for the security plugin to load roles. + // Wait for the security plugin to load roles. private void waitOrThrow(Client client, String index) throws Exception { waitForInit(client); client.execute(MockReplicationAction.INSTANCE, new MockReplicationRequest(index)).actionGet(); } void populateData(Client tc) { - tc.index(new IndexRequest("hr-dls").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"User\": \"testuser\",\"Date\":\"2021-01-18T17:27:20Z\",\"Designation\":\"HR\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("hr-fls").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"User\": \"adminuser\",\"Date\":\"2021-01-18T17:27:20Z\",\"Designation\":\"CEO\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("hr-masking").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"User\": \"maskeduser\",\"Date\":\"2021-01-18T17:27:20Z\",\"Designation\":\"CEO\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("hr-normal").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"User\": \"employee1\",\"Date\":\"2021-01-18T17:27:20Z\",\"Designation\":\"EMPLOYEE\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("hr-dls").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"User\": \"testuser\",\"Date\":\"2021-01-18T17:27:20Z\",\"Designation\":\"HR\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("hr-fls").id("1") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"User\": \"adminuser\",\"Date\":\"2021-01-18T17:27:20Z\",\"Designation\":\"CEO\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("hr-masking").id("1") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"User\": \"maskeduser\",\"Date\":\"2021-01-18T17:27:20Z\",\"Designation\":\"CEO\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("hr-normal").id("1") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"User\": \"employee1\",\"Date\":\"2021-01-18T17:27:20Z\",\"Designation\":\"EMPLOYEE\"}", XContentType.JSON) + ).actionGet(); } @Test public void testReplication() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig().setSecurityRoles("roles_ccreplication.yml"), Settings.EMPTY); - Assert.assertEquals(clusterInfo.numNodes, clusterHelper.nodeClient().admin().cluster().health( - new ClusterHealthRequest().waitForGreenStatus()).actionGet().getNumberOfNodes()); - Assert.assertEquals(ClusterHealthStatus.GREEN, clusterHelper.nodeClient().admin().cluster(). - health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus()); + Assert.assertEquals( + clusterInfo.numNodes, + clusterHelper.nodeClient() + .admin() + .cluster() + .health(new ClusterHealthRequest().waitForGreenStatus()) + .actionGet() + .getNumberOfNodes() + ); + Assert.assertEquals( + ClusterHealthStatus.GREEN, + clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus() + ); - final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) + final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) .put(minimumSecuritySettings(Settings.EMPTY).get(0)) .put("cluster.name", clusterInfo.clustername) .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") @@ -199,39 +227,79 @@ public void testReplication() throws Exception { // Set roles for the user MockReplicationPlugin.injectedRoles = "ccr_user|opendistro_security_human_resources_trainee"; - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class, MockReplicationPlugin.class).start()) { + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + MockReplicationPlugin.class + ).start() + ) { waitOrThrow(node.client(), "hr-dls"); Assert.fail("Expecting exception"); } catch (OpenSearchSecurityException ex) { log.warn(ex.getMessage()); Assert.assertNotNull(ex); - Assert.assertTrue(ex.getMessage().contains("Cross Cluster Replication is not supported when FLS or DLS or Fieldmasking is activated")); + Assert.assertTrue( + ex.getMessage().contains("Cross Cluster Replication is not supported when FLS or DLS or Fieldmasking is activated") + ); Assert.assertEquals(ex.status(), RestStatus.FORBIDDEN); } - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class, MockReplicationPlugin.class).start()) { + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + MockReplicationPlugin.class + ).start() + ) { waitOrThrow(node.client(), "hr-fls"); Assert.fail("Expecting exception"); } catch (OpenSearchSecurityException ex) { log.warn(ex.getMessage()); Assert.assertNotNull(ex); - Assert.assertTrue(ex.getMessage().contains("Cross Cluster Replication is not supported when FLS or DLS or Fieldmasking is activated")); + Assert.assertTrue( + ex.getMessage().contains("Cross Cluster Replication is not supported when FLS or DLS or Fieldmasking is activated") + ); Assert.assertEquals(ex.status(), RestStatus.FORBIDDEN); } - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class, MockReplicationPlugin.class).start()) { + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + MockReplicationPlugin.class + ).start() + ) { waitOrThrow(node.client(), "hr-masking"); Assert.fail("Expecting exception"); } catch (OpenSearchSecurityException ex) { log.warn(ex.getMessage()); Assert.assertNotNull(ex); - Assert.assertTrue(ex.getMessage().contains("Cross Cluster Replication is not supported when FLS or DLS or Fieldmasking is activated")); + Assert.assertTrue( + ex.getMessage().contains("Cross Cluster Replication is not supported when FLS or DLS or Fieldmasking is activated") + ); Assert.assertEquals(ex.status(), RestStatus.FORBIDDEN); } - try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class, MockReplicationPlugin.class).start()) { + try ( + Node node = new PluginAwareNode( + false, + tcSettings, + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + MockReplicationPlugin.class + ).start() + ) { waitOrThrow(node.client(), "hr-normal"); - AcknowledgedResponse res = node.client().execute(MockReplicationAction.INSTANCE, new MockReplicationRequest("hr-normal")).actionGet(); + AcknowledgedResponse res = node.client() + .execute(MockReplicationAction.INSTANCE, new MockReplicationRequest("hr-normal")) + .actionGet(); Assert.assertTrue(res.isAcknowledged()); } } diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/CustomFieldMaskedComplexMappingTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/CustomFieldMaskedComplexMappingTest.java index bbc7bd5479..9be61b30b7 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/CustomFieldMaskedComplexMappingTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/CustomFieldMaskedComplexMappingTest.java @@ -25,19 +25,20 @@ import org.opensearch.security.test.helper.file.FileHelper; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class CustomFieldMaskedComplexMappingTest extends AbstractDlsFlsTest{ - +public class CustomFieldMaskedComplexMappingTest extends AbstractDlsFlsTest { @Override protected void populateData(Client tc) { try { - tc.admin().indices().create(new CreateIndexRequest("logs").mapping(FileHelper.loadFile("dlsfls/masked_field_mapping.json"), XContentType.JSON)).actionGet(); - + tc.admin() + .indices() + .create(new CreateIndexRequest("logs").mapping(FileHelper.loadFile("dlsfls/masked_field_mapping.json"), XContentType.JSON)) + .actionGet(); byte[] data = FileHelper.loadFile("dlsfls/logs_bulk_data.json").getBytes(StandardCharsets.UTF_8); BulkRequest br = new BulkRequest().add(data, 0, data.length, XContentType.JSON).setRefreshPolicy(RefreshPolicy.IMMEDIATE); - if(tc.bulk(br).actionGet().hasFailures()) { + if (tc.bulk(br).actionGet().hasFailures()) { Assert.fail("bulk import failed"); } Thread.sleep(1000); @@ -54,17 +55,17 @@ public void testComplexMappingAggregationsRace() throws Exception { setup(); - - String query = "{"+ - "\"aggs\" : {"+ - "\"ips\" : { \"terms\" : { \"field\" : \"machine.os.keyword\", \"size\": 1002, \"show_term_doc_count_error\": true } }"+ - "}"+ - "}"; - - + String query = "{" + + "\"aggs\" : {" + + "\"ips\" : { \"terms\" : { \"field\" : \"machine.os.keyword\", \"size\": 1002, \"show_term_doc_count_error\": true } }" + + "}" + + "}"; HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/logs/_search?pretty&size=0", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/logs/_search?pretty&size=0", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("win 8")); @@ -84,16 +85,22 @@ public void testComplexMappingAggregationsRace() throws Exception { Assert.assertFalse(res.getBody().contains("88783587fef7")); Assert.assertFalse(res.getBody().contains("c1f04335d9f41")); - for(int i=0;i<10;i++) { - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/logs/_search?pretty&size=0", query, encodeBasicHeader("user_masked_nowc1", "password"))).getStatusCode()); + for (int i = 0; i < 10; i++) { + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/logs/_search?pretty&size=0", query, encodeBasicHeader("user_masked_nowc1", "password"))) + .getStatusCode() + ); System.out.println(res.getBody()); } + for (int i = 0; i < 10; i++) { - - for(int i=0;i<10;i++) { - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/logs/_search?pretty&size=0", query, encodeBasicHeader("user_masked_nowc", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/logs/_search?pretty&size=0", query, encodeBasicHeader("user_masked_nowc", "password"))) + .getStatusCode() + ); System.out.println(res.getBody()); Assert.assertFalse(res.getBody().contains("\"aaa")); @@ -115,21 +122,18 @@ public void testComplexMappingAggregationsRace() throws Exception { Assert.assertFalse(res.getBody().contains("osx")); Assert.assertFalse(res.getBody().contains("win 7")); - - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/logs/_search?pretty&size=0", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); - - + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/logs/_search?pretty&size=0", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); } - - - - - - for(int i=0;i<10;i++) { - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/logs/_search?pretty&size=0", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); + for (int i = 0; i < 10; i++) { + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/logs/_search?pretty&size=0", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("win 8")); Assert.assertTrue(res.getBody().contains("win xp")); Assert.assertTrue(res.getBody().contains("ios")); @@ -157,14 +161,27 @@ public void testComplexMappingSearch() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logs/_search?pretty&size=100", encodeBasicHeader("admin", "admin"))).getStatusCode()); - Assert.assertFalse(res.getBody().contains("88783587fef740690c4fa39476fb86314d034fa3370e1a1fa186f6d9d4644a18ad85063c1e3161f8929f7ca019bb8740611eaf337709113901e7c3a6b59f4166")); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/logs/_search?pretty&size=100", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); + Assert.assertFalse( + res.getBody() + .contains( + "88783587fef740690c4fa39476fb86314d034fa3370e1a1fa186f6d9d4644a18ad85063c1e3161f8929f7ca019bb8740611eaf337709113901e7c3a6b59f4166" + ) + ); Assert.assertFalse(res.getBody().contains("e90a2fdf7b1939ec06e294321fd7d23e1a70d8fc080a3f85d0f3bf08c205b53")); Assert.assertFalse(res.getBody().contains("*.*.*.*")); Assert.assertFalse(res.getBody().contains("430a65d4b9c51de7192e048b2639db0de5c56f1901afccc2a01ef97f6a769a38")); Assert.assertFalse(res.getBody().contains("7f48bb3636edf546a75968ca7cd0bdfe63e9ce7af04ef7cb642931fa15d2d7a3")); Assert.assertFalse(res.getBody().contains("https://www.static.co/downloads/beats/metricbeat")); - Assert.assertFalse(res.getBody().contains("eb551beb79792f3366b3623495bb0d9acf85055e63d4f48ade024289f9aa782fc7bd215b6ed3452d3d3ff3eccd8a7f5e8f55b8d0ef245c7ccbf8b747e0be9807")); + Assert.assertFalse( + res.getBody() + .contains( + "eb551beb79792f3366b3623495bb0d9acf85055e63d4f48ade024289f9aa782fc7bd215b6ed3452d3d3ff3eccd8a7f5e8f55b8d0ef245c7ccbf8b747e0be9807" + ) + ); Assert.assertFalse(res.getBody().contains("XXX.XXX.XXX.XXX")); Assert.assertFalse(res.getBody().contains("ANONYMIZED_BROWSER")); Assert.assertFalse(res.getBody().contains("69ce5643cf2abe2dec163330161e669")); @@ -172,32 +189,59 @@ public void testComplexMappingSearch() throws Exception { Assert.assertTrue(res.getBody().contains("win xp")); Assert.assertTrue(res.getBody().contains("\"timestamp\" : \"2018-07-22T20:45:16.163Z")); - for(int i=0;i<10;i++) { - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logs/_search?pretty&size=100", encodeBasicHeader("user_masked_nowc", "password"))).getStatusCode()); - Assert.assertTrue(res.getBody().contains("88783587fef740690c4fa39476fb86314d034fa3370e1a1fa186f6d9d4644a18ad85063c1e3161f8929f7ca019bb8740611eaf337709113901e7c3a6b59f4166")); - Assert.assertTrue(res.getBody().contains("e90a2fdf7b1939ec06e294321fd7d23e1a70d8fc080a3f85d0f3bf08c205b53")); - Assert.assertTrue(res.getBody().contains("*.*.*.*")); - Assert.assertTrue(res.getBody().contains("430a65d4b9c51de7192e048b2639db0de5c56f1901afccc2a01ef97f6a769a38")); - Assert.assertTrue(res.getBody().contains("7f48bb3636edf546a75968ca7cd0bdfe63e9ce7af04ef7cb642931fa15d2d7a3")); - Assert.assertTrue(res.getBody().contains("https://www.static.co/downloads/beats/metricbeat")); - Assert.assertTrue(res.getBody().contains("eb551beb79792f3366b3623495bb0d9acf85055e63d4f48ade024289f9aa782fc7bd215b6ed3452d3d3ff3eccd8a7f5e8f55b8d0ef245c7ccbf8b747e0be9807")); - Assert.assertTrue(res.getBody().contains("XXX.XXX.XXX.XXX")); - Assert.assertTrue(res.getBody().contains("ANONYMIZED_BROWSER")); - Assert.assertTrue(res.getBody().contains("69ce5643cf2abe2dec163330161e669")); - Assert.assertTrue(res.getBody().contains("0b50856e97a54df444ff8f7c73c67fc3109aa234")); - Assert.assertFalse(res.getBody().contains("win xp")); - Assert.assertFalse(res.getBody().contains("\"timestamp\" : \"2018-07-22T20:45:16.163Z")); + for (int i = 0; i < 10; i++) { + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/logs/_search?pretty&size=100", encodeBasicHeader("user_masked_nowc", "password"))) + .getStatusCode() + ); + Assert.assertTrue( + res.getBody() + .contains( + "88783587fef740690c4fa39476fb86314d034fa3370e1a1fa186f6d9d4644a18ad85063c1e3161f8929f7ca019bb8740611eaf337709113901e7c3a6b59f4166" + ) + ); + Assert.assertTrue(res.getBody().contains("e90a2fdf7b1939ec06e294321fd7d23e1a70d8fc080a3f85d0f3bf08c205b53")); + Assert.assertTrue(res.getBody().contains("*.*.*.*")); + Assert.assertTrue(res.getBody().contains("430a65d4b9c51de7192e048b2639db0de5c56f1901afccc2a01ef97f6a769a38")); + Assert.assertTrue(res.getBody().contains("7f48bb3636edf546a75968ca7cd0bdfe63e9ce7af04ef7cb642931fa15d2d7a3")); + Assert.assertTrue(res.getBody().contains("https://www.static.co/downloads/beats/metricbeat")); + Assert.assertTrue( + res.getBody() + .contains( + "eb551beb79792f3366b3623495bb0d9acf85055e63d4f48ade024289f9aa782fc7bd215b6ed3452d3d3ff3eccd8a7f5e8f55b8d0ef245c7ccbf8b747e0be9807" + ) + ); + Assert.assertTrue(res.getBody().contains("XXX.XXX.XXX.XXX")); + Assert.assertTrue(res.getBody().contains("ANONYMIZED_BROWSER")); + Assert.assertTrue(res.getBody().contains("69ce5643cf2abe2dec163330161e669")); + Assert.assertTrue(res.getBody().contains("0b50856e97a54df444ff8f7c73c67fc3109aa234")); + Assert.assertFalse(res.getBody().contains("win xp")); + Assert.assertFalse(res.getBody().contains("\"timestamp\" : \"2018-07-22T20:45:16.163Z")); } - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logs/_search?pretty&size=100", encodeBasicHeader("admin", "admin"))).getStatusCode()); - Assert.assertFalse(res.getBody().contains("88783587fef740690c4fa39476fb86314d034fa3370e1a1fa186f6d9d4644a18ad85063c1e3161f8929f7ca019bb8740611eaf337709113901e7c3a6b59f4166")); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/logs/_search?pretty&size=100", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); + Assert.assertFalse( + res.getBody() + .contains( + "88783587fef740690c4fa39476fb86314d034fa3370e1a1fa186f6d9d4644a18ad85063c1e3161f8929f7ca019bb8740611eaf337709113901e7c3a6b59f4166" + ) + ); Assert.assertFalse(res.getBody().contains("e90a2fdf7b1939ec06e294321fd7d23e1a70d8fc080a3f85d0f3bf08c205b53")); Assert.assertFalse(res.getBody().contains("*.*.*.*")); Assert.assertFalse(res.getBody().contains("430a65d4b9c51de7192e048b2639db0de5c56f1901afccc2a01ef97f6a769a38")); Assert.assertFalse(res.getBody().contains("7f48bb3636edf546a75968ca7cd0bdfe63e9ce7af04ef7cb642931fa15d2d7a3")); Assert.assertFalse(res.getBody().contains("https://www.static.co/downloads/beats/metricbeat")); - Assert.assertFalse(res.getBody().contains("eb551beb79792f3366b3623495bb0d9acf85055e63d4f48ade024289f9aa782fc7bd215b6ed3452d3d3ff3eccd8a7f5e8f55b8d0ef245c7ccbf8b747e0be9807")); + Assert.assertFalse( + res.getBody() + .contains( + "eb551beb79792f3366b3623495bb0d9acf85055e63d4f48ade024289f9aa782fc7bd215b6ed3452d3d3ff3eccd8a7f5e8f55b8d0ef245c7ccbf8b747e0be9807" + ) + ); Assert.assertFalse(res.getBody().contains("XXX.XXX.XXX.XXX")); Assert.assertFalse(res.getBody().contains("ANONYMIZED_BROWSER")); Assert.assertFalse(res.getBody().contains("69ce5643cf2abe2dec163330161e669")); 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 9d48e0309f..91c6115695 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/CustomFieldMaskedTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/CustomFieldMaskedTest.java @@ -25,18 +25,35 @@ public class CustomFieldMaskedTest extends AbstractDlsFlsTest { protected void populateData(Client tc) { - tc.index(new IndexRequest("deals").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"customer\": {\"name\":\"cust1\", \"street\":\"testroad\"}, \"ip_source\": \"100.100.1.1\",\"ip_dest\": \"123.123.1.1\",\"amount\": 10, \"mynum\": 1000000000000000000}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("deals").id("2").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"customer\": {\"name\":\"cust2\", \"street\":\"testroad\"}, \"ip_source\": \"100.100.2.2\",\"ip_dest\": \"123.123.2.2\",\"amount\": 20, \"mynum\": 1000000000000000000}", XContentType.JSON)).actionGet(); - - - for (int i=0; i<30;i++) { - tc.index(new IndexRequest("deals").id("a"+i).setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"customer\": {\"name\":\"cust1\", \"street\":\"testroad\"}, \"ip_source\": \"200.100.1.1\",\"ip_dest\": \"123.123.1.1\",\"amount\": 10, \"mynum\": 1000000000000000000}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("deals").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source( + "{\"customer\": {\"name\":\"cust1\", \"street\":\"testroad\"}, \"ip_source\": \"100.100.1.1\",\"ip_dest\": \"123.123.1.1\",\"amount\": 10, \"mynum\": 1000000000000000000}", + XContentType.JSON + ) + ).actionGet(); + tc.index( + new IndexRequest("deals").id("2") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source( + "{\"customer\": {\"name\":\"cust2\", \"street\":\"testroad\"}, \"ip_source\": \"100.100.2.2\",\"ip_dest\": \"123.123.2.2\",\"amount\": 20, \"mynum\": 1000000000000000000}", + XContentType.JSON + ) + ).actionGet(); + + for (int i = 0; i < 30; i++) { + tc.index( + new IndexRequest("deals").id("a" + i) + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source( + "{\"customer\": {\"name\":\"cust1\", \"street\":\"testroad\"}, \"ip_source\": \"200.100.1.1\",\"ip_dest\": \"123.123.1.1\",\"amount\": 10, \"mynum\": 1000000000000000000}", + XContentType.JSON + ) + ).actionGet(); } - } + } @Test public void testMaskedAggregations() throws Exception { @@ -45,23 +62,23 @@ public void testMaskedAggregations() throws Exception { String query; HttpResponse res; - //Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); - //Assert.assertTrue(res.getBody().contains("100.100")); - - query = - "{" + - "\"query\" : {" + - "\"match_all\": {" + - "}" + - "}," + - "\"aggs\" : {" + - "\"ips\" : {" + - "\"terms\" : {" + - "\"field\" : \"ip_source.keyword\"" + - "}" + - "}" + - "}"+ - "}"; + // Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, + // encodeBasicHeader("admin", "admin"))).getStatusCode()); + // Assert.assertTrue(res.getBody().contains("100.100")); + + query = "{" + + "\"query\" : {" + + "\"match_all\": {" + + "}" + + "}," + + "\"aggs\" : {" + + "\"ips\" : {" + + "\"terms\" : {" + + "\"field\" : \"ip_source.keyword\"" + + "}" + + "}" + + "}" + + "}"; res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("user_masked_custom", "password")); System.out.println(res.getBody()); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); @@ -69,23 +86,22 @@ public void testMaskedAggregations() throws Exception { Assert.assertTrue(res.getBody().contains("***")); Assert.assertTrue(res.getBody().contains("XXX")); - query = - "{" + - "\"query\" : {" + - "\"match_all\": {" + - "}" + - "}," + - "\"aggs\": {" + - "\"ips\" : {" + - "\"terms\" : {" + - "\"field\" : \"ip_source.keyword\"," + - "\"order\": {" + - "\"_term\" : \"asc\"" + - "}" + - "}" + - "}" + - "}" + - "}"; + query = "{" + + "\"query\" : {" + + "\"match_all\": {" + + "}" + + "}," + + "\"aggs\": {" + + "\"ips\" : {" + + "\"terms\" : {" + + "\"field\" : \"ip_source.keyword\"," + + "\"order\": {" + + "\"_term\" : \"asc\"" + + "}" + + "}" + + "}" + + "}" + + "}"; res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("user_masked_custom", "password")); System.out.println(res.getBody()); @@ -94,23 +110,22 @@ public void testMaskedAggregations() throws Exception { Assert.assertTrue(res.getBody().contains("***")); Assert.assertTrue(res.getBody().contains("XXX")); - query = - "{" + - "\"query\" : {" + - "\"match_all\": {" + - "}" + - "}," + - "\"aggs\": {" + - "\"ips\" : {" + - "\"terms\" : {" + - "\"field\" : \"ip_source.keyword\"," + - "\"order\": {" + - "\"_term\" : \"desc\"" + - "}" + - "}" + - "}" + - "}" + - "}"; + query = "{" + + "\"query\" : {" + + "\"match_all\": {" + + "}" + + "}," + + "\"aggs\": {" + + "\"ips\" : {" + + "\"terms\" : {" + + "\"field\" : \"ip_source.keyword\"," + + "\"order\": {" + + "\"_term\" : \"desc\"" + + "}" + + "}" + + "}" + + "}" + + "}"; res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("user_masked_custom", "password")); System.out.println(res.getBody()); @@ -126,36 +141,41 @@ public void testCustomMaskedAggregationsRace() throws Exception { setup(); + String query = "{" + + "\"aggs\" : {" + + "\"ips\" : { \"terms\" : { \"field\" : \"ip_source.keyword\", \"size\": 1002, \"show_term_doc_count_error\": true } }" + + "}" + + "}"; - String query = "{"+ - "\"aggs\" : {"+ - "\"ips\" : { \"terms\" : { \"field\" : \"ip_source.keyword\", \"size\": 1002, \"show_term_doc_count_error\": true } }"+ - "}"+ - "}"; - - - - HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); - Assert.assertTrue(res.getBody().contains("100.100")); - Assert.assertTrue(res.getBody().contains("200.100")); - Assert.assertTrue(res.getBody().contains("\"doc_count\" : 30")); - Assert.assertTrue(res.getBody().contains("\"doc_count\" : 1")); - Assert.assertFalse(res.getBody().contains("***")); - Assert.assertFalse(res.getBody().contains("XXX")); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("user_masked_custom", "password"))).getStatusCode()); - Assert.assertTrue(res.getBody().contains("\"doc_count\" : 31")); - Assert.assertTrue(res.getBody().contains("\"doc_count\" : 1")); - Assert.assertFalse(res.getBody().contains("100.100")); - Assert.assertFalse(res.getBody().contains("200.100")); - Assert.assertTrue(res.getBody().contains("***.100.1.XXX")); - Assert.assertTrue(res.getBody().contains("***.100.2.XXX")); - + HttpResponse res; + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); + Assert.assertTrue(res.getBody().contains("100.100")); + Assert.assertTrue(res.getBody().contains("200.100")); + Assert.assertTrue(res.getBody().contains("\"doc_count\" : 30")); + Assert.assertTrue(res.getBody().contains("\"doc_count\" : 1")); + Assert.assertFalse(res.getBody().contains("***")); + Assert.assertFalse(res.getBody().contains("XXX")); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("user_masked_custom", "password"))) + .getStatusCode() + ); + Assert.assertTrue(res.getBody().contains("\"doc_count\" : 31")); + Assert.assertTrue(res.getBody().contains("\"doc_count\" : 1")); + Assert.assertFalse(res.getBody().contains("100.100")); + Assert.assertFalse(res.getBody().contains("200.100")); + Assert.assertTrue(res.getBody().contains("***.100.1.XXX")); + Assert.assertTrue(res.getBody().contains("***.100.2.XXX")); - for(int i=0;i<10;i++) { - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); + for (int i = 0; i < 10; i++) { + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("100.100")); Assert.assertTrue(res.getBody().contains("200.100")); Assert.assertTrue(res.getBody().contains("\"doc_count\" : 30")); @@ -173,18 +193,30 @@ public void testCustomMaskedSearch() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=100", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=100", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 32,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); Assert.assertTrue(res.getBody().contains("cust1")); Assert.assertTrue(res.getBody().contains("cust2")); Assert.assertTrue(res.getBody().contains("100.100.1.1")); Assert.assertTrue(res.getBody().contains("100.100.2.2")); - Assert.assertFalse(res.getBody().contains("8976994d0491e35f74fcac67ede9c83334a6ad34dae07c176df32f10225f93c5077ddd302c02ddd618b2406b1e4dfe50a727cbc880cfe264c552decf2d224ffc")); + Assert.assertFalse( + res.getBody() + .contains( + "8976994d0491e35f74fcac67ede9c83334a6ad34dae07c176df32f10225f93c5077ddd302c02ddd618b2406b1e4dfe50a727cbc880cfe264c552decf2d224ffc" + ) + ); Assert.assertFalse(res.getBody().contains("***")); Assert.assertFalse(res.getBody().contains("XXX")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=100", encodeBasicHeader("user_masked_custom", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=100", encodeBasicHeader("user_masked_custom", "password"))) + .getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 32,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -192,7 +224,12 @@ public void testCustomMaskedSearch() throws Exception { Assert.assertFalse(res.getBody().contains("cust2")); Assert.assertFalse(res.getBody().contains("100.100.1.1")); Assert.assertFalse(res.getBody().contains("100.100.2.2")); - Assert.assertTrue(res.getBody().contains("8976994d0491e35f74fcac67ede9c83334a6ad34dae07c176df32f10225f93c5077ddd302c02ddd618b2406b1e4dfe50a727cbc880cfe264c552decf2d224ffc")); + Assert.assertTrue( + res.getBody() + .contains( + "8976994d0491e35f74fcac67ede9c83334a6ad34dae07c176df32f10225f93c5077ddd302c02ddd618b2406b1e4dfe50a727cbc880cfe264c552decf2d224ffc" + ) + ); Assert.assertTrue(res.getBody().contains("***.100.1.XXX")); Assert.assertTrue(res.getBody().contains("123.123.1.XXX")); @@ -205,27 +242,41 @@ public void testCustomMaskedGet() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_doc/0?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_doc/0?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"found\" : true")); Assert.assertTrue(res.getBody().contains("cust1")); Assert.assertFalse(res.getBody().contains("cust2")); Assert.assertTrue(res.getBody().contains("100.100.1.1")); Assert.assertFalse(res.getBody().contains("100.100.2.2")); - Assert.assertFalse(res.getBody().contains("8976994d0491e35f74fcac67ede9c83334a6ad34dae07c176df32f10225f93c5077ddd302c02ddd618b2406b1e4dfe50a727cbc880cfe264c552decf2d224ffc")); + Assert.assertFalse( + res.getBody() + .contains( + "8976994d0491e35f74fcac67ede9c83334a6ad34dae07c176df32f10225f93c5077ddd302c02ddd618b2406b1e4dfe50a727cbc880cfe264c552decf2d224ffc" + ) + ); Assert.assertFalse(res.getBody().contains("***")); Assert.assertFalse(res.getBody().contains("XXX")); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_doc/0?pretty", encodeBasicHeader("user_masked_custom", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_doc/0?pretty", encodeBasicHeader("user_masked_custom", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"found\" : true")); Assert.assertFalse(res.getBody().contains("cust1")); Assert.assertFalse(res.getBody().contains("cust2")); Assert.assertFalse(res.getBody().contains("100.100.1.1")); Assert.assertFalse(res.getBody().contains("100.100.2.2")); - Assert.assertTrue(res.getBody().contains("8976994d0491e35f74fcac67ede9c83334a6ad34dae07c176df32f10225f93c5077ddd302c02ddd618b2406b1e4dfe50a727cbc880cfe264c552decf2d224ffc")); + Assert.assertTrue( + res.getBody() + .contains( + "8976994d0491e35f74fcac67ede9c83334a6ad34dae07c176df32f10225f93c5077ddd302c02ddd618b2406b1e4dfe50a727cbc880cfe264c552decf2d224ffc" + ) + ); Assert.assertTrue(res.getBody().contains("***.100.1.XXX")); Assert.assertTrue(res.getBody().contains("123.123.1.XXX")); } - } diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/DateMathTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/DateMathTest.java index 54110e911f..da4d9db867 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/DateMathTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/DateMathTest.java @@ -26,8 +26,7 @@ import org.opensearch.security.support.SecurityUtils; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class DateMathTest extends AbstractDlsFlsTest{ - +public class DateMathTest extends AbstractDlsFlsTest { protected void populateData(Client tc) { @@ -35,17 +34,25 @@ protected void populateData(Client tc) { sdf.setTimeZone(TimeZone.getTimeZone("UTC")); String date = sdf.format(new Date()); - tc.index(new IndexRequest("logstash-"+date).setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"message\":\"mymsg1a\", \"ipaddr\": \"10.0.0.0\",\"msgid\": \"12\"}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("logstash-"+date).setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"message\":\"mymsg1b\", \"ipaddr\": \"10.0.0.1\",\"msgid\": \"14\"}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("logstash-1-"+date).setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"message\":\"mymsg1c\", \"ipaddr\": \"10.0.0.2\",\"msgid\": \"12\"}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("logstash-1-"+date).setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"message\":\"mymsg1d\", \"ipaddr\": \"10.0.0.3\",\"msgid\": \"14\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("logstash-" + date).setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"message\":\"mymsg1a\", \"ipaddr\": \"10.0.0.0\",\"msgid\": \"12\"}", XContentType.JSON) + ).actionGet(); + + tc.index( + new IndexRequest("logstash-" + date).setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"message\":\"mymsg1b\", \"ipaddr\": \"10.0.0.1\",\"msgid\": \"14\"}", XContentType.JSON) + ).actionGet(); + + tc.index( + new IndexRequest("logstash-1-" + date).setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"message\":\"mymsg1c\", \"ipaddr\": \"10.0.0.2\",\"msgid\": \"12\"}", XContentType.JSON) + ).actionGet(); + + tc.index( + new IndexRequest("logstash-1-" + date).setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"message\":\"mymsg1d\", \"ipaddr\": \"10.0.0.3\",\"msgid\": \"14\"}", XContentType.JSON) + ).actionGet(); } @Test @@ -55,7 +62,10 @@ public void testSearch() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("%3Clogstash-%7Bnow%2Fd%7D%3E/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("%3Clogstash-%7Bnow%2Fd%7D%3E/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -64,7 +74,13 @@ public void testSearch() throws Exception { Assert.assertTrue(res.getBody().contains("mymsg")); Assert.assertTrue(res.getBody().contains("msgid")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("%3Clogstash-%7Bnow%2Fd%7D%3E/_search?pretty", encodeBasicHeader("opendistro_security_logstash", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest( + "%3Clogstash-%7Bnow%2Fd%7D%3E/_search?pretty", + encodeBasicHeader("opendistro_security_logstash", "password") + )).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -81,13 +97,23 @@ public void testFieldCaps() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("%3Clogstash-%7Bnow%2Fd%7D%3E/_field_caps?fields=*&pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("%3Clogstash-%7Bnow%2Fd%7D%3E/_field_caps?fields=*&pretty", encodeBasicHeader("admin", "admin"))) + .getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("ipaddr")); Assert.assertTrue(res.getBody().contains("message")); Assert.assertTrue(res.getBody().contains("msgid")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("%3Clogstash-%7Bnow%2Fd%7D%3E/_field_caps?fields=*&pretty", encodeBasicHeader("opendistro_security_logstash", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest( + "%3Clogstash-%7Bnow%2Fd%7D%3E/_field_caps?fields=*&pretty", + encodeBasicHeader("opendistro_security_logstash", "password") + )).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertFalse(res.getBody().contains("ipaddr")); Assert.assertFalse(res.getBody().contains("message")); @@ -101,7 +127,10 @@ public void testSearchWc() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("logstash-*/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("logstash-*/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 4,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -110,7 +139,11 @@ public void testSearchWc() throws Exception { Assert.assertTrue(res.getBody().contains("mymsg")); Assert.assertTrue(res.getBody().contains("msgid")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("logstash-*/_search?pretty", encodeBasicHeader("opendistro_security_logstash", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("logstash-*/_search?pretty", encodeBasicHeader("opendistro_security_logstash", "password"))) + .getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -127,7 +160,10 @@ public void testSearchWc2() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("logstash-1-*,logstash-20*/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("logstash-1-*,logstash-20*/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 4,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -136,7 +172,10 @@ public void testSearchWc2() throws Exception { Assert.assertTrue(res.getBody().contains("mymsg")); Assert.assertTrue(res.getBody().contains("msgid")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("logstash-1-*,logstash-20*/_search?pretty", encodeBasicHeader("regex", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("logstash-1-*,logstash-20*/_search?pretty", encodeBasicHeader("regex", "password"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); 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 aafffb141f..580cabc66b 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/DfmOverwritesAllTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/DfmOverwritesAllTest.java @@ -37,17 +37,41 @@ public class DfmOverwritesAllTest extends AbstractDlsFlsTest { protected void populateData(Client tc) { - tc.index(new IndexRequest("index1-1").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"field1\": 1, \"field2\": \"value-2-1\", \"field3\": \"value-3-1\", \"field4\": \"value-4-1\" }", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("index1-2").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"field1\": 2, \"field2\": \"value-2-2\", \"field3\": \"value-3-2\", \"field4\": \"value-4-2\" }", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("index1-3").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"field1\": 3, \"field2\": \"value-2-3\", \"field3\": \"value-3-3\", \"field4\": \"value-4-3\" }", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("index1-4").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"field1\": 4, \"field2\": \"value-2-4\", \"field3\": \"value-3-4\", \"field4\": \"value-4-4\" }", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("index1-1").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source( + "{\"field1\": 1, \"field2\": \"value-2-1\", \"field3\": \"value-3-1\", \"field4\": \"value-4-1\" }", + XContentType.JSON + ) + ).actionGet(); + + tc.index( + new IndexRequest("index1-2").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source( + "{\"field1\": 2, \"field2\": \"value-2-2\", \"field3\": \"value-3-2\", \"field4\": \"value-4-2\" }", + XContentType.JSON + ) + ).actionGet(); + + tc.index( + new IndexRequest("index1-3").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source( + "{\"field1\": 3, \"field2\": \"value-2-3\", \"field3\": \"value-3-3\", \"field4\": \"value-4-3\" }", + XContentType.JSON + ) + ).actionGet(); + + tc.index( + new IndexRequest("index1-4").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source( + "{\"field1\": 4, \"field2\": \"value-2-4\", \"field3\": \"value-3-4\", \"field4\": \"value-4-4\" }", + XContentType.JSON + ) + ).actionGet(); } @@ -59,15 +83,17 @@ protected void populateData(Client tc) { public void testDFMUnrestrictedUser() throws Exception { final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_DFM_EMPTY_OVERRIDES_ALL, true).build(); - setup(settings, new DynamicSecurityConfig().setConfig("securityconfig_dfm_empty_overwrites_all.yml") + setup( + settings, + new DynamicSecurityConfig().setConfig("securityconfig_dfm_empty_overwrites_all.yml") .setSecurityInternalUsers("internal_users_dfm_empty_overwrites_all.yml") .setSecurityRoles("roles_dfm_empty_overwrites_all.yml") - .setSecurityRolesMapping("rolesmapping_dfm_empty_overwrites_all.yml")); + .setSecurityRolesMapping("rolesmapping_dfm_empty_overwrites_all.yml") + ); HttpResponse response; - response = rh.executeGetRequest("/index1-*/_search?pretty", - encodeBasicHeader("admin", "password")); + response = rh.executeGetRequest("/index1-*/_search?pretty", encodeBasicHeader("admin", "password")); Assert.assertEquals(200, response.getStatusCode()); // the only document in index1-1 is filtered by DLS query, so normally no hit in index-1-1 @@ -99,21 +125,23 @@ public void testDFMUnrestrictedUser() throws Exception { public void testDFMRestrictedUser() throws Exception { final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_DFM_EMPTY_OVERRIDES_ALL, true).build(); - setup(settings, new DynamicSecurityConfig().setConfig("securityconfig_dfm_empty_overwrites_all.yml") + setup( + settings, + new DynamicSecurityConfig().setConfig("securityconfig_dfm_empty_overwrites_all.yml") .setSecurityInternalUsers("internal_users_dfm_empty_overwrites_all.yml") .setSecurityRoles("roles_dfm_empty_overwrites_all.yml") - .setSecurityRolesMapping("rolesmapping_dfm_empty_overwrites_all.yml")); + .setSecurityRolesMapping("rolesmapping_dfm_empty_overwrites_all.yml") + ); HttpResponse response; - response = rh.executeGetRequest("/index1-*/_search?pretty", - encodeBasicHeader("dfm_restricted_role", "password")); + response = rh.executeGetRequest("/index1-*/_search?pretty", encodeBasicHeader("dfm_restricted_role", "password")); Assert.assertEquals(200, response.getStatusCode()); - // the only document in index1-1 is filtered by DLS query, so no hit in index-1-1 + // the only document in index1-1 is filtered by DLS query, so no hit in index-1-1 Assert.assertFalse(response.getBody().contains("index1-1")); - // field3 and field4 - filtered out by FLS + // field3 and field4 - filtered out by FLS Assert.assertFalse(response.getBody().contains("value-3-1")); Assert.assertFalse(response.getBody().contains("value-4-1")); Assert.assertFalse(response.getBody().contains("value-3-2")); @@ -146,15 +174,20 @@ public void testDFMRestrictedAndUnrestrictedAllIndices() throws Exception { final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_DFM_EMPTY_OVERRIDES_ALL, true).build(); - setup(settings, new DynamicSecurityConfig().setConfig("securityconfig_dfm_empty_overwrites_all.yml") + setup( + settings, + new DynamicSecurityConfig().setConfig("securityconfig_dfm_empty_overwrites_all.yml") .setSecurityInternalUsers("internal_users_dfm_empty_overwrites_all.yml") .setSecurityRoles("roles_dfm_empty_overwrites_all.yml") - .setSecurityRolesMapping("rolesmapping_dfm_empty_overwrites_all.yml")); + .setSecurityRolesMapping("rolesmapping_dfm_empty_overwrites_all.yml") + ); HttpResponse response; - response = rh.executeGetRequest("/index1-*/_search?pretty", - encodeBasicHeader("dfm_restricted_and_unrestricted_all_indices_role", "password")); + response = rh.executeGetRequest( + "/index1-*/_search?pretty", + encodeBasicHeader("dfm_restricted_and_unrestricted_all_indices_role", "password") + ); Assert.assertEquals(200, response.getStatusCode()); // the only document in index1-1 is filtered by DLS query, so normally no hit in index-1-1 @@ -187,18 +220,25 @@ public void testDFMRestrictedAndUnrestrictedAllIndices() throws Exception { @Test public void testDFMRestrictedAndUnrestrictedOneIndex() throws Exception { final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_DFM_EMPTY_OVERRIDES_ALL, true).build(); - setup(settings, new DynamicSecurityConfig().setConfig("securityconfig_dfm_empty_overwrites_all.yml") + setup( + settings, + new DynamicSecurityConfig().setConfig("securityconfig_dfm_empty_overwrites_all.yml") .setSecurityInternalUsers("internal_users_dfm_empty_overwrites_all.yml") .setSecurityRoles("roles_dfm_empty_overwrites_all.yml") - .setSecurityRolesMapping("rolesmapping_dfm_empty_overwrites_all.yml")); + .setSecurityRolesMapping("rolesmapping_dfm_empty_overwrites_all.yml") + ); HttpResponse response; - response = rh.executeGetRequest("/_plugins/_security/authinfo?pretty", - encodeBasicHeader("dfm_restricted_and_unrestricted_one_index_role", "password")); + response = rh.executeGetRequest( + "/_plugins/_security/authinfo?pretty", + encodeBasicHeader("dfm_restricted_and_unrestricted_one_index_role", "password") + ); - response = rh.executeGetRequest("/index1-*/_search?pretty", - encodeBasicHeader("dfm_restricted_and_unrestricted_one_index_role", "password")); + response = rh.executeGetRequest( + "/index1-*/_search?pretty", + encodeBasicHeader("dfm_restricted_and_unrestricted_one_index_role", "password") + ); Assert.assertEquals(200, response.getStatusCode()); // we have a role that places no restrictions on index-1-1, lifting the DLS from the restricted role 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 c4105c11e9..cbd1e09e56 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsDateMathTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsDateMathTest.java @@ -27,58 +27,75 @@ import org.opensearch.security.support.ConfigConstants; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class DlsDateMathTest extends AbstractDlsFlsTest{ - +public class DlsDateMathTest extends AbstractDlsFlsTest { @Override protected void populateData(Client tc) { - - LocalDateTime yesterday = LocalDateTime.now(ZoneId.of("UTC")).minusDays(1); LocalDateTime today = LocalDateTime.now(ZoneId.of("UTC")); LocalDateTime tomorrow = LocalDateTime.now(ZoneId.of("UTC")).plusDays(1); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd"); - - tc.index(new IndexRequest("logstash").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"@timestamp\": \""+formatter.format(yesterday)+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("logstash").id("2").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"@timestamp\": \""+formatter.format(today)+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("logstash").id("3").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"@timestamp\": \""+formatter.format(tomorrow)+"\"}", XContentType.JSON)).actionGet(); + + tc.index( + new IndexRequest("logstash").id("1") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"@timestamp\": \"" + formatter.format(yesterday) + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("logstash").id("2") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"@timestamp\": \"" + formatter.format(today) + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("logstash").id("3") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"@timestamp\": \"" + formatter.format(tomorrow) + "\"}", XContentType.JSON) + ).actionGet(); } - @Test public void testDlsDateMathQuery() throws Exception { - final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_UNSUPPORTED_ALLOW_NOW_IN_DLS,true).build(); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_UNSUPPORTED_ALLOW_NOW_IN_DLS, true).build(); setup(settings); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash/_search?pretty", encodeBasicHeader("date_math", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/logstash/_search?pretty", encodeBasicHeader("date_math", "password"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/logstash/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 3,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); } - + @Test public void testDlsDateMathQueryNotAllowed() throws Exception { setup(); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, (res = rh.executeGetRequest("/logstash/_search?pretty", encodeBasicHeader("date_math", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_BAD_REQUEST, + (res = rh.executeGetRequest("/logstash/_search?pretty", encodeBasicHeader("date_math", "password"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("'now' is not allowed in DLS queries")); Assert.assertTrue(res.getBody().contains("error")); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/logstash/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 3,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsFlsCrossClusterMinimalRoundtripSearchTests.java b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsFlsCrossClusterMinimalRoundtripSearchTests.java index 86b97c1afe..81610b0ee4 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsFlsCrossClusterMinimalRoundtripSearchTests.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsFlsCrossClusterMinimalRoundtripSearchTests.java @@ -13,5 +13,7 @@ public class DlsFlsCrossClusterMinimalRoundtripSearchTests extends DlsFlsCrossClusterSearchTest { @Override - protected boolean ccsMinimizeRoundtrips() { return true; } + protected boolean ccsMinimizeRoundtrips() { + return true; + } } diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsFlsCrossClusterSearchTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsFlsCrossClusterSearchTest.java index 8fcd85f873..a86c49d21d 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsFlsCrossClusterSearchTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsFlsCrossClusterSearchTest.java @@ -31,12 +31,18 @@ public class DlsFlsCrossClusterSearchTest extends AbstractSecurityUnitTest { - private final ClusterHelper cl1 = new ClusterHelper("crl1_n"+num.incrementAndGet()+"_f"+System.getProperty("forkno")+"_t"+System.nanoTime()); - private final ClusterHelper cl2 = new ClusterHelper("crl2_n"+num.incrementAndGet()+"_f"+System.getProperty("forkno")+"_t"+System.nanoTime()); + private final ClusterHelper cl1 = new ClusterHelper( + "crl1_n" + num.incrementAndGet() + "_f" + System.getProperty("forkno") + "_t" + System.nanoTime() + ); + private final ClusterHelper cl2 = new ClusterHelper( + "crl2_n" + num.incrementAndGet() + "_f" + System.getProperty("forkno") + "_t" + System.nanoTime() + ); private ClusterInfo cl1Info; private ClusterInfo cl2Info; - protected boolean ccsMinimizeRoundtrips() { return false; }; + protected boolean ccsMinimizeRoundtrips() { + return false; + }; @Override protected String getResourceFolder() { @@ -45,13 +51,16 @@ protected String getResourceFolder() { private void setupCcs(String remoteRoles) throws Exception { - System.setProperty("security.display_lic_none","true"); + System.setProperty("security.display_lic_none", "true"); - cl2Info = cl2.startCluster(minimumSecuritySettings(Settings.builder().putList("node.roles", "remote_cluster_client").build()), ClusterConfiguration.DEFAULT); + cl2Info = cl2.startCluster( + minimumSecuritySettings(Settings.builder().putList("node.roles", "remote_cluster_client").build()), + ClusterConfiguration.DEFAULT + ); initialize(cl2, cl2Info, new DynamicSecurityConfig().setSecurityRoles(remoteRoles)); System.out.println("### cl2 complete ###"); - //cl1 is coordinating + // cl1 is coordinating cl1Info = cl1.startCluster(minimumSecuritySettings(crossClusterNodeSettings(cl2Info)), ClusterConfiguration.DEFAULT); System.out.println("### cl1 start ###"); initialize(cl1, cl1Info, new DynamicSecurityConfig().setSecurityRoles("roles_983.yml")); @@ -66,8 +75,8 @@ public void tearDown() throws Exception { private Settings crossClusterNodeSettings(ClusterInfo remote) { Settings.Builder builder = Settings.builder() - .putList("cluster.remote.cross_cluster_two.seeds", remote.nodeHost+":"+remote.nodePort) - .putList("node.roles", "remote_cluster_client"); + .putList("cluster.remote.cross_cluster_two.seeds", remote.nodeHost + ":" + remote.nodePort) + .putList("node.roles", "remote_cluster_client"); return builder.build(); } @@ -76,42 +85,71 @@ public void testCcs() throws Exception { setupCcs("roles_983.yml"); try (Client tc = cl1.nodeClient()) { - tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } try (Client tc = cl2.nodeClient()) { - tc.index(new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\","+ - "\"Designation\": \"CEO\","+ - "\"FirstName\": \"__fn__"+cl2Info.clustername+"\","+ - "\"LastName\": \"lastname0\","+ - "\"Salary\": \"salary0\","+ - "\"SecretFiled\": \"secret0\","+ - "\"AnotherSecredField\": \"anothersecret0\","+ - "\"XXX\": \"xxx0\"" - + "}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("1") - .source("{\"cluster\": \""+cl2Info.clustername+"\","+ - "\"Designation\": \"someoneelse\","+ - "\"FirstName\": \"__fn__"+cl2Info.clustername+"\","+ - "\"LastName\": \"lastname1\","+ - "\"Salary\": \"salary1\","+ - "\"SecretFiled\": \"secret1\","+ - "\"AnotherSecredField\": \"anothersecret1\","+ - "\"XXX\": \"xxx1\"" - + "}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source( + "{\"cluster\": \"" + + cl2Info.clustername + + "\"," + + "\"Designation\": \"CEO\"," + + "\"FirstName\": \"__fn__" + + cl2Info.clustername + + "\"," + + "\"LastName\": \"lastname0\"," + + "\"Salary\": \"salary0\"," + + "\"SecretFiled\": \"secret0\"," + + "\"AnotherSecredField\": \"anothersecret0\"," + + "\"XXX\": \"xxx0\"" + + "}", + XContentType.JSON + ) + ).actionGet(); + + tc.index( + new IndexRequest("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("1") + .source( + "{\"cluster\": \"" + + cl2Info.clustername + + "\"," + + "\"Designation\": \"someoneelse\"," + + "\"FirstName\": \"__fn__" + + cl2Info.clustername + + "\"," + + "\"LastName\": \"lastname1\"," + + "\"Salary\": \"salary1\"," + + "\"SecretFiled\": \"secret1\"," + + "\"AnotherSecredField\": \"anothersecret1\"," + + "\"XXX\": \"xxx1\"" + + "}", + XContentType.JSON + ) + ).actionGet(); } HttpResponse ccs = null; System.out.println("###################### query 1"); - //on coordinating cluster - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:humanresources/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("human_resources_trainee", "password")); + // on coordinating cluster + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:humanresources/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("human_resources_trainee", "password") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("crl1")); @@ -134,42 +172,71 @@ public void testCcsDifferentConfig() throws Exception { setupCcs("roles_ccs2.yml"); try (Client tc = cl1.nodeClient()) { - tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); } try (Client tc = cl2.nodeClient()) { - tc.index(new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\","+ - "\"Designation\": \"CEO\","+ - "\"FirstName\": \"__fn__"+cl2Info.clustername+"\","+ - "\"LastName\": \"lastname0\","+ - "\"Salary\": \"salary0\","+ - "\"SecretFiled\": \"secret0\","+ - "\"AnotherSecredField\": \"anothersecret0\","+ - "\"XXX\": \"xxx0\"" - + "}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("1") - .source("{\"cluster\": \""+cl2Info.clustername+"\","+ - "\"Designation\": \"someoneelse\","+ - "\"FirstName\": \"__fn__"+cl2Info.clustername+"\","+ - "\"LastName\": \"lastname1\","+ - "\"Salary\": \"salary1\","+ - "\"SecretFiled\": \"secret1\","+ - "\"AnotherSecredField\": \"anothersecret1\","+ - "\"XXX\": \"xxx1\"" - + "}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source( + "{\"cluster\": \"" + + cl2Info.clustername + + "\"," + + "\"Designation\": \"CEO\"," + + "\"FirstName\": \"__fn__" + + cl2Info.clustername + + "\"," + + "\"LastName\": \"lastname0\"," + + "\"Salary\": \"salary0\"," + + "\"SecretFiled\": \"secret0\"," + + "\"AnotherSecredField\": \"anothersecret0\"," + + "\"XXX\": \"xxx0\"" + + "}", + XContentType.JSON + ) + ).actionGet(); + + tc.index( + new IndexRequest("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("1") + .source( + "{\"cluster\": \"" + + cl2Info.clustername + + "\"," + + "\"Designation\": \"someoneelse\"," + + "\"FirstName\": \"__fn__" + + cl2Info.clustername + + "\"," + + "\"LastName\": \"lastname1\"," + + "\"Salary\": \"salary1\"," + + "\"SecretFiled\": \"secret1\"," + + "\"AnotherSecredField\": \"anothersecret1\"," + + "\"XXX\": \"xxx1\"" + + "}", + XContentType.JSON + ) + ).actionGet(); } HttpResponse ccs = null; System.out.println("###################### query 1"); - //on coordinating cluster - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:humanresources/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("human_resources_trainee", "password")); + // on coordinating cluster + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:humanresources/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("human_resources_trainee", "password") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertFalse(ccs.getBody().contains("crl1")); @@ -192,64 +259,113 @@ public void testCcsDifferentConfigBoth() throws Exception { setupCcs("roles_ccs2.yml"); try (Client tc = cl1.nodeClient()) { - tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl1Info.clustername+"\","+ - "\"Designation\": \"CEO\","+ - "\"FirstName\": \"__fn__"+cl1Info.clustername+"\","+ - "\"LastName\": \"lastname0\","+ - "\"Salary\": \"salary0\","+ - "\"SecretFiled\": \"secret3\","+ - "\"AnotherSecredField\": \"anothersecret3\","+ - "\"XXX\": \"xxx0\"" - + "}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("1") - .source("{\"cluster\": \""+cl1Info.clustername+"\","+ - "\"Designation\": \"someoneelse\","+ - "\"FirstName\": \"__fn__"+cl1Info.clustername+"\","+ - "\"LastName\": \"lastname1\","+ - "\"Salary\": \"salary1\","+ - "\"SecretFiled\": \"secret4\","+ - "\"AnotherSecredField\": \"anothersecret4\","+ - "\"XXX\": \"xxx1\"" - + "}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl1Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + + tc.index( + new IndexRequest("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source( + "{\"cluster\": \"" + + cl1Info.clustername + + "\"," + + "\"Designation\": \"CEO\"," + + "\"FirstName\": \"__fn__" + + cl1Info.clustername + + "\"," + + "\"LastName\": \"lastname0\"," + + "\"Salary\": \"salary0\"," + + "\"SecretFiled\": \"secret3\"," + + "\"AnotherSecredField\": \"anothersecret3\"," + + "\"XXX\": \"xxx0\"" + + "}", + XContentType.JSON + ) + ).actionGet(); + + tc.index( + new IndexRequest("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("1") + .source( + "{\"cluster\": \"" + + cl1Info.clustername + + "\"," + + "\"Designation\": \"someoneelse\"," + + "\"FirstName\": \"__fn__" + + cl1Info.clustername + + "\"," + + "\"LastName\": \"lastname1\"," + + "\"Salary\": \"salary1\"," + + "\"SecretFiled\": \"secret4\"," + + "\"AnotherSecredField\": \"anothersecret4\"," + + "\"XXX\": \"xxx1\"" + + "}", + XContentType.JSON + ) + ).actionGet(); } try (Client tc = cl2.nodeClient()) { - tc.index(new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") - .source("{\"cluster\": \""+cl2Info.clustername+"\","+ - "\"Designation\": \"CEO\","+ - "\"FirstName\": \"__fn__"+cl2Info.clustername+"\","+ - "\"LastName\": \"lastname0\","+ - "\"Salary\": \"salary0\","+ - "\"SecretFiled\": \"secret0\","+ - "\"AnotherSecredField\": \"anothersecret0\","+ - "\"XXX\": \"xxx0\"" - + "}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("1") - .source("{\"cluster\": \""+cl2Info.clustername+"\","+ - "\"Designation\": \"someoneelse\","+ - "\"FirstName\": \"__fn__"+cl2Info.clustername+"\","+ - "\"LastName\": \"lastname1\","+ - "\"Salary\": \"salary1\","+ - "\"SecretFiled\": \"secret1\","+ - "\"AnotherSecredField\": \"anothersecret1\","+ - "\"XXX\": \"xxx1\"" - + "}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("twutter").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source("{\"cluster\": \"" + cl2Info.clustername + "\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("0") + .source( + "{\"cluster\": \"" + + cl2Info.clustername + + "\"," + + "\"Designation\": \"CEO\"," + + "\"FirstName\": \"__fn__" + + cl2Info.clustername + + "\"," + + "\"LastName\": \"lastname0\"," + + "\"Salary\": \"salary0\"," + + "\"SecretFiled\": \"secret0\"," + + "\"AnotherSecredField\": \"anothersecret0\"," + + "\"XXX\": \"xxx0\"" + + "}", + XContentType.JSON + ) + ).actionGet(); + + tc.index( + new IndexRequest("humanresources").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .id("1") + .source( + "{\"cluster\": \"" + + cl2Info.clustername + + "\"," + + "\"Designation\": \"someoneelse\"," + + "\"FirstName\": \"__fn__" + + cl2Info.clustername + + "\"," + + "\"LastName\": \"lastname1\"," + + "\"Salary\": \"salary1\"," + + "\"SecretFiled\": \"secret1\"," + + "\"AnotherSecredField\": \"anothersecret1\"," + + "\"XXX\": \"xxx1\"" + + "}", + XContentType.JSON + ) + ).actionGet(); } HttpResponse ccs = null; System.out.println("###################### query 1"); - //on coordinating cluster - ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("cross_cluster_two:humanresources,humanresources/_search?pretty&ccs_minimize_roundtrips="+ccsMinimizeRoundtrips(), encodeBasicHeader("human_resources_trainee", "password")); + // on coordinating cluster + ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest( + "cross_cluster_two:humanresources,humanresources/_search?pretty&ccs_minimize_roundtrips=" + ccsMinimizeRoundtrips(), + encodeBasicHeader("human_resources_trainee", "password") + ); System.out.println(ccs.getBody()); Assert.assertEquals(HttpStatus.SC_OK, ccs.getStatusCode()); Assert.assertTrue(ccs.getBody().contains("crl1")); diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsNestedTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsNestedTest.java index a89d12770d..afb42d9a4a 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsNestedTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsNestedTest.java @@ -23,35 +23,47 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class DlsNestedTest extends AbstractDlsFlsTest{ +public class DlsNestedTest extends AbstractDlsFlsTest { @Override protected void populateData(Client tc) { - String mapping = "{" + - " \"mytype\" : {" + - " \"properties\" : {" + - " \"amount\" : {\"type\": \"integer\"}," + - " \"owner\" : {\"type\": \"text\"}," + - " \"my_nested_object\" : {\"type\" : \"nested\"}" + - " }" + - " }" + - " }" + - ""; - - tc.admin().indices().create(new CreateIndexRequest("deals") - .simpleMapping("amount", "type=integer", "owner", "type=text", "my_nested_object", "type=nested") - .settings(Settings.builder().put("number_of_shards", 1).put("number_of_replicas", 0).build())) - .actionGet(); - - //tc.index(new IndexRequest("deals").id("3").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - // .source("{\"amount\": 7,\"owner\": \"a\", \"my_nested_object\" : {\"name\": \"spock\"}}", XContentType.JSON)).actionGet(); - //tc.index(new IndexRequest("deals").id("4").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - // .source("{\"amount\": 8, \"my_nested_object\" : {\"name\": \"spock\"}}", XContentType.JSON)).actionGet(); - //tc.index(new IndexRequest("deals").id("5").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - // .source("{\"amount\": 1400,\"owner\": \"a\", \"my_nested_object\" : {\"name\": \"spock\"}}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("deals").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"amount\": 1500,\"owner\": \"b\", \"my_nested_object\" : {\"name\": \"spock\"}}", XContentType.JSON)).actionGet(); + String mapping = "{" + + " \"mytype\" : {" + + " \"properties\" : {" + + " \"amount\" : {\"type\": \"integer\"}," + + " \"owner\" : {\"type\": \"text\"}," + + " \"my_nested_object\" : {\"type\" : \"nested\"}" + + " }" + + " }" + + " }" + + ""; + + tc.admin() + .indices() + .create( + new CreateIndexRequest("deals").simpleMapping( + "amount", + "type=integer", + "owner", + "type=text", + "my_nested_object", + "type=nested" + ).settings(Settings.builder().put("number_of_shards", 1).put("number_of_replicas", 0).build()) + ) + .actionGet(); + + // tc.index(new IndexRequest("deals").id("3").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + // .source("{\"amount\": 7,\"owner\": \"a\", \"my_nested_object\" : {\"name\": \"spock\"}}", XContentType.JSON)).actionGet(); + // tc.index(new IndexRequest("deals").id("4").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + // .source("{\"amount\": 8, \"my_nested_object\" : {\"name\": \"spock\"}}", XContentType.JSON)).actionGet(); + // tc.index(new IndexRequest("deals").id("5").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + // .source("{\"amount\": 1400,\"owner\": \"a\", \"my_nested_object\" : {\"name\": \"spock\"}}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("deals").id("1") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"amount\": 1500,\"owner\": \"b\", \"my_nested_object\" : {\"name\": \"spock\"}}", XContentType.JSON) + ).actionGet(); } @Test @@ -59,34 +71,35 @@ public void testNestedQuery() throws Exception { setup(); - - String query = "{" + - " \"query\": {" + - " \"nested\": {" + - " \"path\": \"my_nested_object\"," + - " \"query\": {" + - " \"match\": {\"my_nested_object.name\" : \"spock\"}" + - " }," + - " \"inner_hits\": {} " + - " }" + - " }" + - "}"; - + String query = "{" + + " \"query\": {" + + " \"nested\": {" + + " \"path\": \"my_nested_object\"," + + " \"query\": {" + + " \"match\": {\"my_nested_object.name\" : \"spock\"}" + + " }," + + " \"inner_hits\": {} " + + " }" + + " }" + + "}"; HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager", "password"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"my_nested_object\" : {")); Assert.assertTrue(res.getBody().contains("\"field\" : \"my_nested_object\",")); Assert.assertTrue(res.getBody().contains("\"offset\" : 0")); - //Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); - //System.out.println(res.getBody()); - //Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); - //Assert.assertTrue(res.getBody().contains("\"value\" : 1510.0")); - //Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); + // Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", + // "admin"))).getStatusCode()); + // System.out.println(res.getBody()); + // Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); + // Assert.assertTrue(res.getBody().contains("\"value\" : 1510.0")); + // Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); } - } diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsPropsReplaceTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsPropsReplaceTest.java index 43d5ecfc5f..2e23a11d2d 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsPropsReplaceTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsPropsReplaceTest.java @@ -21,28 +21,40 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class DlsPropsReplaceTest extends AbstractDlsFlsTest{ - +public class DlsPropsReplaceTest extends AbstractDlsFlsTest { protected void populateData(Client tc) { - tc.index(new IndexRequest("prop1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"prop_replace\": \"yes\", \"amount\": 1010}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("prop1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"prop_replace\": \"no\", \"amount\": 2020}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("prop2").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"role\": \"prole1\", \"amount\": 3030}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("prop2").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"role\": \"prole2\", \"amount\": 4040}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("prop2").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"role\": \"prole3\", \"amount\": 5050}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("prop-mapped").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"securityRole\": \"opendistro_security_mapped\", \"amount\": 6060}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("prop-mapped").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"securityRole\": \"not_assigned\", \"amount\": 7070}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("prop1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"prop_replace\": \"yes\", \"amount\": 1010}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("prop1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"prop_replace\": \"no\", \"amount\": 2020}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("prop2").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"role\": \"prole1\", \"amount\": 3030}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("prop2").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"role\": \"prole2\", \"amount\": 4040}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("prop2").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"role\": \"prole3\", \"amount\": 5050}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("prop-mapped").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"securityRole\": \"opendistro_security_mapped\", \"amount\": 6060}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("prop-mapped").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"securityRole\": \"not_assigned\", \"amount\": 7070}", XContentType.JSON) + ).actionGet(); } - @Test public void testDlsProps() throws Exception { @@ -50,15 +62,26 @@ public void testDlsProps() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/prop1,prop2/_search?pretty&size=100", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/prop1,prop2/_search?pretty&size=100", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 5,\n \"relation")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/prop1,prop2/_search?pretty&size=100", encodeBasicHeader("prop_replace", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/prop1,prop2/_search?pretty&size=100", encodeBasicHeader("prop_replace", "password"))) + .getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 3,\n \"relation")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/prop-mapped/_search?pretty&size=100", encodeBasicHeader("prop_replace", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/prop-mapped/_search?pretty&size=100", encodeBasicHeader("prop_replace", "password"))) + .getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"amount\" : 6060")); diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsScrollTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsScrollTest.java index b1d87734e5..cc7b9e305d 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsScrollTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsScrollTest.java @@ -21,53 +21,67 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class DlsScrollTest extends AbstractDlsFlsTest{ - +public class DlsScrollTest extends AbstractDlsFlsTest { @Override protected void populateData(Client tc) { - tc.index(new IndexRequest("deals").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"amount\": 3}", XContentType.JSON)).actionGet(); //not in + tc.index(new IndexRequest("deals").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"amount\": 3}", XContentType.JSON)) + .actionGet(); // not in - tc.index(new IndexRequest("deals").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"amount\": 10}", XContentType.JSON)).actionGet(); //not in + tc.index(new IndexRequest("deals").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"amount\": 10}", XContentType.JSON)) + .actionGet(); // not in - tc.index(new IndexRequest("deals").id("2").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"amount\": 1500}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("deals").id("2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"amount\": 1500}", XContentType.JSON) + ).actionGet(); - tc.index(new IndexRequest("deals").id("4").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"amount\": 21500}", XContentType.JSON)).actionGet(); //not in + tc.index( + new IndexRequest("deals").id("4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"amount\": 21500}", XContentType.JSON) + ).actionGet(); // not in - for(int i=0; i<100; i++) { - tc.index(new IndexRequest("deals").id("gen"+i).setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"amount\": 1500}", XContentType.JSON)).actionGet(); + for (int i = 0; i < 100; i++) { + tc.index( + new IndexRequest("deals").id("gen" + i) + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"amount\": 1500}", XContentType.JSON) + ).actionGet(); } } - @Test public void testDlsScroll() throws Exception { setup(); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res=rh.executeGetRequest("/deals/_search?scroll=1m&pretty=true&size=5", encodeBasicHeader("dept_manager", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?scroll=1m&pretty=true&size=5", encodeBasicHeader("dept_manager", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 101,")); - int c=0; + int c = 0; - while(true) { + while (true) { int start = res.getBody().indexOf("_scroll_id") + 15; - String scrollid = res.getBody().substring(start, res.getBody().indexOf("\"", start+1)); - Assert.assertEquals(HttpStatus.SC_OK, (res=rh.executePostRequest("/_search/scroll?pretty=true", "{\"scroll\" : \"1m\", \"scroll_id\" : \""+scrollid+"\"}", encodeBasicHeader("dept_manager", "password"))).getStatusCode()); + String scrollid = res.getBody().substring(start, res.getBody().indexOf("\"", start + 1)); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest( + "/_search/scroll?pretty=true", + "{\"scroll\" : \"1m\", \"scroll_id\" : \"" + scrollid + "\"}", + encodeBasicHeader("dept_manager", "password") + )).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 101,")); Assert.assertFalse(res.getBody().contains("\"amount\" : 3")); Assert.assertFalse(res.getBody().contains("\"amount\" : 10")); Assert.assertFalse(res.getBody().contains("\"amount\" : 21500")); c++; - if(res.getBody().contains("\"hits\" : [ ]")) { + if (res.getBody().contains("\"hits\" : [ ]")) { break; } } diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsTermLookupQueryTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsTermLookupQueryTest.java index b4a0d1f129..76112f533c 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsTermLookupQueryTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsTermLookupQueryTest.java @@ -54,543 +54,701 @@ public class DlsTermLookupQueryTest extends AbstractDlsFlsTest { - protected void populateData(Client client) { - // user access codes, basis for TLQ query - client.index(new IndexRequest("user_access_codes").id("tlq_1337").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"access_codes\": [1337] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("user_access_codes").id("tlq_42").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"access_codes\": [42] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("user_access_codes").id("tlq_1337_42").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"access_codes\": [1337, 42] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("user_access_codes").id("tlq_999").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"access_codes\": [999] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("user_access_codes").id("tlq_empty_access_codes") - .setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{ \"access_codes\": [] }", XContentType.JSON)) - .actionGet(); - client.index(new IndexRequest("user_access_codes").id("tlq_no_codes").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bla\": \"blub\" }", XContentType.JSON)).actionGet(); - - // need to have keyword for bu field since we're testing aggregations - client.admin().indices().create(new CreateIndexRequest("tlqdocuments")).actionGet(); - client.admin().indices() - .putMapping(new PutMappingRequest("tlqdocuments").source("bu", "type=keyword")) - .actionGet(); - - // tlqdocuments, protected by TLQ - client.index(new IndexRequest("tlqdocuments").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"AAA\", \"access_codes\": [1337] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("2").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"AAA\", \"access_codes\": [42] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("3").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"AAA\", \"access_codes\": [1337, 42] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("4").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"BBB\", \"access_codes\": [1337] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("5").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"BBB\", \"access_codes\": [42] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("6").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"BBB\", \"access_codes\": [1337, 42] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("7").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"CCC\", \"access_codes\": [1337] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("8").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"CCC\", \"access_codes\": [42] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("9").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"CCC\", \"access_codes\": [1337, 42] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("10").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"DDD\", \"access_codes\": [1337] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("11").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"DDD\", \"access_codes\": [42] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("12").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"DDD\", \"access_codes\": [1337, 42] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("13").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"EEE\", \"access_codes\": [1337] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("14").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"EEE\", \"access_codes\": [42] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("15").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"EEE\", \"access_codes\": [1337, 42] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("16").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"FFF\" }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("17").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"FFF\", \"access_codes\": [12345] }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdocuments").id("18").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"bu\": \"FFF\", \"access_codes\": [12345, 6789] }", XContentType.JSON)).actionGet(); - - // we use a "bu" field here as well to test aggregations over multiple indices - client.admin().indices().create(new CreateIndexRequest("tlqdummy")).actionGet(); - client.admin().indices().putMapping(new PutMappingRequest("tlqdummy").source("bu", "type=keyword")) - .actionGet(); - - // tlqdummy, not protected by TLQ - client.index(new IndexRequest("tlqdummy").id("101").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"mykey\": \"101\", \"bu\": \"GGG\" }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdummy").id("102").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"mykey\": \"102\", \"bu\": \"GGG\" }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdummy").id("103").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"mykey\": \"103\", \"bu\": \"GGG\" }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdummy").id("104").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"mykey\": \"104\", \"bu\": \"GGG\" }", XContentType.JSON)).actionGet(); - client.index(new IndexRequest("tlqdummy").id("105").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{ \"mykey\": \"105\", \"bu\": \"GGG\" }", XContentType.JSON)).actionGet(); - - } - - // ------------------------ - // Test search and msearch - // ------------------------ - - @Test - public void testSimpleSearch_AccessCode_1337() throws Exception { - - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - - HttpResponse response = rh.executeGetRequest("/tlqdocuments/_search?pretty", - encodeBasicHeader("tlq_1337", "password")); - Assert.assertEquals(200, response.getStatusCode()); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, - LoggingDeprecationHandler.INSTANCE, response.getBody()); - SearchResponse searchResponse = SearchResponse.fromXContent(xcp); - // 10 docs, all need to have access code 1337 - Assert.assertEquals(searchResponse.toString(), 10, searchResponse.getHits().getTotalHits().value); - // fields need to have 1337 access code - assertAccessCodesMatch(searchResponse.getHits().getHits(), new Integer[] { 1337 }); - } - - @Test - public void testSimpleSearch_AccessCode_42() throws Exception { - - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - - HttpResponse response = rh.executeGetRequest("/tlqdocuments/_search?pretty", - encodeBasicHeader("tlq_42", "password")); - Assert.assertEquals(200, response.getStatusCode()); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, - LoggingDeprecationHandler.INSTANCE, response.getBody()); - SearchResponse searchResponse = SearchResponse.fromXContent(xcp); - - // 10 docs, all need to have access code 42 - Assert.assertEquals(searchResponse.toString(), 10, searchResponse.getHits().getTotalHits().value); - // fields need to have 42 access code - assertAccessCodesMatch(searchResponse.getHits().getHits(), new Integer[] { 42 }); - - } - - @Test - public void testSimpleSearch_AccessCodes_1337_42() throws Exception { - - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - - HttpResponse response = rh.executeGetRequest("/tlqdocuments/_search?pretty", - encodeBasicHeader("tlq_1337_42", "password")); - Assert.assertEquals(200, response.getStatusCode()); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, - LoggingDeprecationHandler.INSTANCE, response.getBody()); - SearchResponse searchResponse = SearchResponse.fromXContent(xcp); - - // 15 docs, all need to have either access code 1337 or 42 - Assert.assertEquals(searchResponse.toString(), 15, searchResponse.getHits().getTotalHits().value); - // fields need to have 42 or 1337 access code - assertAccessCodesMatch(searchResponse.getHits().getHits(), new Integer[] { 42, 1337 }); - - } - - @Test - public void testSimpleSearch_AccessCodes_999() throws Exception { - - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - - HttpResponse response = rh.executeGetRequest("/tlqdocuments/_search?pretty", - encodeBasicHeader("tlq_999", "password")); - Assert.assertEquals(200, response.getStatusCode()); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, - LoggingDeprecationHandler.INSTANCE, response.getBody()); - SearchResponse searchResponse = SearchResponse.fromXContent(xcp); - - Assert.assertEquals(searchResponse.toString(), 0, searchResponse.getHits().getTotalHits().value); - } - - @Test - public void testSimpleSearch_AccessCodes_emptyAccessCodes() throws Exception { - - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - SearchResponse searchResponse = executeSearch("tlqdocuments", "tlq_empty_access_codes", "password"); - Assert.assertEquals(searchResponse.toString(), 0, searchResponse.getHits().getTotalHits().value); - } - - @Test - public void testSimpleSearch_AccessCodes_noAccessCodes() throws Exception { - - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - SearchResponse searchResponse = executeSearch("tlqdocuments", "tlq_no_codes", "password"); - - Assert.assertEquals(searchResponse.toString(), 0, searchResponse.getHits().getTotalHits().value); - } - - @Test - public void testSimpleSearch_AllIndices_All_AccessCodes_1337() throws Exception { - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - - SearchResponse searchResponse = executeSearch("_all", "tlq_1337", "password"); - - // assume hits from 2 indices: - // - tlqdocuments, must contain only docs with access code 1337 - // - tlqdummy, contains all documents - // no access to user_access_codes must be granted - - // check all 5 tlqdummy entries present, index is not protected by DLS - Set tlqdummyHits = Arrays.asList(searchResponse.getHits().getHits()).stream() - .filter((h) -> h.getIndex().equals("tlqdummy")).collect(Collectors.toSet()); - Assert.assertEquals(searchResponse.toString(), 5, tlqdummyHits.size()); - - // check 10 hits with code 1337 from tlqdocuments index. All other documents - // must be filtered - Set tlqdocumentHits = Arrays.asList(searchResponse.getHits().getHits()).stream() - .filter((h) -> h.getIndex().equals("tlqdocuments")).collect(Collectors.toSet()); - Assert.assertEquals(searchResponse.toString(), 10, tlqdocumentHits.size()); - assertAccessCodesMatch(tlqdocumentHits, new Integer[] { 1337 }); - - // check no access to user_access_codes index - Set userAccessCodesHits = Arrays.asList(searchResponse.getHits().getHits()).stream() - .filter((h) -> h.getIndex().equals("user_access_codes")).collect(Collectors.toSet()); - Assert.assertEquals(searchResponse.toString(), 0, userAccessCodesHits.size()); - } - - @Test - public void testSimpleSearch_AllIndicesWildcard_AccessCodes_1337() throws Exception { - - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - - SearchResponse searchResponse = executeSearch("*", "tlq_1337", "password"); - - // assume hits from 2 indices: - // - tlqdocuments, must contain only docs with access code 1337 - // - tlqdummy, contains all documents - // no access to user_access_codes must be granted - - // check all 5 tlqdummy entries present, index is not protected by DLS - Set tlqdummyHits = Arrays.asList(searchResponse.getHits().getHits()).stream() - .filter((h) -> h.getIndex().equals("tlqdummy")).collect(Collectors.toSet()); - Assert.assertEquals(searchResponse.toString(), 5, tlqdummyHits.size()); - - // check 10 hits with code 1337 from tlqdocuments index. All other documents - // must be filtered - Set tlqdocumentHits = Arrays.asList(searchResponse.getHits().getHits()).stream() - .filter((h) -> h.getIndex().equals("tlqdocuments")).collect(Collectors.toSet()); - Assert.assertEquals(searchResponse.toString(), 10, tlqdocumentHits.size()); - assertAccessCodesMatch(tlqdocumentHits, new Integer[] { 1337 }); - - // check no access to user_access_codes index - Set userAccessCodesHits = Arrays.asList(searchResponse.getHits().getHits()).stream() - .filter((h) -> h.getIndex().equals("user_access_codes")).collect(Collectors.toSet()); - Assert.assertEquals(searchResponse.toString(), 0, userAccessCodesHits.size()); - } - - @Test - public void testSimpleSearch_ThreeIndicesWildcard_AccessCodes_1337() throws Exception { - - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - - SearchResponse searchResponse = executeSearch("tlq*,user*", "tlq_1337", "password"); - - // assume hits from 2 indices: - // - tlqdocuments, must contain only docs with access code 1337 - // - tlqdummy, contains all documents - // no access to user_access_codes must be granted - - // check all 5 tlqdummy entries present, index is not protected by DLS - Set tlqdummyHits = Arrays.asList(searchResponse.getHits().getHits()).stream() - .filter((h) -> h.getIndex().equals("tlqdummy")).collect(Collectors.toSet()); - Assert.assertEquals(searchResponse.toString(), 5, tlqdummyHits.size()); - - // check 10 hits with code 1337 from tlqdocuments index. All other documents - // must be filtered - Set tlqdocumentHits = Arrays.asList(searchResponse.getHits().getHits()).stream() - .filter((h) -> h.getIndex().equals("tlqdocuments")).collect(Collectors.toSet()); - Assert.assertEquals(searchResponse.toString(), 10, tlqdocumentHits.size()); - assertAccessCodesMatch(tlqdocumentHits, new Integer[] { 1337 }); - - // check no access to user_access_codes index - Set userAccessCodesHits = Arrays.asList(searchResponse.getHits().getHits()).stream() - .filter((h) -> h.getIndex().equals("user_access_codes")).collect(Collectors.toSet()); - Assert.assertEquals(searchResponse.toString(), 0, userAccessCodesHits.size()); - - } - - @Test - public void testSimpleSearch_TwoIndicesConcreteNames_AccessCodes_1337() throws Exception { - - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - - SearchResponse searchResponse = executeSearch("tlqdocuments,tlqdummy", "tlq_1337", "password"); - - // assume hits from 2 indices: - // - tlqdocuments, must contains only 10 docs with access code 1337 - // - tlqdummy, must contains all 5 documents - - // check all 5 tlqdummy entries present, index is not protected by DLS - Set tlqdummyHits = Arrays.asList(searchResponse.getHits().getHits()).stream() - .filter((h) -> h.getIndex().equals("tlqdummy")).collect(Collectors.toSet()); - Assert.assertEquals(searchResponse.toString(), 5, tlqdummyHits.size()); - - // ccheck 10 hits with code 1337 from tlqdocuments index. All other documents - // must be filtered - Set tlqdocumentHits = Arrays.asList(searchResponse.getHits().getHits()).stream() - .filter((h) -> h.getIndex().equals("tlqdocuments")).collect(Collectors.toSet()); - Assert.assertEquals(searchResponse.toString(), 10, tlqdocumentHits.size()); - assertAccessCodesMatch(tlqdocumentHits, new Integer[] { 1337 }); - } - - @Test - public void testMSearch_ThreeIndices_AccessCodes_1337() throws Exception { - - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - - MultiSearchResponse searchResponse = executeMSearchMatchAll("tlq_1337", "password", "tlqdummy", "tlqdocuments", - "user_access_codes"); - - Item[] responseItems = searchResponse.getResponses(); - - // as per API order in response is the same as in the msearch request - - // check all 5 tlqdummy entries present - List tlqdummyHits = Arrays.asList(responseItems[0].getResponse().getHits().getHits()); - Assert.assertEquals(searchResponse.toString(), 5, tlqdummyHits.size()); - - // check 10 hits with code 1337 from tlqdocuments index. All other documents - // must be filtered - List tlqdocumentHits = Arrays.asList(responseItems[1].getResponse().getHits().getHits()); - Assert.assertEquals(searchResponse.toString(), 10, tlqdocumentHits.size()); - assertAccessCodesMatch(tlqdocumentHits, new Integer[] { 1337 }); - - // check no access to user_access_codes index, just two indices in the response - Assert.assertTrue(responseItems[2].getResponse() == null); - Assert.assertTrue(responseItems[2].getFailure() != null); - - } - - // ------------------------ - // Test get and mget - // ------------------------ - - @Test - public void testGet_TlqDocumentsIndex_1337() throws Exception { - - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - - // user has 1337, document has 1337 - GetResponse searchResponse = executeGet("tlqdocuments", "1", "tlq_1337", "password"); - Assert.assertTrue(searchResponse != null); - Assert.assertTrue(searchResponse.isExists()); - assertAccessCodesMatch(searchResponse.getSourceAsMap(), "access_codes", new Integer[] { 1337 }); - - // user has 1337, document has 42, not visible - searchResponse = executeGet("tlqdocuments", "2", "tlq_1337", "password"); - Assert.assertFalse(searchResponse.isExists()); - - // user has 1337, document has 42 and 1337 - searchResponse = executeGet("tlqdocuments", "3", "tlq_1337", "password"); - Assert.assertTrue(searchResponse != null); - Assert.assertTrue(searchResponse.isExists()); - assertAccessCodesMatch(searchResponse.getSourceAsMap(), "access_codes", new Integer[] { 1337 }); - - // user has 1337, document has no access codes, not visible - searchResponse = executeGet("tlqdocuments", "16", "tlq_1337", "password"); - Assert.assertFalse(searchResponse.isExists()); - - // user has 1337, document has 12345, not visible - searchResponse = executeGet("tlqdocuments", "17", "tlq_1337", "password"); - Assert.assertFalse(searchResponse.isExists()); - - // user has 1337, document has 12345 and 6789, not visible - searchResponse = executeGet("tlqdocuments", "18", "tlq_1337", "password"); - Assert.assertFalse(searchResponse.isExists()); - - } - - @Test - public void testGet_TlqDocumentsIndex_1337_42() throws Exception { - - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - - // user has 1337 and 42, document has 1337 - GetResponse searchResponse = executeGet("tlqdocuments", "1", "tlq_1337_42", "password"); - Assert.assertTrue(searchResponse != null); - Assert.assertTrue(searchResponse.isExists()); - assertAccessCodesMatch(searchResponse.getSourceAsMap(), "access_codes", new Integer[] { 1337, 42 }); - - // user has 1337 and 42, document has 42 - searchResponse = executeGet("tlqdocuments", "2", "tlq_1337_42", "password"); - Assert.assertTrue(searchResponse != null); - Assert.assertTrue(searchResponse.isExists()); - assertAccessCodesMatch(searchResponse.getSourceAsMap(), "access_codes", new Integer[] { 1337, 42 }); - - // user has 1337 and 42, document has 42 and 1337 - searchResponse = executeGet("tlqdocuments", "3", "tlq_1337_42", "password"); - Assert.assertTrue(searchResponse != null); - Assert.assertTrue(searchResponse.isExists()); - assertAccessCodesMatch(searchResponse.getSourceAsMap(), "access_codes", new Integer[] { 1337, 42 }); - - // user has 1337 and 42, document has no access codes, not visible - searchResponse = executeGet("tlqdocuments", "16", "tlq_1337_42", "password"); - Assert.assertFalse(searchResponse.isExists()); - - // user has 1337 and 42, document has 12345, not visible - searchResponse = executeGet("tlqdocuments", "17", "tlq_1337_42", "password"); - Assert.assertFalse(searchResponse.isExists()); - - // user has 1337 and 42, document has 12345 and 6789, not visible - searchResponse = executeGet("tlqdocuments", "18", "tlq_1337_42", "password"); - Assert.assertFalse(searchResponse.isExists()); - - } - - @Test - public void testGet_TlqDummyIndex_1337() throws Exception { - - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - - // no restrictions on this index - GetResponse searchResponse = executeGet("tlqdummy", "101", "tlq_1337", "password"); - Assert.assertTrue(searchResponse != null); - Assert.assertTrue(searchResponse.isExists()); - - searchResponse = executeGet("tlqdummy", "102", "tlq_1337", "password"); - Assert.assertTrue(searchResponse != null); - Assert.assertTrue(searchResponse.isExists()); - - } - - @Test - public void testGet_UserAccessCodesIndex_1337() throws Exception { - - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - - // we expect a security exception here, user has no direct access to - // user_access_codes index - HttpResponse response = rh.executeGetRequest("/user_access_codes/_doc/tlq_1337", - encodeBasicHeader("tlq_1337", "password")); - Assert.assertEquals(403, response.getStatusCode()); - } - - @Test - public void testMGet_1337() throws Exception { - - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - - Map indicesAndIds = new HashMap<>(); - indicesAndIds.put("tlqdocuments", "1"); - indicesAndIds.put("tlqdocuments", "2"); - indicesAndIds.put("tlqdocuments", "3"); - indicesAndIds.put("tlqdocuments", "16"); - indicesAndIds.put("tlqdocuments", "17"); - indicesAndIds.put("tlqdocuments", "18"); - indicesAndIds.put("tlqdummy", "101"); - indicesAndIds.put("user_access_codes", "tlq_1337"); - - MultiGetResponse searchResponse = executeMGet("tlq_1337", "password", indicesAndIds); - - for (MultiGetItemResponse response : searchResponse.getResponses()) { - // no response from index "user_access_codes" - Assert.assertFalse(response.getIndex().equals("user_access_codes")); - switch (response.getIndex()) { - case "tlqdocuments": - Assert.assertTrue(response.getId(), response.getId().equals("1") | response.getId().equals("3")); - break; - case "tlqdummy": - Assert.assertTrue(response.getId(), response.getId().equals("101")); - break; - default: - Assert.fail("Index " + response.getIndex() + " present in mget response, but should not"); - } - } - } - -// ------------------------ -// Test aggregations -// ------------------------ - - @Test - public void testSimpleAggregation_tlqdocuments_AccessCode_1337() throws Exception { - - setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") - .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") - .setSecurityRolesMapping("roles_mapping_tlq.yml")); - - String body = "" - + " {\n" - + " \"aggs\": {\n" - + " \"buaggregation\": {\n" - + " \"terms\": {\n" - + " \"field\": \"bu\"\n" - + " }\n" - + " }\n" - + " }\n" - + " }\n" - + ""; - - // need to add typed_keys so aggregations can be parsed - // see for example: - // https://stackoverflow.com/questions/49798654/how-do-you-convert-an-elasticsearch-json-string-response-with-an-aggregation-t - HttpResponse response = rh.executePostRequest("/tlqdocuments/_search?pretty&typed_keys", body, - encodeBasicHeader("tlq_1337", "password")); - Assert.assertTrue(response.getStatusCode() == 200); - NamedXContentRegistry registry = new NamedXContentRegistry(getDefaultNamedXContents()); - XContentParser xcp = XContentType.JSON.xContent().createParser(registry, LoggingDeprecationHandler.INSTANCE, - response.getBody()); - SearchResponse searchResponse = SearchResponse.fromXContent(xcp); - - Aggregations aggs = searchResponse.getAggregations(); - Assert.assertNotNull(searchResponse.toString(), aggs); - Terms agg = aggs.get("buaggregation"); - Assert.assertTrue("Expected aggregation with name 'buaggregation'", agg != null); - // expect AAA - EEE (FFF does not match) with 2 docs each - for (String bucketName : new String[] { "AAA", "BBB", "CCC", "DDD", "EEE" }) { - Bucket bucket = agg.getBucketByKey(bucketName); - Assert.assertNotNull("Expected bucket " + bucketName + " to be present in agregations", bucket); - Assert.assertTrue("Expected doc count in bucket " + bucketName + " to be 2", bucket.getDocCount() == 2); - } - // expect FFF to be absent - Assert.assertNull("Expected bucket FFF to be absent", agg.getBucketByKey("FFF")); - } - - - public static List getDefaultNamedXContents() { - Map> map = new HashMap<>(); - map.put(TopHitsAggregationBuilder.NAME, (p, c) -> ParsedTopHits.fromXContent(p, (String) c)); - map.put(StringTerms.NAME, (p, c) -> ParsedStringTerms.fromXContent(p, (String) c)); - List entries = map.entrySet().stream() - .map(entry -> new NamedXContentRegistry.Entry(Aggregation.class, new ParseField(entry.getKey()), entry.getValue())) - .collect(Collectors.toList()); - return entries; - } + protected void populateData(Client client) { + // user access codes, basis for TLQ query + client.index( + new IndexRequest("user_access_codes").id("tlq_1337") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"access_codes\": [1337] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("user_access_codes").id("tlq_42") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"access_codes\": [42] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("user_access_codes").id("tlq_1337_42") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"access_codes\": [1337, 42] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("user_access_codes").id("tlq_999") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"access_codes\": [999] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("user_access_codes").id("tlq_empty_access_codes") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"access_codes\": [] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("user_access_codes").id("tlq_no_codes") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bla\": \"blub\" }", XContentType.JSON) + ).actionGet(); + + // need to have keyword for bu field since we're testing aggregations + client.admin().indices().create(new CreateIndexRequest("tlqdocuments")).actionGet(); + client.admin().indices().putMapping(new PutMappingRequest("tlqdocuments").source("bu", "type=keyword")).actionGet(); + + // tlqdocuments, protected by TLQ + client.index( + new IndexRequest("tlqdocuments").id("1") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"AAA\", \"access_codes\": [1337] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("2") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"AAA\", \"access_codes\": [42] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("3") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"AAA\", \"access_codes\": [1337, 42] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("4") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"BBB\", \"access_codes\": [1337] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("5") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"BBB\", \"access_codes\": [42] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("6") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"BBB\", \"access_codes\": [1337, 42] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("7") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"CCC\", \"access_codes\": [1337] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("8") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"CCC\", \"access_codes\": [42] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("9") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"CCC\", \"access_codes\": [1337, 42] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("10") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"DDD\", \"access_codes\": [1337] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("11") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"DDD\", \"access_codes\": [42] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("12") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"DDD\", \"access_codes\": [1337, 42] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("13") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"EEE\", \"access_codes\": [1337] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("14") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"EEE\", \"access_codes\": [42] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("15") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"EEE\", \"access_codes\": [1337, 42] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("16") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"FFF\" }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("17") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"FFF\", \"access_codes\": [12345] }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdocuments").id("18") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"bu\": \"FFF\", \"access_codes\": [12345, 6789] }", XContentType.JSON) + ).actionGet(); + + // we use a "bu" field here as well to test aggregations over multiple indices + client.admin().indices().create(new CreateIndexRequest("tlqdummy")).actionGet(); + client.admin().indices().putMapping(new PutMappingRequest("tlqdummy").source("bu", "type=keyword")).actionGet(); + + // tlqdummy, not protected by TLQ + client.index( + new IndexRequest("tlqdummy").id("101") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"mykey\": \"101\", \"bu\": \"GGG\" }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdummy").id("102") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"mykey\": \"102\", \"bu\": \"GGG\" }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdummy").id("103") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"mykey\": \"103\", \"bu\": \"GGG\" }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdummy").id("104") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"mykey\": \"104\", \"bu\": \"GGG\" }", XContentType.JSON) + ).actionGet(); + client.index( + new IndexRequest("tlqdummy").id("105") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{ \"mykey\": \"105\", \"bu\": \"GGG\" }", XContentType.JSON) + ).actionGet(); + + } + + // ------------------------ + // Test search and msearch + // ------------------------ + + @Test + public void testSimpleSearch_AccessCode_1337() throws Exception { + + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + + HttpResponse response = rh.executeGetRequest("/tlqdocuments/_search?pretty", encodeBasicHeader("tlq_1337", "password")); + Assert.assertEquals(200, response.getStatusCode()); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + SearchResponse searchResponse = SearchResponse.fromXContent(xcp); + // 10 docs, all need to have access code 1337 + Assert.assertEquals(searchResponse.toString(), 10, searchResponse.getHits().getTotalHits().value); + // fields need to have 1337 access code + assertAccessCodesMatch(searchResponse.getHits().getHits(), new Integer[] { 1337 }); + } + + @Test + public void testSimpleSearch_AccessCode_42() throws Exception { + + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + + HttpResponse response = rh.executeGetRequest("/tlqdocuments/_search?pretty", encodeBasicHeader("tlq_42", "password")); + Assert.assertEquals(200, response.getStatusCode()); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + SearchResponse searchResponse = SearchResponse.fromXContent(xcp); + + // 10 docs, all need to have access code 42 + Assert.assertEquals(searchResponse.toString(), 10, searchResponse.getHits().getTotalHits().value); + // fields need to have 42 access code + assertAccessCodesMatch(searchResponse.getHits().getHits(), new Integer[] { 42 }); + + } + + @Test + public void testSimpleSearch_AccessCodes_1337_42() throws Exception { + + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + + HttpResponse response = rh.executeGetRequest("/tlqdocuments/_search?pretty", encodeBasicHeader("tlq_1337_42", "password")); + Assert.assertEquals(200, response.getStatusCode()); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + SearchResponse searchResponse = SearchResponse.fromXContent(xcp); + + // 15 docs, all need to have either access code 1337 or 42 + Assert.assertEquals(searchResponse.toString(), 15, searchResponse.getHits().getTotalHits().value); + // fields need to have 42 or 1337 access code + assertAccessCodesMatch(searchResponse.getHits().getHits(), new Integer[] { 42, 1337 }); + + } + + @Test + public void testSimpleSearch_AccessCodes_999() throws Exception { + + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + + HttpResponse response = rh.executeGetRequest("/tlqdocuments/_search?pretty", encodeBasicHeader("tlq_999", "password")); + Assert.assertEquals(200, response.getStatusCode()); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + SearchResponse searchResponse = SearchResponse.fromXContent(xcp); + + Assert.assertEquals(searchResponse.toString(), 0, searchResponse.getHits().getTotalHits().value); + } + + @Test + public void testSimpleSearch_AccessCodes_emptyAccessCodes() throws Exception { + + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + SearchResponse searchResponse = executeSearch("tlqdocuments", "tlq_empty_access_codes", "password"); + Assert.assertEquals(searchResponse.toString(), 0, searchResponse.getHits().getTotalHits().value); + } + + @Test + public void testSimpleSearch_AccessCodes_noAccessCodes() throws Exception { + + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + SearchResponse searchResponse = executeSearch("tlqdocuments", "tlq_no_codes", "password"); + + Assert.assertEquals(searchResponse.toString(), 0, searchResponse.getHits().getTotalHits().value); + } + + @Test + public void testSimpleSearch_AllIndices_All_AccessCodes_1337() throws Exception { + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + + SearchResponse searchResponse = executeSearch("_all", "tlq_1337", "password"); + + // assume hits from 2 indices: + // - tlqdocuments, must contain only docs with access code 1337 + // - tlqdummy, contains all documents + // no access to user_access_codes must be granted + + // check all 5 tlqdummy entries present, index is not protected by DLS + Set tlqdummyHits = Arrays.asList(searchResponse.getHits().getHits()) + .stream() + .filter((h) -> h.getIndex().equals("tlqdummy")) + .collect(Collectors.toSet()); + Assert.assertEquals(searchResponse.toString(), 5, tlqdummyHits.size()); + + // check 10 hits with code 1337 from tlqdocuments index. All other documents + // must be filtered + Set tlqdocumentHits = Arrays.asList(searchResponse.getHits().getHits()) + .stream() + .filter((h) -> h.getIndex().equals("tlqdocuments")) + .collect(Collectors.toSet()); + Assert.assertEquals(searchResponse.toString(), 10, tlqdocumentHits.size()); + assertAccessCodesMatch(tlqdocumentHits, new Integer[] { 1337 }); + + // check no access to user_access_codes index + Set userAccessCodesHits = Arrays.asList(searchResponse.getHits().getHits()) + .stream() + .filter((h) -> h.getIndex().equals("user_access_codes")) + .collect(Collectors.toSet()); + Assert.assertEquals(searchResponse.toString(), 0, userAccessCodesHits.size()); + } + + @Test + public void testSimpleSearch_AllIndicesWildcard_AccessCodes_1337() throws Exception { + + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + + SearchResponse searchResponse = executeSearch("*", "tlq_1337", "password"); + + // assume hits from 2 indices: + // - tlqdocuments, must contain only docs with access code 1337 + // - tlqdummy, contains all documents + // no access to user_access_codes must be granted + + // check all 5 tlqdummy entries present, index is not protected by DLS + Set tlqdummyHits = Arrays.asList(searchResponse.getHits().getHits()) + .stream() + .filter((h) -> h.getIndex().equals("tlqdummy")) + .collect(Collectors.toSet()); + Assert.assertEquals(searchResponse.toString(), 5, tlqdummyHits.size()); + + // check 10 hits with code 1337 from tlqdocuments index. All other documents + // must be filtered + Set tlqdocumentHits = Arrays.asList(searchResponse.getHits().getHits()) + .stream() + .filter((h) -> h.getIndex().equals("tlqdocuments")) + .collect(Collectors.toSet()); + Assert.assertEquals(searchResponse.toString(), 10, tlqdocumentHits.size()); + assertAccessCodesMatch(tlqdocumentHits, new Integer[] { 1337 }); + + // check no access to user_access_codes index + Set userAccessCodesHits = Arrays.asList(searchResponse.getHits().getHits()) + .stream() + .filter((h) -> h.getIndex().equals("user_access_codes")) + .collect(Collectors.toSet()); + Assert.assertEquals(searchResponse.toString(), 0, userAccessCodesHits.size()); + } + + @Test + public void testSimpleSearch_ThreeIndicesWildcard_AccessCodes_1337() throws Exception { + + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + + SearchResponse searchResponse = executeSearch("tlq*,user*", "tlq_1337", "password"); + + // assume hits from 2 indices: + // - tlqdocuments, must contain only docs with access code 1337 + // - tlqdummy, contains all documents + // no access to user_access_codes must be granted + + // check all 5 tlqdummy entries present, index is not protected by DLS + Set tlqdummyHits = Arrays.asList(searchResponse.getHits().getHits()) + .stream() + .filter((h) -> h.getIndex().equals("tlqdummy")) + .collect(Collectors.toSet()); + Assert.assertEquals(searchResponse.toString(), 5, tlqdummyHits.size()); + + // check 10 hits with code 1337 from tlqdocuments index. All other documents + // must be filtered + Set tlqdocumentHits = Arrays.asList(searchResponse.getHits().getHits()) + .stream() + .filter((h) -> h.getIndex().equals("tlqdocuments")) + .collect(Collectors.toSet()); + Assert.assertEquals(searchResponse.toString(), 10, tlqdocumentHits.size()); + assertAccessCodesMatch(tlqdocumentHits, new Integer[] { 1337 }); + + // check no access to user_access_codes index + Set userAccessCodesHits = Arrays.asList(searchResponse.getHits().getHits()) + .stream() + .filter((h) -> h.getIndex().equals("user_access_codes")) + .collect(Collectors.toSet()); + Assert.assertEquals(searchResponse.toString(), 0, userAccessCodesHits.size()); + + } + + @Test + public void testSimpleSearch_TwoIndicesConcreteNames_AccessCodes_1337() throws Exception { + + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + + SearchResponse searchResponse = executeSearch("tlqdocuments,tlqdummy", "tlq_1337", "password"); + + // assume hits from 2 indices: + // - tlqdocuments, must contains only 10 docs with access code 1337 + // - tlqdummy, must contains all 5 documents + + // check all 5 tlqdummy entries present, index is not protected by DLS + Set tlqdummyHits = Arrays.asList(searchResponse.getHits().getHits()) + .stream() + .filter((h) -> h.getIndex().equals("tlqdummy")) + .collect(Collectors.toSet()); + Assert.assertEquals(searchResponse.toString(), 5, tlqdummyHits.size()); + + // ccheck 10 hits with code 1337 from tlqdocuments index. All other documents + // must be filtered + Set tlqdocumentHits = Arrays.asList(searchResponse.getHits().getHits()) + .stream() + .filter((h) -> h.getIndex().equals("tlqdocuments")) + .collect(Collectors.toSet()); + Assert.assertEquals(searchResponse.toString(), 10, tlqdocumentHits.size()); + assertAccessCodesMatch(tlqdocumentHits, new Integer[] { 1337 }); + } + + @Test + public void testMSearch_ThreeIndices_AccessCodes_1337() throws Exception { + + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + + MultiSearchResponse searchResponse = executeMSearchMatchAll( + "tlq_1337", + "password", + "tlqdummy", + "tlqdocuments", + "user_access_codes" + ); + + Item[] responseItems = searchResponse.getResponses(); + + // as per API order in response is the same as in the msearch request + + // check all 5 tlqdummy entries present + List tlqdummyHits = Arrays.asList(responseItems[0].getResponse().getHits().getHits()); + Assert.assertEquals(searchResponse.toString(), 5, tlqdummyHits.size()); + + // check 10 hits with code 1337 from tlqdocuments index. All other documents + // must be filtered + List tlqdocumentHits = Arrays.asList(responseItems[1].getResponse().getHits().getHits()); + Assert.assertEquals(searchResponse.toString(), 10, tlqdocumentHits.size()); + assertAccessCodesMatch(tlqdocumentHits, new Integer[] { 1337 }); + + // check no access to user_access_codes index, just two indices in the response + Assert.assertTrue(responseItems[2].getResponse() == null); + Assert.assertTrue(responseItems[2].getFailure() != null); + + } + + // ------------------------ + // Test get and mget + // ------------------------ + + @Test + public void testGet_TlqDocumentsIndex_1337() throws Exception { + + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + + // user has 1337, document has 1337 + GetResponse searchResponse = executeGet("tlqdocuments", "1", "tlq_1337", "password"); + Assert.assertTrue(searchResponse != null); + Assert.assertTrue(searchResponse.isExists()); + assertAccessCodesMatch(searchResponse.getSourceAsMap(), "access_codes", new Integer[] { 1337 }); + + // user has 1337, document has 42, not visible + searchResponse = executeGet("tlqdocuments", "2", "tlq_1337", "password"); + Assert.assertFalse(searchResponse.isExists()); + + // user has 1337, document has 42 and 1337 + searchResponse = executeGet("tlqdocuments", "3", "tlq_1337", "password"); + Assert.assertTrue(searchResponse != null); + Assert.assertTrue(searchResponse.isExists()); + assertAccessCodesMatch(searchResponse.getSourceAsMap(), "access_codes", new Integer[] { 1337 }); + + // user has 1337, document has no access codes, not visible + searchResponse = executeGet("tlqdocuments", "16", "tlq_1337", "password"); + Assert.assertFalse(searchResponse.isExists()); + + // user has 1337, document has 12345, not visible + searchResponse = executeGet("tlqdocuments", "17", "tlq_1337", "password"); + Assert.assertFalse(searchResponse.isExists()); + + // user has 1337, document has 12345 and 6789, not visible + searchResponse = executeGet("tlqdocuments", "18", "tlq_1337", "password"); + Assert.assertFalse(searchResponse.isExists()); + + } + + @Test + public void testGet_TlqDocumentsIndex_1337_42() throws Exception { + + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + + // user has 1337 and 42, document has 1337 + GetResponse searchResponse = executeGet("tlqdocuments", "1", "tlq_1337_42", "password"); + Assert.assertTrue(searchResponse != null); + Assert.assertTrue(searchResponse.isExists()); + assertAccessCodesMatch(searchResponse.getSourceAsMap(), "access_codes", new Integer[] { 1337, 42 }); + + // user has 1337 and 42, document has 42 + searchResponse = executeGet("tlqdocuments", "2", "tlq_1337_42", "password"); + Assert.assertTrue(searchResponse != null); + Assert.assertTrue(searchResponse.isExists()); + assertAccessCodesMatch(searchResponse.getSourceAsMap(), "access_codes", new Integer[] { 1337, 42 }); + + // user has 1337 and 42, document has 42 and 1337 + searchResponse = executeGet("tlqdocuments", "3", "tlq_1337_42", "password"); + Assert.assertTrue(searchResponse != null); + Assert.assertTrue(searchResponse.isExists()); + assertAccessCodesMatch(searchResponse.getSourceAsMap(), "access_codes", new Integer[] { 1337, 42 }); + + // user has 1337 and 42, document has no access codes, not visible + searchResponse = executeGet("tlqdocuments", "16", "tlq_1337_42", "password"); + Assert.assertFalse(searchResponse.isExists()); + + // user has 1337 and 42, document has 12345, not visible + searchResponse = executeGet("tlqdocuments", "17", "tlq_1337_42", "password"); + Assert.assertFalse(searchResponse.isExists()); + + // user has 1337 and 42, document has 12345 and 6789, not visible + searchResponse = executeGet("tlqdocuments", "18", "tlq_1337_42", "password"); + Assert.assertFalse(searchResponse.isExists()); + + } + + @Test + public void testGet_TlqDummyIndex_1337() throws Exception { + + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + + // no restrictions on this index + GetResponse searchResponse = executeGet("tlqdummy", "101", "tlq_1337", "password"); + Assert.assertTrue(searchResponse != null); + Assert.assertTrue(searchResponse.isExists()); + + searchResponse = executeGet("tlqdummy", "102", "tlq_1337", "password"); + Assert.assertTrue(searchResponse != null); + Assert.assertTrue(searchResponse.isExists()); + + } + + @Test + public void testGet_UserAccessCodesIndex_1337() throws Exception { + + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + + // we expect a security exception here, user has no direct access to + // user_access_codes index + HttpResponse response = rh.executeGetRequest("/user_access_codes/_doc/tlq_1337", encodeBasicHeader("tlq_1337", "password")); + Assert.assertEquals(403, response.getStatusCode()); + } + + @Test + public void testMGet_1337() throws Exception { + + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + + Map indicesAndIds = new HashMap<>(); + indicesAndIds.put("tlqdocuments", "1"); + indicesAndIds.put("tlqdocuments", "2"); + indicesAndIds.put("tlqdocuments", "3"); + indicesAndIds.put("tlqdocuments", "16"); + indicesAndIds.put("tlqdocuments", "17"); + indicesAndIds.put("tlqdocuments", "18"); + indicesAndIds.put("tlqdummy", "101"); + indicesAndIds.put("user_access_codes", "tlq_1337"); + + MultiGetResponse searchResponse = executeMGet("tlq_1337", "password", indicesAndIds); + + for (MultiGetItemResponse response : searchResponse.getResponses()) { + // no response from index "user_access_codes" + Assert.assertFalse(response.getIndex().equals("user_access_codes")); + switch (response.getIndex()) { + case "tlqdocuments": + Assert.assertTrue(response.getId(), response.getId().equals("1") | response.getId().equals("3")); + break; + case "tlqdummy": + Assert.assertTrue(response.getId(), response.getId().equals("101")); + break; + default: + Assert.fail("Index " + response.getIndex() + " present in mget response, but should not"); + } + } + } + + // ------------------------ + // Test aggregations + // ------------------------ + + @Test + public void testSimpleAggregation_tlqdocuments_AccessCode_1337() throws Exception { + + setup( + new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") + .setSecurityInternalUsers("internal_users_tlq.yml") + .setSecurityRoles("roles_tlq.yml") + .setSecurityRolesMapping("roles_mapping_tlq.yml") + ); + + String body = "" + + " {\n" + + " \"aggs\": {\n" + + " \"buaggregation\": {\n" + + " \"terms\": {\n" + + " \"field\": \"bu\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + ""; + + // need to add typed_keys so aggregations can be parsed + // see for example: + // https://stackoverflow.com/questions/49798654/how-do-you-convert-an-elasticsearch-json-string-response-with-an-aggregation-t + HttpResponse response = rh.executePostRequest( + "/tlqdocuments/_search?pretty&typed_keys", + body, + encodeBasicHeader("tlq_1337", "password") + ); + Assert.assertTrue(response.getStatusCode() == 200); + NamedXContentRegistry registry = new NamedXContentRegistry(getDefaultNamedXContents()); + XContentParser xcp = XContentType.JSON.xContent().createParser(registry, LoggingDeprecationHandler.INSTANCE, response.getBody()); + SearchResponse searchResponse = SearchResponse.fromXContent(xcp); + + Aggregations aggs = searchResponse.getAggregations(); + Assert.assertNotNull(searchResponse.toString(), aggs); + Terms agg = aggs.get("buaggregation"); + Assert.assertTrue("Expected aggregation with name 'buaggregation'", agg != null); + // expect AAA - EEE (FFF does not match) with 2 docs each + for (String bucketName : new String[] { "AAA", "BBB", "CCC", "DDD", "EEE" }) { + Bucket bucket = agg.getBucketByKey(bucketName); + Assert.assertNotNull("Expected bucket " + bucketName + " to be present in agregations", bucket); + Assert.assertTrue("Expected doc count in bucket " + bucketName + " to be 2", bucket.getDocCount() == 2); + } + // expect FFF to be absent + Assert.assertNull("Expected bucket FFF to be absent", agg.getBucketByKey("FFF")); + } + + public static List getDefaultNamedXContents() { + Map> map = new HashMap<>(); + map.put(TopHitsAggregationBuilder.NAME, (p, c) -> ParsedTopHits.fromXContent(p, (String) c)); + map.put(StringTerms.NAME, (p, c) -> ParsedStringTerms.fromXContent(p, (String) c)); + List entries = map.entrySet() + .stream() + .map(entry -> new NamedXContentRegistry.Entry(Aggregation.class, new ParseField(entry.getKey()), entry.getValue())) + .collect(Collectors.toList()); + return entries; + } } diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsTest.java index 5405146263..a9361d275a 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsTest.java @@ -24,16 +24,16 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class DlsTest extends AbstractDlsFlsTest{ - +public class DlsTest extends AbstractDlsFlsTest { @Override protected void populateData(Client tc) { - tc.index(new IndexRequest("deals").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"amount\": 10}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("deals").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"amount\": 1500}", XContentType.JSON)).actionGet(); + tc.index(new IndexRequest("deals").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"amount\": 10}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("deals").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"amount\": 1500}", XContentType.JSON) + ).actionGet(); try { Thread.sleep(3000); @@ -51,23 +51,28 @@ public void testDlsAggregations() throws Exception { setup(); - - String query = "{"+ - "\"query\" : {"+ - "\"match_all\": {}"+ - "},"+ - "\"aggs\" : {"+ - "\"thesum\" : { \"sum\" : { \"field\" : \"amount\" } }"+ - "}"+ - "}"; + String query = "{" + + "\"query\" : {" + + "\"match_all\": {}" + + "}," + + "\"aggs\" : {" + + "\"thesum\" : { \"sum\" : { \"field\" : \"amount\" } }" + + "}" + + "}"; HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"value\" : 1500.0")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"value\" : 1510.0")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -93,67 +98,88 @@ public void testDls() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=0", encodeBasicHeader("dept_manager", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=0", encodeBasicHeader("dept_manager", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("dept_manager", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("dept_manager", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); Assert.assertEquals(res.getHeaders().toString(), 2, res.getHeaders().size()); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=0", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=0", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - String query = - "{"+ - "\"query\": {"+ - "\"range\" : {"+ - "\"amount\" : {"+ - "\"gte\" : 8,"+ - "\"lte\" : 20,"+ - "\"boost\" : 3.0"+ - "}"+ - "}"+ - "}"+ - "}"; - + "{" + + "\"query\": {" + + "\"range\" : {" + + "\"amount\" : {" + + "\"gte\" : 8," + + "\"lte\" : 20," + + "\"boost\" : 3.0" + + "}" + + "}" + + "}" + + "}"; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query,encodeBasicHeader("dept_manager", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 0,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); query = - "{"+ - "\"query\": {"+ - "\"range\" : {"+ - "\"amount\" : {"+ - "\"gte\" : 100,"+ - "\"lte\" : 2000,"+ - "\"boost\" : 2.0"+ - "}"+ - "}"+ - "}"+ - "}"; - + "{" + + "\"query\": {" + + "\"range\" : {" + + "\"amount\" : {" + + "\"gte\" : 100," + + "\"lte\" : 2000," + + "\"boost\" : 2.0" + + "}" + + "}" + + "}" + + "}"; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query,encodeBasicHeader("dept_manager", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query,encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?q=amount:10&pretty", encodeBasicHeader("dept_manager", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?q=amount:10&pretty", encodeBasicHeader("dept_manager", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 0,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -166,45 +192,57 @@ public void testDls() throws Exception { res = rh.executeGetRequest("/deals/_doc/1?pretty", encodeBasicHeader("dept_manager", "password")); Assert.assertTrue(res.getBody().contains("\"found\" : true")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_count?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_count?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"count\" : 2,")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_count?pretty", encodeBasicHeader("dept_manager", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_count?pretty", encodeBasicHeader("dept_manager", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"count\" : 1,")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - - //mget - //msearch - String msearchBody = - "{\"index\":\"deals\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ - "{\"index\":\"deals\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); - - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("_msearch?pretty", msearchBody, encodeBasicHeader("dept_manager", "password"))).getStatusCode()); + // mget + // msearch + String msearchBody = "{\"index\":\"deals\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator() + + "{\"index\":\"deals\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("_msearch?pretty", msearchBody, encodeBasicHeader("dept_manager", "password"))).getStatusCode() + ); Assert.assertFalse(res.getBody().contains("_opendistro_security_dls_query")); Assert.assertFalse(res.getBody().contains("_opendistro_security_fls_fields")); Assert.assertTrue(res.getBody().contains("\"amount\" : 1500")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - - String mgetBody = "{"+ - "\"docs\" : ["+ - "{"+ - "\"_index\" : \"deals\","+ - "\"_id\" : \"1\""+ - " },"+ - " {"+ - "\"_index\" : \"deals\","+ - " \"_id\" : \"2\""+ - "}"+ - "]"+ - "}"; - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("dept_manager", "password"))).getStatusCode()); + String mgetBody = "{" + + "\"docs\" : [" + + "{" + + "\"_index\" : \"deals\"," + + "\"_id\" : \"1\"" + + " }," + + " {" + + "\"_index\" : \"deals\"," + + " \"_id\" : \"2\"" + + "}" + + "]" + + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("dept_manager", "password"))).getStatusCode() + ); Assert.assertFalse(res.getBody().contains("_opendistro_security_dls_query")); Assert.assertFalse(res.getBody().contains("_opendistro_security_fls_fields")); Assert.assertTrue(res.getBody().contains("amount")); @@ -220,26 +258,26 @@ public void testNonDls() throws Exception { HttpResponse res; String query = - "{"+ - "\"_source\": false,"+ - "\"query\": {"+ - "\"range\" : {"+ - "\"amount\" : {"+ - "\"gte\" : 100,"+ - "\"lte\" : 2000,"+ - "\"boost\" : 2.0"+ - "}"+ - "}"+ - "}"+ - "}"; - - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query,encodeBasicHeader("dept_manager", "password"))).getStatusCode()); + "{" + + "\"_source\": false," + + "\"query\": {" + + "\"range\" : {" + + "\"amount\" : {" + + "\"gte\" : 100," + + "\"lte\" : 2000," + + "\"boost\" : 2.0" + + "}" + + "}" + + "}" + + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - - } @Test @@ -248,11 +286,17 @@ public void testDlsCache() throws Exception { setup(); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("dept_manager", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("dept_manager", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -271,69 +315,86 @@ public void testDlsWithMinDocCountZeroAggregations() throws Exception { client.admin().indices().create(new CreateIndexRequest("logs").simpleMapping("termX", "type=keyword")).actionGet(); for (int i = 0; i < 3; i++) { - client.index(new IndexRequest("logs").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("amount", i, "termX", "A", "timestamp", "2022-01-06T09:05:00Z")).actionGet(); - client.index(new IndexRequest("logs").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("amount", i, "termX", "B", "timestamp", "2022-01-06T09:08:00Z")).actionGet(); - client.index(new IndexRequest("logs").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("amount", i, "termX", "C", "timestamp", "2022-01-06T09:09:00Z")).actionGet(); - client.index(new IndexRequest("logs").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("amount", i, "termX", "D", "timestamp", "2022-01-06T09:10:00Z")).actionGet(); + client.index( + new IndexRequest("logs").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("amount", i, "termX", "A", "timestamp", "2022-01-06T09:05:00Z") + ).actionGet(); + client.index( + new IndexRequest("logs").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("amount", i, "termX", "B", "timestamp", "2022-01-06T09:08:00Z") + ).actionGet(); + client.index( + new IndexRequest("logs").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("amount", i, "termX", "C", "timestamp", "2022-01-06T09:09:00Z") + ).actionGet(); + client.index( + new IndexRequest("logs").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("amount", i, "termX", "D", "timestamp", "2022-01-06T09:10:00Z") + ).actionGet(); } - client.index(new IndexRequest("logs").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("amount", 0, "termX", "E", "timestamp", "2022-01-06T09:11:00Z")).actionGet(); + client.index( + new IndexRequest("logs").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("amount", 0, "termX", "E", "timestamp", "2022-01-06T09:11:00Z") + ).actionGet(); } // Terms Aggregation - // Non-admin user with setting "min_doc_count":0. Expected to get error message "min_doc_count 0 is not supported when DLS is activated". + // Non-admin user with setting "min_doc_count":0. Expected to get error message "min_doc_count 0 is not supported when DLS is + // activated". String query1 = "{\n" - + " \"size\":0,\n" - + " \"query\":{\n" - + " \"bool\":{\n" - + " \"must\":[\n" - + " {\n" - + " \"range\":{\n" - + " \"amount\":{\"gte\":1,\"lte\":100}\n" - + " }\n" - + " }\n" - + " ]\n" - + " }\n" - + " },\n" - + " \"aggs\":{\n" - + " \"a\": {\n" - + " \"terms\": {\n" - + " \"field\": \"termX\",\n" - + " \"min_doc_count\":0,\n" - + "\"size\": 10,\n" - + "\"order\": { \"_count\": \"desc\" }\n" - + " }\n" - + " }\n" - + " }\n" - + "}"; + + " \"size\":0,\n" + + " \"query\":{\n" + + " \"bool\":{\n" + + " \"must\":[\n" + + " {\n" + + " \"range\":{\n" + + " \"amount\":{\"gte\":1,\"lte\":100}\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"aggs\":{\n" + + " \"a\": {\n" + + " \"terms\": {\n" + + " \"field\": \"termX\",\n" + + " \"min_doc_count\":0,\n" + + "\"size\": 10,\n" + + "\"order\": { \"_count\": \"desc\" }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; HttpResponse response1 = rh.executePostRequest("logs*/_search", query1, encodeBasicHeader("dept_manager", "password")); Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, response1.getStatusCode()); Assert.assertTrue(response1.getBody(), response1.getBody().contains("min_doc_count 0 is not supported when DLS is activated")); - // Non-admin user without setting "min_doc_count". Expected to only have access to buckets for dept_manager excluding E with 0 doc_count". + // Non-admin user without setting "min_doc_count". Expected to only have access to buckets for dept_manager excluding E with 0 + // doc_count". String query2 = "{\n" - + " \"size\":0,\n" - + " \"query\":{\n" - + " \"bool\":{\n" - + " \"must\":[\n" - + " {\n" - + " \"range\":{\n" - + " \"amount\":{\"gte\":1,\"lte\":100}\n" - + " }\n" - + " }\n" - + " ]\n" - + " }\n" - + " },\n" - + " \"aggs\":{\n" - + " \"a\": {\n" - + " \"terms\": {\n" - + " \"field\": \"termX\",\n" - + "\"size\": 10,\n" - + "\"order\": { \"_count\": \"desc\" }\n" - + " }\n" - + " }\n" - + " }\n" - + "}"; + + " \"size\":0,\n" + + " \"query\":{\n" + + " \"bool\":{\n" + + " \"must\":[\n" + + " {\n" + + " \"range\":{\n" + + " \"amount\":{\"gte\":1,\"lte\":100}\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"aggs\":{\n" + + " \"a\": {\n" + + " \"terms\": {\n" + + " \"field\": \"termX\",\n" + + "\"size\": 10,\n" + + "\"order\": { \"_count\": \"desc\" }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; HttpResponse response2 = rh.executePostRequest("logs*/_search", query2, encodeBasicHeader("dept_manager", "password")); @@ -366,7 +427,8 @@ public void testDlsWithMinDocCountZeroAggregations() throws Exception { // Significant Text Aggregation is not impacted. // Non-admin user with setting "min_doc_count=0". Expected to only have access to buckets for dept_manager". - String query3 = "{\"size\":100,\"aggregations\":{\"significant_termX\":{\"significant_terms\":{\"field\":\"termX.keyword\",\"min_doc_count\":0}}}}"; + String query3 = + "{\"size\":100,\"aggregations\":{\"significant_termX\":{\"significant_terms\":{\"field\":\"termX.keyword\",\"min_doc_count\":0}}}}"; HttpResponse response5 = rh.executePostRequest("logs*/_search", query3, encodeBasicHeader("dept_manager", "password")); Assert.assertEquals(HttpStatus.SC_OK, response5.getStatusCode()); @@ -443,7 +505,6 @@ public void testDlsWithMinDocCountZeroAggregations() throws Exception { Assert.assertTrue(response11.getBody(), response11.getBody().contains("\"termX\":\"D\"")); Assert.assertTrue(response11.getBody(), response11.getBody().contains("\"termX\":\"E\"")); - // Admin without setting "min_doc_count". Expected to have access to all buckets". HttpResponse response12 = rh.executePostRequest("logs*/_search", query6, encodeBasicHeader("admin", "admin")); @@ -456,7 +517,8 @@ public void testDlsWithMinDocCountZeroAggregations() throws Exception { // Date Histogram Aggregation is not impacted. // Non-admin user with setting "min_doc_count=0". Expected to only have access to buckets for dept_manager". - String query7 = "{\"size\":100,\"aggs\":{\"timestamp\":{\"date_histogram\":{\"field\":\"timestamp\",\"calendar_interval\":\"month\",\"min_doc_count\":0}}}}"; + String query7 = + "{\"size\":100,\"aggs\":{\"timestamp\":{\"date_histogram\":{\"field\":\"timestamp\",\"calendar_interval\":\"month\",\"min_doc_count\":0}}}}"; HttpResponse response13 = rh.executePostRequest("logs*/_search", query7, encodeBasicHeader("dept_manager", "password")); @@ -468,7 +530,8 @@ public void testDlsWithMinDocCountZeroAggregations() throws Exception { Assert.assertFalse(response13.getBody(), response13.getBody().contains("\"termX\":\"E\"")); // Non-admin user without setting "min_doc_count". Expected to only have access to buckets for dept_manager". - String query8 = "{\"size\":100,\"aggs\":{\"timestamp\":{\"date_histogram\":{\"field\":\"timestamp\",\"calendar_interval\":\"month\"}}}}"; + String query8 = + "{\"size\":100,\"aggs\":{\"timestamp\":{\"date_histogram\":{\"field\":\"timestamp\",\"calendar_interval\":\"month\"}}}}"; HttpResponse response14 = rh.executePostRequest("logs*/_search", query8, encodeBasicHeader("dept_manager", "password")); 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 40542e76b7..2628bebbc0 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/FieldMaskedTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/FieldMaskedTest.java @@ -23,21 +23,37 @@ public class FieldMaskedTest extends AbstractDlsFlsTest { - protected void populateData(Client tc) { - tc.index(new IndexRequest("deals").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"customer\": {\"name\":\"cust1\"}, \"ip_source\": \"100.100.1.1\",\"ip_dest\": \"123.123.1.1\",\"amount\": 10}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("deals").id("2").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"customer\": {\"name\":\"cust2\"}, \"ip_source\": \"100.100.2.2\",\"ip_dest\": \"123.123.2.2\",\"amount\": 20}", XContentType.JSON)).actionGet(); - - - for (int i=0; i<30;i++) { - tc.index(new IndexRequest("deals").id("a"+i).setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"customer\": {\"name\":\"cust1\"}, \"ip_source\": \"200.100.1.1\",\"ip_dest\": \"123.123.1.1\",\"amount\": 10}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("deals").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source( + "{\"customer\": {\"name\":\"cust1\"}, \"ip_source\": \"100.100.1.1\",\"ip_dest\": \"123.123.1.1\",\"amount\": 10}", + XContentType.JSON + ) + ).actionGet(); + tc.index( + new IndexRequest("deals").id("2") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source( + "{\"customer\": {\"name\":\"cust2\"}, \"ip_source\": \"100.100.2.2\",\"ip_dest\": \"123.123.2.2\",\"amount\": 20}", + XContentType.JSON + ) + ).actionGet(); + + for (int i = 0; i < 30; i++) { + tc.index( + new IndexRequest("deals").id("a" + i) + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source( + "{\"customer\": {\"name\":\"cust1\"}, \"ip_source\": \"200.100.1.1\",\"ip_dest\": \"123.123.1.1\",\"amount\": 10}", + XContentType.JSON + ) + ).actionGet(); } - } + } @Test public void testMaskedAggregations() throws Exception { @@ -46,61 +62,72 @@ public void testMaskedAggregations() throws Exception { String query; HttpResponse res; - query = "{"+ - "\"query\" : {"+ - "\"match_all\": {}"+ - "},"+ - "\"aggs\" : {"+ - "\"ips\" : { \"terms\" : { \"field\" : \"ip_source.keyword\" } }"+ - "}"+ - "}"; - - //Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); - //Assert.assertTrue(res.getBody().contains("100.100")); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("user_masked", "password"))).getStatusCode()); + query = "{" + + "\"query\" : {" + + "\"match_all\": {}" + + "}," + + "\"aggs\" : {" + + "\"ips\" : { \"terms\" : { \"field\" : \"ip_source.keyword\" } }" + + "}" + + "}"; + + // Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, + // encodeBasicHeader("admin", "admin"))).getStatusCode()); + // Assert.assertTrue(res.getBody().contains("100.100")); + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("user_masked", "password"))) + .getStatusCode() + ); Assert.assertFalse(res.getBody().contains("100.100")); - query = - "{" + - "\"query\" : {" + - "\"match_all\": {" + - "}" + - "}," + - "\"aggs\": {" + - "\"ips\" : {" + - "\"terms\" : {" + - "\"field\" : \"ip_source.keyword\"," + - "\"order\": {" + - "\"_term\" : \"asc\"" + - "}" + - "}" + - "}" + - "}" + - "}"; - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("user_masked", "password"))).getStatusCode()); + query = "{" + + "\"query\" : {" + + "\"match_all\": {" + + "}" + + "}," + + "\"aggs\": {" + + "\"ips\" : {" + + "\"terms\" : {" + + "\"field\" : \"ip_source.keyword\"," + + "\"order\": {" + + "\"_term\" : \"asc\"" + + "}" + + "}" + + "}" + + "}" + + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("user_masked", "password"))) + .getStatusCode() + ); Assert.assertFalse(res.getBody().contains("100.100")); - query = - "{" + - "\"query\" : {" + - "\"match_all\": {" + - "}" + - "}," + - "\"aggs\": {" + - "\"ips\" : {" + - "\"terms\" : {" + - "\"field\" : \"ip_source.keyword\"," + - "\"order\": {" + - "\"_term\" : \"desc\"" + - "}" + - "}" + - "}" + - "}" + - "}"; - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("user_masked", "password"))).getStatusCode()); + query = "{" + + "\"query\" : {" + + "\"match_all\": {" + + "}" + + "}," + + "\"aggs\": {" + + "\"ips\" : {" + + "\"terms\" : {" + + "\"field\" : \"ip_source.keyword\"," + + "\"order\": {" + + "\"_term\" : \"desc\"" + + "}" + + "}" + + "}" + + "}" + + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("user_masked", "password"))) + .getStatusCode() + ); Assert.assertFalse(res.getBody().contains("100.100")); } @@ -109,15 +136,17 @@ public void testMaskedAggregationsRace() throws Exception { setup(); - - String query = "{"+ - "\"aggs\" : {"+ - "\"ips\" : { \"terms\" : { \"field\" : \"ip_source.keyword\", \"size\": 1002, \"show_term_doc_count_error\": true } }"+ - "}"+ - "}"; + String query = "{" + + "\"aggs\" : {" + + "\"ips\" : { \"terms\" : { \"field\" : \"ip_source.keyword\", \"size\": 1002, \"show_term_doc_count_error\": true } }" + + "}" + + "}"; HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("100.100")); Assert.assertTrue(res.getBody().contains("200.100")); Assert.assertTrue(res.getBody().contains("\"doc_count\" : 30")); @@ -126,7 +155,11 @@ public void testMaskedAggregationsRace() throws Exception { Assert.assertFalse(res.getBody().contains("26a8671e57fefc13504f8c61ced67ac98338261ace1e5bf462038b2f2caae16e")); Assert.assertFalse(res.getBody().contains("87873bdb698e5f0f60e0b02b76dad1ec11b2787c628edbc95b7ff0e82274b140")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("user_masked", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("user_masked", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"doc_count\" : 30")); Assert.assertTrue(res.getBody().contains("\"doc_count\" : 1")); Assert.assertFalse(res.getBody().contains("100.100")); @@ -135,8 +168,11 @@ public void testMaskedAggregationsRace() throws Exception { Assert.assertTrue(res.getBody().contains("26a8671e57fefc13504f8c61ced67ac98338261ace1e5bf462038b2f2caae16e")); Assert.assertTrue(res.getBody().contains("87873bdb698e5f0f60e0b02b76dad1ec11b2787c628edbc95b7ff0e82274b140")); - for(int i=0;i<10;i++) { - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); + for (int i = 0; i < 10; i++) { + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty&size=0", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("100.100")); Assert.assertTrue(res.getBody().contains("200.100")); Assert.assertTrue(res.getBody().contains("\"doc_count\" : 30")); @@ -155,7 +191,10 @@ public void testMaskedSearch() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=100", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=100", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 32,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); Assert.assertTrue(res.getBody().contains("cust1")); @@ -164,8 +203,10 @@ public void testMaskedSearch() throws Exception { Assert.assertTrue(res.getBody().contains("100.100.2.2")); Assert.assertFalse(res.getBody().contains("87873bdb698e5f0f60e0b02b76dad1ec11b2787c628edbc95b7ff0e82274b140")); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=100", encodeBasicHeader("user_masked", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=100", encodeBasicHeader("user_masked", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 32,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); Assert.assertTrue(res.getBody().contains("cust1")); @@ -183,7 +224,10 @@ public void testMaskedGet() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_doc/0?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_doc/0?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"found\" : true")); Assert.assertTrue(res.getBody().contains("cust1")); Assert.assertFalse(res.getBody().contains("cust2")); @@ -191,8 +235,10 @@ public void testMaskedGet() throws Exception { Assert.assertFalse(res.getBody().contains("100.100.2.2")); Assert.assertFalse(res.getBody().contains("87873bdb698e5f0f60e0b02b76dad1ec11b2787c628edbc95b7ff0e82274b140")); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_doc/0?pretty", encodeBasicHeader("user_masked", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_doc/0?pretty", encodeBasicHeader("user_masked", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"found\" : true")); Assert.assertTrue(res.getBody().contains("cust1")); Assert.assertFalse(res.getBody().contains("cust2")); @@ -201,5 +247,4 @@ public void testMaskedGet() throws Exception { Assert.assertTrue(res.getBody().contains("87873bdb698e5f0f60e0b02b76dad1ec11b2787c628edbc95b7ff0e82274b140")); } - } diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/Fls983Test.java b/src/test/java/org/opensearch/security/dlic/dlsfls/Fls983Test.java index 6f00dfd348..61bc9b53b3 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/Fls983Test.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/Fls983Test.java @@ -22,13 +22,11 @@ import org.opensearch.security.test.DynamicSecurityConfig; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class Fls983Test extends AbstractDlsFlsTest{ - +public class Fls983Test extends AbstractDlsFlsTest { protected void populateData(Client tc) { - tc.index(new IndexRequest(".kibana").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{}", XContentType.JSON)).actionGet(); + tc.index(new IndexRequest(".kibana").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{}", XContentType.JSON)).actionGet(); } @Test @@ -38,11 +36,13 @@ public void test() throws Exception { HttpResponse res; - String doc = "{\"doc\" : {"+ - "\"x\" : \"y\""+ - "}}"; + String doc = "{\"doc\" : {" + "\"x\" : \"y\"" + "}}"; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/.kibana/_update/0?pretty", doc, encodeBasicHeader("human_resources_trainee", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/.kibana/_update/0?pretty", doc, encodeBasicHeader("human_resources_trainee", "password"))) + .getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("updated")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsDlsTestAB.java b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsDlsTestAB.java index 9cc5cc8b3b..aabe2e4add 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsDlsTestAB.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsDlsTestAB.java @@ -23,28 +23,48 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class FlsDlsTestAB extends AbstractDlsFlsTest{ - +public class FlsDlsTestAB extends AbstractDlsFlsTest { protected void populateData(Client tc) { - //aaa - tc.index(new IndexRequest("aaa").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"f1\": \"f1_a0\", \"f2\": \"f2_a0\", \"f3\": \"f3_a0\", \"f4\": \"f4_a0\",\"type\": \"a\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("aaa").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"f1\": \"f1_a1\", \"f2\": \"f2_a1\", \"f3\": \"f3_a1\", \"f4\": \"f4_a1\",\"type\": \"a\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("aaa").id("2").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"f1\": \"f1_a2\", \"f2\": \"f2_a2\", \"f3\": \"f3_a2\", \"f4\": \"f4_a2\",\"type\": \"x\"}", XContentType.JSON)).actionGet(); - - //bbb - tc.index(new IndexRequest("bbb").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"f1\": \"f1_b0\", \"f2\": \"f2_b0\", \"f3\": \"f3_b0\", \"f4\": \"f4_b0\",\"type\": \"b\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("bbb").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"f1\": \"f1_b1\", \"f2\": \"f2_b1\", \"f3\": \"f3_b1\", \"f4\": \"f4_b1\",\"type\": \"b\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("bbb").id("2").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"f1\": \"f1_b2\", \"f2\": \"f2_b2\", \"f3\": \"f3_b2\", \"f4\": \"f4_b2\",\"type\": \"x\"}", XContentType.JSON)).actionGet(); - - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("aaa","bbb").alias("abalias"))).actionGet(); + // aaa + tc.index( + new IndexRequest("aaa").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"f1\": \"f1_a0\", \"f2\": \"f2_a0\", \"f3\": \"f3_a0\", \"f4\": \"f4_a0\",\"type\": \"a\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("aaa").id("1") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"f1\": \"f1_a1\", \"f2\": \"f2_a1\", \"f3\": \"f3_a1\", \"f4\": \"f4_a1\",\"type\": \"a\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("aaa").id("2") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"f1\": \"f1_a2\", \"f2\": \"f2_a2\", \"f3\": \"f3_a2\", \"f4\": \"f4_a2\",\"type\": \"x\"}", XContentType.JSON) + ).actionGet(); + + // bbb + tc.index( + new IndexRequest("bbb").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"f1\": \"f1_b0\", \"f2\": \"f2_b0\", \"f3\": \"f3_b0\", \"f4\": \"f4_b0\",\"type\": \"b\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("bbb").id("1") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"f1\": \"f1_b1\", \"f2\": \"f2_b1\", \"f3\": \"f3_b1\", \"f4\": \"f4_b1\",\"type\": \"b\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("bbb").id("2") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"f1\": \"f1_b2\", \"f2\": \"f2_b2\", \"f3\": \"f3_b2\", \"f4\": \"f4_b2\",\"type\": \"x\"}", XContentType.JSON) + ).actionGet(); + + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("aaa", "bbb").alias("abalias"))) + .actionGet(); } @@ -55,7 +75,10 @@ public void testDlsFlsAB() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/aaa,bbb/_search?pretty", encodeBasicHeader("user_aaa", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/aaa,bbb/_search?pretty", encodeBasicHeader("user_aaa", "password"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 4,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -69,8 +92,10 @@ public void testDlsFlsAB() throws Exception { Assert.assertTrue(res.getBody().contains("f3_b")); Assert.assertFalse(res.getBody().contains("f1_b")); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/abalias/_search?pretty", encodeBasicHeader("user_aaa", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/abalias/_search?pretty", encodeBasicHeader("user_aaa", "password"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 4,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -84,7 +109,10 @@ public void testDlsFlsAB() throws Exception { Assert.assertTrue(res.getBody().contains("f3_b")); Assert.assertFalse(res.getBody().contains("f1_b")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/aaa,bbb/_search?pretty", encodeBasicHeader("user_bbb", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/aaa,bbb/_search?pretty", encodeBasicHeader("user_bbb", "password"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 4,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -98,8 +126,10 @@ public void testDlsFlsAB() throws Exception { Assert.assertFalse(res.getBody().contains("f3_b")); Assert.assertTrue(res.getBody().contains("f1_b")); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/abalias/_search?pretty", encodeBasicHeader("user_bbb", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/abalias/_search?pretty", encodeBasicHeader("user_bbb", "password"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 4,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsDlsTestForbiddenField.java b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsDlsTestForbiddenField.java index 6df02c2e22..840f574a9f 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsDlsTestForbiddenField.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsDlsTestForbiddenField.java @@ -21,15 +21,23 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class FlsDlsTestForbiddenField extends AbstractDlsFlsTest{ - +public class FlsDlsTestForbiddenField extends AbstractDlsFlsTest { protected void populateData(Client tc) { - tc.index(new IndexRequest("deals").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"customer\": {\"name\":\"cust1\"}, \"zip\": \"12345\",\"secret\": \"tellnoone\",\"amount\": 10}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("deals").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"customer\": {\"name\":\"cust2\", \"ctype\":\"industry\"}, \"amount\": 1500}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("deals").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source( + "{\"customer\": {\"name\":\"cust1\"}, \"zip\": \"12345\",\"secret\": \"tellnoone\",\"amount\": 10}", + XContentType.JSON + ) + ).actionGet(); + tc.index( + new IndexRequest("deals").id("1") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"customer\": {\"name\":\"cust2\", \"ctype\":\"industry\"}, \"amount\": 1500}", XContentType.JSON) + ).actionGet(); } @@ -38,23 +46,29 @@ public void testDlsAggregations() throws Exception { setup(); - - String query = "{"+ - "\"query\" : {"+ - "\"match_all\": {}"+ - "},"+ - "\"aggs\" : {"+ - "\"thesum\" : { \"sum\" : { \"field\" : \"amount\" } }"+ - "}"+ - "}"; + String query = "{" + + "\"query\" : {" + + "\"match_all\": {}" + + "}," + + "\"aggs\" : {" + + "\"thesum\" : { \"sum\" : { \"field\" : \"amount\" } }" + + "}" + + "}"; HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager_fls_dls", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager_fls_dls", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 0,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"value\" : 0")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"value\" : 1510.0")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -66,58 +80,77 @@ public void testDls() throws Exception { setup(); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=0", encodeBasicHeader("dept_manager_fls_dls", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=0", encodeBasicHeader("dept_manager_fls_dls", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 0,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=0", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=0", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - String query = - "{"+ - "\"query\": {"+ - "\"range\" : {"+ - "\"amount\" : {"+ - "\"gte\" : 8,"+ - "\"lte\" : 20,"+ - "\"boost\" : 3.0"+ - "}"+ - "}"+ - "}"+ - "}"; - - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query,encodeBasicHeader("dept_manager_fls_dls", "password"))).getStatusCode()); + "{" + + "\"query\": {" + + "\"range\" : {" + + "\"amount\" : {" + + "\"gte\" : 8," + + "\"lte\" : 20," + + "\"boost\" : 3.0" + + "}" + + "}" + + "}" + + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager_fls_dls", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 0,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); query = - "{"+ - "\"query\": {"+ - "\"range\" : {"+ - "\"amount\" : {"+ - "\"gte\" : 100,"+ - "\"lte\" : 2000,"+ - "\"boost\" : 2.0"+ - "}"+ - "}"+ - "}"+ - "}"; - - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query,encodeBasicHeader("dept_manager_fls_dls", "password"))).getStatusCode()); + "{" + + "\"query\": {" + + "\"range\" : {" + + "\"amount\" : {" + + "\"gte\" : 100," + + "\"lte\" : 2000," + + "\"boost\" : 2.0" + + "}" + + "}" + + "}" + + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager_fls_dls", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 0,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query,encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?q=amount:10&pretty", encodeBasicHeader("dept_manager_fls_dls", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?q=amount:10&pretty", encodeBasicHeader("dept_manager_fls_dls", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 0,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -133,11 +166,17 @@ public void testDls() throws Exception { res = rh.executeGetRequest("/deals/_doc/1?pretty", encodeBasicHeader("dept_manager_fls_dls", "password")); Assert.assertTrue(res.getBody().contains("\"found\" : false")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_count?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_count?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"count\" : 2,")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_count?pretty", encodeBasicHeader("dept_manager_fls_dls", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_count?pretty", encodeBasicHeader("dept_manager_fls_dls", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"count\" : 0,")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); } @@ -149,7 +188,10 @@ public void testCombined() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("user_combined", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("user_combined", "password"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsDlsTestMulti.java b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsDlsTestMulti.java index b177f1d346..e9d32f18ea 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsDlsTestMulti.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsDlsTestMulti.java @@ -21,21 +21,33 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class FlsDlsTestMulti extends AbstractDlsFlsTest{ - +public class FlsDlsTestMulti extends AbstractDlsFlsTest { protected void populateData(Client tc) { - tc.index(new IndexRequest("deals").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"customer\": {\"name\":\"cust1\"}, \"zip\": \"12345\",\"secret\": \"tellnoone\",\"amount\": 10}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("deals").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"customer\": {\"name\":\"cust2\", \"ctype\":\"industry\"}, \"amount\": 1500}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("deals").id("2").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"customer\": {\"name\":\"cust3\", \"ctype\":\"industry\"}, \"amount\": 200}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("deals").id("3").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"customer\": {\"name\":\"cust4\", \"ctype\":\"industry\"}, \"amount\": 20001}", XContentType.JSON)).actionGet(); - - + tc.index( + new IndexRequest("deals").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source( + "{\"customer\": {\"name\":\"cust1\"}, \"zip\": \"12345\",\"secret\": \"tellnoone\",\"amount\": 10}", + XContentType.JSON + ) + ).actionGet(); + tc.index( + new IndexRequest("deals").id("1") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"customer\": {\"name\":\"cust2\", \"ctype\":\"industry\"}, \"amount\": 1500}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("deals").id("2") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"customer\": {\"name\":\"cust3\", \"ctype\":\"industry\"}, \"amount\": 200}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("deals").id("3") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"customer\": {\"name\":\"cust4\", \"ctype\":\"industry\"}, \"amount\": 20001}", XContentType.JSON) + ).actionGet(); } @@ -44,29 +56,34 @@ public void testDlsAggregations() throws Exception { setup(); - - String query = "{"+ - "\"query\" : {"+ - "\"match_all\": {}"+ - "},"+ - "\"aggs\" : {"+ - "\"thesum\" : { \"sum\" : { \"field\" : \"amount\" } }"+ - "}"+ - "}"; + String query = "{" + + "\"query\" : {" + + "\"match_all\": {}" + + "}," + + "\"aggs\" : {" + + "\"thesum\" : { \"sum\" : { \"field\" : \"amount\" } }" + + "}" + + "}"; HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager_multi", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager_multi", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 3,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"value\" : 1710.0")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 4,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"value\" : 21711.0")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); } - @Test public void testDlsFls() throws Exception { @@ -74,63 +91,85 @@ public void testDlsFls() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("dept_manager_multi", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("dept_manager_multi", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("ctype")); Assert.assertFalse(res.getBody().contains("secret")); Assert.assertTrue(res.getBody().contains("zip")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=0", encodeBasicHeader("dept_manager_multi", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=0", encodeBasicHeader("dept_manager_multi", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 3,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=0", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=0", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 4,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - String query = - "{"+ - "\"query\": {"+ - "\"range\" : {"+ - "\"amount\" : {"+ - "\"gte\" : 8,"+ - "\"lte\" : 20,"+ - "\"boost\" : 3.0"+ - "}"+ - "}"+ - "}"+ - "}"; - - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query,encodeBasicHeader("dept_manager_multi", "password"))).getStatusCode()); + "{" + + "\"query\": {" + + "\"range\" : {" + + "\"amount\" : {" + + "\"gte\" : 8," + + "\"lte\" : 20," + + "\"boost\" : 3.0" + + "}" + + "}" + + "}" + + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager_multi", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); query = - "{"+ - "\"query\": {"+ - "\"range\" : {"+ - "\"amount\" : {"+ - "\"gte\" : 100,"+ - "\"lte\" : 2000,"+ - "\"boost\" : 2.0"+ - "}"+ - "}"+ - "}"+ - "}"; - - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query,encodeBasicHeader("dept_manager_multi", "password"))).getStatusCode()); + "{" + + "\"query\": {" + + "\"range\" : {" + + "\"amount\" : {" + + "\"gte\" : 100," + + "\"lte\" : 2000," + + "\"boost\" : 2.0" + + "}" + + "}" + + "}" + + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager_multi", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query,encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?q=amount:10&pretty", encodeBasicHeader("dept_manager_multi", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?q=amount:10&pretty", encodeBasicHeader("dept_manager_multi", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -143,23 +182,34 @@ public void testDlsFls() throws Exception { res = rh.executeGetRequest("/deals/_doc/1?pretty", encodeBasicHeader("dept_manager_multi", "password")); Assert.assertTrue(res.getBody().contains("\"found\" : true")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_count?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_count?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"count\" : 4,")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_count?pretty", encodeBasicHeader("dept_manager_multi", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_count?pretty", encodeBasicHeader("dept_manager_multi", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"count\" : 3,")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - //mget - //msearch - String msearchBody = - "{\"index\":\"deals\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); - //"{\"index\":\".opendistro_security\", \"type\":\"_doc\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - //"{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("_msearch?pretty", msearchBody, encodeBasicHeader("dept_manager_multi", "password"))).getStatusCode()); + // mget + // msearch + String msearchBody = "{\"index\":\"deals\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); + // "{\"index\":\".opendistro_security\", \"type\":\"_doc\", \"ignore_unavailable\": true}"+System.lineSeparator()+ + // "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("_msearch?pretty", msearchBody, encodeBasicHeader("dept_manager_multi", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody(), res.getBody().contains("\"value\" : 3,\n \"relation")); Assert.assertFalse(res.getBody().contains("_opendistro_security_dls_query")); Assert.assertFalse(res.getBody().contains("_opendistro_security_fls_fields")); @@ -169,29 +219,31 @@ public void testDlsFls() throws Exception { Assert.assertTrue(res.getBody().contains("\"amount\" : 20")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - - String mgetBody = "{"+ - "\"docs\" : ["+ - "{"+ - "\"_index\" : \"deals\","+ - "\"_id\" : \"0\""+ - " },"+ - " {"+ - "\"_index\" : \"deals\","+ - " \"_id\" : \"1\""+ - "},"+ - " {"+ - "\"_index\" : \"deals\","+ - " \"_id\" : \"2\""+ - "},"+ - " {"+ - "\"_index\" : \"deals\","+ - " \"_id\" : \"3\""+ - "}"+ - "]"+ - "}"; - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("dept_manager_multi", "password"))).getStatusCode()); + String mgetBody = "{" + + "\"docs\" : [" + + "{" + + "\"_index\" : \"deals\"," + + "\"_id\" : \"0\"" + + " }," + + " {" + + "\"_index\" : \"deals\"," + + " \"_id\" : \"1\"" + + "}," + + " {" + + "\"_index\" : \"deals\"," + + " \"_id\" : \"2\"" + + "}," + + " {" + + "\"_index\" : \"deals\"," + + " \"_id\" : \"3\"" + + "}" + + "]" + + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("dept_manager_multi", "password"))).getStatusCode() + ); Assert.assertFalse(res.getBody().contains("_opendistro_security_dls_query")); Assert.assertFalse(res.getBody().contains("_opendistro_security_fls_fields")); Assert.assertTrue(res.getBody().contains("\"amount\" : 1500")); @@ -209,30 +261,37 @@ public void testDlsSuggest() throws Exception { HttpResponse res; String query = - "{"+ - "\"query\": {"+ - "\"range\" : {"+ - "\"amount\" : {"+ - "\"gte\" : 11,"+ - "\"lte\" : 50000,"+ - "\"boost\" : 1.0"+ - "}"+ - "}"+ - "},"+ - "\"suggest\" : {\n" + - " \"thesuggestion\" : {\n" + - " \"text\" : \"cust\",\n" + - " \"term\" : {\n" + - " \"field\" : \"customer.name\"\n" + - " }\n" + - " }\n" + - " }"+ - "}"; - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); + "{" + + "\"query\": {" + + "\"range\" : {" + + "\"amount\" : {" + + "\"gte\" : 11," + + "\"lte\" : 50000," + + "\"boost\" : 1.0" + + "}" + + "}" + + "}," + + "\"suggest\" : {\n" + + " \"thesuggestion\" : {\n" + + " \"text\" : \"cust\",\n" + + " \"term\" : {\n" + + " \"field\" : \"customer.name\"\n" + + " }\n" + + " }\n" + + " }" + + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("thesuggestion")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager_multi", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager_multi", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("thesuggestion")); } @@ -244,21 +303,28 @@ public void testDlsSuggestOnly() throws Exception { HttpResponse res; String query = - "{"+ - "\"suggest\" : {\n" + - " \"thesuggestion\" : {\n" + - " \"text\" : \"cust\",\n" + - " \"term\" : {\n" + - " \"field\" : \"customer.name\"\n" + - " }\n" + - " }\n" + - " }"+ - "}"; - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); + "{" + + "\"suggest\" : {\n" + + " \"thesuggestion\" : {\n" + + " \"text\" : \"cust\",\n" + + " \"term\" : {\n" + + " \"field\" : \"customer.name\"\n" + + " }\n" + + " }\n" + + " }" + + "}"; + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("thesuggestion")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager_multi", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("dept_manager_multi", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("thesuggestion")); } diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsExistsFieldsTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsExistsFieldsTest.java index 8f056c8244..32cc44efc0 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsExistsFieldsTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsExistsFieldsTest.java @@ -26,33 +26,49 @@ public class FlsExistsFieldsTest extends AbstractDlsFlsTest { protected void populateData(Client tc) { - tc.admin().indices().create(new CreateIndexRequest("data") - .simpleMapping("@timestamp", "type=date", "host", "type=text,norms=false", "response", "type=text,norms=false", "non-existing", "type=text,norms=false")) - .actionGet(); + tc.admin() + .indices() + .create( + new CreateIndexRequest("data").simpleMapping( + "@timestamp", + "type=date", + "host", + "type=text,norms=false", + "response", + "type=text,norms=false", + "non-existing", + "type=text,norms=false" + ) + ) + .actionGet(); for (int i = 0; i < 1; i++) { - String doc = "{\"host\" : \"myhost"+i+"\",\n" + - " \"@timestamp\" : \"2018-01-18T09:03:25.877Z\",\n" + - " \"response\": \"404\"}"; - tc.index(new IndexRequest("data").id("a-normal-" + i).setRefreshPolicy(RefreshPolicy.IMMEDIATE).source(doc, - XContentType.JSON)).actionGet(); + String doc = "{\"host\" : \"myhost" + + i + + "\",\n" + + " \"@timestamp\" : \"2018-01-18T09:03:25.877Z\",\n" + + " \"response\": \"404\"}"; + tc.index(new IndexRequest("data").id("a-normal-" + i).setRefreshPolicy(RefreshPolicy.IMMEDIATE).source(doc, XContentType.JSON)) + .actionGet(); } for (int i = 0; i < 1; i++) { - String doc = "{" + - " \"@timestamp\" : \"2017-01-18T09:03:25.877Z\",\n" + - " \"response\": \"200\"}"; - tc.index(new IndexRequest("data").id("b-missing1-" + i).setRefreshPolicy(RefreshPolicy.IMMEDIATE).source(doc, - XContentType.JSON)).actionGet(); + String doc = "{" + " \"@timestamp\" : \"2017-01-18T09:03:25.877Z\",\n" + " \"response\": \"200\"}"; + tc.index( + new IndexRequest("data").id("b-missing1-" + i).setRefreshPolicy(RefreshPolicy.IMMEDIATE).source(doc, XContentType.JSON) + ).actionGet(); } for (int i = 0; i < 1; i++) { - String doc = "{\"host\" : \"myhost"+i+"\",\n" + - " \"@timestamp\" : \"2018-01-18T09:03:25.877Z\",\n" + - " \"non-existing\": \"xxx\","+ - " \"response\": \"403\"}"; - tc.index(new IndexRequest("data").id("c-missing2-" + i).setRefreshPolicy(RefreshPolicy.IMMEDIATE).source(doc, - XContentType.JSON)).actionGet(); + String doc = "{\"host\" : \"myhost" + + i + + "\",\n" + + " \"@timestamp\" : \"2018-01-18T09:03:25.877Z\",\n" + + " \"non-existing\": \"xxx\"," + + " \"response\": \"403\"}"; + tc.index( + new IndexRequest("data").id("c-missing2-" + i).setRefreshPolicy(RefreshPolicy.IMMEDIATE).source(doc, XContentType.JSON) + ).actionGet(); } } @@ -61,47 +77,50 @@ protected void populateData(Client tc) { public void testExistsField() throws Exception { setup(); - String query = "{\n" + - " \"query\": {\n" + - " \"bool\": {\n" + - - " \"must_not\": \n" + - " {\n" + - " \"exists\": {\n" + - " \"field\": \"non-existing\"\n" + - " \n" + - " }\n" + - " },\n" + - - " \"must\": [\n" + - " {\n" + - " \"exists\": {\n" + - " \"field\": \"@timestamp\"\n" + - " }\n" + - " },\n" + - " {\n" + - " \"exists\": {\n" + - " \"field\": \"host\"\n" + - " }\n" + - " }\n" + - " ]\n" + - " }\n" + - " }\n" + - "}"; + String query = "{\n" + " \"query\": {\n" + " \"bool\": {\n" + + + " \"must_not\": \n" + + " {\n" + + " \"exists\": {\n" + + " \"field\": \"non-existing\"\n" + + " \n" + + " }\n" + + " },\n" + + + + " \"must\": [\n" + + " {\n" + + " \"exists\": {\n" + + " \"field\": \"@timestamp\"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"exists\": {\n" + + " \"field\": \"host\"\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " }\n" + + "}"; HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, - (res = rh.executePostRequest("/data/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/data/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("a-normal-0")); Assert.assertTrue(res.getBody().contains("response")); Assert.assertTrue(res.getBody().contains("404")); - //only see's - timestamp and host field - //therefore non-existing does not exist so we expect c-missing2-0 to be returned - Assert.assertEquals(HttpStatus.SC_OK, - (res = rh.executePostRequest("/data/_search?pretty", query, encodeBasicHeader("fls_exists", "password"))).getStatusCode()); + // only see's - timestamp and host field + // therefore non-existing does not exist so we expect c-missing2-0 to be returned + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/data/_search?pretty", query, encodeBasicHeader("fls_exists", "password"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("a-normal-0")); diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsFieldsTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsFieldsTest.java index d4826222fa..a910cf5663 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsFieldsTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsFieldsTest.java @@ -25,19 +25,22 @@ import org.opensearch.security.test.helper.file.FileHelper; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class FlsFieldsTest extends AbstractDlsFlsTest{ - +public class FlsFieldsTest extends AbstractDlsFlsTest { protected void populateData(Client tc) { - tc.admin().indices().create(new CreateIndexRequest("deals").simpleMapping("timestamp", "type=date", "@timestamp", "type=date")).actionGet(); + tc.admin() + .indices() + .create(new CreateIndexRequest("deals").simpleMapping("timestamp", "type=date", "@timestamp", "type=date")) + .actionGet(); try { String doc = FileHelper.loadFile("dlsfls/doc1.json"); for (int i = 0; i < 10; i++) { final String moddoc = doc.replace("", "cust" + i).replace("", "" + i).replace("", "1970-01-02"); - tc.index(new IndexRequest("deals").id("0" + i).setRefreshPolicy(RefreshPolicy.IMMEDIATE).source(moddoc, XContentType.JSON)).actionGet(); + tc.index(new IndexRequest("deals").id("0" + i).setRefreshPolicy(RefreshPolicy.IMMEDIATE).source(moddoc, XContentType.JSON)) + .actionGet(); } } catch (IOException e) { @@ -46,7 +49,6 @@ protected void populateData(Client tc) { } - @Test public void testFields() throws Exception { setup(); @@ -54,13 +56,19 @@ public void testFields() throws Exception { String query = FileHelper.loadFile("dlsfls/flsquery.json"); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("secret")); Assert.assertTrue(res.getBody().contains("@timestamp")); Assert.assertTrue(res.getBody().contains("\"timestamp")); Assert.assertTrue(res.getBody().contains("numfield5")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("fls_fields", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("fls_fields", "password"))).getStatusCode() + ); Assert.assertFalse(res.getBody().contains("customer")); Assert.assertFalse(res.getBody().contains("secret")); Assert.assertFalse(res.getBody().contains("timestamp")); @@ -74,12 +82,18 @@ public void testFields2() throws Exception { String query = FileHelper.loadFile("dlsfls/flsquery2.json"); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty=true", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty=true", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("secret")); Assert.assertTrue(res.getBody().contains("@timestamp")); Assert.assertTrue(res.getBody().contains("\"timestamp")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty=true", query, encodeBasicHeader("fls_fields", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty=true", query, encodeBasicHeader("fls_fields", "password"))).getStatusCode() + ); Assert.assertFalse(res.getBody().contains("customer")); Assert.assertFalse(res.getBody().contains("secret")); Assert.assertFalse(res.getBody().contains("timestamp")); diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsFieldsWcTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsFieldsWcTest.java index 951e786891..f6cfd036fd 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsFieldsWcTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsFieldsWcTest.java @@ -25,19 +25,22 @@ import org.opensearch.security.test.helper.file.FileHelper; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class FlsFieldsWcTest extends AbstractDlsFlsTest{ - +public class FlsFieldsWcTest extends AbstractDlsFlsTest { protected void populateData(Client tc) { - tc.admin().indices().create(new CreateIndexRequest("deals").simpleMapping("timestamp", "type=date", "@timestamp", "type=date")).actionGet(); + tc.admin() + .indices() + .create(new CreateIndexRequest("deals").simpleMapping("timestamp", "type=date", "@timestamp", "type=date")) + .actionGet(); try { String doc = FileHelper.loadFile("dlsfls/doc1.json"); for (int i = 0; i < 10; i++) { final String moddoc = doc.replace("", "cust" + i).replace("", "" + i).replace("", "1970-01-02"); - tc.index(new IndexRequest("deals").id("0" + i).setRefreshPolicy(RefreshPolicy.IMMEDIATE).source(moddoc, XContentType.JSON)).actionGet(); + tc.index(new IndexRequest("deals").id("0" + i).setRefreshPolicy(RefreshPolicy.IMMEDIATE).source(moddoc, XContentType.JSON)) + .actionGet(); } } catch (IOException e) { @@ -46,7 +49,6 @@ protected void populateData(Client tc) { } - @Test public void testFields() throws Exception { setup(); @@ -54,12 +56,18 @@ public void testFields() throws Exception { String query = FileHelper.loadFile("dlsfls/flsquery.json"); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("secret")); Assert.assertTrue(res.getBody().contains("@timestamp")); Assert.assertTrue(res.getBody().contains("\"timestamp")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("fls_fields_wc", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("fls_fields_wc", "password"))).getStatusCode() + ); Assert.assertFalse(res.getBody().contains("customer")); Assert.assertFalse(res.getBody().contains("secret")); Assert.assertFalse(res.getBody().contains("timestamp")); @@ -73,12 +81,18 @@ public void testFields2() throws Exception { String query = FileHelper.loadFile("dlsfls/flsquery2.json"); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("secret")); Assert.assertTrue(res.getBody().contains("@timestamp")); Assert.assertTrue(res.getBody().contains("\"timestamp")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("fls_fields_wc", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_search?pretty", query, encodeBasicHeader("fls_fields_wc", "password"))).getStatusCode() + ); Assert.assertFalse(res.getBody().contains("customer")); Assert.assertFalse(res.getBody().contains("secret")); Assert.assertFalse(res.getBody().contains("timestamp")); diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsIndexingTests.java b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsIndexingTests.java index bbac74e6eb..2d7ed0efcf 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsIndexingTests.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsIndexingTests.java @@ -32,16 +32,24 @@ public class FlsIndexingTests extends AbstractDlsFlsTest { protected void populateData(final Client tc) { // Create several documents in different indices with shared field names, // different roles will have different levels of FLS restrictions - tc.index(new IndexRequest("yellow-pages").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"phone-all\":1001,\"phone-some\":1002,\"phone-one\":1003}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("green-pages").id("2").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"phone-all\":2001,\"phone-some\":2002,\"phone-one\":2003}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("blue-book").id("3").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"phone-all\":3001,\"phone-some\":3002,\"phone-one\":3003}", XContentType.JSON)).actionGet(); - - // Seperate index used to test aliasing - tc.index(new IndexRequest(".hidden").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("yellow-pages").id("1") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"phone-all\":1001,\"phone-some\":1002,\"phone-one\":1003}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("green-pages").id("2") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"phone-all\":2001,\"phone-some\":2002,\"phone-one\":2003}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("blue-book").id("3") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"phone-all\":3001,\"phone-some\":3002,\"phone-one\":3003}", XContentType.JSON) + ).actionGet(); + + // Seperate index used to test aliasing + tc.index(new IndexRequest(".hidden").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{}", XContentType.JSON)).actionGet(); } private Header asPhoneOneUser = encodeBasicHeader("user_aaa", "password"); @@ -52,10 +60,10 @@ protected void populateData(final Client tc) { @Test public void testSingleIndexFlsApplied() throws Exception { - setup(new DynamicSecurityConfig() - .setSecurityRoles("roles_fls_indexing.yml") - .setSecurityRolesMapping("roles_mapping_fls_indexing.yml")); - + setup( + new DynamicSecurityConfig().setSecurityRoles("roles_fls_indexing.yml").setSecurityRolesMapping("roles_mapping_fls_indexing.yml") + ); + final HttpResponse phoneOneFilteredResponse = rh.executeGetRequest(searchQuery, asPhoneOneUser); assertThat(phoneOneFilteredResponse.getStatusCode(), equalTo(HttpStatus.SC_OK)); assertThat(phoneOneFilteredResponse.getBody(), not(containsString("1003"))); @@ -73,11 +81,14 @@ public void testSingleIndexFlsApplied() throws Exception { @Test public void testSingleIndexFlsAppliedForLimitedResults() throws Exception { - setup(new DynamicSecurityConfig() - .setSecurityRoles("roles_fls_indexing.yml") - .setSecurityRolesMapping("roles_mapping_fls_indexing.yml")); - - final HttpResponse phoneOneFilteredResponse = rh.executeGetRequest("/yellow-pages/_search?filter_path=hits.hits&pretty", asPhoneOneUser); + setup( + new DynamicSecurityConfig().setSecurityRoles("roles_fls_indexing.yml").setSecurityRolesMapping("roles_mapping_fls_indexing.yml") + ); + + final HttpResponse phoneOneFilteredResponse = rh.executeGetRequest( + "/yellow-pages/_search?filter_path=hits.hits&pretty", + asPhoneOneUser + ); assertThat(phoneOneFilteredResponse.getStatusCode(), equalTo(HttpStatus.SC_OK)); assertThat(phoneOneFilteredResponse.getBody(), not(containsString("1003"))); assertThat(phoneOneFilteredResponse.getBody(), containsString("1002")); @@ -94,9 +105,9 @@ public void testSingleIndexFlsAppliedForLimitedResults() throws Exception { @Test public void testSeveralIndexFlsApplied() throws Exception { - setup(new DynamicSecurityConfig() - .setSecurityRoles("roles_fls_indexing.yml") - .setSecurityRolesMapping("roles_mapping_fls_indexing.yml")); + setup( + new DynamicSecurityConfig().setSecurityRoles("roles_fls_indexing.yml").setSecurityRolesMapping("roles_mapping_fls_indexing.yml") + ); final HttpResponse phoneSomeFilteredResponse = rh.executeGetRequest(searchQuery, asPhoneSomeUser); assertThat(phoneSomeFilteredResponse.getStatusCode(), equalTo(HttpStatus.SC_OK)); @@ -115,9 +126,9 @@ public void testSeveralIndexFlsApplied() throws Exception { @Test public void testAllIndexFlsApplied() throws Exception { - setup(new DynamicSecurityConfig() - .setSecurityRoles("roles_fls_indexing.yml") - .setSecurityRolesMapping("roles_mapping_fls_indexing.yml")); + setup( + new DynamicSecurityConfig().setSecurityRoles("roles_fls_indexing.yml").setSecurityRolesMapping("roles_mapping_fls_indexing.yml") + ); final HttpResponse phoneAllFilteredResponse = rh.executeGetRequest(searchQuery, asPhoneAllUser); assertThat(phoneAllFilteredResponse.getStatusCode(), equalTo(HttpStatus.SC_OK)); @@ -136,11 +147,15 @@ public void testAllIndexFlsApplied() throws Exception { @Test public void testAllIndexFlsAppliedWithAlias() throws Exception { - setup(new DynamicSecurityConfig() - .setSecurityRoles("roles_fls_indexing.yml") - .setSecurityRolesMapping("roles_mapping_fls_indexing.yml")); - - final HttpResponse createAlias = rh.executePostRequest("_aliases", "{\"actions\":[{\"add\":{\"index\":\".hidden\",\"alias\":\"ducky\"}}]}", asPhoneAllUser); + setup( + new DynamicSecurityConfig().setSecurityRoles("roles_fls_indexing.yml").setSecurityRolesMapping("roles_mapping_fls_indexing.yml") + ); + + final HttpResponse createAlias = rh.executePostRequest( + "_aliases", + "{\"actions\":[{\"add\":{\"index\":\".hidden\",\"alias\":\"ducky\"}}]}", + asPhoneAllUser + ); assertThat(createAlias.getStatusCode(), equalTo(HttpStatus.SC_OK)); final HttpResponse phoneAllFilteredResponse = rh.executeGetRequest(searchQuery, asPhoneAllUser); diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsKeywordTests.java b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsKeywordTests.java index 25069e48ef..1c51ec99b7 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsKeywordTests.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsKeywordTests.java @@ -32,20 +32,24 @@ public class FlsKeywordTests extends AbstractDlsFlsTest { protected void populateData(Client tc) { - tc.index(new IndexRequest("movies").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"year\": 2013, \"title\": \"Rush\", \"actors\": [\"Daniel Br\u00FChl\", \"Chris Hemsworth\", \"Olivia Wilde\"]}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("movies").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source( + "{\"year\": 2013, \"title\": \"Rush\", \"actors\": [\"Daniel Br\u00FChl\", \"Chris Hemsworth\", \"Olivia Wilde\"]}", + XContentType.JSON + ) + ).actionGet(); } private Header movieUser = encodeBasicHeader("user_aaa", "password"); private Header movieNoActorUser = encodeBasicHeader("user_bbb", "password"); - private String[] actors = new String[] {"Daniel Br\u00FChl", "Chris Hemsworth", "Olivia Wilde"}; + private String[] actors = new String[] { "Daniel Br\u00FChl", "Chris Hemsworth", "Olivia Wilde" }; @Test public void testKeywordsAreAutomaticallyFiltered() throws Exception { - setup(new DynamicSecurityConfig() - .setSecurityRoles("roles_keyword.yml") - .setSecurityRolesMapping("roles_mappings_keyword.yml")); + setup(new DynamicSecurityConfig().setSecurityRoles("roles_keyword.yml").setSecurityRolesMapping("roles_mappings_keyword.yml")); final String searchQuery = "/movies/_search?filter_path=hits.hits._source"; final String aggQuery = "/movies/_search?filter_path=aggregations.actors.buckets.key"; @@ -73,14 +77,10 @@ public void testKeywordsAreAutomaticallyFiltered() throws Exception { } private void assertActorsPresent(final HttpResponse response) { - Arrays.stream(actors).forEach(actor -> { - assertThat(response.getBody(), containsString(actor)); - }); + Arrays.stream(actors).forEach(actor -> { assertThat(response.getBody(), containsString(actor)); }); } private void assertActorsNotPresent(final HttpResponse response) { - Arrays.stream(actors).forEach(actor -> { - assertThat(response.getBody(), not(containsString(actor))); - }); + Arrays.stream(actors).forEach(actor -> { assertThat(response.getBody(), not(containsString(actor))); }); } } diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsPerfTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsPerfTest.java index 565dbdde9c..4fde195860 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsPerfTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsPerfTest.java @@ -30,30 +30,27 @@ import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; @Ignore -public class FlsPerfTest extends AbstractDlsFlsTest{ - +public class FlsPerfTest extends AbstractDlsFlsTest { protected void populateData(Client tc) { Map indexSettings = new HashMap<>(3); - indexSettings.put("index.mapping.total_fields.limit",50000); + indexSettings.put("index.mapping.total_fields.limit", 50000); indexSettings.put("number_of_shards", 10); indexSettings.put("number_of_replicas", 0); - tc.admin().indices().create(new CreateIndexRequest("deals") - .settings(indexSettings)) - .actionGet(); + tc.admin().indices().create(new CreateIndexRequest("deals").settings(indexSettings)).actionGet(); try { - IndexRequest ir = new IndexRequest("deals").id("idx1"); + IndexRequest ir = new IndexRequest("deals").id("idx1"); XContentBuilder b = XContentBuilder.builder(JsonXContent.jsonXContent); b.startObject(); - b.field("amount",1000); + b.field("amount", 1000); b.startObject("xyz"); - b.field("abc","val"); + b.field("abc", "val"); b.endObject(); b.endObject(); @@ -61,13 +58,13 @@ protected void populateData(Client tc) { tc.index(ir).actionGet(); - for(int i=0; i<1500; i++) { + for (int i = 0; i < 1500; i++) { - ir = new IndexRequest("deals").id("id"+i); + ir = new IndexRequest("deals").id("id" + i); b = XContentBuilder.builder(JsonXContent.jsonXContent); b.startObject(); - for(int j=0; j<2000;j++) { - b.field("field"+j,"val"+j); + for (int j = 0; j < 2000; j++) { + b.field("field" + j, "val" + j); } b.endObject(); @@ -94,7 +91,10 @@ public void testFlsPerfNamed() throws Exception { StopWatch sw = new StopWatch("testFlsPerfNamed"); sw.start("non fls"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); sw.stop(); Assert.assertTrue(res.getBody().contains("field1\"")); Assert.assertTrue(res.getBody().contains("field2\"")); @@ -102,7 +102,11 @@ public void testFlsPerfNamed() throws Exception { Assert.assertTrue(res.getBody().contains("field997\"")); sw.start("with fls"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_named_only", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_named_only", "password"))) + .getStatusCode() + ); sw.stop(); Assert.assertFalse(res.getBody().contains("field1\"")); Assert.assertFalse(res.getBody().contains("field2\"")); @@ -111,7 +115,11 @@ public void testFlsPerfNamed() throws Exception { sw.start("with fls 2 after warmup"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_named_only", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_named_only", "password"))) + .getStatusCode() + ); sw.stop(); Assert.assertFalse(res.getBody().contains("field1\"")); @@ -121,7 +129,11 @@ public void testFlsPerfNamed() throws Exception { sw.start("with fls 3 after warmup"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_named_only", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_named_only", "password"))) + .getStatusCode() + ); sw.stop(); Assert.assertFalse(res.getBody().contains("field1\"")); @@ -141,7 +153,10 @@ public void testFlsPerfWcEx() throws Exception { StopWatch sw = new StopWatch("testFlsPerfWcEx"); sw.start("non fls"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); sw.stop(); Assert.assertTrue(res.getBody().contains("field1\"")); Assert.assertTrue(res.getBody().contains("field2\"")); @@ -149,7 +164,10 @@ public void testFlsPerfWcEx() throws Exception { Assert.assertTrue(res.getBody().contains("field997\"")); sw.start("with fls"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_wc_ex", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_wc_ex", "password"))).getStatusCode() + ); sw.stop(); Assert.assertTrue(res.getBody().contains("field1\"")); Assert.assertTrue(res.getBody().contains("field2\"")); @@ -158,7 +176,10 @@ public void testFlsPerfWcEx() throws Exception { sw.start("with fls 2 after warmup"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_wc_ex", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_wc_ex", "password"))).getStatusCode() + ); sw.stop(); Assert.assertTrue(res.getBody().contains("field1\"")); @@ -168,7 +189,10 @@ public void testFlsPerfWcEx() throws Exception { sw.start("with fls 3 after warmup"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_wc_ex", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_wc_ex", "password"))).getStatusCode() + ); sw.stop(); Assert.assertTrue(res.getBody().contains("field1\"")); @@ -188,7 +212,10 @@ public void testFlsPerfNamedEx() throws Exception { StopWatch sw = new StopWatch("testFlsPerfNamedEx"); sw.start("non fls"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); sw.stop(); Assert.assertTrue(res.getBody().contains("field1\"")); Assert.assertTrue(res.getBody().contains("field2\"")); @@ -196,7 +223,10 @@ public void testFlsPerfNamedEx() throws Exception { Assert.assertTrue(res.getBody().contains("field997\"")); sw.start("with fls"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_named_ex", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_named_ex", "password"))).getStatusCode() + ); sw.stop(); Assert.assertTrue(res.getBody().contains("field1\"")); Assert.assertTrue(res.getBody().contains("field2\"")); @@ -205,7 +235,10 @@ public void testFlsPerfNamedEx() throws Exception { sw.start("with fls 2 after warmup"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_named_ex", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_named_ex", "password"))).getStatusCode() + ); sw.stop(); Assert.assertTrue(res.getBody().contains("field1\"")); @@ -215,7 +248,10 @@ public void testFlsPerfNamedEx() throws Exception { sw.start("with fls 3 after warmup"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_named_ex", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_named_ex", "password"))).getStatusCode() + ); sw.stop(); Assert.assertTrue(res.getBody().contains("field1\"")); @@ -235,7 +271,10 @@ public void testFlsWcIn() throws Exception { StopWatch sw = new StopWatch("testFlsWcIn"); sw.start("non fls"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); sw.stop(); Assert.assertTrue(res.getBody().contains("field1\"")); Assert.assertTrue(res.getBody().contains("field2\"")); @@ -243,7 +282,10 @@ public void testFlsWcIn() throws Exception { Assert.assertTrue(res.getBody().contains("field997\"")); sw.start("with fls"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_wc_in", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_wc_in", "password"))).getStatusCode() + ); sw.stop(); Assert.assertFalse(res.getBody().contains("field0\"")); Assert.assertTrue(res.getBody().contains("field50\"")); @@ -251,7 +293,10 @@ public void testFlsWcIn() throws Exception { sw.start("with fls 2 after warmup"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_wc_in", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_wc_in", "password"))).getStatusCode() + ); sw.stop(); Assert.assertFalse(res.getBody().contains("field0\"")); @@ -260,7 +305,10 @@ public void testFlsWcIn() throws Exception { sw.start("with fls 3 after warmup"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_wc_in", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty&size=1000", encodeBasicHeader("perf_wc_in", "password"))).getStatusCode() + ); sw.stop(); Assert.assertFalse(res.getBody().contains("field0\"")); diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsTest.java index c31650e734..180256efd9 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsTest.java @@ -21,15 +21,23 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class FlsTest extends AbstractDlsFlsTest{ - +public class FlsTest extends AbstractDlsFlsTest { protected void populateData(Client tc) { - tc.index(new IndexRequest("deals").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"customer\": {\"name\":\"cust1\"}, \"zip\": \"12345\",\"secret\": \"tellnoone\",\"amount\": 10}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("deals").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"customer\": {\"name\":\"cust2\", \"ctype\":\"industry\"}, \"amount\": 1500}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("deals").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source( + "{\"customer\": {\"name\":\"cust1\"}, \"zip\": \"12345\",\"secret\": \"tellnoone\",\"amount\": 10}", + XContentType.JSON + ) + ).actionGet(); + tc.index( + new IndexRequest("deals").id("1") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"customer\": {\"name\":\"cust2\", \"ctype\":\"industry\"}, \"amount\": 1500}", XContentType.JSON) + ).actionGet(); } @Test @@ -39,8 +47,10 @@ public void testFieldCapabilities() throws Exception { HttpResponse res; - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_field_caps?fields=*&pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_field_caps?fields=*&pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("customer")); Assert.assertTrue(res.getBody().contains("customer.name")); Assert.assertTrue(res.getBody().contains("zip")); @@ -48,7 +58,11 @@ public void testFieldCapabilities() throws Exception { Assert.assertTrue(res.getBody().contains("amount")); Assert.assertTrue(res.getBody().contains("secret")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_field_caps?fields=*&pretty", encodeBasicHeader("dept_manager_fls", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_field_caps?fields=*&pretty", encodeBasicHeader("dept_manager_fls", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("customer")); Assert.assertTrue(res.getBody().contains("customer.name")); Assert.assertTrue(res.getBody().contains("zip")); @@ -56,7 +70,13 @@ public void testFieldCapabilities() throws Exception { Assert.assertFalse(res.getBody().contains("amount")); Assert.assertFalse(res.getBody().contains("secret")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_field_caps?fields=*&pretty", encodeBasicHeader("dept_manager_fls_reversed_fields", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest( + "/deals/_field_caps?fields=*&pretty", + encodeBasicHeader("dept_manager_fls_reversed_fields", "password") + )).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertFalse(res.getBody().contains("customer")); Assert.assertFalse(res.getBody().contains("customer.name")); @@ -73,8 +93,10 @@ public void testMapping() throws Exception { HttpResponse res; - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_mapping?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_mapping?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("customer")); Assert.assertTrue(res.getBody().contains("name")); Assert.assertTrue(res.getBody().contains("zip")); @@ -82,7 +104,10 @@ public void testMapping() throws Exception { Assert.assertTrue(res.getBody().contains("amount")); Assert.assertTrue(res.getBody().contains("secret")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_mapping?pretty", encodeBasicHeader("dept_manager_fls", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_mapping?pretty", encodeBasicHeader("dept_manager_fls", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("customer")); Assert.assertTrue(res.getBody().contains("name")); Assert.assertTrue(res.getBody().contains("zip")); @@ -90,7 +115,11 @@ public void testMapping() throws Exception { Assert.assertFalse(res.getBody().contains("amount")); Assert.assertFalse(res.getBody().contains("secret")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_mapping?pretty", encodeBasicHeader("dept_manager_fls_reversed_fields", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_mapping?pretty", encodeBasicHeader("dept_manager_fls_reversed_fields", "password"))) + .getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("customer")); Assert.assertFalse(res.getBody().contains("name")); @@ -100,7 +129,6 @@ public void testMapping() throws Exception { Assert.assertTrue(res.getBody().contains("secret")); } - @Test public void testFlsSearch() throws Exception { @@ -108,7 +136,10 @@ public void testFlsSearch() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); Assert.assertTrue(res.getBody().contains("cust1")); @@ -118,7 +149,10 @@ public void testFlsSearch() throws Exception { Assert.assertTrue(res.getBody().contains("amount")); Assert.assertTrue(res.getBody().contains("secret")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("dept_manager_fls", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("dept_manager_fls", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); Assert.assertTrue(res.getBody().contains("cust1")); @@ -128,7 +162,11 @@ public void testFlsSearch() throws Exception { Assert.assertFalse(res.getBody().contains("amount")); Assert.assertFalse(res.getBody().contains("secret")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("dept_manager_fls_reversed_fields", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_search?pretty", encodeBasicHeader("dept_manager_fls_reversed_fields", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); Assert.assertFalse(res.getBody().contains("cust1")); @@ -146,7 +184,10 @@ public void testFlsGet() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_doc/0?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_doc/0?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"found\" : true")); Assert.assertTrue(res.getBody().contains("cust1")); Assert.assertFalse(res.getBody().contains("cust2")); @@ -154,7 +195,10 @@ public void testFlsGet() throws Exception { Assert.assertFalse(res.getBody().contains("ctype")); Assert.assertTrue(res.getBody().contains("amount")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_doc/0?pretty", encodeBasicHeader("dept_manager_fls", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_doc/0?pretty", encodeBasicHeader("dept_manager_fls", "password"))).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"found\" : true")); Assert.assertTrue(res.getBody().contains("cust1")); Assert.assertFalse(res.getBody().contains("cust2")); @@ -162,7 +206,11 @@ public void testFlsGet() throws Exception { Assert.assertFalse(res.getBody().contains("ctype")); Assert.assertFalse(res.getBody().contains("amount")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_doc/0?realtime=true&pretty", encodeBasicHeader("dept_manager_fls", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/deals/_doc/0?realtime=true&pretty", encodeBasicHeader("dept_manager_fls", "password"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"found\" : true")); Assert.assertTrue(res.getBody().contains("cust1")); Assert.assertFalse(res.getBody().contains("cust2")); @@ -170,7 +218,13 @@ public void testFlsGet() throws Exception { Assert.assertFalse(res.getBody().contains("ctype")); Assert.assertFalse(res.getBody().contains("amount")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/deals/_doc/0?realtime=true&pretty", encodeBasicHeader("dept_manager_fls_reversed_fields", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest( + "/deals/_doc/0?realtime=true&pretty", + encodeBasicHeader("dept_manager_fls_reversed_fields", "password") + )).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"found\" : true")); Assert.assertFalse(res.getBody().contains("cust1")); Assert.assertFalse(res.getBody().contains("cust2")); @@ -187,11 +241,22 @@ public void testFlsUpdate() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("/deals/_update/0?pretty", "{\"doc\": {\"zip\": \"98765\"}}", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("/deals/_update/0?pretty", "{\"doc\": {\"zip\": \"98765\"}}", encodeBasicHeader("admin", "admin"))) + .getStatusCode() + ); Assert.assertTrue(res.getBody().contains("\"_version\" : 2")); Assert.assertFalse(res.getBody(), res.getBody().contains("\"successful\" : 0")); - Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, (res = rh.executePostRequest("/deals/_update/0?pretty", "{\"doc\": {\"zip\": \"98765000\"}}", encodeBasicHeader("dept_manager_fls", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_INTERNAL_SERVER_ERROR, + (res = rh.executePostRequest( + "/deals/_update/0?pretty", + "{\"doc\": {\"zip\": \"98765000\"}}", + encodeBasicHeader("dept_manager_fls", "password") + )).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("Update is not supported")); } @@ -202,7 +267,14 @@ public void testFlsUpdateIndex() throws Exception { HttpResponse res = null; - Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, (res = rh.executePostRequest("/deals/_update/0?pretty", "{\"doc\": {\"zip\": \"98765000\"}}", encodeBasicHeader("dept_manager_fls", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_INTERNAL_SERVER_ERROR, + (res = rh.executePostRequest( + "/deals/_update/0?pretty", + "{\"doc\": {\"zip\": \"98765000\"}}", + encodeBasicHeader("dept_manager_fls", "password") + )).getStatusCode() + ); Assert.assertTrue(res.getBody().contains("Update is not supported")); } } diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/IndexPatternTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/IndexPatternTest.java index 7348b11341..9b075e0600 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/IndexPatternTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/IndexPatternTest.java @@ -21,20 +21,27 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class IndexPatternTest extends AbstractDlsFlsTest{ - +public class IndexPatternTest extends AbstractDlsFlsTest { protected void populateData(Client tc) { - tc.index(new IndexRequest("logstash-2016").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"message\":\"mymsg1a\", \"ipaddr\": \"10.0.0.0\",\"msgid\": \"12\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("logstash-2016").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"message\":\"mymsg1b\", \"ipaddr\": \"10.0.0.1\",\"msgid\": \"14\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("logstash-2018").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"message\":\"mymsg1c\", \"ipaddr\": \"10.0.0.2\",\"msgid\": \"12\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("logstash-2018").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"message\":\"mymsg1d\", \"ipaddr\": \"10.0.0.3\",\"msgid\": \"14\"}", XContentType.JSON)).actionGet(); - } + tc.index( + new IndexRequest("logstash-2016").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"message\":\"mymsg1a\", \"ipaddr\": \"10.0.0.0\",\"msgid\": \"12\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("logstash-2016").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"message\":\"mymsg1b\", \"ipaddr\": \"10.0.0.1\",\"msgid\": \"14\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("logstash-2018").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"message\":\"mymsg1c\", \"ipaddr\": \"10.0.0.2\",\"msgid\": \"12\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("logstash-2018").setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"message\":\"mymsg1d\", \"ipaddr\": \"10.0.0.3\",\"msgid\": \"14\"}", XContentType.JSON) + ).actionGet(); + } @Test public void testSearch() throws Exception { @@ -43,7 +50,10 @@ public void testSearch() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash-2016/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/logstash-2016/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -52,7 +62,11 @@ public void testSearch() throws Exception { Assert.assertTrue(res.getBody().contains("mymsg")); Assert.assertTrue(res.getBody().contains("msgid")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash-2016/_search?pretty", encodeBasicHeader("opendistro_security_logstash", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/logstash-2016/_search?pretty", encodeBasicHeader("opendistro_security_logstash", "password"))) + .getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -69,13 +83,22 @@ public void testFieldCaps() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash-2016/_field_caps?fields=*&pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/logstash-2016/_field_caps?fields=*&pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("ipaddr")); Assert.assertTrue(res.getBody().contains("message")); Assert.assertTrue(res.getBody().contains("msgid")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash-2016/_field_caps?fields=*&pretty", encodeBasicHeader("opendistro_security_logstash", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest( + "/logstash-2016/_field_caps?fields=*&pretty", + encodeBasicHeader("opendistro_security_logstash", "password") + )).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertFalse(res.getBody().contains("ipaddr")); Assert.assertFalse(res.getBody().contains("message")); @@ -89,7 +112,10 @@ public void testSearchWc() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash-20*/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/logstash-20*/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 4,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -98,7 +124,11 @@ public void testSearchWc() throws Exception { Assert.assertTrue(res.getBody().contains("mymsg")); Assert.assertTrue(res.getBody().contains("msgid")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash-20*/_search?pretty", encodeBasicHeader("opendistro_security_logstash", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/logstash-20*/_search?pretty", encodeBasicHeader("opendistro_security_logstash", "password"))) + .getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -115,7 +145,10 @@ public void testSearchWcRegex() throws Exception { HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash-20*/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/logstash-20*/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 4,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); @@ -124,7 +157,10 @@ public void testSearchWcRegex() throws Exception { Assert.assertTrue(res.getBody().contains("mymsg")); Assert.assertTrue(res.getBody().contains("msgid")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash-20*/_search?pretty", encodeBasicHeader("regex", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("/logstash-20*/_search?pretty", encodeBasicHeader("regex", "password"))).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 2,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/MFlsTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/MFlsTest.java index b7305ee48c..81a2c50fc6 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/MFlsTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/MFlsTest.java @@ -21,15 +21,26 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; -public class MFlsTest extends AbstractDlsFlsTest{ - +public class MFlsTest extends AbstractDlsFlsTest { protected void populateData(Client tc) { - tc.index(new IndexRequest("deals").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"customer\": {\"name\":\"cust1\"}, \"zip\": \"12345\",\"secret\": \"tellnoone\",\"amount\": 10}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("finance").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source("{\"finfield2\":\"fff\",\"xcustomer\": {\"name\":\"cust2\", \"ctype\":\"industry\"}, \"famount\": 1500}", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest("deals").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source( + "{\"customer\": {\"name\":\"cust1\"}, \"zip\": \"12345\",\"secret\": \"tellnoone\",\"amount\": 10}", + XContentType.JSON + ) + ).actionGet(); + tc.index( + new IndexRequest("finance").id("1") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source( + "{\"finfield2\":\"fff\",\"xcustomer\": {\"name\":\"cust2\", \"ctype\":\"industry\"}, \"famount\": 1500}", + XContentType.JSON + ) + ).actionGet(); } @Test @@ -40,7 +51,10 @@ public void testFlsMGetSearch() throws Exception { HttpResponse res; System.out.println("### normal search"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("deals,finance/_search?pretty", encodeBasicHeader("dept_manager_fls", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("deals,finance/_search?pretty", encodeBasicHeader("dept_manager_fls", "password"))).getStatusCode() + ); Assert.assertFalse(res.getBody().contains("_opendistro_security_")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); Assert.assertFalse(res.getBody().contains("xception")); @@ -50,16 +64,22 @@ public void testFlsMGetSearch() throws Exception { Assert.assertFalse(res.getBody().contains("amount")); Assert.assertFalse(res.getBody().contains("secret")); - //mget - //msearch - String msearchBody = - "{\"index\":\"deals\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ - "{\"index\":\"finance\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); + // mget + // msearch + String msearchBody = "{\"index\":\"deals\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator() + + "{\"index\":\"finance\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); System.out.println("### msearch"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("_msearch?pretty", msearchBody, encodeBasicHeader("dept_manager_fls", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("_msearch?pretty", msearchBody, encodeBasicHeader("dept_manager_fls", "password"))).getStatusCode() + ); Assert.assertFalse(res.getBody().contains("_opendistro_security_")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); Assert.assertFalse(res.getBody().contains("xception")); @@ -69,22 +89,24 @@ public void testFlsMGetSearch() throws Exception { Assert.assertFalse(res.getBody().contains("amount")); Assert.assertFalse(res.getBody().contains("secret")); - - String mgetBody = "{"+ - "\"docs\" : ["+ - "{"+ - "\"_index\" : \"deals\","+ - "\"_id\" : \"0\""+ - " },"+ - " {"+ - "\"_index\" : \"finance\","+ - " \"_id\" : \"1\""+ - "}"+ - "]"+ - "}"; + String mgetBody = "{" + + "\"docs\" : [" + + "{" + + "\"_index\" : \"deals\"," + + "\"_id\" : \"0\"" + + " }," + + " {" + + "\"_index\" : \"finance\"," + + " \"_id\" : \"1\"" + + "}" + + "]" + + "}"; System.out.println("### mget"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("dept_manager_fls", "password"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("dept_manager_fls", "password"))).getStatusCode() + ); Assert.assertFalse(res.getBody().contains("_opendistro_security_")); Assert.assertTrue(res.getBody().contains("\"found\" : true")); Assert.assertFalse(res.getBody().contains("\"found\" : false")); 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 7b590f1d46..e7752c21d1 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 @@ -44,8 +44,8 @@ public abstract class AbstractRestApiUnitTest extends SingleClusterTest { - protected RestHelper rh = null; - protected boolean init = true; + protected RestHelper rh = null; + protected boolean init = true; @Override protected String getResourceFolder() { @@ -53,247 +53,259 @@ protected String getResourceFolder() { } @Override - protected final void setup() throws Exception { - Settings.Builder builder = Settings.builder(); + protected final void setup() throws Exception { + Settings.Builder builder = Settings.builder(); - builder.put("plugins.security.ssl.http.enabled", true) - .put(SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH, PasswordValidator.ScoreStrength.FAIR.name()) - .put("plugins.security.ssl.http.keystore_filepath", - FileHelper.getAbsoluteFilePathFromClassPath("restapi/node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", - FileHelper.getAbsoluteFilePathFromClassPath("restapi/truststore.jks")); + builder.put("plugins.security.ssl.http.enabled", true) + .put(SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH, PasswordValidator.ScoreStrength.FAIR.name()) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("restapi/node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("restapi/truststore.jks")); - setup(Settings.EMPTY, new DynamicSecurityConfig(), builder.build(), init); - rh = restHelper(); - rh.keystore = "restapi/kirk-keystore.jks"; - } + setup(Settings.EMPTY, new DynamicSecurityConfig(), builder.build(), init); + rh = restHelper(); + rh.keystore = "restapi/kirk-keystore.jks"; + } @Override - protected final void setup(Settings nodeOverride) throws Exception { - Settings.Builder builder = Settings.builder(); + protected final void setup(Settings nodeOverride) throws Exception { + Settings.Builder builder = Settings.builder(); - builder.put("plugins.security.ssl.http.enabled", true) - .put("plugins.security.ssl.http.keystore_filepath", - FileHelper.getAbsoluteFilePathFromClassPath("restapi/node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", - FileHelper.getAbsoluteFilePathFromClassPath("restapi/truststore.jks")) - .put(nodeOverride); + builder.put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("restapi/node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("restapi/truststore.jks")) + .put(nodeOverride); - System.out.println(builder.toString()); + System.out.println(builder.toString()); - setup(Settings.EMPTY, new DynamicSecurityConfig(), builder.build(), init); - rh = restHelper(); - rh.keystore = "restapi/kirk-keystore.jks"; - } + setup(Settings.EMPTY, new DynamicSecurityConfig(), builder.build(), init); + rh = restHelper(); + rh.keystore = "restapi/kirk-keystore.jks"; + } - protected final void setupWithRestRoles() throws Exception { + protected final void setupWithRestRoles() throws Exception { setupWithRestRoles(null); } - protected final void setupWithRestRoles(Settings nodeOverride) throws Exception { - Settings.Builder builder = Settings.builder(); - - builder.put("plugins.security.ssl.http.enabled", true) - .put(SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH, PasswordValidator.ScoreStrength.FAIR.name()) - .put("plugins.security.ssl.http.keystore_filepath", - FileHelper.getAbsoluteFilePathFromClassPath("restapi/node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", - FileHelper.getAbsoluteFilePathFromClassPath("restapi/truststore.jks")); - - builder.put(rolesSettings()); - - if (null != nodeOverride) { - builder.put(nodeOverride); - } - - setup(Settings.EMPTY, new DynamicSecurityConfig(), builder.build(), init); - rh = restHelper(); - rh.keystore = "restapi/kirk-keystore.jks"; - - AuditTestUtils.updateAuditConfig(rh, nodeOverride != null ? nodeOverride : Settings.EMPTY); - } - - protected Settings rolesSettings() { - return Settings.builder() - .put("plugins.security.restapi.roles_enabled.0", "opendistro_security_role_klingons") - .put("plugins.security.restapi.roles_enabled.1", "opendistro_security_role_vulcans") - .put("plugins.security.restapi.roles_enabled.2", "opendistro_security_test") - .put("plugins.security.restapi.endpoints_disabled.global.CACHE.0", "*") - .put("plugins.security.restapi.endpoints_disabled.opendistro_security_role_klingons.conFiGuration.0", "*") - .put("plugins.security.restapi.endpoints_disabled.opendistro_security_role_klingons.wRongType.0", "WRONGType") - .put("plugins.security.restapi.endpoints_disabled.opendistro_security_role_klingons.ROLESMAPPING.0", "PUT") - .put("plugins.security.restapi.endpoints_disabled.opendistro_security_role_klingons.ROLESMAPPING.1", "DELETE") - .put("plugins.security.restapi.endpoints_disabled.opendistro_security_role_vulcans.CONFIG.0", "*") - .build(); - } - - protected void deleteUser(String username) throws Exception { - boolean sendAdminCertificate = rh.sendAdminCertificate; - rh.sendAdminCertificate = true; - HttpResponse response = rh.executeDeleteRequest("/_opendistro/_security/api/internalusers/" + username, new Header[0]); - Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - rh.sendAdminCertificate = sendAdminCertificate; - } - - protected void addUserWithPassword(String username, String password, int status) throws Exception { - addUserWithPassword(username, password, status, null); - } - - protected void addUserWithPassword(String username, String password, int status, String message) throws Exception { - boolean sendAdminCertificate = rh.sendAdminCertificate; - rh.sendAdminCertificate = true; - HttpResponse response = rh.executePutRequest("/_opendistro/_security/api/internalusers/" + username, - "{\"password\": \"" + password + "\"}", new Header[0]); - Assert.assertEquals(status, response.getStatusCode()); - rh.sendAdminCertificate = sendAdminCertificate; - if (Objects.nonNull(message)) { - Assert.assertTrue(response.getBody().contains(message)); - } - } - - protected void addUserWithPassword(String username, String password, String[] roles, int status) throws Exception { - boolean sendAdminCertificate = rh.sendAdminCertificate; - rh.sendAdminCertificate = true; - String payload = "{" + "\"password\": \"" + password + "\"," + "\"backend_roles\": ["; - for (int i = 0; i < roles.length; i++) { - payload += "\"" + roles[i] + "\""; - if (i + 1 < roles.length) { - payload += ","; - } - } - payload += "]}"; - HttpResponse response = rh.executePutRequest("/_opendistro/_security/api/internalusers/" + username, payload, new Header[0]); - Assert.assertEquals(status, response.getStatusCode()); - rh.sendAdminCertificate = sendAdminCertificate; - } - - protected void addUserWithoutPasswordOrHash(String username, String[] roles, int status) throws Exception { - boolean sendAdminCertificate = rh.sendAdminCertificate; - rh.sendAdminCertificate = true; - String payload = "{ \"backend_roles\": ["; - for (int i = 0; i < roles.length; i++) { - payload += "\" " + roles[i] + " \""; - if (i + 1 < roles.length) { - payload += ","; - } - } - payload += "]}"; - HttpResponse response = rh.executePutRequest("/_opendistro/_security/api/internalusers/" + username, payload, new Header[0]); - Assert.assertEquals(status, response.getStatusCode()); - rh.sendAdminCertificate = sendAdminCertificate; - } - - protected void addUserWithHash(String username, String hash) throws Exception { - addUserWithHash(username, hash, HttpStatus.SC_OK); - } - - protected void addUserWithHash(String username, String hash, int status) throws Exception { - boolean sendAdminCertificate = rh.sendAdminCertificate; - rh.sendAdminCertificate = true; - HttpResponse response = rh.executePutRequest("/_opendistro/_security/api/internalusers/" + username, "{\"hash\": \"" + hash + "\"}", - new Header[0]); - Assert.assertEquals(status, response.getStatusCode()); - rh.sendAdminCertificate = sendAdminCertificate; - } - - protected void addUserWithPasswordAndHash(String username, String password, String hash, int status) throws Exception { - boolean sendAdminCertificate = rh.sendAdminCertificate; - rh.sendAdminCertificate = true; - HttpResponse response = rh.executePutRequest("/_opendistro/_security/api/internalusers/" + username, "{\"hash\": \"" + hash + "\", \"password\": \"" + password + "\"}", - new Header[0]); - Assert.assertEquals(status, response.getStatusCode()); - rh.sendAdminCertificate = sendAdminCertificate; - } - - protected void checkGeneralAccess(int status, String username, String password) throws Exception { - boolean sendAdminCertificate = rh.sendAdminCertificate; - rh.sendAdminCertificate = false; - Assert.assertEquals(status, - rh.executeGetRequest("", - encodeBasicHeader(username, password)) - .getStatusCode()); - rh.sendAdminCertificate = sendAdminCertificate; - } - - protected String checkReadAccess(int status, String username, String password, String indexName, String actionType, - int id) throws Exception { - rh.sendAdminCertificate = false; - String action = indexName + "/" + actionType + "/" + id; - HttpResponse response = rh.executeGetRequest(action, encodeBasicHeader(username, password)); - int returnedStatus = response.getStatusCode(); - Assert.assertEquals(status, returnedStatus); - return response.getBody(); - - } - - protected String checkWriteAccess(int status, String username, String password, String indexName, String actionType, - int id) throws Exception { - rh.sendAdminCertificate = false; - String action = indexName + "/" + actionType + "/" + id; - String payload = "{\"value\" : \"true\"}"; - HttpResponse response = rh.executePutRequest(action, payload, encodeBasicHeader(username, password)); - int returnedStatus = response.getStatusCode(); - Assert.assertEquals(response.getBody(), status, returnedStatus); - return response.getBody(); - } - - protected void setupStarfleetIndex() throws Exception { - boolean sendAdminCertificate = rh.sendAdminCertificate; - rh.sendAdminCertificate = true; - rh.executePutRequest("sf", null, new Header[0]); - rh.executePutRequest("sf/_doc/0", "{\"number\" : \"NCC-1701-D\"}", new Header[0]); - rh.executePutRequest("sf/_doc/0", "{\"some\" : \"value\"}", new Header[0]); - rh.sendAdminCertificate = sendAdminCertificate; - } - - protected void assertHealthy() throws Exception { - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_opendistro/_security/health?pretty").getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("admin", "admin")).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("admin", "admin")).getStatusCode()); - } - - protected Settings defaultNodeSettings(boolean enableRestSSL) { - Settings.Builder builder = Settings.builder(); - - if (enableRestSSL) { - builder.put("plugins.security.ssl.http.enabled", true) - .put("plugins.security.ssl.http.keystore_filepath", - FileHelper.getAbsoluteFilePathFromClassPath("restapi/node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", - FileHelper.getAbsoluteFilePathFromClassPath("restapi/truststore.jks")); - } - return builder.build(); - } - - protected Map jsonStringToMap(String json) throws JsonParseException, JsonMappingException, IOException { - TypeReference> typeRef = new TypeReference>() {}; - return DefaultObjectMapper.objectMapper.readValue(json, typeRef); - } - - protected static Collection> asCollection(Class... plugins) { - return Arrays.asList(plugins); - } - - String createRestAdminPermissionsPayload(String... additionPerms) throws JsonProcessingException { - final ObjectNode rootNode = (ObjectNode) DefaultObjectMapper.objectMapper.createObjectNode(); - rootNode.set("cluster_permissions", clusterPermissionsForRestAdmin(additionPerms)); - return DefaultObjectMapper.objectMapper.writeValueAsString(rootNode); - } - - ArrayNode clusterPermissionsForRestAdmin(String... additionPerms) { - final ArrayNode permissionsArray = (ArrayNode) DefaultObjectMapper.objectMapper.createArrayNode(); - for (final Map.Entry entry : RestApiAdminPrivilegesEvaluator.ENDPOINTS_WITH_PERMISSIONS.entrySet()) { - if (entry.getKey() == Endpoint.SSL) { - permissionsArray - .add(entry.getValue().build("certs")) - .add(entry.getValue().build("reloadcerts")); - } else { - permissionsArray.add(entry.getValue().build()); - } - } - if (additionPerms.length != 0) { - Stream.of(additionPerms).forEach(permissionsArray::add); - } - return permissionsArray; - } + protected final void setupWithRestRoles(Settings nodeOverride) throws Exception { + Settings.Builder builder = Settings.builder(); + + builder.put("plugins.security.ssl.http.enabled", true) + .put(SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH, PasswordValidator.ScoreStrength.FAIR.name()) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("restapi/node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("restapi/truststore.jks")); + + builder.put(rolesSettings()); + + if (null != nodeOverride) { + builder.put(nodeOverride); + } + + setup(Settings.EMPTY, new DynamicSecurityConfig(), builder.build(), init); + rh = restHelper(); + rh.keystore = "restapi/kirk-keystore.jks"; + + AuditTestUtils.updateAuditConfig(rh, nodeOverride != null ? nodeOverride : Settings.EMPTY); + } + + protected Settings rolesSettings() { + return Settings.builder() + .put("plugins.security.restapi.roles_enabled.0", "opendistro_security_role_klingons") + .put("plugins.security.restapi.roles_enabled.1", "opendistro_security_role_vulcans") + .put("plugins.security.restapi.roles_enabled.2", "opendistro_security_test") + .put("plugins.security.restapi.endpoints_disabled.global.CACHE.0", "*") + .put("plugins.security.restapi.endpoints_disabled.opendistro_security_role_klingons.conFiGuration.0", "*") + .put("plugins.security.restapi.endpoints_disabled.opendistro_security_role_klingons.wRongType.0", "WRONGType") + .put("plugins.security.restapi.endpoints_disabled.opendistro_security_role_klingons.ROLESMAPPING.0", "PUT") + .put("plugins.security.restapi.endpoints_disabled.opendistro_security_role_klingons.ROLESMAPPING.1", "DELETE") + .put("plugins.security.restapi.endpoints_disabled.opendistro_security_role_vulcans.CONFIG.0", "*") + .build(); + } + + protected void deleteUser(String username) throws Exception { + boolean sendAdminCertificate = rh.sendAdminCertificate; + rh.sendAdminCertificate = true; + HttpResponse response = rh.executeDeleteRequest("/_opendistro/_security/api/internalusers/" + username, new Header[0]); + Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); + rh.sendAdminCertificate = sendAdminCertificate; + } + + protected void addUserWithPassword(String username, String password, int status) throws Exception { + addUserWithPassword(username, password, status, null); + } + + protected void addUserWithPassword(String username, String password, int status, String message) throws Exception { + boolean sendAdminCertificate = rh.sendAdminCertificate; + rh.sendAdminCertificate = true; + HttpResponse response = rh.executePutRequest( + "/_opendistro/_security/api/internalusers/" + username, + "{\"password\": \"" + password + "\"}", + new Header[0] + ); + Assert.assertEquals(status, response.getStatusCode()); + rh.sendAdminCertificate = sendAdminCertificate; + if (Objects.nonNull(message)) { + Assert.assertTrue(response.getBody().contains(message)); + } + } + + protected void addUserWithPassword(String username, String password, String[] roles, int status) throws Exception { + boolean sendAdminCertificate = rh.sendAdminCertificate; + rh.sendAdminCertificate = true; + String payload = "{" + "\"password\": \"" + password + "\"," + "\"backend_roles\": ["; + for (int i = 0; i < roles.length; i++) { + payload += "\"" + roles[i] + "\""; + if (i + 1 < roles.length) { + payload += ","; + } + } + payload += "]}"; + HttpResponse response = rh.executePutRequest("/_opendistro/_security/api/internalusers/" + username, payload, new Header[0]); + Assert.assertEquals(status, response.getStatusCode()); + rh.sendAdminCertificate = sendAdminCertificate; + } + + protected void addUserWithoutPasswordOrHash(String username, String[] roles, int status) throws Exception { + boolean sendAdminCertificate = rh.sendAdminCertificate; + rh.sendAdminCertificate = true; + String payload = "{ \"backend_roles\": ["; + for (int i = 0; i < roles.length; i++) { + payload += "\" " + roles[i] + " \""; + if (i + 1 < roles.length) { + payload += ","; + } + } + payload += "]}"; + HttpResponse response = rh.executePutRequest("/_opendistro/_security/api/internalusers/" + username, payload, new Header[0]); + Assert.assertEquals(status, response.getStatusCode()); + rh.sendAdminCertificate = sendAdminCertificate; + } + + protected void addUserWithHash(String username, String hash) throws Exception { + addUserWithHash(username, hash, HttpStatus.SC_OK); + } + + protected void addUserWithHash(String username, String hash, int status) throws Exception { + boolean sendAdminCertificate = rh.sendAdminCertificate; + rh.sendAdminCertificate = true; + HttpResponse response = rh.executePutRequest( + "/_opendistro/_security/api/internalusers/" + username, + "{\"hash\": \"" + hash + "\"}", + new Header[0] + ); + Assert.assertEquals(status, response.getStatusCode()); + rh.sendAdminCertificate = sendAdminCertificate; + } + + protected void addUserWithPasswordAndHash(String username, String password, String hash, int status) throws Exception { + boolean sendAdminCertificate = rh.sendAdminCertificate; + rh.sendAdminCertificate = true; + HttpResponse response = rh.executePutRequest( + "/_opendistro/_security/api/internalusers/" + username, + "{\"hash\": \"" + hash + "\", \"password\": \"" + password + "\"}", + new Header[0] + ); + Assert.assertEquals(status, response.getStatusCode()); + rh.sendAdminCertificate = sendAdminCertificate; + } + + protected void checkGeneralAccess(int status, String username, String password) throws Exception { + boolean sendAdminCertificate = rh.sendAdminCertificate; + rh.sendAdminCertificate = false; + Assert.assertEquals(status, rh.executeGetRequest("", encodeBasicHeader(username, password)).getStatusCode()); + rh.sendAdminCertificate = sendAdminCertificate; + } + + protected String checkReadAccess(int status, String username, String password, String indexName, String actionType, int id) + throws Exception { + rh.sendAdminCertificate = false; + String action = indexName + "/" + actionType + "/" + id; + HttpResponse response = rh.executeGetRequest(action, encodeBasicHeader(username, password)); + int returnedStatus = response.getStatusCode(); + Assert.assertEquals(status, returnedStatus); + return response.getBody(); + + } + + protected String checkWriteAccess(int status, String username, String password, String indexName, String actionType, int id) + throws Exception { + rh.sendAdminCertificate = false; + String action = indexName + "/" + actionType + "/" + id; + String payload = "{\"value\" : \"true\"}"; + HttpResponse response = rh.executePutRequest(action, payload, encodeBasicHeader(username, password)); + int returnedStatus = response.getStatusCode(); + Assert.assertEquals(response.getBody(), status, returnedStatus); + return response.getBody(); + } + + protected void setupStarfleetIndex() throws Exception { + boolean sendAdminCertificate = rh.sendAdminCertificate; + rh.sendAdminCertificate = true; + rh.executePutRequest("sf", null, new Header[0]); + rh.executePutRequest("sf/_doc/0", "{\"number\" : \"NCC-1701-D\"}", new Header[0]); + rh.executePutRequest("sf/_doc/0", "{\"some\" : \"value\"}", new Header[0]); + rh.sendAdminCertificate = sendAdminCertificate; + } + + protected void assertHealthy() throws Exception { + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_opendistro/_security/health?pretty").getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("admin", "admin")).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("admin", "admin")).getStatusCode() + ); + } + + protected Settings defaultNodeSettings(boolean enableRestSSL) { + Settings.Builder builder = Settings.builder(); + + if (enableRestSSL) { + builder.put("plugins.security.ssl.http.enabled", true) + .put( + "plugins.security.ssl.http.keystore_filepath", + FileHelper.getAbsoluteFilePathFromClassPath("restapi/node-0-keystore.jks") + ) + .put( + "plugins.security.ssl.http.truststore_filepath", + FileHelper.getAbsoluteFilePathFromClassPath("restapi/truststore.jks") + ); + } + return builder.build(); + } + + protected Map jsonStringToMap(String json) throws JsonParseException, JsonMappingException, IOException { + TypeReference> typeRef = new TypeReference>() { + }; + return DefaultObjectMapper.objectMapper.readValue(json, typeRef); + } + + protected static Collection> asCollection(Class... plugins) { + return Arrays.asList(plugins); + } + + String createRestAdminPermissionsPayload(String... additionPerms) throws JsonProcessingException { + final ObjectNode rootNode = (ObjectNode) DefaultObjectMapper.objectMapper.createObjectNode(); + rootNode.set("cluster_permissions", clusterPermissionsForRestAdmin(additionPerms)); + return DefaultObjectMapper.objectMapper.writeValueAsString(rootNode); + } + + ArrayNode clusterPermissionsForRestAdmin(String... additionPerms) { + final ArrayNode permissionsArray = (ArrayNode) DefaultObjectMapper.objectMapper.createArrayNode(); + for (final Map.Entry< + Endpoint, + RestApiAdminPrivilegesEvaluator.PermissionBuilder> entry : RestApiAdminPrivilegesEvaluator.ENDPOINTS_WITH_PERMISSIONS + .entrySet()) { + if (entry.getKey() == Endpoint.SSL) { + permissionsArray.add(entry.getValue().build("certs")).add(entry.getValue().build("reloadcerts")); + } else { + permissionsArray.add(entry.getValue().build()); + } + } + if (additionPerms.length != 0) { + Stream.of(additionPerms).forEach(permissionsArray::add); + } + return permissionsArray; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/AccountApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/AccountApiTest.java index 9f6bcb65c9..c07b0f1333 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/AccountApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/AccountApiTest.java @@ -29,13 +29,14 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class AccountApiTest extends AbstractRestApiUnitTest { - private final String BASE_ENDPOINT; - private final String ENDPOINT; + private final String BASE_ENDPOINT; + private final String ENDPOINT; + protected String getEndpointPrefix() { return PLUGINS_PREFIX; } - public AccountApiTest(){ + public AccountApiTest() { BASE_ENDPOINT = getEndpointPrefix() + "/api/"; ENDPOINT = getEndpointPrefix() + "/api/account"; } @@ -189,14 +190,16 @@ public void testPutAccountRetainsAccountInformation() throws Exception { final String testUsername = "test"; final String testPassword = "test-password"; final String newPassword = "new-password"; - final String createInternalUserPayload = "{\n" + - " \"password\": \"" + testPassword + "\",\n" + - " \"backend_roles\": [\"test-backend-role-1\"],\n" + - " \"opendistro_security_roles\": [\"opendistro_security_all_access\"],\n" + - " \"attributes\": {\n" + - " \"attribute1\": \"value1\"\n" + - " }\n" + - "}"; + final String createInternalUserPayload = "{\n" + + " \"password\": \"" + + testPassword + + "\",\n" + + " \"backend_roles\": [\"test-backend-role-1\"],\n" + + " \"opendistro_security_roles\": [\"opendistro_security_all_access\"],\n" + + " \"attributes\": {\n" + + " \"attribute1\": \"value1\"\n" + + " }\n" + + "}"; final String changePasswordPayload = "{\"password\":\"" + newPassword + "\", \"current_password\":\"" + testPassword + "\"}"; final String internalUserEndpoint = BASE_ENDPOINT + "internalusers/" + testUsername; @@ -215,9 +218,9 @@ public void testPutAccountRetainsAccountInformation() throws Exception { response = rh.executeGetRequest(internalUserEndpoint); assertEquals(HttpStatus.SC_OK, response.getStatusCode()); Settings responseBody = Settings.builder() - .loadFromSource(response.getBody(), XContentType.JSON) - .build() - .getAsSettings(testUsername); + .loadFromSource(response.getBody(), XContentType.JSON) + .build() + .getAsSettings(testUsername); assertTrue(responseBody.getAsList("backend_roles").contains("test-backend-role-1")); assertTrue(responseBody.getAsList("opendistro_security_roles").contains("opendistro_security_all_access")); assertEquals(responseBody.getAsSettings("attributes").get("attribute1"), "value1"); diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/ActionGroupsApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/ActionGroupsApiTest.java index 926ee23f28..c87698155f 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/ActionGroupsApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/ActionGroupsApiTest.java @@ -32,12 +32,13 @@ import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; public class ActionGroupsApiTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; + protected String getEndpointPrefix() { return PLUGINS_PREFIX; } - public ActionGroupsApiTest(){ + public ActionGroupsApiTest() { ENDPOINT = getEndpointPrefix() + "/api/actiongroups"; } @@ -69,7 +70,7 @@ public void testActionGroupsApi() throws Exception { void verifyGetForSuperAdmin(final Header[] header) throws Exception { // --- GET_UT // GET_UT, actiongroup exists - HttpResponse response = rh.executeGetRequest(ENDPOINT+"/CRUD_UT", header); + HttpResponse response = rh.executeGetRequest(ENDPOINT + "/CRUD_UT", header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); Settings settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); List permissions = settings.getAsList("CRUD_UT.allowed_actions"); @@ -79,7 +80,7 @@ void verifyGetForSuperAdmin(final Header[] header) throws Exception { Assert.assertTrue(permissions.contains("OPENDISTRO_SECURITY_WRITE")); // GET_UT, actiongroup does not exist - response = rh.executeGetRequest(ENDPOINT+"/nothinghthere", header); + response = rh.executeGetRequest(ENDPOINT + "/nothinghthere", header); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // GET_UT, old endpoint @@ -112,13 +113,13 @@ void verifyDeleteForSuperAdmin(final Header[] header, final boolean userAdminCer // Non-existing role rh.sendAdminCertificate = userAdminCert; - HttpResponse response = rh.executeDeleteRequest(ENDPOINT+"/idonotexist", header); + HttpResponse response = rh.executeDeleteRequest(ENDPOINT + "/idonotexist", header); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // remove action group READ_UT, read access not possible since // opendistro_security_role_starfleet // uses this action group. - response = rh.executeDeleteRequest(ENDPOINT+"/READ_UT", header); + response = rh.executeDeleteRequest(ENDPOINT + "/READ_UT", header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); rh.sendAdminCertificate = false; @@ -133,7 +134,7 @@ void verifyDeleteForSuperAdmin(final Header[] header, final boolean userAdminCer // now remove also CRUD_UT groups, write also not possible anymore rh.sendAdminCertificate = true; - response = rh.executeDeleteRequest(ENDPOINT+"/CRUD_UT", new Header[0]); + response = rh.executeDeleteRequest(ENDPOINT + "/CRUD_UT", new Header[0]); rh.sendAdminCertificate = false; checkWriteAccess(HttpStatus.SC_FORBIDDEN, "picard", "picardpicardpicard", "sf", "_doc", 0); checkReadAccess(HttpStatus.SC_FORBIDDEN, "picard", "picardpicardpicard", "sf", "_doc", 0); @@ -143,19 +144,18 @@ void verifyPutForSuperAdmin(final Header[] header, final boolean userAdminCert) // -- PUT // put with empty payload, must fail rh.sendAdminCertificate = userAdminCert; - HttpResponse response = rh.executePutRequest(ENDPOINT+"/SOMEGROUP", "", header); + HttpResponse response = rh.executePutRequest(ENDPOINT + "/SOMEGROUP", "", header); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Settings settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.PAYLOAD_MANDATORY.getMessage(), settings.get("reason")); // put new configuration with invalid payload, must fail - response = rh.executePutRequest(ENDPOINT+"/SOMEGROUP", FileHelper.loadFile("restapi/actiongroup_not_parseable.json"), - header); + response = rh.executePutRequest(ENDPOINT + "/SOMEGROUP", FileHelper.loadFile("restapi/actiongroup_not_parseable.json"), header); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.BODY_NOT_PARSEABLE.getMessage(), settings.get("reason")); - response = rh.executePutRequest(ENDPOINT+"/CRUD_UT", FileHelper.loadFile("restapi/actiongroup_crud.json"), header); + response = rh.executePutRequest(ENDPOINT + "/CRUD_UT", FileHelper.loadFile("restapi/actiongroup_crud.json"), header); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); rh.sendAdminCertificate = false; @@ -166,7 +166,7 @@ void verifyPutForSuperAdmin(final Header[] header, final boolean userAdminCert) // restore READ_UT action groups rh.sendAdminCertificate = userAdminCert; - response = rh.executePutRequest(ENDPOINT+"/READ_UT", FileHelper.loadFile("restapi/actiongroup_read.json"), header); + response = rh.executePutRequest(ENDPOINT + "/READ_UT", FileHelper.loadFile("restapi/actiongroup_read.json"), header); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); rh.sendAdminCertificate = false; @@ -176,49 +176,51 @@ void verifyPutForSuperAdmin(final Header[] header, final boolean userAdminCert) // -- PUT, new JSON format including readonly flag, disallowed in REST API rh.sendAdminCertificate = userAdminCert; - response = rh.executePutRequest(ENDPOINT+"/CRUD_UT", FileHelper.loadFile("restapi/actiongroup_readonly.json"), header); + response = rh.executePutRequest(ENDPOINT + "/CRUD_UT", FileHelper.loadFile("restapi/actiongroup_readonly.json"), header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); // -- DELETE read only resource, must be forbidden // superAdmin can delete read only resource rh.sendAdminCertificate = userAdminCert; - response = rh.executeDeleteRequest(ENDPOINT+"/GET_UT", header); + response = rh.executeDeleteRequest(ENDPOINT + "/GET_UT", header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); // -- PUT read only resource, must be forbidden // superAdmin can add/update read only resource rh.sendAdminCertificate = userAdminCert; - response = rh.executePutRequest(ENDPOINT+"/GET_UT", FileHelper.loadFile("restapi/actiongroup_read.json"), header); + response = rh.executePutRequest(ENDPOINT + "/GET_UT", FileHelper.loadFile("restapi/actiongroup_read.json"), header); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); Assert.assertFalse(response.getBody().contains("Resource 'GET_UT' is read-only.")); // PUT with role name rh.sendAdminCertificate = userAdminCert; - response = rh.executePutRequest(ENDPOINT+"/kibana_user", FileHelper.loadFile("restapi/actiongroup_read.json"), header); + response = rh.executePutRequest(ENDPOINT + "/kibana_user", FileHelper.loadFile("restapi/actiongroup_read.json"), header); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); - Assert.assertTrue(response.getBody().contains("kibana_user is an existing role. A action group cannot be named with an existing role name.")); + Assert.assertTrue( + response.getBody().contains("kibana_user is an existing role. A action group cannot be named with an existing role name.") + ); // PUT with self-referencing action groups rh.sendAdminCertificate = userAdminCert; - response = rh.executePutRequest(ENDPOINT+"/reference_itself", "{\"allowed_actions\": [\"reference_itself\"]}", header); + response = rh.executePutRequest(ENDPOINT + "/reference_itself", "{\"allowed_actions\": [\"reference_itself\"]}", header); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertTrue(response.getBody().contains("reference_itself cannot be an allowed_action of itself")); // -- GET_UT hidden resource, must be 404 but super admin can find it rh.sendAdminCertificate = userAdminCert; - response = rh.executeGetRequest(ENDPOINT+"/INTERNAL", header); + response = rh.executeGetRequest(ENDPOINT + "/INTERNAL", header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); Assert.assertTrue(response.getBody().contains("\"hidden\":true")); // -- DELETE hidden resource, must be 404 rh.sendAdminCertificate = userAdminCert; - response = rh.executeDeleteRequest(ENDPOINT+"/INTERNAL", header); + response = rh.executeDeleteRequest(ENDPOINT + "/INTERNAL", header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); Assert.assertTrue(response.getBody().contains("'INTERNAL' deleted.")); // -- PUT hidden resource, must be forbidden rh.sendAdminCertificate = userAdminCert; - response = rh.executePutRequest(ENDPOINT+"/INTERNAL", FileHelper.loadFile("restapi/actiongroup_read.json"), header); + response = rh.executePutRequest(ENDPOINT + "/INTERNAL", FileHelper.loadFile("restapi/actiongroup_read.json"), header); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); } @@ -226,52 +228,79 @@ void verifyPatchForSuperAdmin(final Header[] header, final boolean userAdminCert // -- PATCH // PATCH on non-existing resource rh.sendAdminCertificate = userAdminCert; - HttpResponse response = rh.executePatchRequest(ENDPOINT+"/imnothere", - "[{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }]", header); + HttpResponse response = rh.executePatchRequest( + ENDPOINT + "/imnothere", + "[{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }]", + header + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // PATCH read only resource, must be forbidden // SuperAdmin can patch read only resource rh.sendAdminCertificate = userAdminCert; - response = rh.executePatchRequest(ENDPOINT+"/GET_UT", "[{ \"op\": \"add\", \"path\": \"/description\", \"value\": \"foo\" }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/GET_UT", + "[{ \"op\": \"add\", \"path\": \"/description\", \"value\": \"foo\" }]", + header + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); // PATCH with self-referencing action groups rh.sendAdminCertificate = userAdminCert; - response = rh.executePatchRequest(ENDPOINT+"/GET_UT", "[{ \"op\": \"add\", \"path\": \"/allowed_actions/-\", \"value\": \"GET_UT\" }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/GET_UT", + "[{ \"op\": \"add\", \"path\": \"/allowed_actions/-\", \"value\": \"GET_UT\" }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertTrue(response.getBody().contains("GET_UT cannot be an allowed_action of itself")); // bulk PATCH with self-referencing action groups - response = rh.executePatchRequest(ENDPOINT, "[{ \"op\": \"add\", \"path\": \"/BULKNEW1\", \"value\": {\"allowed_actions\": [\"BULKNEW1\"] } }," + - "{ \"op\": \"add\", \"path\": \"/BULKNEW2\", \"value\": {\"allowed_actions\": [\"READ_UT\"] } }]", header); + response = rh.executePatchRequest( + ENDPOINT, + "[{ \"op\": \"add\", \"path\": \"/BULKNEW1\", \"value\": {\"allowed_actions\": [\"BULKNEW1\"] } }," + + "{ \"op\": \"add\", \"path\": \"/BULKNEW2\", \"value\": {\"allowed_actions\": [\"READ_UT\"] } }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertTrue(response.getBody().contains("BULKNEW1 cannot be an allowed_action of itself")); // PATCH hidden resource, must be not found, can be found by superadmin, but fails with no path exist error rh.sendAdminCertificate = userAdminCert; - response = rh.executePatchRequest(ENDPOINT+"/INTERNAL", - "[{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/INTERNAL", + "[{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // PATCH value of hidden flag, must fail with validation error rh.sendAdminCertificate = userAdminCert; - response = rh.executePatchRequest(ENDPOINT+"/CRUD_UT", "[{ \"op\": \"add\", \"path\": \"/hidden\", \"value\": true }]", header); + response = rh.executePatchRequest(ENDPOINT + "/CRUD_UT", "[{ \"op\": \"add\", \"path\": \"/hidden\", \"value\": true }]", header); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); - Assert.assertTrue(response.getBody(), response.getBody().matches(".*\"invalid_keys\"\\s*:\\s*\\{\\s*\"keys\"\\s*:\\s*\"hidden\"\\s*\\}.*")); + Assert.assertTrue( + response.getBody(), + response.getBody().matches(".*\"invalid_keys\"\\s*:\\s*\\{\\s*\"keys\"\\s*:\\s*\"hidden\"\\s*\\}.*") + ); // PATCH with relative JSON pointer, must fail rh.sendAdminCertificate = userAdminCert; - response = rh.executePatchRequest(ENDPOINT+"/CRUD_UT", "[{ \"op\": \"add\", \"path\": \"1/INTERNAL/allowed_actions/-\", " + - "\"value\": \"OPENDISTRO_SECURITY_DELETE\" }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/CRUD_UT", + "[{ \"op\": \"add\", \"path\": \"1/INTERNAL/allowed_actions/-\", " + "\"value\": \"OPENDISTRO_SECURITY_DELETE\" }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // PATCH new format rh.sendAdminCertificate = userAdminCert; - response = rh.executePatchRequest(ENDPOINT+"/CRUD_UT", "[{ \"op\": \"add\", \"path\": \"/allowed_actions/-\", " + - "\"value\": \"OPENDISTRO_SECURITY_DELETE\" }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/CRUD_UT", + "[{ \"op\": \"add\", \"path\": \"/allowed_actions/-\", " + "\"value\": \"OPENDISTRO_SECURITY_DELETE\" }]", + header + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - response = rh.executeGetRequest(ENDPOINT+"/CRUD_UT", header); + response = rh.executeGetRequest(ENDPOINT + "/CRUD_UT", header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); Settings settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); List permissions = settings.getAsList("CRUD_UT.allowed_actions"); @@ -281,12 +310,15 @@ void verifyPatchForSuperAdmin(final Header[] header, final boolean userAdminCert Assert.assertTrue(permissions.contains("OPENDISTRO_SECURITY_WRITE")); Assert.assertTrue(permissions.contains("OPENDISTRO_SECURITY_DELETE")); - // -- PATCH on whole config resource // PATCH read only resource, must be forbidden // SuperAdmin can patch read only resource rh.sendAdminCertificate = userAdminCert; - response = rh.executePatchRequest(ENDPOINT, "[{ \"op\": \"add\", \"path\": \"/GET_UT/a\", \"value\": [ \"foo\", \"bar\" ] }]", header); + response = rh.executePatchRequest( + ENDPOINT, + "[{ \"op\": \"add\", \"path\": \"/GET_UT/a\", \"value\": [ \"foo\", \"bar\" ] }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); rh.sendAdminCertificate = userAdminCert; @@ -295,7 +327,11 @@ void verifyPatchForSuperAdmin(final Header[] header, final boolean userAdminCert // PATCH hidden resource, must be bad request rh.sendAdminCertificate = userAdminCert; - response = rh.executePatchRequest(ENDPOINT, "[{ \"op\": \"add\", \"path\": \"/INTERNAL/a\", \"value\": [ \"foo\", \"bar\" ] }]", header); + response = rh.executePatchRequest( + ENDPOINT, + "[{ \"op\": \"add\", \"path\": \"/INTERNAL/a\", \"value\": [ \"foo\", \"bar\" ] }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // PATCH delete read only resource, must be forbidden @@ -310,7 +346,6 @@ void verifyPatchForSuperAdmin(final Header[] header, final boolean userAdminCert Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); Assert.assertTrue(response.getBody().contains("\"message\":\"Resource updated.")); - // PATCH value of hidden flag, must fail with validation error rh.sendAdminCertificate = userAdminCert; response = rh.executePatchRequest(ENDPOINT, "[{ \"op\": \"add\", \"path\": \"/CRUD_UT/hidden\", \"value\": true }]", header); @@ -319,16 +354,24 @@ void verifyPatchForSuperAdmin(final Header[] header, final boolean userAdminCert // add new resource with hidden flag, must fail with validation error rh.sendAdminCertificate = userAdminCert; - response = rh.executePatchRequest(ENDPOINT, - "[{ \"op\": \"add\", \"path\": \"/NEWNEWNEW\", \"value\": {\"allowed_actions\": [\"indices:data/write*\"], \"hidden\":true }}]", header); + response = rh.executePatchRequest( + ENDPOINT, + "[{ \"op\": \"add\", \"path\": \"/NEWNEWNEW\", \"value\": {\"allowed_actions\": [\"indices:data/write*\"], \"hidden\":true }}]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertTrue(response.getBody().matches(".*\"invalid_keys\"\\s*:\\s*\\{\\s*\"keys\"\\s*:\\s*\"hidden\"\\s*\\}.*")); // add new valid resources rh.sendAdminCertificate = userAdminCert; - response = rh.executePatchRequest(ENDPOINT, "[{ \"op\": \"add\", \"path\": \"/BULKNEW1\", \"value\": {\"allowed_actions\": [\"indices:data/*\", \"cluster:monitor/*\"] } }," + "{ \"op\": \"add\", \"path\": \"/BULKNEW2\", \"value\": {\"allowed_actions\": [\"READ_UT\"] } }]", header); + response = rh.executePatchRequest( + ENDPOINT, + "[{ \"op\": \"add\", \"path\": \"/BULKNEW1\", \"value\": {\"allowed_actions\": [\"indices:data/*\", \"cluster:monitor/*\"] } }," + + "{ \"op\": \"add\", \"path\": \"/BULKNEW2\", \"value\": {\"allowed_actions\": [\"READ_UT\"] } }]", + header + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - response = rh.executeGetRequest(ENDPOINT+"/BULKNEW1", header); + response = rh.executeGetRequest(ENDPOINT + "/BULKNEW1", header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); permissions = settings.getAsList("BULKNEW1.allowed_actions"); @@ -337,7 +380,7 @@ void verifyPatchForSuperAdmin(final Header[] header, final boolean userAdminCert Assert.assertTrue(permissions.contains("indices:data/*")); Assert.assertTrue(permissions.contains("cluster:monitor/*")); - response = rh.executeGetRequest(ENDPOINT+"/BULKNEW2", header); + response = rh.executeGetRequest(ENDPOINT + "/BULKNEW2", header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); permissions = settings.getAsList("BULKNEW2.allowed_actions"); @@ -348,11 +391,11 @@ void verifyPatchForSuperAdmin(final Header[] header, final boolean userAdminCert // delete resource response = rh.executePatchRequest(ENDPOINT, "[{ \"op\": \"remove\", \"path\": \"/BULKNEW1\" }]", header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - response = rh.executeGetRequest(ENDPOINT+"/BULKNEW1", header); + response = rh.executeGetRequest(ENDPOINT + "/BULKNEW1", header); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // assert other resource is still there - response = rh.executeGetRequest(ENDPOINT+"/BULKNEW2", header); + response = rh.executeGetRequest(ENDPOINT + "/BULKNEW2", header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); permissions = settings.getAsList("BULKNEW2.allowed_actions"); @@ -373,10 +416,10 @@ public void testActionGroupsApiForRestAdmin() throws Exception { addUserWithPassword("picard", "picardpicardpicard", new String[] { "starfleet" }, HttpStatus.SC_CREATED); checkReadAccess(HttpStatus.SC_OK, "picard", "picardpicardpicard", "sf", "_doc", 0); checkWriteAccess(HttpStatus.SC_FORBIDDEN, "picard", "picardpicardpicard", "sf", "_doc", 0); - verifyGetForSuperAdmin(new Header[] {restApiAdminHeader}); - verifyDeleteForSuperAdmin(new Header[]{restApiAdminHeader}, false); - verifyPutForSuperAdmin(new Header[]{restApiAdminHeader}, false); - verifyPatchForSuperAdmin(new Header[]{restApiAdminHeader}, false); + verifyGetForSuperAdmin(new Header[] { restApiAdminHeader }); + verifyDeleteForSuperAdmin(new Header[] { restApiAdminHeader }, false); + verifyPutForSuperAdmin(new Header[] { restApiAdminHeader }, false); + verifyPatchForSuperAdmin(new Header[] { restApiAdminHeader }, false); } @Test @@ -391,10 +434,10 @@ public void testActionGroupsApiForActionGroupsRestApiAdmin() throws Exception { addUserWithPassword("picard", "picardpicardpicard", new String[] { "starfleet" }, HttpStatus.SC_CREATED); checkReadAccess(HttpStatus.SC_OK, "picard", "picardpicardpicard", "sf", "_doc", 0); checkWriteAccess(HttpStatus.SC_FORBIDDEN, "picard", "picardpicardpicard", "sf", "_doc", 0); - verifyGetForSuperAdmin(new Header[] {restApiAdminActionGroupsHeader}); - verifyDeleteForSuperAdmin(new Header[]{restApiAdminActionGroupsHeader}, false); - verifyPutForSuperAdmin(new Header[]{restApiAdminActionGroupsHeader}, false); - verifyPatchForSuperAdmin(new Header[]{restApiAdminActionGroupsHeader}, false); + verifyGetForSuperAdmin(new Header[] { restApiAdminActionGroupsHeader }); + verifyDeleteForSuperAdmin(new Header[] { restApiAdminActionGroupsHeader }, false); + verifyPutForSuperAdmin(new Header[] { restApiAdminActionGroupsHeader }, false); + verifyPatchForSuperAdmin(new Header[] { restApiAdminActionGroupsHeader }, false); } @Test @@ -405,8 +448,7 @@ public void testCreateActionGroupWithRestAdminPermissionsForbidden() throws Exce final Header restApiAdminActionGroupsHeader = encodeBasicHeader("rest_api_admin_actiongroups", "rest_api_admin_actiongroups"); final Header restApiHeader = encodeBasicHeader("test", "test"); - HttpResponse response = rh.executePutRequest(ENDPOINT + "/rest_api_admin_group", restAdminAllowedActions(), - restApiAdminHeader); + HttpResponse response = rh.executePutRequest(ENDPOINT + "/rest_api_admin_group", restAdminAllowedActions(), restApiAdminHeader); Assert.assertEquals(response.getBody(), HttpStatus.SC_FORBIDDEN, response.getStatusCode()); response = rh.executePutRequest(ENDPOINT + "/rest_api_admin_group", restAdminAllowedActions(), restApiAdminActionGroupsHeader); Assert.assertEquals(response.getBody(), HttpStatus.SC_FORBIDDEN, response.getStatusCode()); @@ -432,10 +474,7 @@ String restAdminPatchBody() throws JsonProcessingException { final ObjectNode opAddRootNode = DefaultObjectMapper.objectMapper.createObjectNode(); final ObjectNode allowedActionsNode = DefaultObjectMapper.objectMapper.createObjectNode(); allowedActionsNode.set("allowed_actions", clusterPermissionsForRestAdmin("cluster/*")); - opAddRootNode - .put("op", "add") - .put("path", "/rest_api_admin_group") - .set("value", allowedActionsNode); + opAddRootNode.put("op", "add").put("path", "/rest_api_admin_group").set("value", allowedActionsNode); rootNode.add(opAddRootNode); return DefaultObjectMapper.objectMapper.writeValueAsString(rootNode); } @@ -452,44 +491,60 @@ public void testActionGroupsApiForNonSuperAdmin() throws Exception { HttpResponse response; // Delete read only actiongroups - response = rh.executeDeleteRequest(ENDPOINT+"/create_index" , new Header[0]); + response = rh.executeDeleteRequest(ENDPOINT + "/create_index", new Header[0]); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // Put read only actiongroups - response = rh.executePutRequest(ENDPOINT+"/create_index", FileHelper.loadFile("restapi/actiongroup_crud.json"), new Header[0]); + response = rh.executePutRequest(ENDPOINT + "/create_index", FileHelper.loadFile("restapi/actiongroup_crud.json"), new Header[0]); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // Patch single read only actiongroups - response = rh.executePatchRequest(ENDPOINT+"/create_index", "[{ \"op\": \"replace\", \"path\": \"/description\", \"value\": \"foo\" }]", new Header[0]); + response = rh.executePatchRequest( + ENDPOINT + "/create_index", + "[{ \"op\": \"replace\", \"path\": \"/description\", \"value\": \"foo\" }]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // Patch multiple read only actiongroups - response = rh.executePatchRequest(ENDPOINT, "[{ \"op\": \"replace\", \"path\": \"/create_index/description\", \"value\": \"foo\" }]", new Header[0]); + response = rh.executePatchRequest( + ENDPOINT, + "[{ \"op\": \"replace\", \"path\": \"/create_index/description\", \"value\": \"foo\" }]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); - response = rh.executeGetRequest(ENDPOINT+"/INTERNAL" , new Header[0]); + response = rh.executeGetRequest(ENDPOINT + "/INTERNAL", new Header[0]); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // Delete hidden actiongroups - response = rh.executeDeleteRequest(ENDPOINT+"/INTERNAL" , new Header[0]); + response = rh.executeDeleteRequest(ENDPOINT + "/INTERNAL", new Header[0]); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // Put hidden actiongroups - response = rh.executePutRequest(ENDPOINT+"/INTERNAL", FileHelper.loadFile("restapi/actiongroup_crud.json"), new Header[0]); + response = rh.executePutRequest(ENDPOINT + "/INTERNAL", FileHelper.loadFile("restapi/actiongroup_crud.json"), new Header[0]); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // Patch hidden actiongroups - response = rh.executePatchRequest(ENDPOINT+"/INTERNAL", "[{ \"op\": \"replace\", \"path\": \"/description\", \"value\": \"foo\" }]", new Header[0]); + response = rh.executePatchRequest( + ENDPOINT + "/INTERNAL", + "[{ \"op\": \"replace\", \"path\": \"/description\", \"value\": \"foo\" }]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // Patch multiple hidden actiongroups - response = rh.executePatchRequest(ENDPOINT, "[{ \"op\": \"replace\", \"path\": \"/INTERNAL/description\", \"value\": \"foo\" }]", new Header[0]); + response = rh.executePatchRequest( + ENDPOINT, + "[{ \"op\": \"replace\", \"path\": \"/INTERNAL/description\", \"value\": \"foo\" }]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); } @Test - public void checkNullElementsInArray() throws Exception{ + public void checkNullElementsInArray() throws Exception { setup(); rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; 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 50090fcfcc..79ce591723 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 @@ -11,7 +11,6 @@ package org.opensearch.security.dlic.rest.api; - import java.util.Map; import java.util.stream.Collectors; @@ -60,24 +59,32 @@ public class AllowlistApiTest extends AbstractRestApiUnitTest { * * @throws Exception */ - private void checkGetAndPutAllowlistPermissions(final int expectedStatus, final boolean sendAdminCertificate, final Header... headers) throws Exception { + private void checkGetAndPutAllowlistPermissions(final int expectedStatus, final boolean sendAdminCertificate, final Header... headers) + throws Exception { final boolean prevSendAdminCertificate = rh.sendAdminCertificate; rh.sendAdminCertificate = sendAdminCertificate; - //CHECK GET REQUEST + // CHECK GET REQUEST response = rh.executeGetRequest(ENDPOINT, headers); assertThat(response.getBody(), response.getStatusCode(), equalTo(expectedStatus)); if (expectedStatus == HttpStatus.SC_OK) { - //Note: the response has no whitespaces, so the .json file does not have whitespaces - Assert.assertEquals(FileHelper.loadFile("restapi/whitelist_response_success.json"), FileHelper.loadFile("restapi/whitelist_response_success.json")); + // Note: the response has no whitespaces, so the .json file does not have whitespaces + Assert.assertEquals( + FileHelper.loadFile("restapi/whitelist_response_success.json"), + FileHelper.loadFile("restapi/whitelist_response_success.json") + ); } - //FORBIDDEN FOR NON SUPER ADMIN + // FORBIDDEN FOR NON SUPER ADMIN if (expectedStatus == HttpStatus.SC_FORBIDDEN) { assertTrue(response.getBody().contains("API allowed only for super admin.")); } - //CHECK PUT REQUEST - response = rh.executePutRequest(ENDPOINT, "{\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}", headers); + // CHECK PUT REQUEST + response = rh.executePutRequest( + ENDPOINT, + "{\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}", + headers + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(expectedStatus)); rh.sendAdminCertificate = prevSendAdminCertificate; @@ -100,7 +107,10 @@ public void testPutUnknownKey() throws Exception { setup(); rh.sendAdminCertificate = true; - RestHelper.HttpResponse response = rh.executePutRequest(ENDPOINT, "{ \"unknownkey\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}"); + RestHelper.HttpResponse response = rh.executePutRequest( + ENDPOINT, + "{ \"unknownkey\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}" + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); assertTrue(response.getBody().contains("invalid_keys")); assertHealthy(); @@ -111,7 +121,10 @@ public void testPutInvalidJson() throws Exception { setup(); rh.sendAdminCertificate = true; - RestHelper.HttpResponse response = rh.executePutRequest(ENDPOINT, "{ \"invalid\"::{{ [\"*\"], \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}"); + RestHelper.HttpResponse response = rh.executePutRequest( + ENDPOINT, + "{ \"invalid\"::{{ [\"*\"], \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}" + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); assertHealthy(); } @@ -147,7 +160,7 @@ public void testAllowlistApi() throws Exception { // No creds, no admin certificate - UNAUTHORIZED checkGetAndPutAllowlistPermissions(HttpStatus.SC_UNAUTHORIZED, false); - //non admin creds, no admin certificate - FORBIDDEN + // non admin creds, no admin certificate - FORBIDDEN checkGetAndPutAllowlistPermissions(HttpStatus.SC_FORBIDDEN, false, nonAdminCredsHeader); // admin creds, no admin certificate - FORBIDDEN @@ -183,37 +196,45 @@ public void testAllowlistApiWithAllowListPermissions() throws Exception { @Test public void testAllowlistAuditComplianceLogging() throws Exception { Settings settings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_LOG_DIFFS, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) - .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_LOG_DIFFS, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) + .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .build(); setupWithRestRoles(settings); TestAuditlogImpl.clear(); // any creds, admin certificate - OK checkGetAndPutAllowlistPermissions(HttpStatus.SC_OK, true, nonAdminCredsHeader); - //TESTS THAT 1 READ AND 1 WRITE HAPPENS IN testGetAndPut() + // TESTS THAT 1 READ AND 1 WRITE HAPPENS IN testGetAndPut() final Map expectedCategoryCounts = ImmutableMap.of( - AuditCategory.COMPLIANCE_INTERNAL_CONFIG_READ, 1L, - AuditCategory.COMPLIANCE_INTERNAL_CONFIG_WRITE, 1L); - Map actualCategoryCounts = TestAuditlogImpl.messages.stream().collect(Collectors.groupingBy(AuditMessage::getCategory, Collectors.counting())); + AuditCategory.COMPLIANCE_INTERNAL_CONFIG_READ, + 1L, + AuditCategory.COMPLIANCE_INTERNAL_CONFIG_WRITE, + 1L + ); + Map actualCategoryCounts = TestAuditlogImpl.messages.stream() + .collect(Collectors.groupingBy(AuditMessage::getCategory, Collectors.counting())); assertThat(actualCategoryCounts, equalTo(expectedCategoryCounts)); } @Test - public void testAllowlistInvalidHttpRequestMethod() throws Exception{ + public void testAllowlistInvalidHttpRequestMethod() throws Exception { setup(); rh.sendAdminCertificate = true; - response = rh.executePutRequest(ENDPOINT, "{\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GE\"],\"/_cat/indices\": [\"PUT\"] }}", adminCredsHeader); + response = rh.executePutRequest( + ENDPOINT, + "{\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GE\"],\"/_cat/indices\": [\"PUT\"] }}", + adminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_INTERNAL_SERVER_ERROR)); assertTrue(response.getBody().contains("\\\"GE\\\": not one of the values accepted for Enum class")); } @@ -226,37 +247,53 @@ public void testAllowlistInvalidHttpRequestMethod() throws Exception{ * @throws Exception */ @Test - public void testPatchApi() throws Exception{ + public void testPatchApi() throws Exception { setup(); rh.sendAdminCertificate = true; - //PATCH entire config entry - response = rh.executePatchRequest(ENDPOINT, "[{ \"op\": \"replace\", \"path\": \"/config\", \"value\": {\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"PUT\"] }}}]", new Header[0]); + // PATCH entire config entry + response = rh.executePatchRequest( + ENDPOINT, + "[{ \"op\": \"replace\", \"path\": \"/config\", \"value\": {\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"PUT\"] }}}]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executeGetRequest(ENDPOINT, adminCredsHeader); - assertEquals(response.getBody(),"{\"config\":{\"enabled\":true,\"requests\":{\"/_cat/nodes\":[\"GET\"],\"/_cat/indices\":[\"PUT\"]}}}"); - - //PATCH just requests - response = rh.executePatchRequest(ENDPOINT, "[{ \"op\": \"replace\", \"path\": \"/config/requests\", \"value\": {\"/_cat/nodes\": [\"GET\"]}}]", new Header[0]); + assertEquals( + response.getBody(), + "{\"config\":{\"enabled\":true,\"requests\":{\"/_cat/nodes\":[\"GET\"],\"/_cat/indices\":[\"PUT\"]}}}" + ); + + // PATCH just requests + response = rh.executePatchRequest( + ENDPOINT, + "[{ \"op\": \"replace\", \"path\": \"/config/requests\", \"value\": {\"/_cat/nodes\": [\"GET\"]}}]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executeGetRequest(ENDPOINT, adminCredsHeader); assertTrue(response.getBody().contains("\"requests\":{\"/_cat/nodes\":[\"GET\"]}")); - //PATCH just allowlisted_enabled using "replace" operation - works when enabled is already true - response = rh.executePatchRequest(ENDPOINT, "[{ \"op\": \"replace\", \"path\": \"/config/enabled\", \"value\": false}]", new Header[0]); + // PATCH just allowlisted_enabled using "replace" operation - works when enabled is already true + response = rh.executePatchRequest( + ENDPOINT, + "[{ \"op\": \"replace\", \"path\": \"/config/enabled\", \"value\": false}]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executeGetRequest(ENDPOINT, adminCredsHeader); assertTrue(response.getBody().contains("\"enabled\":false")); - //PATCH just enabled using "add" operation when it is currently false - works correctly + // PATCH just enabled using "add" operation when it is currently false - works correctly response = rh.executePatchRequest(ENDPOINT, "[{ \"op\": \"add\", \"path\": \"/config/enabled\", \"value\": true}]", new Header[0]); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executeGetRequest(ENDPOINT, adminCredsHeader); assertTrue(response.getBody().contains("\"enabled\":true")); - //PATCH just enabled using "add" operation when it is currently true - works correctly + // PATCH just enabled using "add" operation when it is currently true - works correctly response = rh.executePatchRequest(ENDPOINT, "[{ \"op\": \"add\", \"path\": \"/config/enabled\", \"value\": false}]", new Header[0]); - Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode());response = rh.executeGetRequest(ENDPOINT, adminCredsHeader); + Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); + response = rh.executeGetRequest(ENDPOINT, adminCredsHeader); response = rh.executeGetRequest(ENDPOINT, adminCredsHeader); assertTrue(response.getBody().contains("\"enabled\":false")); } 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 450a5de83b..3f97bae693 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 @@ -51,13 +51,14 @@ public class AuditApiActionTest extends AbstractRestApiUnitTest { // non-admin final Header nonAdminCredsHeader = encodeBasicHeader("random", "random"); - private final String ENDPOINT; + private final String ENDPOINT; private final String CONFIG_ENDPOINT; + protected String getEndpointPrefix() { return PLUGINS_PREFIX; } - public AuditApiActionTest(){ + public AuditApiActionTest() { ENDPOINT = getEndpointPrefix() + "/api/audit"; CONFIG_ENDPOINT = ENDPOINT + "/config"; } @@ -106,16 +107,18 @@ public void testDisabledCategoryOrder() throws Exception { setup(); final List testCategories = ImmutableList.of("SSL_EXCEPTION", "AUTHENTICATED", "BAD_HEADERS"); - final AuditConfig auditConfig = new AuditConfig(true, AuditConfig.Filter.from( - ImmutableMap.of("disabled_rest_categories", testCategories) - ), ComplianceConfig.DEFAULT); + final AuditConfig auditConfig = new AuditConfig( + true, + AuditConfig.Filter.from(ImmutableMap.of("disabled_rest_categories", testCategories)), + ComplianceConfig.DEFAULT + ); final ObjectNode json = DefaultObjectMapper.objectMapper.valueToTree(auditConfig); testPutRequest(json, HttpStatus.SC_OK, true); RestHelper.HttpResponse response = rh.executeGetRequest(ENDPOINT, adminCredsHeader); List actual = Streams.stream(readTree(response.getBody()).at("/config/audit/disabled_rest_categories").iterator()) - .map(JsonNode::textValue) - .collect(Collectors.toList()); + .map(JsonNode::textValue) + .collect(Collectors.toList()); assertEquals(testCategories, actual); } @@ -125,36 +128,69 @@ public void testInvalidDisabledCategories() throws Exception { rh.sendAdminCertificate = true; // test bad request for REST disabled categories - AuditConfig auditConfig = new AuditConfig(true, AuditConfig.Filter.from( - ImmutableMap.of("disabled_rest_categories", ImmutableList.of("INDEX_EVENT", "COMPLIANCE_DOC_READ")) - ), ComplianceConfig.DEFAULT); + AuditConfig auditConfig = new AuditConfig( + true, + AuditConfig.Filter.from(ImmutableMap.of("disabled_rest_categories", ImmutableList.of("INDEX_EVENT", "COMPLIANCE_DOC_READ"))), + ComplianceConfig.DEFAULT + ); ObjectNode json = DefaultObjectMapper.objectMapper.valueToTree(auditConfig); RestHelper.HttpResponse response = rh.executePutRequest(CONFIG_ENDPOINT, writeValueAsString(json, false)); assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // test success for REST disabled categories - auditConfig = new AuditConfig(true, AuditConfig.Filter.from( - ImmutableMap.of("disabled_rest_categories", - ImmutableList.of("BAD_HEADERS", "SSL_EXCEPTION", "AUTHENTICATED", "FAILED_LOGIN", "GRANTED_PRIVILEGES", "MISSING_PRIVILEGES")) - ), ComplianceConfig.DEFAULT); + auditConfig = new AuditConfig( + true, + AuditConfig.Filter.from( + ImmutableMap.of( + "disabled_rest_categories", + ImmutableList.of( + "BAD_HEADERS", + "SSL_EXCEPTION", + "AUTHENTICATED", + "FAILED_LOGIN", + "GRANTED_PRIVILEGES", + "MISSING_PRIVILEGES" + ) + ) + ), + ComplianceConfig.DEFAULT + ); json = DefaultObjectMapper.objectMapper.valueToTree(auditConfig); response = rh.executePutRequest(CONFIG_ENDPOINT, writeValueAsString(json, false)); assertEquals(HttpStatus.SC_OK, response.getStatusCode()); // test bad request for transport disabled categories - auditConfig = new AuditConfig(true, AuditConfig.Filter.from( - ImmutableMap.of("disabled_transport_categories", - ImmutableList.of("COMPLIANCE_DOC_READ", "COMPLIANCE_DOC_WRITE")) - ), ComplianceConfig.DEFAULT); + auditConfig = new AuditConfig( + true, + AuditConfig.Filter.from( + ImmutableMap.of("disabled_transport_categories", ImmutableList.of("COMPLIANCE_DOC_READ", "COMPLIANCE_DOC_WRITE")) + ), + ComplianceConfig.DEFAULT + ); json = DefaultObjectMapper.objectMapper.valueToTree(auditConfig); response = rh.executePutRequest(CONFIG_ENDPOINT, writeValueAsString(json, false)); assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // test success for transport disabled categories - auditConfig = new AuditConfig(true, AuditConfig.Filter.from( - ImmutableMap.of("disabled_transport_categories", - ImmutableList.of("BAD_HEADERS", "SSL_EXCEPTION", "AUTHENTICATED", "FAILED_LOGIN", "GRANTED_PRIVILEGES", "MISSING_PRIVILEGES", "INDEX_EVENT", "OPENDISTRO_SECURITY_INDEX_ATTEMPT")) - ), ComplianceConfig.DEFAULT); + auditConfig = new AuditConfig( + true, + AuditConfig.Filter.from( + ImmutableMap.of( + "disabled_transport_categories", + ImmutableList.of( + "BAD_HEADERS", + "SSL_EXCEPTION", + "AUTHENTICATED", + "FAILED_LOGIN", + "GRANTED_PRIVILEGES", + "MISSING_PRIVILEGES", + "INDEX_EVENT", + "OPENDISTRO_SECURITY_INDEX_ATTEMPT" + ) + ) + ), + ComplianceConfig.DEFAULT + ); json = DefaultObjectMapper.objectMapper.valueToTree(auditConfig); response = rh.executePutRequest(CONFIG_ENDPOINT, writeValueAsString(json, false)); assertEquals(HttpStatus.SC_OK, response.getStatusCode()); @@ -162,7 +198,12 @@ public void testInvalidDisabledCategories() throws Exception { @Test public void testReadonlyApi() throws Exception { - final List readonlyFields = ImmutableList.of("/audit/enable_rest", "/audit/disabled_rest_categories", "/audit/ignore_requests", "/compliance/read_watched_fields"); + final List readonlyFields = ImmutableList.of( + "/audit/enable_rest", + "/audit/disabled_rest_categories", + "/audit/ignore_requests", + "/compliance/read_watched_fields" + ); updateStaticResourceReadonly(readonlyFields); setupWithRestRoles(null); @@ -172,8 +213,8 @@ public void testReadonlyApi() throws Exception { RestHelper.HttpResponse response = rh.executeGetRequest(ENDPOINT, adminCredsHeader); assertEquals(HttpStatus.SC_OK, response.getStatusCode()); List actual = Streams.stream(readTree(response.getBody()).get("_readonly").iterator()) - .map(JsonNode::textValue) - .collect(Collectors.toList()); + .map(JsonNode::textValue) + .collect(Collectors.toList()); assertEquals(readonlyFields, actual); // test config @@ -209,13 +250,15 @@ public void testReadonlyApi() throws Exception { private void updateStaticResourceReadonly(List readonly) throws IOException { // create audit config - final Map result = ImmutableMap.of( - AuditApiAction.READONLY_FIELD, readonly + final Map result = ImmutableMap.of(AuditApiAction.READONLY_FIELD, readonly); + DefaultObjectMapper.YAML_MAPPER.writeValue( + FileHelper.getAbsoluteFilePathFromClassPath(AuditApiAction.STATIC_RESOURCE.substring(1)).toFile(), + result ); - DefaultObjectMapper.YAML_MAPPER.writeValue(FileHelper.getAbsoluteFilePathFromClassPath(AuditApiAction.STATIC_RESOURCE.substring(1)).toFile(), result); } - private void testPutRequest(final JsonNode json, final int expectedStatus, final boolean sendAdminCertificate, final Header... header) throws Exception { + private void testPutRequest(final JsonNode json, final int expectedStatus, final boolean sendAdminCertificate, final Header... header) + throws Exception { rh.sendAdminCertificate = sendAdminCertificate; RestHelper.HttpResponse response = rh.executePutRequest(CONFIG_ENDPOINT, writeValueAsString(json, false), header); assertEquals(expectedStatus, response.getStatusCode()); @@ -223,12 +266,12 @@ private void testPutRequest(final JsonNode json, final int expectedStatus, final private void testReadonlyBoolean(final ObjectNode json, final String config, final String resource) throws Exception { final String resourcePath = "/config" + config + "/" + resource; - ((ObjectNode)json.at(config)).put(resource, true); + ((ObjectNode) json.at(config)).put(resource, true); testPutRequest(json, HttpStatus.SC_OK, true); - ((ObjectNode)json.at(config)).put(resource, false); + ((ObjectNode) json.at(config)).put(resource, false); testPutRequest(json, HttpStatus.SC_CONFLICT, false, adminCredsHeader); testBooleanPatch(resourcePath, false, HttpStatus.SC_CONFLICT, adminCredsHeader); - ((ObjectNode)json.at(config)).put(resource, true); + ((ObjectNode) json.at(config)).put(resource, true); testPutRequest(json, HttpStatus.SC_OK, true); testBooleanPatch(resourcePath, true, HttpStatus.SC_OK, adminCredsHeader); testBooleanPatch(resourcePath, true, HttpStatus.SC_OK, adminCredsHeader); @@ -236,79 +279,96 @@ private void testReadonlyBoolean(final ObjectNode json, final String config, fin private void testReadonlyList(final ObjectNode json, final String config, final String resource) throws Exception { final String resourcePath = "/config" + config + "/" + resource; - ((ObjectNode)json.at(config)).putPOJO(resource, ImmutableList.of("test-resource-1", "test-resource-2")); + ((ObjectNode) json.at(config)).putPOJO(resource, ImmutableList.of("test-resource-1", "test-resource-2")); testPutRequest(json, HttpStatus.SC_OK, true); // change order List testList = ImmutableList.of("test-resource-2", "test-resource-1"); - ((ObjectNode)json.at(config)).putPOJO(resource, testList); + ((ObjectNode) json.at(config)).putPOJO(resource, testList); testPutRequest(json, HttpStatus.SC_CONFLICT, false, adminCredsHeader); testList(resourcePath, testList, HttpStatus.SC_CONFLICT, adminCredsHeader); // change values testList = ImmutableList.of("test-resource-3", "test-resource-4"); - ((ObjectNode)json.at(config)).putPOJO(resource, testList); + ((ObjectNode) json.at(config)).putPOJO(resource, testList); testPutRequest(json, HttpStatus.SC_CONFLICT, false, adminCredsHeader); testList(resourcePath, testList, HttpStatus.SC_CONFLICT, adminCredsHeader); // change values testList = Collections.emptyList(); - ((ObjectNode)json.at(config)).putPOJO(resource, testList); + ((ObjectNode) json.at(config)).putPOJO(resource, testList); testPutRequest(json, HttpStatus.SC_CONFLICT, false, adminCredsHeader); testList(resourcePath, testList, HttpStatus.SC_CONFLICT, adminCredsHeader); } private void testReadonlyMap(final ObjectNode json, final String config, final String resource) throws Exception { final String resourcePath = "/config" + config + "/" + resource; - ((ObjectNode)json.at(config)).putPOJO(resource, ImmutableMap.of("test-read-index-1", Collections.singletonList("test-field-1"), "test-read-index-2", Collections.singletonList("test-field-2"))); + ((ObjectNode) json.at(config)).putPOJO( + resource, + ImmutableMap.of( + "test-read-index-1", + Collections.singletonList("test-field-1"), + "test-read-index-2", + Collections.singletonList("test-field-2") + ) + ); testPutRequest(json, HttpStatus.SC_OK, true); // change values - Map> testMap = ImmutableMap.of("test-read-index-1", Collections.singletonList("test-field-1")); - ((ObjectNode)json.at(config)).putPOJO(resource, testMap); + Map> testMap = ImmutableMap.of("test-read-index-1", Collections.singletonList("test-field-1")); + ((ObjectNode) json.at(config)).putPOJO(resource, testMap); testPutRequest(json, HttpStatus.SC_CONFLICT, false, adminCredsHeader); testMap(resourcePath, testMap, HttpStatus.SC_CONFLICT, adminCredsHeader); // change values - testMap = ImmutableMap.of("test-read-index-1", ImmutableList.of("test-field-1", "test-field-2")); - ((ObjectNode)json.at(config)).putPOJO(resource, testMap); + testMap = ImmutableMap.of("test-read-index-1", ImmutableList.of("test-field-1", "test-field-2")); + ((ObjectNode) json.at(config)).putPOJO(resource, testMap); testPutRequest(json, HttpStatus.SC_CONFLICT, false, adminCredsHeader); testMap(resourcePath, testMap, HttpStatus.SC_CONFLICT, adminCredsHeader); // change values testMap = ImmutableMap.of("test-read-index", ImmutableList.of("test-field")); - ((ObjectNode)json.at(config)).putPOJO(resource, testMap); + ((ObjectNode) json.at(config)).putPOJO(resource, testMap); testPutRequest(json, HttpStatus.SC_CONFLICT, false, adminCredsHeader); testMap(resourcePath, testMap, HttpStatus.SC_CONFLICT, adminCredsHeader); // same object different order is valid - testMap = ImmutableMap.of("test-read-index-2", Collections.singletonList("test-field-2"), "test-read-index-1", Collections.singletonList("test-field-1")); - ((ObjectNode)json.at(config)).putPOJO(resource, testMap); + testMap = ImmutableMap.of( + "test-read-index-2", + Collections.singletonList("test-field-2"), + "test-read-index-1", + Collections.singletonList("test-field-1") + ); + ((ObjectNode) json.at(config)).putPOJO(resource, testMap); testPutRequest(json, HttpStatus.SC_OK, false, adminCredsHeader); - RestHelper.HttpResponse response = rh.executePatchRequest(ENDPOINT, "[{\"op\": \"add\",\"path\": \"" + resourcePath + "\",\"value\": " + writeValueAsString(testMap, false) + "}]", adminCredsHeader); + RestHelper.HttpResponse response = rh.executePatchRequest( + ENDPOINT, + "[{\"op\": \"add\",\"path\": \"" + resourcePath + "\",\"value\": " + writeValueAsString(testMap, false) + "}]", + adminCredsHeader + ); assertEquals(HttpStatus.SC_OK, response.getStatusCode()); } private void testReadonlyCategories(final ObjectNode json, final String config, final String resource) throws Exception { final String resourcePath = "/config" + config + "/" + resource; // change disabled_rest_categories readonly property - ((ObjectNode)json.at(config)).putPOJO(resource, ImmutableList.of("SSL_EXCEPTION", "AUTHENTICATED")); + ((ObjectNode) json.at(config)).putPOJO(resource, ImmutableList.of("SSL_EXCEPTION", "AUTHENTICATED")); testPutRequest(json, HttpStatus.SC_OK, true); // change order List testList = ImmutableList.of("AUTHENTICATED", "SSL_EXCEPTION"); - ((ObjectNode)json.at(config)).putPOJO(resource, testList); + ((ObjectNode) json.at(config)).putPOJO(resource, testList); testPutRequest(json, HttpStatus.SC_CONFLICT, false, adminCredsHeader); testList(resourcePath, testList, HttpStatus.SC_CONFLICT, adminCredsHeader); // change values testList = ImmutableList.of("AUTHENTICATED", "SSL_EXCEPTION", "FAILED_LOGIN"); - ((ObjectNode)json.at(config)).putPOJO(resource, testList); + ((ObjectNode) json.at(config)).putPOJO(resource, testList); testPutRequest(json, HttpStatus.SC_CONFLICT, false, adminCredsHeader); testList(resourcePath, testList, HttpStatus.SC_CONFLICT, adminCredsHeader); // change values testList = null; - ((ObjectNode)json.at(config)).putPOJO(resource, testList); + ((ObjectNode) json.at(config)).putPOJO(resource, testList); testPutRequest(json, HttpStatus.SC_CONFLICT, false, adminCredsHeader); testList(resourcePath, testList, HttpStatus.SC_CONFLICT, adminCredsHeader); } @@ -332,9 +392,15 @@ public void testBadRequest() throws Exception { // incorrect category final String jsonValue = DefaultObjectMapper.writeValueAsString(ImmutableList.of("RANDOM", "Test"), true); RestHelper.HttpResponse response; - response = rh.executePatchRequest(ENDPOINT, "[{\"op\": \"add\",\"path\": \"" + "/config/audit/disabled_rest_categories" + "\",\"value\": " + jsonValue + "}]"); + response = rh.executePatchRequest( + ENDPOINT, + "[{\"op\": \"add\",\"path\": \"" + "/config/audit/disabled_rest_categories" + "\",\"value\": " + jsonValue + "}]" + ); assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); - response = rh.executePatchRequest(ENDPOINT, "[{\"op\": \"add\",\"path\": \"" + "/config/audit/disabled_transport_categories" + "\",\"value\": " + jsonValue + "}]"); + response = rh.executePatchRequest( + ENDPOINT, + "[{\"op\": \"add\",\"path\": \"" + "/config/audit/disabled_transport_categories" + "\",\"value\": " + jsonValue + "}]" + ); assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); } @@ -432,15 +498,25 @@ private void testPatchAction(final int expectedStatus, final Header... headers) testBoolean("/config/compliance/external_config", expectedStatus, headers); testBoolean("/config/compliance/read_metadata_only", expectedStatus, headers); testList("/config/compliance/read_ignore_users", ImmutableList.of("test-user-1"), expectedStatus, headers); - testMap("/config/compliance/read_watched_fields", ImmutableMap.of("test-index-1", Collections.singletonList("test-field")), expectedStatus, headers); + testMap( + "/config/compliance/read_watched_fields", + ImmutableMap.of("test-index-1", Collections.singletonList("test-field")), + expectedStatus, + headers + ); testBoolean("/config/compliance/write_metadata_only", expectedStatus, headers); testBoolean("/config/compliance/write_log_diffs", expectedStatus, headers); testList("/config/compliance/write_ignore_users", ImmutableList.of("test-user-1"), expectedStatus, headers); testList("/config/compliance/write_watched_indices", ImmutableList.of("test-index-1"), expectedStatus, headers); } - private void testBooleanPatch(final String patchResource, final boolean value, final int expected, final Header... headers) throws Exception { - RestHelper.HttpResponse response = rh.executePatchRequest(ENDPOINT, "[{\"op\": \"add\",\"path\": \"" + patchResource + "\",\"value\": " + value + "}]", headers); + private void testBooleanPatch(final String patchResource, final boolean value, final int expected, final Header... headers) + throws Exception { + RestHelper.HttpResponse response = rh.executePatchRequest( + ENDPOINT, + "[{\"op\": \"add\",\"path\": \"" + patchResource + "\",\"value\": " + value + "}]", + headers + ); assertEquals(expected, response.getStatusCode()); if (expected == HttpStatus.SC_OK) { assertEquals(value, readTree(rh.executeGetRequest(ENDPOINT, headers).getBody()).at(patchResource).asBoolean()); @@ -458,22 +534,35 @@ private void testBoolean(final String patchResource, final int expected, final H testBooleanPatch(patchResource, true, expected, headers); } - private void testList(final String patchResource, final List expectedList, final int expectedStatus, final Header... headers) throws Exception { + private void testList(final String patchResource, final List expectedList, final int expectedStatus, final Header... headers) + throws Exception { final String jsonValue = DefaultObjectMapper.writeValueAsString(expectedList, true); // make empty - RestHelper.HttpResponse response = rh.executePatchRequest(ENDPOINT, "[{\"op\": \"add\",\"path\": \"" + patchResource + "\",\"value\": []}]", headers); + RestHelper.HttpResponse response = rh.executePatchRequest( + ENDPOINT, + "[{\"op\": \"add\",\"path\": \"" + patchResource + "\",\"value\": []}]", + headers + ); assertEquals(expectedStatus, response.getStatusCode()); if (expectedStatus == HttpStatus.SC_OK) { assertEquals(0, readTree(rh.executeGetRequest(ENDPOINT, headers).getBody()).at(patchResource).size()); } // add value - response = rh.executePatchRequest(ENDPOINT, "[{\"op\": \"add\",\"path\": \"" + patchResource + "\",\"value\": " + jsonValue + "}]", headers); + response = rh.executePatchRequest( + ENDPOINT, + "[{\"op\": \"add\",\"path\": \"" + patchResource + "\",\"value\": " + jsonValue + "}]", + headers + ); assertEquals(expectedStatus, response.getStatusCode()); if (expectedStatus == HttpStatus.SC_OK) { final JsonNode responseJson = readTree(rh.executeGetRequest(ENDPOINT, headers).getBody()); - final List actualList = DefaultObjectMapper.readValue(responseJson.at(patchResource).toString(), new TypeReference>(){}); + final List actualList = DefaultObjectMapper.readValue( + responseJson.at(patchResource).toString(), + new TypeReference>() { + } + ); assertEquals(expectedList.size(), actualList.size()); assertTrue(actualList.containsAll(expectedList)); } @@ -486,22 +575,39 @@ private void testList(final String patchResource, final List expectedLis } } - private void testMap(final String patchResource, final Map> expectedMap, final int expectedStatus, final Header... headers) throws Exception { + private void testMap( + final String patchResource, + final Map> expectedMap, + final int expectedStatus, + final Header... headers + ) throws Exception { final String jsonValue = DefaultObjectMapper.writeValueAsString(expectedMap, true); // make empty - RestHelper.HttpResponse response = rh.executePatchRequest(ENDPOINT, "[{\"op\": \"add\",\"path\": \"" + patchResource + "\",\"value\": {}}]", headers); + RestHelper.HttpResponse response = rh.executePatchRequest( + ENDPOINT, + "[{\"op\": \"add\",\"path\": \"" + patchResource + "\",\"value\": {}}]", + headers + ); assertEquals(expectedStatus, response.getStatusCode()); if (expectedStatus == HttpStatus.SC_OK) { assertEquals(0, readTree(rh.executeGetRequest(ENDPOINT, headers).getBody()).at(patchResource).size()); } // add value - response = rh.executePatchRequest(ENDPOINT, "[{\"op\": \"add\",\"path\": \"" + patchResource + "\",\"value\": " + jsonValue + "}]", headers); + response = rh.executePatchRequest( + ENDPOINT, + "[{\"op\": \"add\",\"path\": \"" + patchResource + "\",\"value\": " + jsonValue + "}]", + headers + ); assertEquals(expectedStatus, response.getStatusCode()); if (expectedStatus == HttpStatus.SC_OK) { final JsonNode responseJson = readTree(rh.executeGetRequest(ENDPOINT, headers).getBody()); - final Map> actualMap = DefaultObjectMapper.readValue(responseJson.at(patchResource).toString(), new TypeReference>>(){}); + final Map> actualMap = DefaultObjectMapper.readValue( + responseJson.at(patchResource).toString(), + new TypeReference>>() { + } + ); assertEquals(actualMap, expectedMap); } @@ -520,32 +626,38 @@ public void testPatchRequest() throws Exception { rh.sendAdminCertificate = true; // update with non-default configuration - AuditConfig auditConfig = new AuditConfig(true, AuditConfig.Filter.from( + AuditConfig auditConfig = new AuditConfig( + true, + AuditConfig.Filter.from( ImmutableMap.builder() - .put("enable_rest", false) - .put("disabled_rest_categories", Collections.emptyList()) - .put("enable_transport", false) - .put("disabled_transport_categories", Collections.emptyList()) - .put("resolve_bulk_requests", false) - .put("resolve_indices", false) - .put("log_request_body", false) - .put("exclude_sensitive_headers", false) - .put("ignore_users", Collections.emptyList()) - .put("ignore_requests", Collections.emptyList()) - .build()) - , ComplianceConfig.from( + .put("enable_rest", false) + .put("disabled_rest_categories", Collections.emptyList()) + .put("enable_transport", false) + .put("disabled_transport_categories", Collections.emptyList()) + .put("resolve_bulk_requests", false) + .put("resolve_indices", false) + .put("log_request_body", false) + .put("exclude_sensitive_headers", false) + .put("ignore_users", Collections.emptyList()) + .put("ignore_requests", Collections.emptyList()) + .build() + ), + ComplianceConfig.from( ImmutableMap.builder() - .put("enabled", true) - .put("external_config", false) - .put("internal_config", false) - .put("read_metadata_only", false) - .put("read_watched_fields", Collections.emptyMap()) - .put("read_ignore_users", Collections.emptyList()) - .put("write_metadata_only", true) - .put("write_log_diffs", true) - .put("write_watched_indices", Collections.emptyList()) - .put("write_ignore_users", Collections.emptyList()) - .build(), Settings.EMPTY)); + .put("enabled", true) + .put("external_config", false) + .put("internal_config", false) + .put("read_metadata_only", false) + .put("read_watched_fields", Collections.emptyMap()) + .put("read_ignore_users", Collections.emptyList()) + .put("write_metadata_only", true) + .put("write_log_diffs", true) + .put("write_watched_indices", Collections.emptyList()) + .put("write_ignore_users", Collections.emptyList()) + .build(), + Settings.EMPTY + ) + ); final String payload = DefaultObjectMapper.writeValueAsString(auditConfig, false); // update config @@ -566,18 +678,18 @@ public void testPatchRequest() throws Exception { } private String getTestPayload() { - return "{" + - "\"enabled\":true," + - "\"audit\":{" + - "\"enable_rest\":true,\"disabled_rest_categories\":[\"AUTHENTICATED\"]," + - "\"enable_transport\":true,\"disabled_transport_categories\":[\"SSL_EXCEPTION\"]," + - "\"resolve_bulk_requests\":true,\"log_request_body\":true,\"resolve_indices\":true,\"exclude_sensitive_headers\":true," + - "\"ignore_users\":[\"test-user-1\"],\"ignore_requests\":[\"test-request\"]}," + - "\"compliance\":{" + - "\"enabled\":true," + - "\"internal_config\":true,\"external_config\":true," + - "\"read_metadata_only\":true,\"read_watched_fields\":{\"test-read-watch-field\":[]},\"read_ignore_users\":[\"test-user-2\"]," + - "\"write_metadata_only\":true,\"write_log_diffs\":true,\"write_watched_indices\":[\"test-write-watch-index\"],\"write_ignore_users\":[\"test-user-3\"]}" + - "}"; + return "{" + + "\"enabled\":true," + + "\"audit\":{" + + "\"enable_rest\":true,\"disabled_rest_categories\":[\"AUTHENTICATED\"]," + + "\"enable_transport\":true,\"disabled_transport_categories\":[\"SSL_EXCEPTION\"]," + + "\"resolve_bulk_requests\":true,\"log_request_body\":true,\"resolve_indices\":true,\"exclude_sensitive_headers\":true," + + "\"ignore_users\":[\"test-user-1\"],\"ignore_requests\":[\"test-request\"]}," + + "\"compliance\":{" + + "\"enabled\":true," + + "\"internal_config\":true,\"external_config\":true," + + "\"read_metadata_only\":true,\"read_watched_fields\":{\"test-read-watch-field\":[]},\"read_ignore_users\":[\"test-user-2\"]," + + "\"write_metadata_only\":true,\"write_log_diffs\":true,\"write_watched_indices\":[\"test-write-watch-index\"],\"write_ignore_users\":[\"test-user-3\"]}" + + "}"; } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/DashboardsInfoActionTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/DashboardsInfoActionTest.java index c17e997dc3..46128f5a71 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/DashboardsInfoActionTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/DashboardsInfoActionTest.java @@ -22,18 +22,21 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class DashboardsInfoActionTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; + protected String getEndpoint() { return PLUGINS_PREFIX + "/dashboardsinfo"; } - public DashboardsInfoActionTest(){ + public DashboardsInfoActionTest() { ENDPOINT = getEndpoint(); } @Test public void testDashboardsInfo() throws Exception { - Settings settings = Settings.builder().put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true).build(); + Settings settings = Settings.builder() + .put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true) + .build(); setup(settings); rh.keystore = "restapi/kirk-keystore.jks"; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/FlushCacheApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/FlushCacheApiTest.java index c998bf5a19..120596f046 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/FlushCacheApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/FlushCacheApiTest.java @@ -23,11 +23,13 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class FlushCacheApiTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; + protected String getEndpointPrefix() { return PLUGINS_PREFIX; } - public FlushCacheApiTest(){ + + public FlushCacheApiTest() { ENDPOINT = getEndpointPrefix() + "/api/cache"; } 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 ea5e96d37e..09c4a762b5 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 @@ -24,12 +24,13 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class GetConfigurationApiTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; + protected String getEndpointPrefix() { return PLUGINS_PREFIX; } - public GetConfigurationApiTest(){ + public GetConfigurationApiTest() { ENDPOINT = getEndpointPrefix() + "/api"; } @@ -48,9 +49,7 @@ public void testGetConfiguration() throws Exception { response = rh.executeGetRequest(ENDPOINT + "/securityconfig"); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); Settings settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); - Assert.assertEquals( - settings.getAsBoolean("config.dynamic.authc.authentication_domain_basic_internal.http_enabled", false), - true); + Assert.assertEquals(settings.getAsBoolean("config.dynamic.authc.authentication_domain_basic_internal.http_enabled", false), true); Assert.assertNull(settings.get("_opendistro_security_meta.type")); // internalusers 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 c2313fe434..22035bba28 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 @@ -24,12 +24,13 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class IndexMissingTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; + protected String getEndpointPrefix() { return PLUGINS_PREFIX; } - public IndexMissingTest(){ + public IndexMissingTest() { ENDPOINT = getEndpointPrefix() + "/api"; } @@ -81,7 +82,11 @@ protected void testHttpOperations() throws Exception { Assert.assertEquals("{\"status\":\"INTERNAL_SERVER_ERROR\",\"message\":\"Security index not initialized\"}", errorString); // PUT request - response = rh.executePutRequest(ENDPOINT + "/actiongroups/READ", FileHelper.loadFile("restapi/actiongroup_read.json"), new Header[0]); + response = rh.executePutRequest( + ENDPOINT + "/actiongroups/READ", + FileHelper.loadFile("restapi/actiongroup_read.json"), + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, response.getStatusCode()); // DELETE request @@ -95,7 +100,10 @@ protected void testHttpOperations() throws Exception { response = rh.executeGetRequest(ENDPOINT + "/roles"); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); SecurityJsonNode securityJsonNode = new SecurityJsonNode(DefaultObjectMapper.readTree(response.getBody())); - Assert.assertEquals("OPENDISTRO_SECURITY_CLUSTER_ALL", securityJsonNode.get("opendistro_security_admin").get("cluster_permissions").get(0).asString()); + Assert.assertEquals( + "OPENDISTRO_SECURITY_CLUSTER_ALL", + securityJsonNode.get("opendistro_security_admin").get("cluster_permissions").get(0).asString() + ); } } 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 24aa8737c6..7132dcc491 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 @@ -31,27 +31,28 @@ private void verifyTenantUpdate(final Header... header) throws Exception { final HttpResponse getSettingResponse = rh.executeGetRequest("/_plugins/_security/api/tenancy/config", header); assertThat(getSettingResponse.getBody(), getSettingResponse.getStatusCode(), equalTo(HttpStatus.SC_OK)); assertThat( - getSettingResponse.getBody(), - getSettingResponse.findValueInJson("default_tenant"), - equalTo(ConfigConstants.TENANCY_GLOBAL_TENANT_DEFAULT_NAME) + getSettingResponse.getBody(), + getSettingResponse.findValueInJson("default_tenant"), + equalTo(ConfigConstants.TENANCY_GLOBAL_TENANT_DEFAULT_NAME) ); HttpResponse getDashboardsinfoResponse = rh.executeGetRequest("/_plugins/_security/dashboardsinfo", header); assertThat(getDashboardsinfoResponse.getStatusCode(), equalTo(HttpStatus.SC_OK)); assertThat( - getDashboardsinfoResponse.getBody(), - getDashboardsinfoResponse.findValueInJson("default_tenant"), - equalTo(ConfigConstants.TENANCY_GLOBAL_TENANT_DEFAULT_NAME) + getDashboardsinfoResponse.getBody(), + getDashboardsinfoResponse.findValueInJson("default_tenant"), + equalTo(ConfigConstants.TENANCY_GLOBAL_TENANT_DEFAULT_NAME) ); final HttpResponse setPrivateTenantAsDefaultResponse = rh.executePutRequest( - "/_plugins/_security/api/tenancy/config", - "{\"default_tenant\": \"Private\"}", header + "/_plugins/_security/api/tenancy/config", + "{\"default_tenant\": \"Private\"}", + header ); assertThat( - setPrivateTenantAsDefaultResponse.getBody(), - setPrivateTenantAsDefaultResponse.getStatusCode(), - equalTo(HttpStatus.SC_OK) + setPrivateTenantAsDefaultResponse.getBody(), + setPrivateTenantAsDefaultResponse.getStatusCode(), + equalTo(HttpStatus.SC_OK) ); getDashboardsinfoResponse = rh.executeGetRequest("/_plugins/_security/dashboardsinfo", ADMIN_FULL_ACCESS_USER); assertThat(getDashboardsinfoResponse.getStatusCode(), equalTo(HttpStatus.SC_OK)); @@ -73,67 +74,79 @@ public void testUpdateRestAPIAdmin() throws Exception { verifyTenantUpdate(ADMIN_FULL_ACCESS_USER); } - private void verifyTenantUpdateFailed(final Header... header) throws Exception { final HttpResponse disablePrivateTenantResponse = rh.executePutRequest( - "/_plugins/_security/api/tenancy/config", - "{\"private_tenant_enabled\":false}", header + "/_plugins/_security/api/tenancy/config", + "{\"private_tenant_enabled\":false}", + header ); assertThat(disablePrivateTenantResponse.getBody(), disablePrivateTenantResponse.getStatusCode(), equalTo(HttpStatus.SC_OK)); final HttpResponse setPrivateTenantAsDefaultFailResponse = rh.executePutRequest( - "/_plugins/_security/api/tenancy/config", - "{\"default_tenant\": \"Private\"}", header + "/_plugins/_security/api/tenancy/config", + "{\"default_tenant\": \"Private\"}", + header + ); + assertThat( + setPrivateTenantAsDefaultFailResponse.getBody(), + setPrivateTenantAsDefaultFailResponse.getStatusCode(), + equalTo(HttpStatus.SC_BAD_REQUEST) ); - assertThat(setPrivateTenantAsDefaultFailResponse.getBody(), setPrivateTenantAsDefaultFailResponse.getStatusCode(), equalTo(HttpStatus.SC_BAD_REQUEST)); assertThat( - setPrivateTenantAsDefaultFailResponse.getBody(), - setPrivateTenantAsDefaultFailResponse.findValueInJson("error.reason"), - containsString("Private tenant can not be disabled if it is the default tenant.") + setPrivateTenantAsDefaultFailResponse.getBody(), + setPrivateTenantAsDefaultFailResponse.findValueInJson("error.reason"), + containsString("Private tenant can not be disabled if it is the default tenant.") ); final HttpResponse enablePrivateTenantResponse = rh.executePutRequest( - "/_plugins/_security/api/tenancy/config", - "{\"private_tenant_enabled\":true}", - header + "/_plugins/_security/api/tenancy/config", + "{\"private_tenant_enabled\":true}", + header ); assertThat(enablePrivateTenantResponse.getBody(), enablePrivateTenantResponse.getStatusCode(), equalTo(HttpStatus.SC_OK)); final HttpResponse setPrivateTenantAsDefaultResponse = rh.executePutRequest( - "/_plugins/_security/api/tenancy/config", - "{\"default_tenant\": \"Private\"}", - header + "/_plugins/_security/api/tenancy/config", + "{\"default_tenant\": \"Private\"}", + header + ); + assertThat( + setPrivateTenantAsDefaultResponse.getBody(), + setPrivateTenantAsDefaultResponse.getStatusCode(), + equalTo(HttpStatus.SC_OK) + ); + final HttpResponse updatePrivateSettingResponse = rh.executePutRequest( + "/_plugins/_security/api/tenancy/config", + "{\"private_tenant_enabled\":false}", + header ); - assertThat(setPrivateTenantAsDefaultResponse.getBody(), setPrivateTenantAsDefaultResponse.getStatusCode(), equalTo(HttpStatus.SC_OK)); - final HttpResponse updatePrivateSettingResponse = - rh.executePutRequest("/_plugins/_security/api/tenancy/config", "{\"private_tenant_enabled\":false}", header); assertThat(updatePrivateSettingResponse.getStatusCode(), equalTo(HttpStatus.SC_BAD_REQUEST)); - assertThat(updatePrivateSettingResponse.findValueInJson("error.reason"), containsString("Private tenant can not be disabled if it is the default tenant.")); + assertThat( + updatePrivateSettingResponse.findValueInJson("error.reason"), + containsString("Private tenant can not be disabled if it is the default tenant.") + ); final HttpResponse getSettingResponseAfterUpdate = rh.executeGetRequest("/_plugins/_security/api/tenancy/config", header); assertThat(getSettingResponseAfterUpdate.getBody(), getSettingResponseAfterUpdate.getStatusCode(), equalTo(HttpStatus.SC_OK)); assertThat( - getSettingResponseAfterUpdate.getBody(), - getSettingResponseAfterUpdate.findValueInJson("default_tenant"), - equalTo("Private") + getSettingResponseAfterUpdate.getBody(), + getSettingResponseAfterUpdate.findValueInJson("default_tenant"), + equalTo("Private") ); final HttpResponse getDashboardsinfoResponse = rh.executeGetRequest("/_plugins/_security/dashboardsinfo", header); - assertThat( - getDashboardsinfoResponse.getBody(), - getDashboardsinfoResponse.findValueInJson("default_tenant"), - equalTo("Private") - ); + assertThat(getDashboardsinfoResponse.getBody(), getDashboardsinfoResponse.findValueInJson("default_tenant"), equalTo("Private")); final HttpResponse setRandomStringAsDefaultTenant = rh.executePutRequest( - "/_plugins/_security/api/tenancy/config", - "{\"default_tenant\": \"NonExistentTenant\"}", - header + "/_plugins/_security/api/tenancy/config", + "{\"default_tenant\": \"NonExistentTenant\"}", + header ); assertThat(setRandomStringAsDefaultTenant.getStatusCode(), equalTo(HttpStatus.SC_BAD_REQUEST)); - assertThat(setPrivateTenantAsDefaultFailResponse.getBody(), - setRandomStringAsDefaultTenant.findValueInJson("error.reason"), - containsString("Default tenant should be selected from one of the available tenants.") + assertThat( + setPrivateTenantAsDefaultFailResponse.getBody(), + setRandomStringAsDefaultTenant.findValueInJson("error.reason"), + containsString("Default tenant should be selected from one of the available tenants.") ); } @@ -160,11 +173,11 @@ public void testForbiddenAccess() throws Exception { HttpResponse getSettingResponse = rh.executeGetRequest("/_plugins/_security/api/tenancy/config", USER_NO_REST_API_ACCESS); assertThat(getSettingResponse.getBody(), getSettingResponse.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); HttpResponse updateSettingResponse = rh.executePutRequest( - "/_plugins/_security/api/tenancy/config", - "{\"default_tenant\": \"Private\"}", USER_NO_REST_API_ACCESS + "/_plugins/_security/api/tenancy/config", + "{\"default_tenant\": \"Private\"}", + USER_NO_REST_API_ACCESS ); assertThat(getSettingResponse.getBody(), updateSettingResponse.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); } - } 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 ef1042682b..a549ad4dd9 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 @@ -42,12 +42,13 @@ public class NodesDnApiTest extends AbstractRestApiUnitTest { private HttpResponse response; private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - private final String ENDPOINT; + private final String ENDPOINT; + protected String getEndpointPrefix() { return PLUGINS_PREFIX; } - public NodesDnApiTest(){ + public NodesDnApiTest() { ENDPOINT = getEndpointPrefix() + "/api"; } @@ -55,7 +56,7 @@ private JsonNode asJsonNode(T t) throws Exception { return OBJECT_MAPPER.readTree(OBJECT_MAPPER.writeValueAsString(t)); } - private Map> nodesDnEntry(String...nodesDn) { + private Map> nodesDnEntry(String... nodesDn) { return ImmutableMap.of("nodes_dn", Arrays.asList(nodesDn)); } @@ -63,9 +64,14 @@ private void testCrudScenarios(final int expectedStatus, final Header... headers response = rh.executeGetRequest(ENDPOINT + "/nodesdn?show_all=true", headers); assertThat(response.getStatusCode(), equalTo(expectedStatus)); if (expectedStatus == HttpStatus.SC_OK) { - JsonNode expected = asJsonNode(ImmutableMap.of( - "cluster1", nodesDnEntry("cn=popeye"), - NodesDnApiAction.STATIC_OPENSEARCH_YML_NODES_DN, nodesDnEntry("CN=example.com"))); + JsonNode expected = asJsonNode( + ImmutableMap.of( + "cluster1", + nodesDnEntry("cn=popeye"), + NodesDnApiAction.STATIC_OPENSEARCH_YML_NODES_DN, + nodesDnEntry("CN=example.com") + ) + ); JsonNode node = OBJECT_MAPPER.readTree(response.getBody()); assertThat(node, equalTo(asJsonNode(expected))); @@ -98,7 +104,11 @@ private void testCrudScenarios(final int expectedStatus, final Header... headers response = rh.executePutRequest(ENDPOINT + "/nodesdn/cluster1", "{\"nodes_dn\": [\"cn=popeye\"]}", headers); assertThat(response.getBody(), response.getStatusCode(), equalTo(expectedStatus)); - response = rh.executePatchRequest(ENDPOINT + "/nodesdn/cluster1", "[{ \"op\": \"add\", \"path\": \"/nodes_dn/-\", \"value\": \"bluto\" }]", headers); + response = rh.executePatchRequest( + ENDPOINT + "/nodesdn/cluster1", + "[{ \"op\": \"add\", \"path\": \"/nodes_dn/-\", \"value\": \"bluto\" }]", + headers + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(expectedStatus)); response = rh.executePatchRequest(ENDPOINT + "/nodesdn", "[{ \"op\": \"remove\", \"path\": \"/cluster1/nodes_dn/0\"}]", headers); @@ -108,7 +118,7 @@ private void testCrudScenarios(final int expectedStatus, final Header... headers assertThat(response.getBody(), response.getStatusCode(), equalTo(expectedStatus)); } - private void checkNullElementsInArray(final Header headers) throws Exception{ + private void checkNullElementsInArray(final Header headers) throws Exception { String body = FileHelper.loadFile("restapi/nodesdn_null_array_element.json"); HttpResponse response = rh.executePutRequest(ENDPOINT + "/nodesdn/cluster1", body, headers); @@ -128,7 +138,8 @@ public void testNodesDnApiWithDynamicConfigDisabled() throws Exception { @Test public void testNodesDnApi() throws Exception { - Settings settings = Settings.builder().put(ConfigConstants.SECURITY_NODES_DN_DYNAMIC_CONFIG_ENABLED, true) + Settings settings = Settings.builder() + .put(ConfigConstants.SECURITY_NODES_DN_DYNAMIC_CONFIG_ENABLED, true) .putList(ConfigConstants.SECURITY_NODES_DN, "CN=example.com") .build(); setupWithRestRoles(settings); @@ -170,67 +181,70 @@ public void testNodesDnApi() throws Exception { final int expectedStatus = HttpStatus.SC_FORBIDDEN; - response = rh.executePutRequest(ENDPOINT + "/nodesdn/" + NodesDnApiAction.STATIC_OPENSEARCH_YML_NODES_DN, "{\"nodes_dn\": [\"cn=popeye\"]}", nonAdminCredsHeader); + response = rh.executePutRequest( + ENDPOINT + "/nodesdn/" + NodesDnApiAction.STATIC_OPENSEARCH_YML_NODES_DN, + "{\"nodes_dn\": [\"cn=popeye\"]}", + nonAdminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(expectedStatus)); - response = rh.executePatchRequest(ENDPOINT + "/nodesdn/" + NodesDnApiAction.STATIC_OPENSEARCH_YML_NODES_DN, - "[{ \"op\": \"add\", \"path\": \"/nodes_dn/-\", \"value\": \"bluto\" }]" , nonAdminCredsHeader); + response = rh.executePatchRequest( + ENDPOINT + "/nodesdn/" + NodesDnApiAction.STATIC_OPENSEARCH_YML_NODES_DN, + "[{ \"op\": \"add\", \"path\": \"/nodes_dn/-\", \"value\": \"bluto\" }]", + nonAdminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(expectedStatus)); - response = rh.executeDeleteRequest(ENDPOINT + "/nodesdn/" + NodesDnApiAction.STATIC_OPENSEARCH_YML_NODES_DN, nonAdminCredsHeader); + response = rh.executeDeleteRequest( + ENDPOINT + "/nodesdn/" + NodesDnApiAction.STATIC_OPENSEARCH_YML_NODES_DN, + nonAdminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(expectedStatus)); } } - @Test public void testNodesDnApiWithPermissions() throws Exception { - Settings settings = - Settings.builder() - .put(ConfigConstants.SECURITY_NODES_DN_DYNAMIC_CONFIG_ENABLED, true) - .put(SECURITY_RESTAPI_ADMIN_ENABLED, true) - .build(); + Settings settings = Settings.builder() + .put(ConfigConstants.SECURITY_NODES_DN_DYNAMIC_CONFIG_ENABLED, true) + .put(SECURITY_RESTAPI_ADMIN_ENABLED, true) + .build(); setupWithRestRoles(settings); final Header restApiAdminHeader = encodeBasicHeader("rest_api_admin_user", "rest_api_admin_user"); final Header restApiNodesDnHeader = encodeBasicHeader("rest_api_admin_nodesdn", "rest_api_admin_nodesdn"); final Header restApiUserHeader = encodeBasicHeader("test", "test"); - //full access admin + // full access admin { rh.sendAdminCertificate = false; - response = rh.executeGetRequest( - ENDPOINT + "/nodesdn", restApiAdminHeader); + response = rh.executeGetRequest(ENDPOINT + "/nodesdn", restApiAdminHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - response = rh.executePutRequest( - ENDPOINT + "/nodesdn/c1", "{\"nodes_dn\": [\"cn=popeye\"]}", - restApiAdminHeader); + response = rh.executePutRequest(ENDPOINT + "/nodesdn/c1", "{\"nodes_dn\": [\"cn=popeye\"]}", restApiAdminHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_CREATED)); response = rh.executePatchRequest( - ENDPOINT + "/nodesdn/c1", - "[{ \"op\": \"add\", \"path\": \"/nodes_dn/-\", \"value\": \"bluto\" }]", - restApiAdminHeader + ENDPOINT + "/nodesdn/c1", + "[{ \"op\": \"add\", \"path\": \"/nodes_dn/-\", \"value\": \"bluto\" }]", + restApiAdminHeader ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); response = rh.executeDeleteRequest(ENDPOINT + "/nodesdn/c1", restApiAdminHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); } - //NodesDN only + // NodesDN only { rh.sendAdminCertificate = false; response = rh.executeGetRequest(ENDPOINT + "/nodesdn", restApiNodesDnHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - response = rh.executePutRequest( - ENDPOINT + "/nodesdn/c1", "{\"nodes_dn\": [\"cn=popeye\"]}", - restApiNodesDnHeader); + response = rh.executePutRequest(ENDPOINT + "/nodesdn/c1", "{\"nodes_dn\": [\"cn=popeye\"]}", restApiNodesDnHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_CREATED)); response = rh.executePatchRequest( - ENDPOINT + "/nodesdn/c1", - "[{ \"op\": \"add\", \"path\": \"/nodes_dn/-\", \"value\": \"bluto\" }]", - restApiNodesDnHeader + ENDPOINT + "/nodesdn/c1", + "[{ \"op\": \"add\", \"path\": \"/nodes_dn/-\", \"value\": \"bluto\" }]", + restApiNodesDnHeader ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); @@ -240,21 +254,19 @@ public void testNodesDnApiWithPermissions() throws Exception { response = rh.executeGetRequest(ENDPOINT + "/actiongroups", restApiNodesDnHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); } - //rest api user + // rest api user { rh.sendAdminCertificate = false; response = rh.executeGetRequest(ENDPOINT + "/nodesdn", restApiUserHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - response = rh.executePutRequest( - ENDPOINT + "/nodesdn/c1", "{\"nodes_dn\": [\"cn=popeye\"]}", - restApiUserHeader); + response = rh.executePutRequest(ENDPOINT + "/nodesdn/c1", "{\"nodes_dn\": [\"cn=popeye\"]}", restApiUserHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); response = rh.executePatchRequest( - ENDPOINT + "/nodesdn/c1", - "[{ \"op\": \"add\", \"path\": \"/nodes_dn/-\", \"value\": \"bluto\" }]", - restApiUserHeader + ENDPOINT + "/nodesdn/c1", + "[{ \"op\": \"add\", \"path\": \"/nodes_dn/-\", \"value\": \"bluto\" }]", + restApiUserHeader ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); @@ -266,7 +278,8 @@ public void testNodesDnApiWithPermissions() throws Exception { @Test public void testNodesDnApiAuditComplianceLogging() throws Exception { - Settings settings = Settings.builder().put(ConfigConstants.SECURITY_NODES_DN_DYNAMIC_CONFIG_ENABLED, true) + Settings settings = Settings.builder() + .put(ConfigConstants.SECURITY_NODES_DN_DYNAMIC_CONFIG_ENABLED, true) .putList(ConfigConstants.SECURITY_NODES_DN, "CN=example.com") .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) @@ -293,9 +306,13 @@ public void testNodesDnApiAuditComplianceLogging() throws Exception { System.out.println(TestAuditlogImpl.sb.toString()); final Map expectedCategoryCounts = ImmutableMap.of( - AuditCategory.COMPLIANCE_INTERNAL_CONFIG_READ, 4L, - AuditCategory.COMPLIANCE_INTERNAL_CONFIG_WRITE, 4L); - Map actualCategoryCounts = TestAuditlogImpl.messages.stream().collect(Collectors.groupingBy(AuditMessage::getCategory, Collectors.counting())); + AuditCategory.COMPLIANCE_INTERNAL_CONFIG_READ, + 4L, + AuditCategory.COMPLIANCE_INTERNAL_CONFIG_WRITE, + 4L + ); + Map actualCategoryCounts = TestAuditlogImpl.messages.stream() + .collect(Collectors.groupingBy(AuditMessage::getCategory, Collectors.counting())); assertThat(actualCategoryCounts, equalTo(expectedCategoryCounts)); } 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 6573082e5b..bbe1bf90f8 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 @@ -34,12 +34,14 @@ public class RestApiPrivilegesEvaluatorTest { @Before public void setUp() { - this.privilegesEvaluator = new RestApiPrivilegesEvaluator(Settings.EMPTY, - mock(AdminDNs.class), - mock(PrivilegesEvaluator.class), - mock(PrincipalExtractor.class), - mock(Path.class), - mock(ThreadPool.class)); + this.privilegesEvaluator = new RestApiPrivilegesEvaluator( + Settings.EMPTY, + mock(AdminDNs.class), + mock(PrivilegesEvaluator.class), + mock(PrincipalExtractor.class), + mock(Path.class), + mock(ThreadPool.class) + ); } @Test 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 5adac7ca78..fc5c59d36f 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 @@ -25,12 +25,13 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class RoleBasedAccessTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; + protected String getEndpointPrefix() { return PLUGINS_PREFIX; } - public RoleBasedAccessTest(){ + public RoleBasedAccessTest() { ENDPOINT = getEndpointPrefix() + "/api"; } @@ -100,7 +101,6 @@ public void testActionGroupsApi() throws Exception { Assert.assertEquals("", settings.getAsList("opendistro_security_role_starfleet_library.backend_roles").get(0), "starfleet*"); Assert.assertEquals("", settings.getAsList("opendistro_security_zdummy_all.users").get(0), "bug108"); - // Deprecated get configuration API, acessible for sarek // response = rh.executeGetRequest("_opendistro/_security/api/configuration/internalusers", encodeBasicHeader("sarek", "sarek")); // settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); @@ -119,9 +119,9 @@ public void testActionGroupsApi() throws Exception { // Assert.assertEquals("", settings.getAsList("CRUD.permissions").get(0), "READ_UT"); // configuration API, not accessible for worf -// response = rh.executeGetRequest("_opendistro/_security/api/configuration/actiongroups", encodeBasicHeader("worf", "worf")); -// Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); -// Assert.assertTrue(response.getBody().contains("does not have any access to endpoint CONFIGURATION")); + // response = rh.executeGetRequest("_opendistro/_security/api/configuration/actiongroups", encodeBasicHeader("worf", "worf")); + // Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); + // Assert.assertTrue(response.getBody().contains("does not have any access to endpoint CONFIGURATION")); // cache API, not accessible for worf since it's disabled globally response = rh.executeDeleteRequest("_opendistro/_security/api/cache", encodeBasicHeader("worf", "worf")); @@ -173,10 +173,18 @@ public void testActionGroupsApi() throws Exception { // Worf, has access to roles API, get captains role response = rh.executeGetRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", encodeBasicHeader("worf", "worf")); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - Assert.assertEquals(new SecurityJsonNode(DefaultObjectMapper.readTree(response.getBody())).getDotted("opendistro_security_role_starfleet_captains.cluster_permissions").get(0).asString(), "cluster:monitor*"); + Assert.assertEquals( + new SecurityJsonNode(DefaultObjectMapper.readTree(response.getBody())).getDotted( + "opendistro_security_role_starfleet_captains.cluster_permissions" + ).get(0).asString(), + "cluster:monitor*" + ); // Worf, has access to roles API, able to delete - response = rh.executeDeleteRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", encodeBasicHeader("worf", "worf")); + response = rh.executeDeleteRequest( + ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", + encodeBasicHeader("worf", "worf") + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); Assert.assertTrue(response.getBody().contains("'opendistro_security_role_starfleet_captains' deleted")); @@ -196,20 +204,31 @@ public void testActionGroupsApi() throws Exception { // --- PUT --- // admin, no access - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/roles_captains_tenants.json"), encodeBasicHeader("admin", "admin")); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/roles_captains_tenants.json"), + encodeBasicHeader("admin", "admin") + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // worf, restore role starfleet captains - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/roles_captains_different_content.json"), encodeBasicHeader("worf", "worf")); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/roles_captains_different_content.json"), + encodeBasicHeader("worf", "worf") + ); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); // starfleet role present again response = rh.executeGetRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", encodeBasicHeader("worf", "worf")); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - Assert.assertEquals(new SecurityJsonNode(DefaultObjectMapper.readTree(response.getBody())).getDotted("opendistro_security_role_starfleet_captains.index_permissions").get(0).get("allowed_actions").get(0).asString(), "blafasel"); + Assert.assertEquals( + new SecurityJsonNode(DefaultObjectMapper.readTree(response.getBody())).getDotted( + "opendistro_security_role_starfleet_captains.index_permissions" + ).get(0).get("allowed_actions").get(0).asString(), + "blafasel" + ); // Try the same, but now with admin certificate rh.sendAdminCertificate = true; @@ -245,8 +264,11 @@ public void testActionGroupsApi() throws Exception { Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // PUT roles - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/roles_captains_different_content.json"), encodeBasicHeader("test", "test")); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/roles_captains_different_content.json"), + encodeBasicHeader("test", "test") + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); // GET captions role @@ -254,7 +276,10 @@ public void testActionGroupsApi() throws Exception { Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); // Delete captions role - response = rh.executeDeleteRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", encodeBasicHeader("test", "test")); + response = rh.executeDeleteRequest( + ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", + encodeBasicHeader("test", "test") + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); Assert.assertTrue(response.getBody().contains("'opendistro_security_role_starfleet_captains' deleted")); @@ -262,6 +287,5 @@ public void testActionGroupsApi() throws Exception { response = rh.executeGetRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", encodeBasicHeader("test", "test")); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); - } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/RolesApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/RolesApiTest.java index a85566dc91..bf703fea35 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/RolesApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/RolesApiTest.java @@ -81,7 +81,7 @@ public void testAllRolesForRestAdmin() throws Exception { setupWithRestRoles(Settings.builder().put(SECURITY_RESTAPI_ADMIN_ENABLED, true).build()); final Header restApiAdminHeader = encodeBasicHeader("rest_api_admin_user", "rest_api_admin_user"); rh.sendAdminCertificate = false; - checkSuperAdminRoles(new Header[]{restApiAdminHeader}); + checkSuperAdminRoles(new Header[] { restApiAdminHeader }); } @Test @@ -89,7 +89,7 @@ public void testAllRolesForRolesRestAdmin() throws Exception { setupWithRestRoles(Settings.builder().put(SECURITY_RESTAPI_ADMIN_ENABLED, true).build()); final Header restApiAdminRolesHeader = encodeBasicHeader("rest_api_admin_roles", "rest_api_admin_roles"); rh.sendAdminCertificate = false; - checkSuperAdminRoles(new Header[]{restApiAdminRolesHeader}); + checkSuperAdminRoles(new Header[] { restApiAdminRolesHeader }); } void checkSuperAdminRoles(final Header[] header) { @@ -108,12 +108,14 @@ public void testPutDuplicateKeys() throws Exception { rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - HttpResponse response = rh.executePutRequest(ENDPOINT + "/roles/dup", "{ \"cluster_permissions\": [\"*\"], \"cluster_permissions\": [\"*\"] }"); + HttpResponse response = rh.executePutRequest( + ENDPOINT + "/roles/dup", + "{ \"cluster_permissions\": [\"*\"], \"cluster_permissions\": [\"*\"] }" + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); assertHealthy(); } - @Test public void testPutUnknownKey() throws Exception { @@ -121,7 +123,10 @@ public void testPutUnknownKey() throws Exception { rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - HttpResponse response = rh.executePutRequest(ENDPOINT + "/roles/dup", "{ \"unknownkey\": [\"*\"], \"cluster_permissions\": [\"*\"] }"); + HttpResponse response = rh.executePutRequest( + ENDPOINT + "/roles/dup", + "{ \"unknownkey\": [\"*\"], \"cluster_permissions\": [\"*\"] }" + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertTrue(response.getBody().contains("invalid_keys")); assertHealthy(); @@ -134,7 +139,10 @@ public void testPutInvalidJson() throws Exception { rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - HttpResponse response = rh.executePutRequest(ENDPOINT + "/roles/dup", "{ \"invalid\"::{{ [\"*\"], \"cluster_permissions\": [\"*\"] }"); + HttpResponse response = rh.executePutRequest( + ENDPOINT + "/roles/dup", + "{ \"invalid\"::{{ [\"*\"], \"cluster_permissions\": [\"*\"] }" + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); assertHealthy(); } @@ -151,7 +159,7 @@ public void testRolesApi() throws Exception { setupStarfleetIndex(); // add user picard, role starfleet, maps to opendistro_security_role_starfleet - addUserWithPassword("picard", "picardpicardpicardpicard", new String[]{"starfleet", "captains"}, HttpStatus.SC_CREATED); + addUserWithPassword("picard", "picardpicardpicardpicard", new String[] { "starfleet", "captains" }, HttpStatus.SC_CREATED); checkReadAccess(HttpStatus.SC_OK, "picard", "picardpicardpicardpicard", "sf", "_doc", 0); checkWriteAccess(HttpStatus.SC_OK, "picard", "picardpicardpicardpicard", "sf", "_doc", 0); @@ -242,25 +250,37 @@ void verifyPutForSuperAdmin(final Header[] header, final boolean sendAdminCert) Assert.assertEquals(AbstractConfigurationValidator.ErrorType.PAYLOAD_MANDATORY.getMessage(), settings.get("reason").asText()); // put new configuration with invalid payload, must fail - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet", - FileHelper.loadFile("restapi/roles_not_parseable.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_role_starfleet", + FileHelper.loadFile("restapi/roles_not_parseable.json"), + header + ); settings = DefaultObjectMapper.readTree(response.getBody()); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.BODY_NOT_PARSEABLE.getMessage(), settings.get("reason").asText()); // put new configuration with invalid keys, must fail - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet", - FileHelper.loadFile("restapi/roles_invalid_keys.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_role_starfleet", + FileHelper.loadFile("restapi/roles_invalid_keys.json"), + header + ); settings = DefaultObjectMapper.readTree(response.getBody()); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.INVALID_CONFIGURATION.getMessage(), settings.get("reason").asText()); - Assert.assertTrue(settings.get(AbstractConfigurationValidator.INVALID_KEYS_KEY).get("keys").asText().contains("indexx_permissions")); Assert.assertTrue( - settings.get(AbstractConfigurationValidator.INVALID_KEYS_KEY).get("keys").asText().contains("kluster_permissions")); + settings.get(AbstractConfigurationValidator.INVALID_KEYS_KEY).get("keys").asText().contains("indexx_permissions") + ); + Assert.assertTrue( + settings.get(AbstractConfigurationValidator.INVALID_KEYS_KEY).get("keys").asText().contains("kluster_permissions") + ); // put new configuration with wrong datatypes, must fail - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet", - FileHelper.loadFile("restapi/roles_wrong_datatype.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_role_starfleet", + FileHelper.loadFile("restapi/roles_wrong_datatype.json"), + header + ); settings = DefaultObjectMapper.readTree(response.getBody()); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.WRONG_DATATYPE.getMessage(), settings.get("reason").asText()); @@ -268,18 +288,27 @@ void verifyPutForSuperAdmin(final Header[] header, final boolean sendAdminCert) // put read only role, must be forbidden // But SuperAdmin can still create it - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_transport_client", - FileHelper.loadFile("restapi/roles_captains.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_transport_client", + FileHelper.loadFile("restapi/roles_captains.json"), + header + ); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); // put hidden role, must be forbidden, but allowed for super admin - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_internal", - FileHelper.loadFile("restapi/roles_captains.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_internal", + FileHelper.loadFile("restapi/roles_captains.json"), + header + ); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); // restore starfleet role - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet", - FileHelper.loadFile("restapi/roles_starfleet.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_role_starfleet", + FileHelper.loadFile("restapi/roles_starfleet.json"), + header + ); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); rh.sendAdminCertificate = false; checkReadAccess(HttpStatus.SC_OK, "picard", "picardpicardpicardpicard", "sf", "_doc", 0); @@ -287,53 +316,94 @@ void verifyPutForSuperAdmin(final Header[] header, final boolean sendAdminCert) // now picard is only in opendistro_security_role_starfleet, which has write access to // all indices. We collapse all document types in ODFE7 so this permission in the // starfleet role grants all permissions: - // _doc: - // - 'indices:*' + // _doc: + // - 'indices:*' checkWriteAccess(HttpStatus.SC_OK, "picard", "picardpicardpicardpicard", "sf", "_doc", 0); rh.sendAdminCertificate = sendAdminCert; // restore captains role - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/roles_captains.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/roles_captains.json"), + header + ); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); rh.sendAdminCertificate = false; checkReadAccess(HttpStatus.SC_OK, "picard", "picardpicardpicardpicard", "sf", "_doc", 0); checkWriteAccess(HttpStatus.SC_OK, "picard", "picardpicardpicardpicard", "sf", "_doc", 0); rh.sendAdminCertificate = sendAdminCert; - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/roles_complete_invalid.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/roles_complete_invalid.json"), + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/roles_multiple_2.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/roles_multiple_2.json"), + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // check tenants rh.sendAdminCertificate = sendAdminCert; - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/roles_captains_tenants.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/roles_captains_tenants.json"), + header + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); settings = DefaultObjectMapper.readTree(response.getBody()); Assert.assertEquals(2, settings.size()); Assert.assertEquals(settings.get("status").asText(), "OK"); - response = rh.executeGetRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); System.out.println(response.getBody()); settings = DefaultObjectMapper.readTree(response.getBody()); Assert.assertEquals(1, settings.size()); - Assert.assertEquals(new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions").get(1).get("tenant_patterns").get(0).asString(), "tenant1"); - Assert.assertEquals(new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions").get(1).get("allowed_actions").get(0).asString(), "kibana_all_read"); + Assert.assertEquals( + new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions") + .get(1) + .get("tenant_patterns") + .get(0) + .asString(), + "tenant1" + ); + Assert.assertEquals( + new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions") + .get(1) + .get("allowed_actions") + .get(0) + .asString(), + "kibana_all_read" + ); + + Assert.assertEquals( + new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions") + .get(0) + .get("tenant_patterns") + .get(0) + .asString(), + "tenant2" + ); + Assert.assertEquals( + new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions") + .get(0) + .get("allowed_actions") + .get(0) + .asString(), + "kibana_all_write" + ); - Assert.assertEquals(new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions").get(0).get("tenant_patterns").get(0).asString(), "tenant2"); - Assert.assertEquals(new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions").get(0).get("allowed_actions").get(0).asString(), "kibana_all_write"); - - - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/roles_captains_tenants2.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/roles_captains_tenants2.json"), + header + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); settings = DefaultObjectMapper.readTree(response.getBody()); Assert.assertEquals(2, settings.size()); @@ -344,18 +414,63 @@ void verifyPutForSuperAdmin(final Header[] header, final boolean sendAdminCert) settings = DefaultObjectMapper.readTree(response.getBody()); Assert.assertEquals(1, settings.size()); - Assert.assertEquals(new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions").get(0).get("tenant_patterns").get(0).asString(), "tenant2"); - Assert.assertEquals(new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions").get(0).get("tenant_patterns").get(1).asString(), "tenant4"); - - Assert.assertEquals(new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions").get(0).get("allowed_actions").get(0).asString(), "kibana_all_write"); - - Assert.assertEquals(new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions").get(1).get("tenant_patterns").get(0).asString(), "tenant1"); - Assert.assertEquals(new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions").get(1).get("tenant_patterns").get(1).asString(), "tenant3"); - Assert.assertEquals(new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions").get(1).get("allowed_actions").get(0).asString(), "kibana_all_read"); + Assert.assertEquals( + new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions") + .get(0) + .get("tenant_patterns") + .get(0) + .asString(), + "tenant2" + ); + Assert.assertEquals( + new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions") + .get(0) + .get("tenant_patterns") + .get(1) + .asString(), + "tenant4" + ); + + Assert.assertEquals( + new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions") + .get(0) + .get("allowed_actions") + .get(0) + .asString(), + "kibana_all_write" + ); + + Assert.assertEquals( + new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions") + .get(1) + .get("tenant_patterns") + .get(0) + .asString(), + "tenant1" + ); + Assert.assertEquals( + new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions") + .get(1) + .get("tenant_patterns") + .get(1) + .asString(), + "tenant3" + ); + Assert.assertEquals( + new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions") + .get(1) + .get("allowed_actions") + .get(0) + .asString(), + "kibana_all_read" + ); // remove tenants from role - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/roles_captains_no_tenants.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/roles_captains_no_tenants.json"), + header + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); settings = DefaultObjectMapper.readTree(response.getBody()); Assert.assertEquals(2, settings.size()); @@ -365,11 +480,18 @@ void verifyPutForSuperAdmin(final Header[] header, final boolean sendAdminCert) Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); settings = DefaultObjectMapper.readTree(response.getBody()); Assert.assertEquals(1, settings.size()); - Assert.assertFalse(new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.cluster_permissions").get(0).isNull()); - Assert.assertTrue(new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions").get(0).isNull()); + Assert.assertFalse( + new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.cluster_permissions").get(0).isNull() + ); + Assert.assertTrue( + new SecurityJsonNode(settings).getDotted("opendistro_security_role_starfleet_captains.tenant_permissions").get(0).isNull() + ); - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/roles_captains_tenants_malformed.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/roles_captains_tenants_malformed.json"), + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); settings = DefaultObjectMapper.readTree(response.getBody()); Assert.assertEquals(settings.get("status").asText(), "error"); @@ -381,36 +503,43 @@ void verifyPatchForSuperAdmin(final Header[] header, final boolean sendAdminCert // PATCH on non-existing resource rh.sendAdminCertificate = sendAdminCert; HttpResponse response = rh.executePatchRequest( - ENDPOINT + "/roles/imnothere", - "[{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }]", - header); + ENDPOINT + "/roles/imnothere", + "[{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }]", + header + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // PATCH read only resource, must be forbidden // SuperAdmin can patch it rh.sendAdminCertificate = sendAdminCert; response = rh.executePatchRequest( - ENDPOINT + "/roles/opendistro_security_transport_client", - "[{ \"op\": \"add\", \"path\": \"/description\", \"value\": \"foo\" }]", - header); + ENDPOINT + "/roles/opendistro_security_transport_client", + "[{ \"op\": \"add\", \"path\": \"/description\", \"value\": \"foo\" }]", + header + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); // PATCH hidden resource, must be not found, can be found for superadmin, but will fail with no path present exception rh.sendAdminCertificate = sendAdminCert; response = rh.executePatchRequest( - ENDPOINT + "/roles/opendistro_security_internal", - "[{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }]", - header); + ENDPOINT + "/roles/opendistro_security_internal", + "[{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // PATCH value of hidden flag, must fail with validation error rh.sendAdminCertificate = sendAdminCert; response = rh.executePatchRequest( - ENDPOINT + "/roles/opendistro_security_role_starfleet", - "[{ \"op\": \"add\", \"path\": \"/hidden\", \"value\": true }]", - header); + ENDPOINT + "/roles/opendistro_security_role_starfleet", + "[{ \"op\": \"add\", \"path\": \"/hidden\", \"value\": true }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); - Assert.assertTrue(response.getBody(), response.getBody().matches(".*\"invalid_keys\"\\s*:\\s*\\{\\s*\"keys\"\\s*:\\s*\"hidden\"\\s*\\}.*")); + Assert.assertTrue( + response.getBody(), + response.getBody().matches(".*\"invalid_keys\"\\s*:\\s*\\{\\s*\"keys\"\\s*:\\s*\"hidden\"\\s*\\}.*") + ); List permissions = null; @@ -433,61 +562,69 @@ void verifyPatchForSuperAdmin(final Header[] header, final boolean sendAdminCert // PATCH on non-existing resource rh.sendAdminCertificate = sendAdminCert; response = rh.executePatchRequest( - ENDPOINT + "/roles", - "[{ \"op\": \"add\", \"path\": \"/imnothere/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }]", - header); + ENDPOINT + "/roles", + "[{ \"op\": \"add\", \"path\": \"/imnothere/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // PATCH read only resource, must be forbidden rh.sendAdminCertificate = sendAdminCert; response = rh.executePatchRequest( - ENDPOINT + "/roles", - "[{ \"op\": \"add\", \"path\": \"/opendistro_security_transport_client/a\", \"value\": [ \"foo\", \"bar\" ] }]", - header); + ENDPOINT + "/roles", + "[{ \"op\": \"add\", \"path\": \"/opendistro_security_transport_client/a\", \"value\": [ \"foo\", \"bar\" ] }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // PATCH hidden resource, must be bad request rh.sendAdminCertificate = sendAdminCert; response = rh.executePatchRequest( - ENDPOINT + "/roles", - "[{ \"op\": \"add\", \"path\": \"/opendistro_security_internal/a\", \"value\": [ \"foo\", \"bar\" ] }]", - header); + ENDPOINT + "/roles", + "[{ \"op\": \"add\", \"path\": \"/opendistro_security_internal/a\", \"value\": [ \"foo\", \"bar\" ] }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // PATCH delete read only resource, must be forbidden // SuperAdmin can delete read only user rh.sendAdminCertificate = sendAdminCert; response = rh.executePatchRequest( - ENDPOINT + "/roles", "[{ \"op\": \"remove\", \"path\": \"/opendistro_security_transport_client\" }]", - header); + ENDPOINT + "/roles", + "[{ \"op\": \"remove\", \"path\": \"/opendistro_security_transport_client\" }]", + header + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); // PATCH hidden resource, must be bad request, but allowed for superadmin rh.sendAdminCertificate = sendAdminCert; response = rh.executePatchRequest( - ENDPOINT + "/roles", - "[{ \"op\": \"remove\", \"path\": \"/opendistro_security_internal\"}]", - header); + ENDPOINT + "/roles", + "[{ \"op\": \"remove\", \"path\": \"/opendistro_security_internal\"}]", + header + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); Assert.assertTrue(response.getBody().contains("\"message\":\"Resource updated.")); // PATCH value of hidden flag, must fail with validation error rh.sendAdminCertificate = sendAdminCert; response = rh.executePatchRequest( - ENDPOINT + "/roles", - "[{ \"op\": \"add\", \"path\": \"/newnewnew\", \"value\": { \"hidden\": true, \"index_permissions\" : " + - "[ {\"index_patterns\" : [ \"sf\" ],\"allowed_actions\" : [ \"OPENDISTRO_SECURITY_READ\" ]}] }}]", - header); + ENDPOINT + "/roles", + "[{ \"op\": \"add\", \"path\": \"/newnewnew\", \"value\": { \"hidden\": true, \"index_permissions\" : " + + "[ {\"index_patterns\" : [ \"sf\" ],\"allowed_actions\" : [ \"OPENDISTRO_SECURITY_READ\" ]}] }}]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertTrue(response.getBody().matches(".*\"invalid_keys\"\\s*:\\s*\\{\\s*\"keys\"\\s*:\\s*\"hidden\"\\s*\\}.*")); // PATCH rh.sendAdminCertificate = sendAdminCert; response = rh.executePatchRequest( - ENDPOINT + "/roles", - "[{ \"op\": \"add\", \"path\": \"/bulknew1\", \"value\": { \"index_permissions\" : " + - "[ {\"index_patterns\" : [ \"sf\" ],\"allowed_actions\" : [ \"OPENDISTRO_SECURITY_READ\" ]}] }}]", - header); + ENDPOINT + "/roles", + "[{ \"op\": \"add\", \"path\": \"/bulknew1\", \"value\": { \"index_permissions\" : " + + "[ {\"index_patterns\" : [ \"sf\" ],\"allowed_actions\" : [ \"OPENDISTRO_SECURITY_READ\" ]}] }}]", + header + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executeGetRequest(ENDPOINT + "/roles/bulknew1", header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); @@ -505,13 +642,19 @@ void verifyPatchForSuperAdmin(final Header[] header, final boolean sendAdminCert Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // put valid field masks - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_field_mask_valid", - FileHelper.loadFile("restapi/roles_field_masks_valid.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_field_mask_valid", + FileHelper.loadFile("restapi/roles_field_masks_valid.json"), + header + ); Assert.assertEquals(response.getBody(), HttpStatus.SC_CREATED, response.getStatusCode()); // put invalid field masks - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_field_mask_invalid", - FileHelper.loadFile("restapi/roles_field_masks_invalid.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_field_mask_invalid", + FileHelper.loadFile("restapi/roles_field_masks_invalid.json"), + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); } @@ -525,14 +668,14 @@ public void testRolesApiWithAllRestApiPermissions() throws Exception { setupStarfleetIndex(); // add user picard, role starfleet, maps to opendistro_security_role_starfleet - addUserWithPassword("picard", "picardpicardpicardpicard", new String[]{"starfleet", "captains"}, HttpStatus.SC_CREATED); + addUserWithPassword("picard", "picardpicardpicardpicard", new String[] { "starfleet", "captains" }, HttpStatus.SC_CREATED); checkReadAccess(HttpStatus.SC_OK, "picard", "picardpicardpicardpicard", "sf", "_doc", 0); checkWriteAccess(HttpStatus.SC_OK, "picard", "picardpicardpicardpicard", "sf", "_doc", 0); - verifyGetForSuperAdmin(new Header[]{restApiAdminHeader}); - verifyDeleteForSuperAdmin(new Header[]{restApiAdminHeader}, false); - verifyPutForSuperAdmin(new Header[]{restApiAdminHeader}, false); - verifyPatchForSuperAdmin(new Header[]{restApiAdminHeader}, false); + verifyGetForSuperAdmin(new Header[] { restApiAdminHeader }); + verifyDeleteForSuperAdmin(new Header[] { restApiAdminHeader }, false); + verifyPutForSuperAdmin(new Header[] { restApiAdminHeader }, false); + verifyPatchForSuperAdmin(new Header[] { restApiAdminHeader }, false); } @Test @@ -545,15 +688,14 @@ public void testRolesApiWithRestApiRolePermission() throws Exception { setupStarfleetIndex(); // add user picard, role starfleet, maps to opendistro_security_role_starfleet - addUserWithPassword("picard", "picardpicardpicardpicard", new String[]{"starfleet", "captains"}, HttpStatus.SC_CREATED); + addUserWithPassword("picard", "picardpicardpicardpicard", new String[] { "starfleet", "captains" }, HttpStatus.SC_CREATED); checkReadAccess(HttpStatus.SC_OK, "picard", "picardpicardpicardpicard", "sf", "_doc", 0); checkWriteAccess(HttpStatus.SC_OK, "picard", "picardpicardpicardpicard", "sf", "_doc", 0); - - verifyGetForSuperAdmin(new Header[]{restApiRolesHeader}); - verifyDeleteForSuperAdmin(new Header[]{restApiRolesHeader}, false); - verifyPutForSuperAdmin(new Header[]{restApiRolesHeader}, false); - verifyPatchForSuperAdmin(new Header[]{restApiRolesHeader}, false); + verifyGetForSuperAdmin(new Header[] { restApiRolesHeader }); + verifyDeleteForSuperAdmin(new Header[] { restApiRolesHeader }, false); + verifyPutForSuperAdmin(new Header[] { restApiRolesHeader }, false); + verifyPatchForSuperAdmin(new Header[] { restApiRolesHeader }, false); } @Test @@ -567,63 +709,45 @@ public void testCreateOrUpdateRestApiAdminRoleForbiddenForNonSuperAdmin() throws final String restAdminPermissionsPayload = createRestAdminPermissionsPayload("cluster/*"); HttpResponse response = rh.executePutRequest( - ENDPOINT + "/roles/new_rest_admin_role", restAdminPermissionsPayload, restApiAdminHeader); + ENDPOINT + "/roles/new_rest_admin_role", + restAdminPermissionsPayload, + restApiAdminHeader + ); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); - response = rh.executePutRequest( - ENDPOINT + "/roles/rest_admin_role_to_delete", restAdminPermissionsPayload, restApiAdminHeader); + response = rh.executePutRequest(ENDPOINT + "/roles/rest_admin_role_to_delete", restAdminPermissionsPayload, restApiAdminHeader); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); // attempt to create a new rest admin role by admin - response = rh.executePutRequest( - ENDPOINT + "/roles/some_rest_admin_role", - restAdminPermissionsPayload, - adminHeader); + response = rh.executePutRequest(ENDPOINT + "/roles/some_rest_admin_role", restAdminPermissionsPayload, adminHeader); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // attempt to update exiting admin role - response = rh.executePutRequest( - ENDPOINT + "/roles/new_rest_admin_role", - restAdminPermissionsPayload, - adminHeader); + response = rh.executePutRequest(ENDPOINT + "/roles/new_rest_admin_role", restAdminPermissionsPayload, adminHeader); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // attempt to patch exiting admin role response = rh.executePatchRequest( - ENDPOINT + "/roles/new_rest_admin_role", - createPatchRestAdminPermissionsPayload("replace"), - adminHeader); + ENDPOINT + "/roles/new_rest_admin_role", + createPatchRestAdminPermissionsPayload("replace"), + adminHeader + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // attempt to update exiting admin role - response = rh.executePutRequest( - ENDPOINT + "/roles/new_rest_admin_role", - restAdminPermissionsPayload, - restApiHeader); + response = rh.executePutRequest(ENDPOINT + "/roles/new_rest_admin_role", restAdminPermissionsPayload, restApiHeader); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // attempt to create a new rest admin role by admin - response = rh.executePutRequest( - ENDPOINT + "/roles/some_rest_admin_role", - restAdminPermissionsPayload, - restApiHeader); + response = rh.executePutRequest(ENDPOINT + "/roles/some_rest_admin_role", restAdminPermissionsPayload, restApiHeader); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // attempt to patch exiting admin role and crate a new one - response = rh.executePatchRequest( - ENDPOINT + "/roles", - createPatchRestAdminPermissionsPayload("replace"), - restApiHeader); + response = rh.executePatchRequest(ENDPOINT + "/roles", createPatchRestAdminPermissionsPayload("replace"), restApiHeader); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); - response = rh.executePatchRequest( - ENDPOINT + "/roles", - createPatchRestAdminPermissionsPayload("add"), - restApiHeader); + response = rh.executePatchRequest(ENDPOINT + "/roles", createPatchRestAdminPermissionsPayload("add"), restApiHeader); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); - response = rh.executePatchRequest( - ENDPOINT + "/roles", - createPatchRestAdminPermissionsPayload("remove"), - restApiHeader); + response = rh.executePatchRequest(ENDPOINT + "/roles", createPatchRestAdminPermissionsPayload("remove"), restApiHeader); System.out.println("RESPONSE: " + response.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); } @@ -640,51 +764,42 @@ public void testDeleteRestApiAdminRoleForbiddenForNonSuperAdmin() throws Excepti final String allRestAdminPermissionsPayload = createRestAdminPermissionsPayload("cluster/*"); HttpResponse response = rh.executePutRequest( - ENDPOINT + "/roles/new_rest_admin_role", allRestAdminPermissionsPayload, restApiAdminHeader); + ENDPOINT + "/roles/new_rest_admin_role", + allRestAdminPermissionsPayload, + restApiAdminHeader + ); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); // attempt to update exiting admin role - response = rh.executeDeleteRequest( - ENDPOINT + "/roles/new_rest_admin_role", - adminHeader); + response = rh.executeDeleteRequest(ENDPOINT + "/roles/new_rest_admin_role", adminHeader); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); - //true to change - response = rh.executeDeleteRequest( - ENDPOINT + "/roles/new_rest_admin_role", - allRestAdminPermissionsPayload, - restApiHeader); + // true to change + response = rh.executeDeleteRequest(ENDPOINT + "/roles/new_rest_admin_role", allRestAdminPermissionsPayload, restApiHeader); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); } - private String createPatchRestAdminPermissionsPayload(final String op) throws JsonProcessingException { final ArrayNode rootNode = (ArrayNode) DefaultObjectMapper.objectMapper.createArrayNode(); final ObjectNode opAddObjectNode = DefaultObjectMapper.objectMapper.createObjectNode(); final ObjectNode clusterPermissionsNode = DefaultObjectMapper.objectMapper.createObjectNode(); clusterPermissionsNode.set("cluster_permissions", clusterPermissionsForRestAdmin("cluster/*")); if ("add".equals(op)) { - opAddObjectNode - .put("op", "add") - .put("path", "/some_rest_admin_role") - .set("value", clusterPermissionsNode); + opAddObjectNode.put("op", "add").put("path", "/some_rest_admin_role").set("value", clusterPermissionsNode); rootNode.add(opAddObjectNode); } if ("remove".equals(op)) { final ObjectNode opRemoveObjectNode = DefaultObjectMapper.objectMapper.createObjectNode(); - opRemoveObjectNode - .put("op", "remove") - .put("path", "/rest_admin_role_to_delete"); + opRemoveObjectNode.put("op", "remove").put("path", "/rest_admin_role_to_delete"); rootNode.add(opRemoveObjectNode); } if ("replace".equals(op)) { final ObjectNode replaceRemoveObjectNode = DefaultObjectMapper.objectMapper.createObjectNode(); - replaceRemoveObjectNode - .put("op", "replace") - .put("path", "/new_rest_admin_role/cluster_permissions") - .set("value", clusterPermissionsForRestAdmin("*")); + replaceRemoveObjectNode.put("op", "replace") + .put("path", "/new_rest_admin_role/cluster_permissions") + .set("value", clusterPermissionsForRestAdmin("*")); rootNode.add(replaceRemoveObjectNode); } @@ -709,21 +824,27 @@ void checkNonSuperAdminRoles(final Header[] header) throws Exception { Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // Put read only roles - response = rh.executePutRequest(ENDPOINT + "/roles/opendistro_security_transport_client", - FileHelper.loadFile("restapi/roles_captains.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/roles/opendistro_security_transport_client", + FileHelper.loadFile("restapi/roles_captains.json"), + header + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // Patch single read only roles response = rh.executePatchRequest( - ENDPOINT + "/roles/opendistro_security_transport_client", - "[{ \"op\": \"replace\", \"path\": \"/description\", \"value\": \"foo\" }]", - header); + ENDPOINT + "/roles/opendistro_security_transport_client", + "[{ \"op\": \"replace\", \"path\": \"/description\", \"value\": \"foo\" }]", + header + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // Patch multiple read only roles - response = rh.executePatchRequest(ENDPOINT + "/roles/", - "[{ \"op\": \"add\", \"path\": \"/opendistro_security_transport_client/description\", \"value\": \"foo\" }]", - header); + response = rh.executePatchRequest( + ENDPOINT + "/roles/", + "[{ \"op\": \"add\", \"path\": \"/opendistro_security_transport_client/description\", \"value\": \"foo\" }]", + header + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // get hidden role @@ -740,14 +861,19 @@ void checkNonSuperAdminRoles(final Header[] header) throws Exception { Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // Patch single hidden roles - response = rh.executePatchRequest(ENDPOINT + "/roles/opendistro_security_internal", - "[{ \"op\": \"replace\", \"path\": \"/description\", \"value\": \"foo\" }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/roles/opendistro_security_internal", + "[{ \"op\": \"replace\", \"path\": \"/description\", \"value\": \"foo\" }]", + header + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // Patch multiple hidden roles - response = rh.executePatchRequest(ENDPOINT + "/roles/", - "[{ \"op\": \"add\", \"path\": \"/opendistro_security_internal/description\", \"value\": \"foo\" }]", - header); + response = rh.executePatchRequest( + ENDPOINT + "/roles/", + "[{ \"op\": \"add\", \"path\": \"/opendistro_security_internal/description\", \"value\": \"foo\" }]", + header + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/RolesMappingApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/RolesMappingApiTest.java index 3bc647bf12..42fb111281 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/RolesMappingApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/RolesMappingApiTest.java @@ -32,12 +32,13 @@ import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; public class RolesMappingApiTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; + protected String getEndpointPrefix() { return PLUGINS_PREFIX; } - public RolesMappingApiTest(){ + public RolesMappingApiTest() { ENDPOINT = getEndpointPrefix() + "/api"; } @@ -56,7 +57,7 @@ public void testRolesMappingApi() throws Exception { addUserWithPassword("picard", "picardpicardpicard", new String[] { "captains" }, HttpStatus.SC_CREATED); checkWriteAccess(HttpStatus.SC_CREATED, "picard", "picardpicardpicard", "sf", "_doc", 1); // TODO: only one doctype allowed for ES6 - //checkWriteAccess(HttpStatus.SC_CREATED, "picard", "picard", "sf", "_doc", 1); + // checkWriteAccess(HttpStatus.SC_CREATED, "picard", "picard", "sf", "_doc", 1); rh.sendAdminCertificate = true; verifyGetForSuperAdmin(new Header[0]); rh.sendAdminCertificate = true; @@ -65,35 +66,35 @@ public void testRolesMappingApi() throws Exception { verifyPutForSuperAdmin(new Header[0]); verifyPatchForSuperAdmin(new Header[0]); // mapping with several backend roles, one of the is captain - deleteAndPutNewMapping(new Header[0],"rolesmapping_backendroles_captains_list.json", true); + deleteAndPutNewMapping(new Header[0], "rolesmapping_backendroles_captains_list.json", true); checkAllSfAllowed(); // mapping with one backend role, captain - deleteAndPutNewMapping(new Header[0],"rolesmapping_backendroles_captains_single.json", true); + deleteAndPutNewMapping(new Header[0], "rolesmapping_backendroles_captains_single.json", true); checkAllSfAllowed(); // mapping with several users, one is picard - deleteAndPutNewMapping(new Header[0],"rolesmapping_users_picard_list.json", true); + deleteAndPutNewMapping(new Header[0], "rolesmapping_users_picard_list.json", true); checkAllSfAllowed(); // just user picard - deleteAndPutNewMapping(new Header[0],"rolesmapping_users_picard_single.json", true); + deleteAndPutNewMapping(new Header[0], "rolesmapping_users_picard_single.json", true); checkAllSfAllowed(); // hosts - deleteAndPutNewMapping(new Header[0],"rolesmapping_hosts_list.json", true); + deleteAndPutNewMapping(new Header[0], "rolesmapping_hosts_list.json", true); checkAllSfAllowed(); // hosts - deleteAndPutNewMapping(new Header[0],"rolesmapping_hosts_single.json", true); + deleteAndPutNewMapping(new Header[0], "rolesmapping_hosts_single.json", true); checkAllSfAllowed(); // full settings, access - deleteAndPutNewMapping(new Header[0],"rolesmapping_all_access.json", true); + deleteAndPutNewMapping(new Header[0], "rolesmapping_all_access.json", true); checkAllSfAllowed(); // full settings, no access - deleteAndPutNewMapping(new Header[0],"rolesmapping_all_noaccess.json", true); + deleteAndPutNewMapping(new Header[0], "rolesmapping_all_noaccess.json", true); checkAllSfForbidden(); } @@ -110,42 +111,42 @@ public void testRolesMappingApiWithFullPermissions() throws Exception { addUserWithPassword("picard", "picardpicardpicard", new String[] { "captains" }, HttpStatus.SC_CREATED); checkWriteAccess(HttpStatus.SC_CREATED, "picard", "picardpicardpicard", "sf", "_doc", 1); // TODO: only one doctype allowed for ES6 - //checkWriteAccess(HttpStatus.SC_CREATED, "picard", "picard", "sf", "_doc", 1); + // checkWriteAccess(HttpStatus.SC_CREATED, "picard", "picard", "sf", "_doc", 1); - verifyGetForSuperAdmin(new Header[]{restApiAdminHeader}); - verifyDeleteForSuperAdmin(new Header[]{restApiAdminHeader}, false); - verifyPutForSuperAdmin(new Header[]{restApiAdminHeader}); - verifyPatchForSuperAdmin(new Header[]{restApiAdminHeader}); + verifyGetForSuperAdmin(new Header[] { restApiAdminHeader }); + verifyDeleteForSuperAdmin(new Header[] { restApiAdminHeader }, false); + verifyPutForSuperAdmin(new Header[] { restApiAdminHeader }); + verifyPatchForSuperAdmin(new Header[] { restApiAdminHeader }); // mapping with several backend roles, one of the is captain - deleteAndPutNewMapping(new Header[]{restApiAdminHeader}, "rolesmapping_backendroles_captains_list.json", false); + deleteAndPutNewMapping(new Header[] { restApiAdminHeader }, "rolesmapping_backendroles_captains_list.json", false); checkAllSfAllowed(); // mapping with one backend role, captain - deleteAndPutNewMapping(new Header[]{restApiAdminHeader},"rolesmapping_backendroles_captains_single.json", true); + deleteAndPutNewMapping(new Header[] { restApiAdminHeader }, "rolesmapping_backendroles_captains_single.json", true); checkAllSfAllowed(); // mapping with several users, one is picard - deleteAndPutNewMapping(new Header[]{restApiAdminHeader},"rolesmapping_users_picard_list.json", true); + deleteAndPutNewMapping(new Header[] { restApiAdminHeader }, "rolesmapping_users_picard_list.json", true); checkAllSfAllowed(); // just user picard - deleteAndPutNewMapping(new Header[]{restApiAdminHeader},"rolesmapping_users_picard_single.json", true); + deleteAndPutNewMapping(new Header[] { restApiAdminHeader }, "rolesmapping_users_picard_single.json", true); checkAllSfAllowed(); // hosts - deleteAndPutNewMapping(new Header[]{restApiAdminHeader},"rolesmapping_hosts_list.json", true); + deleteAndPutNewMapping(new Header[] { restApiAdminHeader }, "rolesmapping_hosts_list.json", true); checkAllSfAllowed(); // hosts - deleteAndPutNewMapping(new Header[]{restApiAdminHeader},"rolesmapping_hosts_single.json", true); + deleteAndPutNewMapping(new Header[] { restApiAdminHeader }, "rolesmapping_hosts_single.json", true); checkAllSfAllowed(); // full settings, access - deleteAndPutNewMapping(new Header[]{restApiAdminHeader},"rolesmapping_all_access.json", true); + deleteAndPutNewMapping(new Header[] { restApiAdminHeader }, "rolesmapping_all_access.json", true); checkAllSfAllowed(); // full settings, no access - deleteAndPutNewMapping(new Header[]{restApiAdminHeader},"rolesmapping_all_noaccess.json", true); + deleteAndPutNewMapping(new Header[] { restApiAdminHeader }, "rolesmapping_all_noaccess.json", true); checkAllSfForbidden(); } @@ -166,7 +167,6 @@ void verifyGetForSuperAdmin(final Header[] header) throws Exception { // Superadmin should be able to see reserved rolesmapping Assert.assertTrue(response.getBody().contains("opendistro_security_reserved")); - // -- GET // GET opendistro_security_role_starfleet, exists response = rh.executeGetRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet", header); @@ -242,26 +242,34 @@ void verifyPutForSuperAdmin(final Header[] header) throws Exception { Assert.assertEquals(AbstractConfigurationValidator.ErrorType.PAYLOAD_MANDATORY.getMessage(), settings.get("reason")); // put new configuration with invalid payload, must fail - response = rh.executePutRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/rolesmapping_not_parseable.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/rolesmapping_not_parseable.json"), + header + ); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.BODY_NOT_PARSEABLE.getMessage(), settings.get("reason")); // put new configuration with invalid keys, must fail - response = rh.executePutRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/rolesmapping_invalid_keys.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/rolesmapping_invalid_keys.json"), + header + ); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.INVALID_CONFIGURATION.getMessage(), settings.get("reason")); Assert.assertTrue(settings.get(AbstractConfigurationValidator.INVALID_KEYS_KEY + ".keys").contains("theusers")); - Assert.assertTrue( - settings.get(AbstractConfigurationValidator.INVALID_KEYS_KEY + ".keys").contains("thebackendroles")); + Assert.assertTrue(settings.get(AbstractConfigurationValidator.INVALID_KEYS_KEY + ".keys").contains("thebackendroles")); Assert.assertTrue(settings.get(AbstractConfigurationValidator.INVALID_KEYS_KEY + ".keys").contains("thehosts")); // wrong datatypes - response = rh.executePutRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/rolesmapping_backendroles_captains_single_wrong_datatype.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/rolesmapping_backendroles_captains_single_wrong_datatype.json"), + header + ); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.WRONG_DATATYPE.getMessage(), settings.get("reason")); @@ -269,8 +277,11 @@ void verifyPutForSuperAdmin(final Header[] header) throws Exception { Assert.assertTrue(settings.get("hosts") == null); Assert.assertTrue(settings.get("users") == null); - response = rh.executePutRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/rolesmapping_hosts_single_wrong_datatype.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/rolesmapping_hosts_single_wrong_datatype.json"), + header + ); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.WRONG_DATATYPE.getMessage(), settings.get("reason")); @@ -278,8 +289,11 @@ void verifyPutForSuperAdmin(final Header[] header) throws Exception { Assert.assertTrue(settings.get("backend_roles") == null); Assert.assertTrue(settings.get("users") == null); - response = rh.executePutRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/rolesmapping_users_picard_single_wrong_datatype.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/rolesmapping_users_picard_single_wrong_datatype.json"), + header + ); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.WRONG_DATATYPE.getMessage(), settings.get("reason")); @@ -289,46 +303,70 @@ void verifyPutForSuperAdmin(final Header[] header) throws Exception { // Read only role mapping // SuperAdmin can add read only roles - mappings - response = rh.executePutRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_library", - FileHelper.loadFile("restapi/rolesmapping_all_access.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_library", + FileHelper.loadFile("restapi/rolesmapping_all_access.json"), + header + ); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); // hidden role, allowed for super admin - response = rh.executePutRequest(ENDPOINT + "/rolesmapping/opendistro_security_internal", - FileHelper.loadFile("restapi/rolesmapping_all_access.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/rolesmapping/opendistro_security_internal", + FileHelper.loadFile("restapi/rolesmapping_all_access.json"), + header + ); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); - response = rh.executePutRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/rolesmapping_all_access.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/rolesmapping_all_access.json"), + header + ); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); } void verifyPatchForSuperAdmin(final Header[] header) throws Exception { // PATCH on non-existing resource - HttpResponse response = rh.executePatchRequest(ENDPOINT + "/rolesmapping/imnothere", "[{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }]", header); + HttpResponse response = rh.executePatchRequest( + ENDPOINT + "/rolesmapping/imnothere", + "[{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }]", + header + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // PATCH read only resource, must be forbidden // SuperAdmin can patch read-only resource - response = rh.executePatchRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_library", - "[{ \"op\": \"add\", \"path\": \"/description\", \"value\": \"foo\"] }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_library", + "[{ \"op\": \"add\", \"path\": \"/description\", \"value\": \"foo\"] }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // PATCH hidden resource, must be not found, can be found by super admin - response = rh.executePatchRequest(ENDPOINT + "/rolesmapping/opendistro_security_internal", - "[{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ " + - "\"foo\", \"bar\" ] }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/rolesmapping/opendistro_security_internal", + "[{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ " + "\"foo\", \"bar\" ] }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // PATCH value of hidden flag, must fail with validation error - response = rh.executePatchRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_vulcans", - "[{ \"op\": \"add\", \"path\": \"/hidden\", \"value\": true }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/rolesmapping/opendistro_security_role_vulcans", + "[{ \"op\": \"add\", \"path\": \"/hidden\", \"value\": true }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertTrue(response.getBody().matches(".*\"invalid_keys\"\\s*:\\s*\\{\\s*\"keys\"\\s*:\\s*\"hidden\"\\s*\\}.*")); // PATCH - response = rh.executePatchRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_vulcans", - "[{ \"op\": \"add\", \"path\": \"/backend_roles/-\", \"value\": \"spring\" }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/rolesmapping/opendistro_security_role_vulcans", + "[{ \"op\": \"add\", \"path\": \"/backend_roles/-\", \"value\": \"spring\" }]", + header + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executeGetRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_vulcans", header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); @@ -339,32 +377,48 @@ void verifyPatchForSuperAdmin(final Header[] header) throws Exception { // -- PATCH on whole config resource // PATCH on non-existing resource - response = rh.executePatchRequest(ENDPOINT + "/rolesmapping", - "[{ \"op\": \"add\", \"path\": \"/imnothere/a\", \"value\": [ \"foo\", \"bar\" ] }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/rolesmapping", + "[{ \"op\": \"add\", \"path\": \"/imnothere/a\", \"value\": [ \"foo\", \"bar\" ] }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // PATCH read only resource, must be forbidden // SuperAdmin can patch read only resource rh.sendAdminCertificate = true; - response = rh.executePatchRequest(ENDPOINT + "/rolesmapping", - "[{ \"op\": \"add\", \"path\": \"/opendistro_security_role_starfleet_library/description\", \"value\": \"foo\" }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/rolesmapping", + "[{ \"op\": \"add\", \"path\": \"/opendistro_security_role_starfleet_library/description\", \"value\": \"foo\" }]", + header + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); // PATCH hidden resource, must be bad request rh.sendAdminCertificate = true; - response = rh.executePatchRequest(ENDPOINT + "/rolesmapping", "[{ \"op\": \"add\", \"path\": \"/opendistro_security_internal/a\", \"value\": [ \"foo\", \"bar\" ] }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/rolesmapping", + "[{ \"op\": \"add\", \"path\": \"/opendistro_security_internal/a\", \"value\": [ \"foo\", \"bar\" ] }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // PATCH value of hidden flag, must fail with validation error rh.sendAdminCertificate = true; - response = rh.executePatchRequest(ENDPOINT + "/rolesmapping", - "[{ \"op\": \"add\", \"path\": \"/opendistro_security_role_vulcans/hidden\", \"value\": true }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/rolesmapping", + "[{ \"op\": \"add\", \"path\": \"/opendistro_security_role_vulcans/hidden\", \"value\": true }]", + header + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertTrue(response.getBody().matches(".*\"invalid_keys\"\\s*:\\s*\\{\\s*\"keys\"\\s*:\\s*\"hidden\"\\s*\\}.*")); // PATCH - response = rh.executePatchRequest(ENDPOINT + "/rolesmapping", - "[{ \"op\": \"add\", \"path\": \"/bulknew1\", \"value\": { \"backend_roles\":[\"vulcanadmin\"]} }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/rolesmapping", + "[{ \"op\": \"add\", \"path\": \"/bulknew1\", \"value\": { \"backend_roles\":[\"vulcanadmin\"]} }]", + header + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executeGetRequest(ENDPOINT + "/rolesmapping/bulknew1", header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); @@ -394,11 +448,13 @@ private void checkAllSfForbidden() throws Exception { private HttpResponse deleteAndPutNewMapping(final Header[] header, final String fileName, final boolean useAdminCert) throws Exception { rh.sendAdminCertificate = useAdminCert; - HttpResponse response = rh.executeDeleteRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", - header); + HttpResponse response = rh.executeDeleteRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - response = rh.executePutRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", - FileHelper.loadFile("restapi/"+fileName), header); + response = rh.executePutRequest( + ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", + FileHelper.loadFile("restapi/" + fileName), + header + ); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); rh.sendAdminCertificate = false; return response; @@ -421,27 +477,38 @@ public void testRolesMappingApiForNonSuperAdminRestApiUser() throws Exception { setupWithRestRoles(); rh.sendAdminCertificate = false; final Header restApiHeader = encodeBasicHeader("test", "test"); - verifyNonSuperAdminUser(new Header[] {restApiHeader}); + verifyNonSuperAdminUser(new Header[] { restApiHeader }); } void verifyNonSuperAdminUser(final Header[] header) throws Exception { HttpResponse response; // Delete read only roles mapping - response = rh.executeDeleteRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_library" , header); + response = rh.executeDeleteRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_library", header); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // Put read only roles mapping - response = rh.executePutRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_library", - FileHelper.loadFile("restapi/rolesmapping_all_access.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_library", + FileHelper.loadFile("restapi/rolesmapping_all_access.json"), + header + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // Patch single read only roles mapping - response = rh.executePatchRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_library", "[{ \"op\": \"add\", \"path\": \"/description\", \"value\": \"foo\" }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_library", + "[{ \"op\": \"add\", \"path\": \"/description\", \"value\": \"foo\" }]", + header + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // Patch multiple read only roles mapping - response = rh.executePatchRequest(ENDPOINT + "/rolesmapping", "[{ \"op\": \"add\", \"path\": \"/opendistro_security_role_starfleet_library/description\", \"value\": \"foo\" }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/rolesmapping", + "[{ \"op\": \"add\", \"path\": \"/opendistro_security_role_starfleet_library/description\", \"value\": \"foo\" }]", + header + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // GET, rolesmapping is hidden, allowed for super admin @@ -449,21 +516,33 @@ void verifyNonSuperAdminUser(final Header[] header) throws Exception { Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // Delete hidden roles mapping - response = rh.executeDeleteRequest(ENDPOINT + "/rolesmapping/opendistro_security_internal" , header); + response = rh.executeDeleteRequest(ENDPOINT + "/rolesmapping/opendistro_security_internal", header); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // Put hidden roles mapping - response = rh.executePutRequest(ENDPOINT + "/rolesmapping/opendistro_security_internal", - FileHelper.loadFile("restapi/rolesmapping_all_access.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/rolesmapping/opendistro_security_internal", + FileHelper.loadFile("restapi/rolesmapping_all_access.json"), + header + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // Patch hidden roles mapping - response = rh.executePatchRequest(ENDPOINT + "/rolesmapping/opendistro_security_internal", "[{ \"op\": \"add\", \"path\": \"/description\", \"value\": \"foo\" }]", header); + response = rh.executePatchRequest( + ENDPOINT + "/rolesmapping/opendistro_security_internal", + "[{ \"op\": \"add\", \"path\": \"/description\", \"value\": \"foo\" }]", + header + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // Patch multiple hidden roles mapping - response = rh.executePatchRequest(ENDPOINT + "/rolesmapping", "[{ \"op\": \"add\", \"path\": \"/opendistro_security_internal/description\", \"value\": \"foo\" }]", header); - Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); } + response = rh.executePatchRequest( + ENDPOINT + "/rolesmapping", + "[{ \"op\": \"add\", \"path\": \"/opendistro_security_internal/description\", \"value\": \"foo\" }]", + header + ); + Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); + } @Test public void testChangeRestApiAdminRoleMappingForbiddenForNonSuperAdmin() throws Exception { @@ -475,16 +554,22 @@ public void testChangeRestApiAdminRoleMappingForbiddenForNonSuperAdmin() throws final Header restApiHeader = encodeBasicHeader("test", "test"); HttpResponse response = rh.executePutRequest( - ENDPOINT + "/roles/new_rest_api_role", - createRestAdminPermissionsPayload(), restApiAdminHeader); + ENDPOINT + "/roles/new_rest_api_role", + createRestAdminPermissionsPayload(), + restApiAdminHeader + ); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); response = rh.executePutRequest( - ENDPOINT + "/roles/new_rest_api_role_without_mapping", - createRestAdminPermissionsPayload(), restApiAdminHeader); + ENDPOINT + "/roles/new_rest_api_role_without_mapping", + createRestAdminPermissionsPayload(), + restApiAdminHeader + ); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); response = rh.executePutRequest( - ENDPOINT + "/rolesmapping/new_rest_api_role", - createUsersPayload("a", "b", "c"), restApiAdminHeader); + ENDPOINT + "/rolesmapping/new_rest_api_role", + createUsersPayload("a", "b", "c"), + restApiAdminHeader + ); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); verifyRestApiPutAndDeleteForNonRestApiAdmin(adminHeader); @@ -497,11 +582,13 @@ public void testChangeRestApiAdminRoleMappingForbiddenForNonSuperAdmin() throws private void verifyRestApiPutAndDeleteForNonRestApiAdmin(final Header header) throws Exception { HttpResponse response = rh.executePutRequest( - ENDPOINT + "/rolesmapping/new_rest_api_role", createUsersPayload("a", "b", "c"), header); + ENDPOINT + "/rolesmapping/new_rest_api_role", + createUsersPayload("a", "b", "c"), + header + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); - response = rh.executeDeleteRequest( - ENDPOINT + "/rolesmapping/new_rest_api_role", "", header); + response = rh.executeDeleteRequest(ENDPOINT + "/rolesmapping/new_rest_api_role", "", header); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); } @@ -552,28 +639,29 @@ private String createPathPayload(final String op) throws JsonProcessingException } @Test - public void checkNullElementsInArray() throws Exception{ + public void checkNullElementsInArray() throws Exception { setup(); rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; String body = FileHelper.loadFile("restapi/rolesmapping_null_array_element_users.json"); - HttpResponse response = rh.executePutRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", - body, new Header[0]); + HttpResponse response = rh.executePutRequest( + ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", + body, + new Header[0] + ); Settings settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.NULL_ARRAY_ELEMENT.getMessage(), settings.get("reason")); body = FileHelper.loadFile("restapi/rolesmapping_null_array_element_backend_roles.json"); - response = rh.executePutRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", - body, new Header[0]); + response = rh.executePutRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", body, new Header[0]); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.NULL_ARRAY_ELEMENT.getMessage(), settings.get("reason")); body = FileHelper.loadFile("restapi/rolesmapping_null_array_element_hosts.json"); - response = rh.executePutRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", - body, new Header[0]); + response = rh.executePutRequest(ENDPOINT + "/rolesmapping/opendistro_security_role_starfleet_captains", body, new Header[0]); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.NULL_ARRAY_ELEMENT.getMessage(), settings.get("reason")); diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityApiAccessTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityApiAccessTest.java index 83630c036a..81fad7d4ff 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityApiAccessTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityApiAccessTest.java @@ -18,12 +18,13 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class SecurityApiAccessTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; + protected String getEndpointPrefix() { return PLUGINS_PREFIX; } - public SecurityApiAccessTest(){ + public SecurityApiAccessTest() { ENDPOINT = getEndpointPrefix() + "/api/internalusers"; } @@ -33,22 +34,14 @@ public void testRestApi() throws Exception { setup(); // test with no cert, must fail - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, - rh.executeGetRequest(ENDPOINT).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, - rh.executeGetRequest(ENDPOINT, - encodeBasicHeader("admin", "admin")) - .getStatusCode()); + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest(ENDPOINT).getStatusCode()); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest(ENDPOINT, encodeBasicHeader("admin", "admin")).getStatusCode()); // test with non-admin cert, must fail rh.keystore = "restapi/node-0-keystore.jks"; rh.sendAdminCertificate = true; - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, - rh.executeGetRequest(ENDPOINT).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, - rh.executeGetRequest(ENDPOINT, - encodeBasicHeader("admin", "admin")) - .getStatusCode()); + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest(ENDPOINT).getStatusCode()); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest(ENDPOINT, encodeBasicHeader("admin", "admin")).getStatusCode()); } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityConfigApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityConfigApiTest.java index d717dcbf6c..8fc6ae1dd8 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityConfigApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityConfigApiTest.java @@ -25,12 +25,13 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class SecurityConfigApiTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; + protected String getEndpointPrefix() { return PLUGINS_PREFIX; } - public SecurityConfigApiTest(){ + public SecurityConfigApiTest() { ENDPOINT = getEndpointPrefix() + "/api"; } @@ -57,11 +58,13 @@ public void testSecurityConfigApiRead() throws Exception { response = rh.executeDeleteRequest(ENDPOINT + "/securityconfig", new Header[0]); Assert.assertEquals(HttpStatus.SC_METHOD_NOT_ALLOWED, response.getStatusCode()); } - + @Test public void testSecurityConfigApiWrite() throws Exception { - Settings settings = Settings.builder().put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true).build(); + Settings settings = Settings.builder() + .put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true) + .build(); setup(settings); rh.keystore = "restapi/kirk-keystore.jks"; @@ -70,13 +73,25 @@ public void testSecurityConfigApiWrite() throws Exception { HttpResponse response = rh.executeGetRequest(ENDPOINT + "/securityconfig", new Header[0]); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - response = rh.executePutRequest(ENDPOINT + "/securityconfig/xxx", FileHelper.loadFile("restapi/securityconfig.json"), new Header[0]); + response = rh.executePutRequest( + ENDPOINT + "/securityconfig/xxx", + FileHelper.loadFile("restapi/securityconfig.json"), + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); - response = rh.executePutRequest(ENDPOINT + "/securityconfig/config", FileHelper.loadFile("restapi/securityconfig.json"), new Header[0]); + response = rh.executePutRequest( + ENDPOINT + "/securityconfig/config", + FileHelper.loadFile("restapi/securityconfig.json"), + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - response = rh.executePutRequest(ENDPOINT + "/securityconfig/config", FileHelper.loadFile("restapi/invalid_config.json"), new Header[0]); + response = rh.executePutRequest( + ENDPOINT + "/securityconfig/config", + FileHelper.loadFile("restapi/invalid_config.json"), + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, response.getStatusCode()); Assert.assertTrue(response.getContentType(), response.isJsonContentType()); Assert.assertTrue(response.getBody().contains("Unrecognized field")); @@ -87,7 +102,11 @@ public void testSecurityConfigApiWrite() throws Exception { response = rh.executePostRequest(ENDPOINT + "/securityconfig", "{\"xxx\": 1}", new Header[0]); Assert.assertEquals(HttpStatus.SC_METHOD_NOT_ALLOWED, response.getStatusCode()); - response = rh.executePatchRequest(ENDPOINT + "/securityconfig", "[{\"op\": \"replace\",\"path\": \"/config/dynamic/hosts_resolver_mode\",\"value\": \"other\"}]", new Header[0]); + response = rh.executePatchRequest( + ENDPOINT + "/securityconfig", + "[{\"op\": \"replace\",\"path\": \"/config/dynamic/hosts_resolver_mode\",\"value\": \"other\"}]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executeDeleteRequest(ENDPOINT + "/securityconfig", new Header[0]); @@ -98,30 +117,35 @@ public void testSecurityConfigApiWrite() throws Exception { @Test public void testSecurityConfigForHTTPPatch() throws Exception { - Settings settings = Settings.builder().put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true).build(); + Settings settings = Settings.builder() + .put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true) + .build(); setup(settings); rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - //non-default config + // non-default config String updatedConfig = FileHelper.loadFile("restapi/securityconfig_nondefault.json"); - //update config + // update config HttpResponse response = rh.executePutRequest(ENDPOINT + "/securityconfig/config", updatedConfig, new Header[0]); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - //make patch request - response = rh.executePatchRequest(ENDPOINT + "/securityconfig", "[{\"op\": \"add\",\"path\": \"/config/dynamic/do_not_fail_on_forbidden\",\"value\": \"false\"}]", new Header[0]); + // make patch request + response = rh.executePatchRequest( + ENDPOINT + "/securityconfig", + "[{\"op\": \"add\",\"path\": \"/config/dynamic/do_not_fail_on_forbidden\",\"value\": \"false\"}]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - //get config + // get config response = rh.executeGetRequest(ENDPOINT + "/securityconfig", new Header[0]); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); // verify configs are same Assert.assertEquals(DefaultObjectMapper.readTree(updatedConfig), DefaultObjectMapper.readTree(response.getBody()).get("config")); - } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityHealthActionTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityHealthActionTest.java index 13dc4ee885..d7a6edfea9 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityHealthActionTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityHealthActionTest.java @@ -22,18 +22,21 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class SecurityHealthActionTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; + protected String getEndpointPrefix() { return PLUGINS_PREFIX; } - public SecurityHealthActionTest(){ + public SecurityHealthActionTest() { ENDPOINT = getEndpointPrefix(); } @Test public void testSecurityHealthAPI() throws Exception { - Settings settings = Settings.builder().put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true).build(); + Settings settings = Settings.builder() + .put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true) + .build(); setup(settings); rh.keystore = "restapi/kirk-keystore.jks"; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityInfoActionTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityInfoActionTest.java index 506ea3bdd2..db27be85ee 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityInfoActionTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityInfoActionTest.java @@ -22,18 +22,21 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class SecurityInfoActionTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; + protected String getEndpointPrefix() { return PLUGINS_PREFIX; } - public SecurityInfoActionTest(){ + public SecurityInfoActionTest() { ENDPOINT = getEndpointPrefix() + "/authinfo"; } @Test public void testSecurityInfoAPI() throws Exception { - Settings settings = Settings.builder().put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true).build(); + Settings settings = Settings.builder() + .put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true) + .build(); setup(settings); rh.keystore = "restapi/kirk-keystore.jks"; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/SslCertsApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/SslCertsApiTest.java index 425c2dca50..8797d196f5 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/SslCertsApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/SslCertsApiTest.java @@ -36,32 +36,38 @@ public class SslCertsApiTest extends AbstractRestApiUnitTest { static final String TRANSPORT_CERTS = "transport"; - private final static List> EXPECTED_CERTIFICATES = - ImmutableList.of( - ImmutableMap.of( - "issuer_dn", "CN=Example Com Inc. Signing CA,OU=Example Com Inc. Signing CA,O=Example Com Inc.,DC=example,DC=com", - "subject_dn", "CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE", - "san", "[[2, node-0.example.com], [2, localhost], [7, 127.0.0.1], [8, 1.2.3.4.5.5]]", - "not_before", "2018-05-05T14:37:09Z", - "not_after", "2028-05-02T14:37:09Z" - ), - ImmutableMap.of( - "issuer_dn", "CN=Example Com Inc. Root CA,OU=Example Com Inc. Root CA,O=Example Com Inc.,DC=example,DC=com", - "subject_dn", "CN=Example Com Inc. Signing CA,OU=Example Com Inc. Signing CA,O=Example Com Inc.,DC=example,DC=com", - "san", "", - "not_before", "2018-05-05T14:37:08Z", - "not_after", "2028-05-04T14:37:08Z" - ) - ); + private final static List> EXPECTED_CERTIFICATES = ImmutableList.of( + ImmutableMap.of( + "issuer_dn", + "CN=Example Com Inc. Signing CA,OU=Example Com Inc. Signing CA,O=Example Com Inc.,DC=example,DC=com", + "subject_dn", + "CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE", + "san", + "[[2, node-0.example.com], [2, localhost], [7, 127.0.0.1], [8, 1.2.3.4.5.5]]", + "not_before", + "2018-05-05T14:37:09Z", + "not_after", + "2028-05-02T14:37:09Z" + ), + ImmutableMap.of( + "issuer_dn", + "CN=Example Com Inc. Root CA,OU=Example Com Inc. Root CA,O=Example Com Inc.,DC=example,DC=com", + "subject_dn", + "CN=Example Com Inc. Signing CA,OU=Example Com Inc. Signing CA,O=Example Com Inc.,DC=example,DC=com", + "san", + "", + "not_before", + "2018-05-05T14:37:08Z", + "not_after", + "2028-05-04T14:37:08Z" + ) + ); private final static String EXPECTED_CERTIFICATES_BY_TYPE; static { try { EXPECTED_CERTIFICATES_BY_TYPE = DefaultObjectMapper.objectMapper.writeValueAsString( - ImmutableMap.of( - "http_certificates_list", EXPECTED_CERTIFICATES, - "transport_certificates_list", EXPECTED_CERTIFICATES - ) + ImmutableMap.of("http_certificates_list", EXPECTED_CERTIFICATES, "transport_certificates_list", EXPECTED_CERTIFICATES) ); } catch (JsonProcessingException e) { throw new RuntimeException(e); @@ -71,11 +77,13 @@ public class SslCertsApiTest extends AbstractRestApiUnitTest { private final Header restApiAdminHeader = encodeBasicHeader("rest_api_admin_user", "rest_api_admin_user"); private final Header restApiCertsInfoAdminHeader = encodeBasicHeader("rest_api_admin_ssl_info", "rest_api_admin_ssl_info"); - private final Header restApiReloadCertsAdminHeader = encodeBasicHeader("rest_api_admin_ssl_reloadcerts", "rest_api_admin_ssl_reloadcerts"); + private final Header restApiReloadCertsAdminHeader = encodeBasicHeader( + "rest_api_admin_ssl_reloadcerts", + "rest_api_admin_ssl_reloadcerts" + ); private final Header restApiHeader = encodeBasicHeader("test", "test"); - public String certsInfoEndpoint() { return PLUGINS_PREFIX + "/api/ssl/certs"; } @@ -165,9 +173,7 @@ private void sendAdminCert() { } Settings reloadEnabled() { - return Settings.builder() - .put(ConfigConstants.SECURITY_SSL_CERT_RELOAD_ENABLED, true) - .build(); + return Settings.builder().put(ConfigConstants.SECURITY_SSL_CERT_RELOAD_ENABLED, true).build(); } } 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 ab7e807153..2c6a45faf7 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 @@ -23,23 +23,26 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class TenantInfoActionTest extends AbstractRestApiUnitTest { - private String payload = "{\"hosts\":[],\"users\":[\"sarek\"]," + - "\"backend_roles\":[\"starfleet*\",\"ambassador\"],\"and_backend_roles\":[],\"description\":\"Migrated " + - "from v6\"}"; + private String payload = "{\"hosts\":[],\"users\":[\"sarek\"]," + + "\"backend_roles\":[\"starfleet*\",\"ambassador\"],\"and_backend_roles\":[],\"description\":\"Migrated " + + "from v6\"}"; private final String BASE_ENDPOINT; - private final String ENDPOINT; + private final String ENDPOINT; + protected String getEndpointPrefix() { return PLUGINS_PREFIX; } - public TenantInfoActionTest(){ + public TenantInfoActionTest() { BASE_ENDPOINT = getEndpointPrefix(); ENDPOINT = getEndpointPrefix() + "/tenantinfo"; } @Test public void testTenantInfoAPIAccess() throws Exception { - Settings settings = Settings.builder().put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true).build(); + Settings settings = Settings.builder() + .put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true) + .build(); setup(settings); rh.keystore = "restapi/kirk-keystore.jks"; @@ -58,16 +61,21 @@ public void testTenantInfoAPIAccess() throws Exception { @Test public void testTenantInfoAPIUpdate() throws Exception { - Settings settings = Settings.builder().put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true).build(); + Settings settings = Settings.builder() + .put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true) + .build(); setup(settings); - + rh.keystore = "restapi/kirk-keystore.jks"; rh.sendHTTPClientCredentials = true; rh.sendAdminCertificate = true; - //update security config - RestHelper.HttpResponse response = rh.executePatchRequest(BASE_ENDPOINT + "/api/securityconfig", "[{\"op\": \"add\",\"path\": \"/config/dynamic/kibana/opendistro_role\"," + - "\"value\": \"opendistro_security_internal\"}]", new Header[0]); + // update security config + RestHelper.HttpResponse response = rh.executePatchRequest( + BASE_ENDPOINT + "/api/securityconfig", + "[{\"op\": \"add\",\"path\": \"/config/dynamic/kibana/opendistro_role\"," + "\"value\": \"opendistro_security_internal\"}]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executePutRequest(BASE_ENDPOINT + "/api/rolesmapping/opendistro_security_internal", payload, new Header[0]); diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/UserApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/UserApiTest.java index abcda9a69c..895f65bc81 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/UserApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/UserApiTest.java @@ -37,43 +37,42 @@ import static org.opensearch.security.dlic.rest.api.InternalUsersApiAction.RESTRICTED_FROM_USERNAME; import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; - public class UserApiTest extends AbstractRestApiUnitTest { private final String ENDPOINT; + protected String getEndpointPrefix() { return PLUGINS_PREFIX; } - final int USER_SETTING_SIZE = 7 * 19; // Lines per account entry * number of accounts - private static final String ENABLED_SERVICE_ACCOUNT_BODY = "{" - + " \"attributes\": { \"service\": \"true\", " - + "\"enabled\": \"true\"}" - + " }\n"; + private static final String ENABLED_SERVICE_ACCOUNT_BODY = "{" + + " \"attributes\": { \"service\": \"true\", " + + "\"enabled\": \"true\"}" + + " }\n"; private static final String DISABLED_SERVICE_ACCOUNT_BODY = "{" - + " \"attributes\": { \"service\": \"true\", " - + "\"enabled\": \"false\"}" - + " }\n"; + + " \"attributes\": { \"service\": \"true\", " + + "\"enabled\": \"false\"}" + + " }\n"; private static final String ENABLED_NOT_SERVICE_ACCOUNT_BODY = "{" - + " \"attributes\": { \"service\": \"false\", " - + "\"enabled\": \"true\"}" - + " }\n"; + + " \"attributes\": { \"service\": \"false\", " + + "\"enabled\": \"true\"}" + + " }\n"; private static final String PASSWORD_SERVICE = "{ \"password\" : \"test\"," - + " \"attributes\": { \"service\": \"true\", " - + "\"enabled\": \"true\"}" - + " }\n"; + + " \"attributes\": { \"service\": \"true\", " + + "\"enabled\": \"true\"}" + + " }\n"; private static final String HASH_SERVICE = "{ \"owner\" : \"test_owner\"," - + " \"attributes\": { \"service\": \"true\", " - + "\"enabled\": \"true\"}" - + " }\n"; + + " \"attributes\": { \"service\": \"true\", " + + "\"enabled\": \"true\"}" + + " }\n"; private static final String PASSWORD_HASH_SERVICE = "{ \"password\" : \"test\", \"hash\" : \"123\"," - + " \"attributes\": { \"service\": \"true\", " - + "\"enabled\": \"true\"}" - + " }\n"; + + " \"attributes\": { \"service\": \"true\", " + + "\"enabled\": \"true\"}" + + " }\n"; - public UserApiTest(){ + public UserApiTest() { ENDPOINT = getEndpointPrefix() + "/api"; } @@ -86,17 +85,16 @@ public void testSecurityRoles() throws Exception { rh.sendAdminCertificate = true; // initial configuration, 6 users - HttpResponse response = rh - .executeGetRequest(ENDPOINT + "/" + CType.INTERNALUSERS.toLCString()); + HttpResponse response = rh.executeGetRequest(ENDPOINT + "/" + CType.INTERNALUSERS.toLCString()); Assert.assertEquals(response.getBody(), HttpStatus.SC_OK, response.getStatusCode()); Settings settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(133, settings.size()); response = rh.executePatchRequest( - ENDPOINT + "/internalusers", - "[{ \"op\": \"add\", \"path\": \"/newuser\", " + - "\"value\": {\"password\": \"fair password for the user\", " + - "\"opendistro_security_roles\": [\"opendistro_security_all_access\"] } }]", - new Header[0] + ENDPOINT + "/internalusers", + "[{ \"op\": \"add\", \"path\": \"/newuser\", " + + "\"value\": {\"password\": \"fair password for the user\", " + + "\"opendistro_security_roles\": [\"opendistro_security_all_access\"] } }]", + new Header[0] ); Assert.assertEquals(response.getBody(), HttpStatus.SC_OK, response.getStatusCode()); @@ -116,8 +114,11 @@ public void testParallelPutRequests() throws Exception { rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - HttpResponse[] responses = rh.executeMultipleAsyncPutRequest(10, - ENDPOINT + "/internalusers/test1", "{\"password\":\"test1test1test1test1test1test1\"}"); + HttpResponse[] responses = rh.executeMultipleAsyncPutRequest( + 10, + ENDPOINT + "/internalusers/test1", + "{\"password\":\"test1test1test1test1test1test1\"}" + ); boolean created = false; for (HttpResponse response : responses) { int sc = response.getStatusCode(); @@ -188,8 +189,7 @@ private void verifyPut(final Header... header) throws Exception { Assert.assertEquals(HttpStatus.SC_METHOD_NOT_ALLOWED, response.getStatusCode()); // Faulty JSON payload - response = rh.executePutRequest(ENDPOINT + "/internalusers/nagilum", "{some: \"thing\" asd other: \"thing\"}", - header); + response = rh.executePutRequest(ENDPOINT + "/internalusers/nagilum", "{some: \"thing\" asd other: \"thing\"}", header); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Settings settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(settings.get("reason"), AbstractConfigurationValidator.ErrorType.BODY_NOT_PARSEABLE.getMessage()); @@ -198,37 +198,44 @@ private void verifyPut(final Header... header) throws Exception { response = rh.executePutRequest(ENDPOINT + "/internalusers/nagilum", "{some: \"thing\", other: \"thing\"}", header); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); - //JK: this should be "Could not parse content of request." because JSON is truly invalid - //Assert.assertEquals(settings.get("reason"), AbstractConfigurationValidator.ErrorType.INVALID_CONFIGURATION.getMessage()); - //Assert.assertTrue(settings.get(AbstractConfigurationValidator.INVALID_KEYS_KEY + ".keys").contains("some")); - //Assert.assertTrue(settings.get(AbstractConfigurationValidator.INVALID_KEYS_KEY + ".keys").contains("other")); + // JK: this should be "Could not parse content of request." because JSON is truly invalid + // Assert.assertEquals(settings.get("reason"), AbstractConfigurationValidator.ErrorType.INVALID_CONFIGURATION.getMessage()); + // Assert.assertTrue(settings.get(AbstractConfigurationValidator.INVALID_KEYS_KEY + ".keys").contains("some")); + // Assert.assertTrue(settings.get(AbstractConfigurationValidator.INVALID_KEYS_KEY + ".keys").contains("other")); // Get hidden role - response = rh.executeGetRequest(ENDPOINT + "/internalusers/hide" , header); + response = rh.executeGetRequest(ENDPOINT + "/internalusers/hide", header); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); Assert.assertTrue(response.getBody().contains("\"hidden\":true")); // Associating with hidden role is allowed (for superadmin) - response = rh.executePutRequest(ENDPOINT + "/internalusers/test", "{ \"opendistro_security_roles\": " + - "[\"opendistro_security_hidden\"]}", header); + response = rh.executePutRequest( + ENDPOINT + "/internalusers/test", + "{ \"opendistro_security_roles\": " + "[\"opendistro_security_hidden\"]}", + header + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); // Associating with reserved role is allowed (for superadmin) - response = rh.executePutRequest(ENDPOINT + "/internalusers/test", "{ \"opendistro_security_roles\": [\"opendistro_security_reserved\"], " + - "\"hash\": \"123\"}", - header); + response = rh.executePutRequest( + ENDPOINT + "/internalusers/test", + "{ \"opendistro_security_roles\": [\"opendistro_security_reserved\"], " + "\"hash\": \"123\"}", + header + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); // Associating with non-existent role is not allowed - response = rh.executePutRequest(ENDPOINT + "/internalusers/nagilum", "{ \"opendistro_security_roles\": [\"non_existent\"]}", - header); + response = rh.executePutRequest( + ENDPOINT + "/internalusers/nagilum", + "{ \"opendistro_security_roles\": [\"non_existent\"]}", + header + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(settings.get("message"), "Role 'non_existent' is not available for role-mapping."); // Wrong config keys - response = rh.executePutRequest(ENDPOINT + "/internalusers/nagilum", "{\"some\": \"thing\", \"other\": \"thing\"}", - header); + response = rh.executePutRequest(ENDPOINT + "/internalusers/nagilum", "{\"some\": \"thing\", \"other\": \"thing\"}", header); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(settings.get("reason"), AbstractConfigurationValidator.ErrorType.INVALID_CONFIGURATION.getMessage()); @@ -241,29 +248,49 @@ private void verifyPatch(final boolean sendAdminCert, Header... restAdminHeader) // -- PATCH // PATCH on non-existing resource rh.sendAdminCertificate = sendAdminCert; - HttpResponse response = rh.executePatchRequest(ENDPOINT + "/internalusers/imnothere", "[{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }]", restAdminHeader); + HttpResponse response = rh.executePatchRequest( + ENDPOINT + "/internalusers/imnothere", + "[{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }]", + restAdminHeader + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // PATCH read only resource, must be forbidden, // but SuperAdmin can PATCH read-only resource rh.sendAdminCertificate = sendAdminCert; - response = rh.executePatchRequest(ENDPOINT + "/internalusers/sarek", "[{ \"op\": \"add\", \"path\": \"/description\", \"value\": \"foo\" }]", restAdminHeader); + response = rh.executePatchRequest( + ENDPOINT + "/internalusers/sarek", + "[{ \"op\": \"add\", \"path\": \"/description\", \"value\": \"foo\" }]", + restAdminHeader + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); // PATCH hidden resource, must be not found, can be found for super admin rh.sendAdminCertificate = sendAdminCert; - response = rh.executePatchRequest(ENDPOINT + "/internalusers/q", "[{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }]", restAdminHeader); + response = rh.executePatchRequest( + ENDPOINT + "/internalusers/q", + "[{ \"op\": \"add\", \"path\": \"/a/b/c\", \"value\": [ \"foo\", \"bar\" ] }]", + restAdminHeader + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // PATCH value of hidden flag, must fail with validation error rh.sendAdminCertificate = sendAdminCert; - response = rh.executePatchRequest(ENDPOINT + "/internalusers/test", "[{ \"op\": \"add\", \"path\": \"/hidden\", \"value\": true }]", restAdminHeader); + response = rh.executePatchRequest( + ENDPOINT + "/internalusers/test", + "[{ \"op\": \"add\", \"path\": \"/hidden\", \"value\": true }]", + restAdminHeader + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertTrue(response.getBody().matches(".*\"invalid_keys\"\\s*:\\s*\\{\\s*\"keys\"\\s*:\\s*\"hidden\"\\s*\\}.*")); // PATCH password rh.sendAdminCertificate = sendAdminCert; - response = rh.executePatchRequest(ENDPOINT + "/internalusers/test", "[{ \"op\": \"add\", \"path\": \"/password\", \"value\": \"neu password 42\" }]", restAdminHeader); + response = rh.executePatchRequest( + ENDPOINT + "/internalusers/test", + "[{ \"op\": \"add\", \"path\": \"/password\", \"value\": \"neu password 42\" }]", + restAdminHeader + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executeGetRequest(ENDPOINT + "/internalusers/test", restAdminHeader); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); @@ -274,34 +301,56 @@ private void verifyPatch(final boolean sendAdminCert, Header... restAdminHeader) // -- PATCH on whole config resource // PATCH on non-existing resource rh.sendAdminCertificate = sendAdminCert; - response = rh.executePatchRequest(ENDPOINT + "/internalusers", "[{ \"op\": \"add\", \"path\": \"/imnothere/a\", \"value\": [ \"foo\", \"bar\" ] }]", restAdminHeader); + response = rh.executePatchRequest( + ENDPOINT + "/internalusers", + "[{ \"op\": \"add\", \"path\": \"/imnothere/a\", \"value\": [ \"foo\", \"bar\" ] }]", + restAdminHeader + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // PATCH read only resource, must be forbidden, // but SuperAdmin can PATCH read only resouce rh.sendAdminCertificate = sendAdminCert; - response = rh.executePatchRequest(ENDPOINT + "/internalusers", "[{ \"op\": \"add\", \"path\": \"/sarek/description\", \"value\": \"foo\" }]", restAdminHeader); + response = rh.executePatchRequest( + ENDPOINT + "/internalusers", + "[{ \"op\": \"add\", \"path\": \"/sarek/description\", \"value\": \"foo\" }]", + restAdminHeader + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); rh.sendAdminCertificate = false; - response = rh.executePatchRequest(ENDPOINT + "/internalusers", "[{ \"op\": \"add\", \"path\": \"/sarek/a\", \"value\": [ \"foo\", \"bar\" ] }]"); + response = rh.executePatchRequest( + ENDPOINT + "/internalusers", + "[{ \"op\": \"add\", \"path\": \"/sarek/a\", \"value\": [ \"foo\", \"bar\" ] }]" + ); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusCode()); // PATCH hidden resource, must be bad request rh.sendAdminCertificate = sendAdminCert; - response = rh.executePatchRequest(ENDPOINT + "/internalusers", "[{ \"op\": \"add\", \"path\": \"/q/a\", \"value\": [ \"foo\", \"bar\" ] }]", restAdminHeader); + response = rh.executePatchRequest( + ENDPOINT + "/internalusers", + "[{ \"op\": \"add\", \"path\": \"/q/a\", \"value\": [ \"foo\", \"bar\" ] }]", + restAdminHeader + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // PATCH value of hidden flag, must fail with validation error rh.sendAdminCertificate = sendAdminCert; - response = rh.executePatchRequest(ENDPOINT + "/internalusers", "[{ \"op\": \"add\", \"path\": \"/test/hidden\", \"value\": true }]", restAdminHeader); + response = rh.executePatchRequest( + ENDPOINT + "/internalusers", + "[{ \"op\": \"add\", \"path\": \"/test/hidden\", \"value\": true }]", + restAdminHeader + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertTrue(response.getBody().matches(".*\"invalid_keys\"\\s*:\\s*\\{\\s*\"keys\"\\s*:\\s*\"hidden\"\\s*\\}.*")); // PATCH rh.sendAdminCertificate = sendAdminCert; - response = rh.executePatchRequest(ENDPOINT + "/internalusers", - "[{ \"op\": \"add\", \"path\": \"/bulknew1\", \"value\": {\"password\": \"bla bla bla password 42\", \"backend_roles\": [\"vulcan\"] } }]", restAdminHeader); + response = rh.executePatchRequest( + ENDPOINT + "/internalusers", + "[{ \"op\": \"add\", \"path\": \"/bulknew1\", \"value\": {\"password\": \"bla bla bla password 42\", \"backend_roles\": [\"vulcan\"] } }]", + restAdminHeader + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executeGetRequest(ENDPOINT + "/internalusers/bulknew1", restAdminHeader); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); @@ -320,46 +369,36 @@ private void verifyPatch(final boolean sendAdminCert, Header... restAdminHeader) // add/update user, user is read only, forbidden // SuperAdmin can add read only users rh.sendAdminCertificate = sendAdminCert; - addUserWithHash("sarek", "$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m", - HttpStatus.SC_OK); + addUserWithHash("sarek", "$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m", HttpStatus.SC_OK); // add/update user, user is hidden, forbidden, allowed for super admin rh.sendAdminCertificate = sendAdminCert; - addUserWithHash("q", "$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m", - HttpStatus.SC_OK); + addUserWithHash("q", "$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m", HttpStatus.SC_OK); // add users rh.sendAdminCertificate = sendAdminCert; - addUserWithHash("nagilum", "$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m", - HttpStatus.SC_CREATED); + addUserWithHash("nagilum", "$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m", HttpStatus.SC_CREATED); // Add enabled service account then get it - response = rh.executePutRequest(ENDPOINT + "/internalusers/happyServiceLive", - ENABLED_SERVICE_ACCOUNT_BODY, restAdminHeader); + response = rh.executePutRequest(ENDPOINT + "/internalusers/happyServiceLive", ENABLED_SERVICE_ACCOUNT_BODY, restAdminHeader); Assert.assertEquals(response.getBody(), HttpStatus.SC_CREATED, response.getStatusCode()); response = rh.executeGetRequest(ENDPOINT + "/internalusers/happyServiceLive", restAdminHeader); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - // Add disabled service account - response = rh.executePutRequest(ENDPOINT + "/internalusers/happyServiceDead", - DISABLED_SERVICE_ACCOUNT_BODY, restAdminHeader); + response = rh.executePutRequest(ENDPOINT + "/internalusers/happyServiceDead", DISABLED_SERVICE_ACCOUNT_BODY, restAdminHeader); Assert.assertEquals(response.getBody(), HttpStatus.SC_CREATED, response.getStatusCode()); - // Add service account with password -- Should Fail - response = rh.executePutRequest(ENDPOINT + "/internalusers/passwordService", - PASSWORD_SERVICE, restAdminHeader); + response = rh.executePutRequest(ENDPOINT + "/internalusers/passwordService", PASSWORD_SERVICE, restAdminHeader); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); - //Add service with hash -- should fail - response = rh.executePutRequest(ENDPOINT + "/internalusers/hashService", - HASH_SERVICE, restAdminHeader); + // Add service with hash -- should fail + response = rh.executePutRequest(ENDPOINT + "/internalusers/hashService", HASH_SERVICE, restAdminHeader); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // Add Service account with password & Hash -- should fail - response = rh.executePutRequest(ENDPOINT + "/internalusers/passwordHashService", - PASSWORD_HASH_SERVICE, restAdminHeader); + response = rh.executePutRequest(ENDPOINT + "/internalusers/passwordHashService", PASSWORD_HASH_SERVICE, restAdminHeader); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); // access must be allowed now @@ -403,12 +442,11 @@ private void verifyPatch(final boolean sendAdminCert, Header... restAdminHeader) rh.sendAdminCertificate = sendAdminCert; // new user, password or hash is mandatory - addUserWithoutPasswordOrHash("nagilum", new String[]{"starfleet"}, HttpStatus.SC_BAD_REQUEST); + addUserWithoutPasswordOrHash("nagilum", new String[] { "starfleet" }, HttpStatus.SC_BAD_REQUEST); // new user, add hash - addUserWithHash("nagilum", "$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m", - HttpStatus.SC_CREATED); + addUserWithHash("nagilum", "$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m", HttpStatus.SC_CREATED); // update user, do not specify hash or password, hash must remain the same - addUserWithoutPasswordOrHash("nagilum", new String[]{"starfleet"}, HttpStatus.SC_OK); + addUserWithoutPasswordOrHash("nagilum", new String[] { "starfleet" }, HttpStatus.SC_OK); // get user, check hash, must be untouched response = rh.executeGetRequest(ENDPOINT + "/internalusers/nagilum", restAdminHeader); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); @@ -421,42 +459,51 @@ private void verifyAuthToken(final boolean sendAdminCert, Header... restAdminHea // Add enabled service account then generate auth token rh.sendAdminCertificate = sendAdminCert; - HttpResponse response = rh.executePutRequest(ENDPOINT + "/internalusers/happyServiceLive", - ENABLED_SERVICE_ACCOUNT_BODY, restAdminHeader); + HttpResponse response = rh.executePutRequest( + ENDPOINT + "/internalusers/happyServiceLive", + ENABLED_SERVICE_ACCOUNT_BODY, + restAdminHeader + ); Assert.assertEquals(response.getBody(), HttpStatus.SC_CREATED, response.getStatusCode()); rh.sendAdminCertificate = sendAdminCert; response = rh.executeGetRequest(ENDPOINT + "/internalusers/happyServiceLive", restAdminHeader); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - response = rh.executePostRequest(ENDPOINT + "/internalusers/happyServiceLive/authtoken", - ENABLED_SERVICE_ACCOUNT_BODY, restAdminHeader); + response = rh.executePostRequest( + ENDPOINT + "/internalusers/happyServiceLive/authtoken", + ENABLED_SERVICE_ACCOUNT_BODY, + restAdminHeader + ); Assert.assertEquals(response.getBody(), HttpStatus.SC_CREATED, response.getStatusCode()); String tokenFromResponse = response.getBody(); byte[] decodedResponse = Base64.getUrlDecoder().decode(tokenFromResponse); String[] decodedResponseString = new String(decodedResponse).split(":", 2); String username = decodedResponseString[0]; String password = decodedResponseString[1]; - Assert.assertEquals("Username is: " + username,username, "happyServiceLive"); + Assert.assertEquals("Username is: " + username, username, "happyServiceLive"); // Add disabled service account then try to get its auth token rh.sendAdminCertificate = sendAdminCert; - response = rh.executePutRequest(ENDPOINT + "/internalusers/happyServiceDead", - DISABLED_SERVICE_ACCOUNT_BODY, restAdminHeader); + response = rh.executePutRequest(ENDPOINT + "/internalusers/happyServiceDead", DISABLED_SERVICE_ACCOUNT_BODY, restAdminHeader); Assert.assertEquals(response.getBody(), HttpStatus.SC_CREATED, response.getStatusCode()); - response = rh.executePostRequest(ENDPOINT + "/internalusers/happyServiceDead/authtoken", - ENABLED_SERVICE_ACCOUNT_BODY, restAdminHeader); + response = rh.executePostRequest( + ENDPOINT + "/internalusers/happyServiceDead/authtoken", + ENABLED_SERVICE_ACCOUNT_BODY, + restAdminHeader + ); Assert.assertEquals(response.getBody(), HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); - // Add enabled non-service account rh.sendAdminCertificate = sendAdminCert; - response = rh.executePutRequest(ENDPOINT + "/internalusers/user_is_owner_1", - ENABLED_NOT_SERVICE_ACCOUNT_BODY, restAdminHeader); + response = rh.executePutRequest(ENDPOINT + "/internalusers/user_is_owner_1", ENABLED_NOT_SERVICE_ACCOUNT_BODY, restAdminHeader); Assert.assertEquals(HttpStatus.SC_CREATED, response.getStatusCode()); - response = rh.executePostRequest(ENDPOINT + "/internalusers/user_is_owner_1/authtoken", - ENABLED_SERVICE_ACCOUNT_BODY, restAdminHeader); + response = rh.executePostRequest( + ENDPOINT + "/internalusers/user_is_owner_1/authtoken", + ENABLED_SERVICE_ACCOUNT_BODY, + restAdminHeader + ); Assert.assertEquals(response.getBody(), HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); } @@ -464,7 +511,11 @@ private void verifyAuthToken(final boolean sendAdminCert, Header... restAdminHea private void verifyRoles(final boolean sendAdminCert, Header... header) throws Exception { // wrong datatypes in roles file rh.sendAdminCertificate = sendAdminCert; - HttpResponse response = rh.executePutRequest(ENDPOINT + "/internalusers/picard", FileHelper.loadFile("restapi/users_wrong_datatypes.json"), header); + HttpResponse response = rh.executePutRequest( + ENDPOINT + "/internalusers/picard", + FileHelper.loadFile("restapi/users_wrong_datatypes.json"), + header + ); Settings settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.WRONG_DATATYPE.getMessage(), settings.get("reason")); @@ -472,7 +523,11 @@ private void verifyRoles(final boolean sendAdminCert, Header... header) throws E rh.sendAdminCertificate = false; rh.sendAdminCertificate = sendAdminCert; - response = rh.executePutRequest(ENDPOINT + "/internalusers/picard", FileHelper.loadFile("restapi/users_wrong_datatypes.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/internalusers/picard", + FileHelper.loadFile("restapi/users_wrong_datatypes.json"), + header + ); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.WRONG_DATATYPE.getMessage(), settings.get("reason")); @@ -480,7 +535,11 @@ private void verifyRoles(final boolean sendAdminCert, Header... header) throws E rh.sendAdminCertificate = false; rh.sendAdminCertificate = sendAdminCert; - response = rh.executePutRequest(ENDPOINT + "/internalusers/picard", FileHelper.loadFile("restapi/users_wrong_datatypes2.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/internalusers/picard", + FileHelper.loadFile("restapi/users_wrong_datatypes2.json"), + header + ); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.WRONG_DATATYPE.getMessage(), settings.get("reason")); @@ -489,7 +548,11 @@ private void verifyRoles(final boolean sendAdminCert, Header... header) throws E rh.sendAdminCertificate = false; rh.sendAdminCertificate = sendAdminCert; - response = rh.executePutRequest(ENDPOINT + "/internalusers/picard", FileHelper.loadFile("restapi/users_wrong_datatypes3.json"), header); + response = rh.executePutRequest( + ENDPOINT + "/internalusers/picard", + FileHelper.loadFile("restapi/users_wrong_datatypes3.json"), + header + ); settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); Assert.assertEquals(AbstractConfigurationValidator.ErrorType.WRONG_DATATYPE.getMessage(), settings.get("reason")); @@ -507,14 +570,14 @@ private void verifyRoles(final boolean sendAdminCert, Header... header) throws E checkReadAccess(HttpStatus.SC_FORBIDDEN, "picard", "picardpicardpicardpicardpicard", "sf", "_doc", 0); // overwrite user picard, and give him role "starfleet". - addUserWithPassword("picard", "picardpicardpicardpicardpicard", new String[]{"starfleet"}, HttpStatus.SC_OK); + addUserWithPassword("picard", "picardpicardpicardpicardpicard", new String[] { "starfleet" }, HttpStatus.SC_OK); checkReadAccess(HttpStatus.SC_OK, "picard", "picardpicardpicardpicardpicard", "sf", "_doc", 0); checkWriteAccess(HttpStatus.SC_FORBIDDEN, "picard", "picardpicardpicardpicardpicard", "sf", "_doc", 1); // overwrite user picard, and give him role "starfleet" plus "captains. Now // document can be created. - addUserWithPassword("picard", "picardpicardpicardpicardpicard", new String[]{"starfleet", "captains"}, HttpStatus.SC_OK); + addUserWithPassword("picard", "picardpicardpicardpicardpicard", new String[] { "starfleet", "captains" }, HttpStatus.SC_OK); checkReadAccess(HttpStatus.SC_OK, "picard", "picardpicardpicardpicardpicard", "sf", "_doc", 0); checkWriteAccess(HttpStatus.SC_CREATED, "picard", "picardpicardpicardpicardpicard", "sf", "_doc", 1); @@ -576,14 +639,11 @@ public void testUserApiWithRestInternalUsersAdminPermissions() throws Exception @Test public void testRegExpPasswordRules() throws Exception { - Settings nodeSettings = - Settings.builder() - .put(ConfigConstants.SECURITY_RESTAPI_PASSWORD_VALIDATION_ERROR_MESSAGE, "xxx") - .put(ConfigConstants.SECURITY_RESTAPI_PASSWORD_VALIDATION_REGEX, - "(?=.*[A-Z])(?=.*[^a-zA-Z\\\\d])(?=.*[0-9])(?=.*[a-z]).{8,}") - .put(ConfigConstants.SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH, - PasswordValidator.ScoreStrength.FAIR.name()) - .build(); + Settings nodeSettings = Settings.builder() + .put(ConfigConstants.SECURITY_RESTAPI_PASSWORD_VALIDATION_ERROR_MESSAGE, "xxx") + .put(ConfigConstants.SECURITY_RESTAPI_PASSWORD_VALIDATION_REGEX, "(?=.*[A-Z])(?=.*[^a-zA-Z\\\\d])(?=.*[0-9])(?=.*[a-z]).{8,}") + .put(ConfigConstants.SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH, PasswordValidator.ScoreStrength.FAIR.name()) + .build(); setup(nodeSettings); @@ -591,8 +651,7 @@ public void testRegExpPasswordRules() throws Exception { rh.sendAdminCertificate = true; // initial configuration, 6 users - HttpResponse response = rh - .executeGetRequest("_plugins/_security/api/" + CType.INTERNALUSERS.toLCString()); + HttpResponse response = rh.executeGetRequest("_plugins/_security/api/" + CType.INTERNALUSERS.toLCString()); Assert.assertEquals(response.getBody(), HttpStatus.SC_OK, response.getStatusCode()); Settings settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(USER_SETTING_SIZE, settings.size()); @@ -611,7 +670,7 @@ public void testRegExpPasswordRules() throws Exception { private void verifyCouldNotCreatePasswords(final int expectedStatus) throws Exception { addUserWithPassword("tooshoort", "", expectedStatus); - addUserWithPassword("tooshoort", "123",expectedStatus); + addUserWithPassword("tooshoort", "123", expectedStatus); addUserWithPassword("tooshoort", "1234567", expectedStatus); addUserWithPassword("tooshoort", "1Aa%", expectedStatus); addUserWithPassword("no-nonnumeric", "123456789", expectedStatus); @@ -619,39 +678,65 @@ private void verifyCouldNotCreatePasswords(final int expectedStatus) throws Exce addUserWithPassword("no-lowercase", "A123456789", expectedStatus); addUserWithPassword("empty_password_no_hash", "", expectedStatus); HttpResponse response = rh.executePatchRequest( - PLUGINS_PREFIX + "/api/internalusers", - "[{ \"op\": \"add\", \"path\": \"/ok4\", \"value\": {\"password\": \"bla\", \"backend_roles\": [\"vulcan\"] } }]", - new Header[0] + PLUGINS_PREFIX + "/api/internalusers", + "[{ \"op\": \"add\", \"path\": \"/ok4\", \"value\": {\"password\": \"bla\", \"backend_roles\": [\"vulcan\"] } }]", + new Header[0] ); Assert.assertEquals(response.getBody(), expectedStatus, response.getStatusCode()); - response = rh.executePatchRequest(PLUGINS_PREFIX + "/api/internalusers", "[{ \"op\": \"replace\", \"path\": \"/ok4\", \"value\": {\"password\": \"bla\", \"backend_roles\": [\"vulcan\"] } }]", new Header[0]); + response = rh.executePatchRequest( + PLUGINS_PREFIX + "/api/internalusers", + "[{ \"op\": \"replace\", \"path\": \"/ok4\", \"value\": {\"password\": \"bla\", \"backend_roles\": [\"vulcan\"] } }]", + new Header[0] + ); Assert.assertEquals(response.getBody(), expectedStatus, response.getStatusCode()); addUserWithPassword("ok4", "123", expectedStatus); - //its not allowed to use the username as password (case insensitive) - response = rh.executePatchRequest(PLUGINS_PREFIX + "/api/internalusers", "[{ \"op\": \"add\", \"path\": \"/$1aAAAAAAAAB\", \"value\": {\"password\": \"$1aAAAAAAAAB\", \"backend_roles\": [\"vulcan\"] } }]", new Header[0]); + // its not allowed to use the username as password (case insensitive) + response = rh.executePatchRequest( + PLUGINS_PREFIX + "/api/internalusers", + "[{ \"op\": \"add\", \"path\": \"/$1aAAAAAAAAB\", \"value\": {\"password\": \"$1aAAAAAAAAB\", \"backend_roles\": [\"vulcan\"] } }]", + new Header[0] + ); Assert.assertEquals(response.getBody(), expectedStatus, response.getStatusCode()); addUserWithPassword("$1aAAAAAAAAC", "$1aAAAAAAAAC", expectedStatus); addUserWithPassword("$1aAAAAAAAac", "$1aAAAAAAAAC", expectedStatus); addUserWithPassword(URLEncoder.encode("$1aAAAAAAAac%", "UTF-8"), "$1aAAAAAAAAC%", expectedStatus); - addUserWithPassword(URLEncoder.encode("$1aAAAAAAAac%!=\"/\\;:test&~@^", "UTF-8").replace("+", "%2B"), "$1aAAAAAAAac%!=\\\"/\\\\;:test&~@^", expectedStatus); - addUserWithPassword(URLEncoder.encode("$1aAAAAAAAac%!=\"/\\;: test&", "UTF-8"), "$1aAAAAAAAac%!=\\\"/\\\\;: test&123", expectedStatus); - String patchPayload = "[ " + - "{ \"op\": \"add\", \"path\": \"/testuser1\", \"value\": { \"password\": \"$aA123456789\", \"backend_roles\": [\"testrole1\"] } }," + - "{ \"op\": \"add\", \"path\": \"/testuser2\", \"value\": { \"password\": \"testpassword2\", \"backend_roles\": [\"testrole2\"] } }" + - "]"; - - response = rh.executePatchRequest(PLUGINS_PREFIX + "/api/internalusers", patchPayload, new BasicHeader("Content-Type", "application/json")); + addUserWithPassword( + URLEncoder.encode("$1aAAAAAAAac%!=\"/\\;:test&~@^", "UTF-8").replace("+", "%2B"), + "$1aAAAAAAAac%!=\\\"/\\\\;:test&~@^", + expectedStatus + ); + addUserWithPassword( + URLEncoder.encode("$1aAAAAAAAac%!=\"/\\;: test&", "UTF-8"), + "$1aAAAAAAAac%!=\\\"/\\\\;: test&123", + expectedStatus + ); + String patchPayload = "[ " + + "{ \"op\": \"add\", \"path\": \"/testuser1\", \"value\": { \"password\": \"$aA123456789\", \"backend_roles\": [\"testrole1\"] } }," + + "{ \"op\": \"add\", \"path\": \"/testuser2\", \"value\": { \"password\": \"testpassword2\", \"backend_roles\": [\"testrole2\"] } }" + + "]"; + + response = rh.executePatchRequest( + PLUGINS_PREFIX + "/api/internalusers", + patchPayload, + new BasicHeader("Content-Type", "application/json") + ); Assert.assertEquals(expectedStatus, response.getStatusCode()); Assert.assertTrue(response.getBody().contains("error")); Assert.assertTrue(response.getBody().contains("xxx")); - response = rh.executePutRequest(PLUGINS_PREFIX + "/api/internalusers/ok1", "{\"backend_roles\":[\"my-backend-role\"],\"attributes\":{},\"password\":\"\"}", new Header[0]); + response = rh.executePutRequest( + PLUGINS_PREFIX + "/api/internalusers/ok1", + "{\"backend_roles\":[\"my-backend-role\"],\"attributes\":{},\"password\":\"\"}", + new Header[0] + ); Assert.assertEquals(expectedStatus, response.getStatusCode()); - response = rh.executePutRequest(PLUGINS_PREFIX + "/api/internalusers/ok1", - "{\"backend_roles\":[\"my-backend-role\"],\"attributes\":{},\"password\":\"bla\"}", - new Header[0]); + response = rh.executePutRequest( + PLUGINS_PREFIX + "/api/internalusers/ok1", + "{\"backend_roles\":[\"my-backend-role\"],\"attributes\":{},\"password\":\"bla\"}", + new Header[0] + ); Assert.assertEquals(expectedStatus, response.getStatusCode()); } @@ -662,35 +747,35 @@ private void verifyCanCreatePasswords() throws Exception { addUserWithPassword("ok4", "$1aAAAAAAAAA", HttpStatus.SC_CREATED); addUserWithPassword("ok4", "$1aAAAAAAAAC", HttpStatus.SC_OK); HttpResponse response = rh.executePatchRequest( - PLUGINS_PREFIX + "/api/internalusers", - "[{ \"op\": \"add\", \"path\": \"/ok4\", \"value\": {\"password\": \"$1aAAAAAAAAB\", \"backend_roles\": [\"vulcan\"] } }]", - new Header[0] + PLUGINS_PREFIX + "/api/internalusers", + "[{ \"op\": \"add\", \"path\": \"/ok4\", \"value\": {\"password\": \"$1aAAAAAAAAB\", \"backend_roles\": [\"vulcan\"] } }]", + new Header[0] ); Assert.assertEquals(response.getBody(), HttpStatus.SC_OK, response.getStatusCode()); - response = rh.executePutRequest(PLUGINS_PREFIX + "/api/internalusers/ok1", "{\"backend_roles\":[\"my-backend-role\"],\"attributes\":{},\"password\":\"Admin_123\"}", new Header[0]); + response = rh.executePutRequest( + PLUGINS_PREFIX + "/api/internalusers/ok1", + "{\"backend_roles\":[\"my-backend-role\"],\"attributes\":{},\"password\":\"Admin_123\"}", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - response = rh.executePutRequest(PLUGINS_PREFIX + "/api/internalusers/ok1", "{\"backend_roles\":[\"my-backend-role\"],\"attributes\":{}}", new Header[0]); + response = rh.executePutRequest( + PLUGINS_PREFIX + "/api/internalusers/ok1", + "{\"backend_roles\":[\"my-backend-role\"],\"attributes\":{}}", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); } - private void verifySimilarity(final String expectedMessage) throws Exception { - addUserWithPassword( - "some_user_name", "H3235,cc,some_User_Name", - HttpStatus.SC_BAD_REQUEST, - expectedMessage - ); + addUserWithPassword("some_user_name", "H3235,cc,some_User_Name", HttpStatus.SC_BAD_REQUEST, expectedMessage); } @Test public void testScoreBasedPasswordRules() throws Exception { - Settings nodeSettings = - Settings.builder() - .put(ConfigConstants.SECURITY_RESTAPI_PASSWORD_MIN_LENGTH, 9) - .build(); + Settings nodeSettings = Settings.builder().put(ConfigConstants.SECURITY_RESTAPI_PASSWORD_MIN_LENGTH, 9).build(); setup(nodeSettings); @@ -698,28 +783,25 @@ public void testScoreBasedPasswordRules() throws Exception { rh.sendAdminCertificate = true; // initial configuration, 6 users - HttpResponse response = rh - .executeGetRequest("_plugins/_security/api/" + CType.INTERNALUSERS.toLCString()); + HttpResponse response = rh.executeGetRequest("_plugins/_security/api/" + CType.INTERNALUSERS.toLCString()); Assert.assertEquals(response.getBody(), HttpStatus.SC_OK, response.getStatusCode()); Settings settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(133, settings.size()); addUserWithPassword( - "admin", "password89", - HttpStatus.SC_BAD_REQUEST, - AbstractConfigurationValidator.ErrorType.WEAK_PASSWORD.getMessage() + "admin", + "password89", + HttpStatus.SC_BAD_REQUEST, + AbstractConfigurationValidator.ErrorType.WEAK_PASSWORD.getMessage() ); addUserWithPassword( - "admin", "A123456789", - HttpStatus.SC_BAD_REQUEST, - AbstractConfigurationValidator.ErrorType.WEAK_PASSWORD.getMessage() + "admin", + "A123456789", + HttpStatus.SC_BAD_REQUEST, + AbstractConfigurationValidator.ErrorType.WEAK_PASSWORD.getMessage() ); - addUserWithPassword( - "admin", "pas", - HttpStatus.SC_BAD_REQUEST, - "Password does not match minimum criteria" - ); + addUserWithPassword("admin", "pas", HttpStatus.SC_BAD_REQUEST, "Password does not match minimum criteria"); verifySimilarity(AbstractConfigurationValidator.ErrorType.SIMILAR_PASSWORD.getMessage()); @@ -735,23 +817,18 @@ public void testUserApiWithDots() throws Exception { rh.sendAdminCertificate = true; // initial configuration, 6 users - HttpResponse response = rh - .executeGetRequest(ENDPOINT + "/" + CType.INTERNALUSERS.toLCString()); + HttpResponse response = rh.executeGetRequest(ENDPOINT + "/" + CType.INTERNALUSERS.toLCString()); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); Settings settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(USER_SETTING_SIZE, settings.size()); - addUserWithPassword(".my.dotuser0", "$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m", - HttpStatus.SC_CREATED); + addUserWithPassword(".my.dotuser0", "$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m", HttpStatus.SC_CREATED); - addUserWithPassword(".my.dot.user0", "12345678Sd", - HttpStatus.SC_CREATED); + addUserWithPassword(".my.dot.user0", "12345678Sd", HttpStatus.SC_CREATED); - addUserWithHash(".my.dotuser1", "$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m", - HttpStatus.SC_CREATED); + addUserWithHash(".my.dotuser1", "$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m", HttpStatus.SC_CREATED); - addUserWithPassword(".my.dot.user2", "12345678Sd", - HttpStatus.SC_CREATED); + addUserWithPassword(".my.dot.user2", "12345678Sd", HttpStatus.SC_CREATED); } @@ -766,25 +843,32 @@ public void testUserApiNoPasswordChange() throws Exception { // initial configuration, 5 users HttpResponse response; - addUserWithHash("user1", "$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m", - HttpStatus.SC_CREATED); + addUserWithHash("user1", "$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m", HttpStatus.SC_CREATED); - response = rh.executePutRequest(ENDPOINT + "/internalusers/user1", "{\"hash\":\"$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m\",\"password\":\"\",\"backend_roles\":[\"admin\",\"rolea\"]}"); + response = rh.executePutRequest( + ENDPOINT + "/internalusers/user1", + "{\"hash\":\"$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m\",\"password\":\"\",\"backend_roles\":[\"admin\",\"rolea\"]}" + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); - response = rh.executePutRequest(ENDPOINT + "/internalusers/user1", "{\"hash\":\"$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m\",\"password\":\"Admin_123345Yq\",\"backend_roles\":[\"admin\",\"rolea\"]}"); + response = rh.executePutRequest( + ENDPOINT + "/internalusers/user1", + "{\"hash\":\"$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m\",\"password\":\"Admin_123345Yq\",\"backend_roles\":[\"admin\",\"rolea\"]}" + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executeGetRequest(ENDPOINT + "/internalusers/user1"); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - addUserWithHash("user2", "$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m", - HttpStatus.SC_CREATED); + addUserWithHash("user2", "$2a$12$n5nubfWATfQjSYHiWtUyeOxMIxFInUHOAx8VMmGmxFNPGpaBmeB.m", HttpStatus.SC_CREATED); response = rh.executePutRequest(ENDPOINT + "/internalusers/user2", "{\"password\":\"\",\"backend_roles\":[\"admin\",\"rolex\"]}"); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); - response = rh.executePutRequest(ENDPOINT + "/internalusers/user2", "{\"password\":\"Admin_123Qerty\",\"backend_roles\":[\"admin\",\"rolex\"]}"); + response = rh.executePutRequest( + ENDPOINT + "/internalusers/user2", + "{\"password\":\"Admin_123Qerty\",\"backend_roles\":[\"admin\",\"rolex\"]}" + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executeGetRequest(ENDPOINT + "/internalusers/user2"); @@ -803,54 +887,89 @@ public void testUserApiForNonSuperAdmin() throws Exception { HttpResponse response; // Delete read only user - response = rh.executeDeleteRequest(ENDPOINT + "/internalusers/sarek" , new Header[0]); + response = rh.executeDeleteRequest(ENDPOINT + "/internalusers/sarek", new Header[0]); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // Patch read only users - response = rh.executePatchRequest(ENDPOINT + "/internalusers/sarek", "[{ \"op\": \"add\", \"path\": \"/sarek/description\", \"value\": \"foo\" }]", new Header[0]); + response = rh.executePatchRequest( + ENDPOINT + "/internalusers/sarek", + "[{ \"op\": \"add\", \"path\": \"/sarek/description\", \"value\": \"foo\" }]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // Put read only users - response = rh.executePutRequest(ENDPOINT + "/internalusers/sarek", "{ \"opendistro_security_roles\": [\"opendistro_security_reserved\"]}", new Header[0]); + response = rh.executePutRequest( + ENDPOINT + "/internalusers/sarek", + "{ \"opendistro_security_roles\": [\"opendistro_security_reserved\"]}", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // Patch single read only user - response = rh.executePatchRequest(ENDPOINT + "/internalusers/sarek", "[{ \"op\": \"add\", \"path\": \"/description\", \"value\": \"foo\" }]", new Header[0]); + response = rh.executePatchRequest( + ENDPOINT + "/internalusers/sarek", + "[{ \"op\": \"add\", \"path\": \"/description\", \"value\": \"foo\" }]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // Patch multiple read only users - response = rh.executePatchRequest(ENDPOINT + "/internalusers", "[{ \"op\": \"add\", \"path\": \"/sarek/description\", \"value\": \"foo\" }]", new Header[0]); + response = rh.executePatchRequest( + ENDPOINT + "/internalusers", + "[{ \"op\": \"add\", \"path\": \"/sarek/description\", \"value\": \"foo\" }]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); // Get hidden role - response = rh.executeGetRequest(ENDPOINT + "/internalusers/hide" , new Header[0]); + response = rh.executeGetRequest(ENDPOINT + "/internalusers/hide", new Header[0]); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // Delete hidden user - response = rh.executeDeleteRequest(ENDPOINT + "/internalusers/hide" , new Header[0]); + response = rh.executeDeleteRequest(ENDPOINT + "/internalusers/hide", new Header[0]); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // Patch hidden users - response = rh.executePatchRequest(ENDPOINT + "/internalusers/hide", "[{ \"op\": \"add\", \"path\": \"/sarek/description\", \"value\": \"foo\" }]", new Header[0]); + response = rh.executePatchRequest( + ENDPOINT + "/internalusers/hide", + "[{ \"op\": \"add\", \"path\": \"/sarek/description\", \"value\": \"foo\" }]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // Put hidden users - response = rh.executePutRequest(ENDPOINT + "/internalusers/hide", "{ \"opendistro_security_roles\": [\"opendistro_security_reserved\"]}", new Header[0]); + response = rh.executePutRequest( + ENDPOINT + "/internalusers/hide", + "{ \"opendistro_security_roles\": [\"opendistro_security_reserved\"]}", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // Put reserved role is forbidden for non-superadmin - response = rh.executePutRequest(ENDPOINT + "/internalusers/nagilum", "{ \"opendistro_security_roles\": [\"opendistro_security_reserved\"]}", - new Header[0]); + response = rh.executePutRequest( + ENDPOINT + "/internalusers/nagilum", + "{ \"opendistro_security_roles\": [\"opendistro_security_reserved\"]}", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); Settings settings = Settings.builder().loadFromSource(response.getBody(), XContentType.JSON).build(); Assert.assertEquals(settings.get("message"), "Resource 'opendistro_security_reserved' is read-only."); // Patch single hidden user - response = rh.executePatchRequest(ENDPOINT + "/internalusers/hide", "[{ \"op\": \"add\", \"path\": \"/description\", \"value\": \"foo\" }]", new Header[0]); + response = rh.executePatchRequest( + ENDPOINT + "/internalusers/hide", + "[{ \"op\": \"add\", \"path\": \"/description\", \"value\": \"foo\" }]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); // Patch multiple hidden users - response = rh.executePatchRequest(ENDPOINT + "/internalusers", "[{ \"op\": \"add\", \"path\": \"/hide/description\", \"value\": \"foo\" }]", new Header[0]); + response = rh.executePatchRequest( + ENDPOINT + "/internalusers", + "[{ \"op\": \"add\", \"path\": \"/hide/description\", \"value\": \"foo\" }]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatusCode()); } @@ -873,7 +992,7 @@ public void restrictedUsernameContents() throws Exception { } @Test - public void checkNullElementsInArray() throws Exception{ + public void checkNullElementsInArray() throws Exception { setup(); rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; 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 e4fca1e99b..371341147e 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 @@ -51,12 +51,13 @@ public class WhitelistApiTest extends AbstractRestApiUnitTest { */ private final Header adminCredsHeader = encodeBasicHeader("admin_all_access", "admin_all_access"); private final Header nonAdminCredsHeader = encodeBasicHeader("sarek", "sarek"); - private final String ENDPOINT; + private final String ENDPOINT; + protected String getEndpointPrefix() { return PLUGINS_PREFIX; } - public WhitelistApiTest(){ + public WhitelistApiTest() { ENDPOINT = getEndpointPrefix() + "/api"; } @@ -65,24 +66,32 @@ public WhitelistApiTest(){ * * @throws Exception */ - private void checkGetAndPutWhitelistPermissions(final int expectedStatus, final boolean sendAdminCertificate, final Header... headers) throws Exception { + private void checkGetAndPutWhitelistPermissions(final int expectedStatus, final boolean sendAdminCertificate, final Header... headers) + throws Exception { final boolean prevSendAdminCertificate = rh.sendAdminCertificate; rh.sendAdminCertificate = sendAdminCertificate; - //CHECK GET REQUEST + // CHECK GET REQUEST response = rh.executeGetRequest(ENDPOINT + "/whitelist", headers); assertThat(response.getBody(), response.getStatusCode(), equalTo(expectedStatus)); if (expectedStatus == HttpStatus.SC_OK) { - //Note: the response has no whitespaces, so the .json file does not have whitespaces - Assert.assertEquals(FileHelper.loadFile("restapi/whitelist_response_success.json"), FileHelper.loadFile("restapi/whitelist_response_success.json")); + // Note: the response has no whitespaces, so the .json file does not have whitespaces + Assert.assertEquals( + FileHelper.loadFile("restapi/whitelist_response_success.json"), + FileHelper.loadFile("restapi/whitelist_response_success.json") + ); } - //FORBIDDEN FOR NON SUPER ADMIN + // FORBIDDEN FOR NON SUPER ADMIN if (expectedStatus == HttpStatus.SC_FORBIDDEN) { assertTrue(response.getBody().contains("API allowed only for super admin.")); } - //CHECK PUT REQUEST - response = rh.executePutRequest(ENDPOINT + "/whitelist", "{\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}", headers); + // CHECK PUT REQUEST + response = rh.executePutRequest( + ENDPOINT + "/whitelist", + "{\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}", + headers + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(expectedStatus)); rh.sendAdminCertificate = prevSendAdminCertificate; @@ -105,7 +114,10 @@ public void testPutUnknownKey() throws Exception { setup(); rh.sendAdminCertificate = true; - RestHelper.HttpResponse response = rh.executePutRequest(ENDPOINT + "/whitelist", "{ \"unknownkey\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}"); + RestHelper.HttpResponse response = rh.executePutRequest( + ENDPOINT + "/whitelist", + "{ \"unknownkey\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}" + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); assertTrue(response.getBody().contains("invalid_keys")); assertHealthy(); @@ -116,7 +128,10 @@ public void testPutInvalidJson() throws Exception { setup(); rh.sendAdminCertificate = true; - RestHelper.HttpResponse response = rh.executePutRequest(ENDPOINT + "/whitelist", "{ \"invalid\"::{{ [\"*\"], \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}"); + RestHelper.HttpResponse response = rh.executePutRequest( + ENDPOINT + "/whitelist", + "{ \"invalid\"::{{ [\"*\"], \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}" + ); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatusCode()); assertHealthy(); } @@ -152,7 +167,7 @@ public void testWhitelistApi() throws Exception { // No creds, no admin certificate - UNAUTHORIZED checkGetAndPutWhitelistPermissions(HttpStatus.SC_UNAUTHORIZED, false); - //non admin creds, no admin certificate - FORBIDDEN + // non admin creds, no admin certificate - FORBIDDEN checkGetAndPutWhitelistPermissions(HttpStatus.SC_FORBIDDEN, false, nonAdminCredsHeader); // admin creds, no admin certificate - FORBIDDEN @@ -165,37 +180,45 @@ public void testWhitelistApi() throws Exception { @Test public void testWhitelistAuditComplianceLogging() throws Exception { Settings settings = Settings.builder() - .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_LOG_DIFFS, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) - .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") - .build(); + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_TRANSPORT, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_ENABLE_REST, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_RESOLVE_BULK_REQUESTS, false) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_WRITE_LOG_DIFFS, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_EXTERNAL_CONFIG_ENABLED, false) + .put(ConfigConstants.SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, true) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "authenticated,GRANTED_PRIVILEGES") + .build(); setupWithRestRoles(settings); TestAuditlogImpl.clear(); // any creds, admin certificate - OK checkGetAndPutWhitelistPermissions(HttpStatus.SC_OK, true, nonAdminCredsHeader); - //TESTS THAT 1 READ AND 1 WRITE HAPPENS IN testGetAndPut() + // TESTS THAT 1 READ AND 1 WRITE HAPPENS IN testGetAndPut() final Map expectedCategoryCounts = ImmutableMap.of( - AuditCategory.COMPLIANCE_INTERNAL_CONFIG_READ, 1L, - AuditCategory.COMPLIANCE_INTERNAL_CONFIG_WRITE, 1L); - Map actualCategoryCounts = TestAuditlogImpl.messages.stream().collect(Collectors.groupingBy(AuditMessage::getCategory, Collectors.counting())); + AuditCategory.COMPLIANCE_INTERNAL_CONFIG_READ, + 1L, + AuditCategory.COMPLIANCE_INTERNAL_CONFIG_WRITE, + 1L + ); + Map actualCategoryCounts = TestAuditlogImpl.messages.stream() + .collect(Collectors.groupingBy(AuditMessage::getCategory, Collectors.counting())); assertThat(actualCategoryCounts, equalTo(expectedCategoryCounts)); } @Test - public void testWhitelistInvalidHttpRequestMethod() throws Exception{ + public void testWhitelistInvalidHttpRequestMethod() throws Exception { setup(); rh.sendAdminCertificate = true; - response = rh.executePutRequest(ENDPOINT + "/whitelist", "{\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GE\"],\"/_cat/indices\": [\"PUT\"] }}", adminCredsHeader); + response = rh.executePutRequest( + ENDPOINT + "/whitelist", + "{\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GE\"],\"/_cat/indices\": [\"PUT\"] }}", + adminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_INTERNAL_SERVER_ERROR)); assertTrue(response.getBody().contains("\\\"GE\\\": not one of the values accepted for Enum class")); } @@ -208,37 +231,61 @@ public void testWhitelistInvalidHttpRequestMethod() throws Exception{ * @throws Exception */ @Test - public void testPatchApi() throws Exception{ + public void testPatchApi() throws Exception { setup(); rh.sendAdminCertificate = true; - //PATCH entire config entry - response = rh.executePatchRequest(ENDPOINT + "/whitelist", "[{ \"op\": \"replace\", \"path\": \"/config\", \"value\": {\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"PUT\"] }}}]", new Header[0]); + // PATCH entire config entry + response = rh.executePatchRequest( + ENDPOINT + "/whitelist", + "[{ \"op\": \"replace\", \"path\": \"/config\", \"value\": {\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"PUT\"] }}}]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executeGetRequest(ENDPOINT + "/whitelist", adminCredsHeader); - assertEquals(response.getBody(),"{\"config\":{\"enabled\":true,\"requests\":{\"/_cat/nodes\":[\"GET\"],\"/_cat/indices\":[\"PUT\"]}}}"); - - //PATCH just requests - response = rh.executePatchRequest(ENDPOINT + "/whitelist", "[{ \"op\": \"replace\", \"path\": \"/config/requests\", \"value\": {\"/_cat/nodes\": [\"GET\"]}}]", new Header[0]); + assertEquals( + response.getBody(), + "{\"config\":{\"enabled\":true,\"requests\":{\"/_cat/nodes\":[\"GET\"],\"/_cat/indices\":[\"PUT\"]}}}" + ); + + // PATCH just requests + response = rh.executePatchRequest( + ENDPOINT + "/whitelist", + "[{ \"op\": \"replace\", \"path\": \"/config/requests\", \"value\": {\"/_cat/nodes\": [\"GET\"]}}]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executeGetRequest(ENDPOINT + "/whitelist", adminCredsHeader); assertTrue(response.getBody().contains("\"requests\":{\"/_cat/nodes\":[\"GET\"]}")); - //PATCH just whitelisted_enabled using "replace" operation - works when enabled is already true - response = rh.executePatchRequest(ENDPOINT + "/whitelist", "[{ \"op\": \"replace\", \"path\": \"/config/enabled\", \"value\": false}]", new Header[0]); + // PATCH just whitelisted_enabled using "replace" operation - works when enabled is already true + response = rh.executePatchRequest( + ENDPOINT + "/whitelist", + "[{ \"op\": \"replace\", \"path\": \"/config/enabled\", \"value\": false}]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executeGetRequest(ENDPOINT + "/whitelist", adminCredsHeader); assertTrue(response.getBody().contains("\"enabled\":false")); - //PATCH just enabled using "add" operation when it is currently false - works correctly - response = rh.executePatchRequest(ENDPOINT + "/whitelist", "[{ \"op\": \"add\", \"path\": \"/config/enabled\", \"value\": true}]", new Header[0]); + // PATCH just enabled using "add" operation when it is currently false - works correctly + response = rh.executePatchRequest( + ENDPOINT + "/whitelist", + "[{ \"op\": \"add\", \"path\": \"/config/enabled\", \"value\": true}]", + new Header[0] + ); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); response = rh.executeGetRequest(ENDPOINT + "/whitelist", adminCredsHeader); assertTrue(response.getBody().contains("\"enabled\":true")); - //PATCH just enabled using "add" operation when it is currently true - works correctly - response = rh.executePatchRequest(ENDPOINT + "/whitelist", "[{ \"op\": \"add\", \"path\": \"/config/enabled\", \"value\": false}]", new Header[0]); - Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode());response = rh.executeGetRequest(ENDPOINT + "/whitelist", adminCredsHeader); + // PATCH just enabled using "add" operation when it is currently true - works correctly + response = rh.executePatchRequest( + ENDPOINT + "/whitelist", + "[{ \"op\": \"add\", \"path\": \"/config/enabled\", \"value\": false}]", + new Header[0] + ); + Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); + response = rh.executeGetRequest(ENDPOINT + "/whitelist", adminCredsHeader); response = rh.executeGetRequest(ENDPOINT + "/whitelist", adminCredsHeader); assertTrue(response.getBody().contains("\"enabled\":false")); } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyAccountApiTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyAccountApiTests.java index a48a7d2e3a..925d90ccba 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyAccountApiTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyAccountApiTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacyAccountApiTests extends AccountApiTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyActionGroupsApiTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyActionGroupsApiTests.java index 9aa4b70c77..e92f046f65 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyActionGroupsApiTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyActionGroupsApiTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacyActionGroupsApiTests extends ActionGroupsApiTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyAuditApiActionTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyAuditApiActionTests.java index 4d97da8bbb..fbde68e911 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyAuditApiActionTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyAuditApiActionTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacyAuditApiActionTests extends AuditApiActionTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyDashboardsInfoActionTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyDashboardsInfoActionTests.java index a9baec37bd..ee39f93ee0 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyDashboardsInfoActionTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyDashboardsInfoActionTests.java @@ -16,7 +16,7 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacyDashboardsInfoActionTests extends DashboardsInfoActionTest { - @Override + @Override protected String getEndpoint() { return LEGACY_OPENDISTRO_PREFIX + "/kibanainfo"; } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyFlushCacheApiTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyFlushCacheApiTests.java index ab09a6e2f2..df9cc3d59d 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyFlushCacheApiTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyFlushCacheApiTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacyFlushCacheApiTests extends FlushCacheApiTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyGetConfigurationApiTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyGetConfigurationApiTests.java index cca6739733..07983bad0d 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyGetConfigurationApiTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyGetConfigurationApiTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacyGetConfigurationApiTests extends GetConfigurationApiTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyIndexMissingTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyIndexMissingTests.java index 0680aa2c2e..fef436f4d7 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyIndexMissingTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyIndexMissingTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacyIndexMissingTests extends IndexMissingTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyNodesDnApiTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyNodesDnApiTests.java index 22237ece3f..a316785f02 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyNodesDnApiTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyNodesDnApiTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacyNodesDnApiTests extends NodesDnApiTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyRoleBasedAccessTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyRoleBasedAccessTests.java index c9f421058c..329404dfe7 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyRoleBasedAccessTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyRoleBasedAccessTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacyRoleBasedAccessTests extends RoleBasedAccessTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyRolesApiTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyRolesApiTests.java index b4ec33a2d5..118f8e1ebe 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyRolesApiTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyRolesApiTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacyRolesApiTests extends RolesApiTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyRolesMappingApiTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyRolesMappingApiTests.java index c659fb57bc..dd29b524c1 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyRolesMappingApiTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyRolesMappingApiTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacyRolesMappingApiTests extends RolesMappingApiTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacySecurityApiAccessTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacySecurityApiAccessTests.java index 72b6086c1e..85428d645d 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacySecurityApiAccessTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacySecurityApiAccessTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacySecurityApiAccessTests extends SecurityApiAccessTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacySecurityConfigApiTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacySecurityConfigApiTests.java index fd03e7248a..6175809b4a 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacySecurityConfigApiTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacySecurityConfigApiTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacySecurityConfigApiTests extends SecurityConfigApiTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacySecurityHealthActionTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacySecurityHealthActionTests.java index 470db0a526..99fa4a99ae 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacySecurityHealthActionTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacySecurityHealthActionTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacySecurityHealthActionTests extends SecurityHealthActionTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacySecurityInfoActionTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacySecurityInfoActionTests.java index 8480787423..75c5238f7f 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacySecurityInfoActionTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacySecurityInfoActionTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacySecurityInfoActionTests extends SecurityInfoActionTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyTenantInfoActionTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyTenantInfoActionTests.java index 1f2ac9a77d..49963d7d55 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyTenantInfoActionTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyTenantInfoActionTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacyTenantInfoActionTests extends TenantInfoActionTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyUserApiTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyUserApiTests.java index 5753688097..449bce270d 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyUserApiTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyUserApiTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacyUserApiTests extends UserApiTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyWhitelistApiTests.java b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyWhitelistApiTests.java index 3ae501f9a4..689981aa2a 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyWhitelistApiTests.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/legacy/LegacyWhitelistApiTests.java @@ -16,8 +16,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; public class LegacyWhitelistApiTests extends WhitelistApiTest { - @Override - protected String getEndpointPrefix() { - return LEGACY_OPENDISTRO_PREFIX; - } + @Override + protected String getEndpointPrefix() { + return LEGACY_OPENDISTRO_PREFIX; + } } 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 b5d27827b8..7ea6f23898 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 @@ -25,126 +25,120 @@ public class PasswordValidatorTest { - static final List WEAK_PASSWORDS = ImmutableList.of( - "q", "5", "&", "admin", "123456", "password" - ); + static final List WEAK_PASSWORDS = ImmutableList.of("q", "5", "&", "admin", "123456", "password"); static final List FAIR_PASSWORDS = ImmutableList.of( - "p@$$word@dmin", "qwertyuiop@[", - "zxcvbnm,./_", "asdfghjkl;:]", "20300101", - "pandapandapandapandapandapandapandapandapandaa", - "appleappleappleappleappleappleappleappleapplea", - "aelppaaelppaaelppaaelppaaelppaaelppaaelppaaelppa" + "p@$$word@dmin", + "qwertyuiop@[", + "zxcvbnm,./_", + "asdfghjkl;:]", + "20300101", + "pandapandapandapandapandapandapandapandapandaa", + "appleappleappleappleappleappleappleappleapplea", + "aelppaaelppaaelppaaelppaaelppaaelppaaelppaaelppa" ); static final List GOOD_PASSWORDS = ImmutableList.of( - "xsw234rfvb", "yaq123edc", "cde345tgbn", "yaqwedcvb", - "Tr0ub4dour&3", "qwER43@!" + "xsw234rfvb", + "yaq123edc", + "cde345tgbn", + "yaqwedcvb", + "Tr0ub4dour&3", + "qwER43@!" ); - static final List STRONG_PASSWORDS = ImmutableList.of( - "YWert,H90", "Admincc,H90", "Hadmin,120" - ); + static final List STRONG_PASSWORDS = ImmutableList.of("YWert,H90", "Admincc,H90", "Hadmin,120"); static final List VERY_STRONG_PASSWORDS = ImmutableList.of( - "AeTq($%u-44c_j9NJB45a#2#JP7sH", "IB7~EOw!51gug+7s#+%A9P1O/w8f", - "1v_f%7JvS8w!_t398+ON-CObI#v0", "8lFmfc0!w)&iU9DM6~4_w)D)Y44J" + "AeTq($%u-44c_j9NJB45a#2#JP7sH", + "IB7~EOw!51gug+7s#+%A9P1O/w8f", + "1v_f%7JvS8w!_t398+ON-CObI#v0", + "8lFmfc0!w)&iU9DM6~4_w)D)Y44J" ); static final List SIMILAR_PASSWORDS = ImmutableList.of( - "some_user_name,H2344cc", "H3235,Some_User_Name,cc", - "H3235,cc,some_User_Name", "H3235,SOME_User_Name,cc", - "H3235,eman_resu_emos,cc" + "some_user_name,H2344cc", + "H3235,Some_User_Name,cc", + "H3235,cc,some_User_Name", + "H3235,SOME_User_Name,cc", + "H3235,eman_resu_emos,cc" ); - public void verifyWeakPasswords(final PasswordValidator passwordValidator, - final AbstractConfigurationValidator.ErrorType expectedValidationResult) { + public void verifyWeakPasswords( + final PasswordValidator passwordValidator, + final AbstractConfigurationValidator.ErrorType expectedValidationResult + ) { for (final String password : WEAK_PASSWORDS) - assertEquals( - password, - expectedValidationResult, - passwordValidator.validate("some_user_name", password) - ); + assertEquals(password, expectedValidationResult, passwordValidator.validate("some_user_name", password)); } - public void verifyFairPasswords(final PasswordValidator passwordValidator, - final AbstractConfigurationValidator.ErrorType expectedValidationResult) { + public void verifyFairPasswords( + final PasswordValidator passwordValidator, + final AbstractConfigurationValidator.ErrorType expectedValidationResult + ) { for (final String password : FAIR_PASSWORDS) - assertEquals( - password, - expectedValidationResult, - passwordValidator.validate("some_user_name", password) - ); + assertEquals(password, expectedValidationResult, passwordValidator.validate("some_user_name", password)); } - public void verifyGoodPasswords(final PasswordValidator passwordValidator, - final AbstractConfigurationValidator.ErrorType expectedValidationResult) { + public void verifyGoodPasswords( + final PasswordValidator passwordValidator, + final AbstractConfigurationValidator.ErrorType expectedValidationResult + ) { for (final String password : GOOD_PASSWORDS) - assertEquals( - password, - expectedValidationResult, - passwordValidator.validate("some_user_name", password) - ); + assertEquals(password, expectedValidationResult, passwordValidator.validate("some_user_name", password)); } - public void verifyStrongPasswords(final PasswordValidator passwordValidator, - final AbstractConfigurationValidator.ErrorType expectedValidationResult) { + public void verifyStrongPasswords( + final PasswordValidator passwordValidator, + final AbstractConfigurationValidator.ErrorType expectedValidationResult + ) { for (final String password : STRONG_PASSWORDS) - assertEquals( - password, - expectedValidationResult, - passwordValidator.validate("some_user_name", password) - ); + assertEquals(password, expectedValidationResult, passwordValidator.validate("some_user_name", password)); } - public void verifyVeryStrongPasswords(final PasswordValidator passwordValidator, - final AbstractConfigurationValidator.ErrorType expectedValidationResult) { + public void verifyVeryStrongPasswords( + final PasswordValidator passwordValidator, + final AbstractConfigurationValidator.ErrorType expectedValidationResult + ) { for (final String password : VERY_STRONG_PASSWORDS) - assertEquals( - password, - expectedValidationResult, - passwordValidator.validate("some_user_name", password) - ); + assertEquals(password, expectedValidationResult, passwordValidator.validate("some_user_name", password)); } public void verifySimilarPasswords(final PasswordValidator passwordValidator) { for (final String password : SIMILAR_PASSWORDS) assertEquals( - password, - AbstractConfigurationValidator.ErrorType.SIMILAR_PASSWORD, - passwordValidator.validate("some_user_name", password) + password, + AbstractConfigurationValidator.ErrorType.SIMILAR_PASSWORD, + passwordValidator.validate("some_user_name", password) ); } @Test public void testRegExpBasedValidation() { - final PasswordValidator passwordValidator = - PasswordValidator.of( - Settings.builder() - .put( - SECURITY_RESTAPI_PASSWORD_VALIDATION_REGEX, - "(?=.*[A-Z])(?=.*[^a-zA-Z\\\\d])(?=.*[0-9])(?=.*[a-z]).{8,}") - .build() - ); + final PasswordValidator passwordValidator = PasswordValidator.of( + Settings.builder() + .put(SECURITY_RESTAPI_PASSWORD_VALIDATION_REGEX, "(?=.*[A-Z])(?=.*[^a-zA-Z\\\\d])(?=.*[0-9])(?=.*[a-z]).{8,}") + .build() + ); verifyWeakPasswords(passwordValidator, AbstractConfigurationValidator.ErrorType.INVALID_PASSWORD); verifyFairPasswords(passwordValidator, AbstractConfigurationValidator.ErrorType.INVALID_PASSWORD); for (final String password : GOOD_PASSWORDS.subList(0, GOOD_PASSWORDS.size() - 2)) assertEquals( - password, - AbstractConfigurationValidator.ErrorType.INVALID_PASSWORD, - passwordValidator.validate("some_user_name", password) + password, + AbstractConfigurationValidator.ErrorType.INVALID_PASSWORD, + passwordValidator.validate("some_user_name", password) ); - for (final String password: GOOD_PASSWORDS.subList(GOOD_PASSWORDS.size() - 2, GOOD_PASSWORDS.size())) + for (final String password : GOOD_PASSWORDS.subList(GOOD_PASSWORDS.size() - 2, GOOD_PASSWORDS.size())) assertEquals( - password, - AbstractConfigurationValidator.ErrorType.WEAK_PASSWORD, - passwordValidator.validate("some_user_name", password) + password, + AbstractConfigurationValidator.ErrorType.WEAK_PASSWORD, + passwordValidator.validate("some_user_name", password) ); verifyStrongPasswords(passwordValidator, AbstractConfigurationValidator.ErrorType.NONE); verifyVeryStrongPasswords(passwordValidator, AbstractConfigurationValidator.ErrorType.NONE); @@ -153,17 +147,11 @@ public void testRegExpBasedValidation() { @Test public void testMinLength() { - final PasswordValidator passwordValidator = - PasswordValidator.of( - Settings.builder() - .put(SECURITY_RESTAPI_PASSWORD_MIN_LENGTH, 15) - .build() - ); - for (final String password: STRONG_PASSWORDS) { - assertEquals( - AbstractConfigurationValidator.ErrorType.INVALID_PASSWORD, - passwordValidator.validate(password, "some_user_name") - ); + final PasswordValidator passwordValidator = PasswordValidator.of( + Settings.builder().put(SECURITY_RESTAPI_PASSWORD_MIN_LENGTH, 15).build() + ); + for (final String password : STRONG_PASSWORDS) { + assertEquals(AbstractConfigurationValidator.ErrorType.INVALID_PASSWORD, passwordValidator.validate(password, "some_user_name")); } } @@ -178,13 +166,11 @@ public void testScoreBasedValidation() { verifyVeryStrongPasswords(passwordValidator, AbstractConfigurationValidator.ErrorType.NONE); verifySimilarPasswords(passwordValidator); - passwordValidator = - PasswordValidator.of( - Settings.builder() - .put( - SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH, - PasswordValidator.ScoreStrength.FAIR.name() - ).build()); + passwordValidator = PasswordValidator.of( + Settings.builder() + .put(SECURITY_RESTAPI_PASSWORD_SCORE_BASED_VALIDATION_STRENGTH, PasswordValidator.ScoreStrength.FAIR.name()) + .build() + ); verifyWeakPasswords(passwordValidator, AbstractConfigurationValidator.ErrorType.WEAK_PASSWORD); verifyFairPasswords(passwordValidator, AbstractConfigurationValidator.ErrorType.NONE); diff --git a/src/test/java/org/opensearch/security/filter/SecurityFilterTest.java b/src/test/java/org/opensearch/security/filter/SecurityFilterTest.java index 9430450875..3e9cfe4b5e 100644 --- a/src/test/java/org/opensearch/security/filter/SecurityFilterTest.java +++ b/src/test/java/org/opensearch/security/filter/SecurityFilterTest.java @@ -59,32 +59,33 @@ public SecurityFilterTest(Settings settings, WildcardMatcher expected) { @Parameterized.Parameters public static Collection data() { - return Arrays.asList(new Object[][]{ - {Settings.EMPTY, WildcardMatcher.NONE}, - {Settings.builder() - .putList(ConfigConstants.SECURITY_COMPLIANCE_IMMUTABLE_INDICES, "immutable1", "immutable2") - .build(), - WildcardMatcher.from(ImmutableSet.of("immutable1", "immutable2"))}, - {Settings.builder() + return Arrays.asList( + new Object[][] { + { Settings.EMPTY, WildcardMatcher.NONE }, + { + Settings.builder().putList(ConfigConstants.SECURITY_COMPLIANCE_IMMUTABLE_INDICES, "immutable1", "immutable2").build(), + WildcardMatcher.from(ImmutableSet.of("immutable1", "immutable2")) }, + { + Settings.builder() .putList(ConfigConstants.SECURITY_COMPLIANCE_IMMUTABLE_INDICES, "immutable1", "immutable2", "immutable2") .build(), - WildcardMatcher.from(ImmutableSet.of("immutable1", "immutable2"))}, - }); + WildcardMatcher.from(ImmutableSet.of("immutable1", "immutable2")) }, } + ); } @Test public void testImmutableIndicesWildcardMatcher() { final SecurityFilter filter = new SecurityFilter( - settings, - mock(PrivilegesEvaluator.class), - mock(AdminDNs.class), - mock(DlsFlsRequestValve.class), - mock(AuditLog.class), - mock(ThreadPool.class), - mock(ClusterService.class), - mock(CompatConfig.class), - mock(IndexResolverReplacer.class), - mock(XFFResolver.class) + settings, + mock(PrivilegesEvaluator.class), + mock(AdminDNs.class), + mock(DlsFlsRequestValve.class), + mock(AuditLog.class), + mock(ThreadPool.class), + mock(ClusterService.class), + mock(CompatConfig.class), + mock(IndexResolverReplacer.class), + mock(XFFResolver.class) ); assertThat(expected, equalTo(filter.getImmutableIndicesMatcher())); } @@ -103,7 +104,7 @@ public void testUnexepectedCausesAreNotSendToCallers() { mock(AdminDNs.class), mock(DlsFlsRequestValve.class), auditLog, - new ThreadPool(Settings.builder().put("node.name", "mock").build()), + new ThreadPool(Settings.builder().put("node.name", "mock").build()), mock(ClusterService.class), mock(CompatConfig.class), mock(IndexResolverReplacer.class), @@ -119,8 +120,12 @@ public void testUnexepectedCausesAreNotSendToCallers() { final ArgumentCaptor cap = ArgumentCaptor.forClass(OpenSearchSecurityException.class); verify(listener).onFailure(cap.capture()); - assertThat("The cause should never be included as it will leak to callers", cap.getValue().getCause(), nullValue()); - assertThat("Make sure the cause exception wasn't toStringed in the method", cap.getValue().getMessage(), not(containsString("ABC!"))); + assertThat("The cause should never be included as it will leak to callers", cap.getValue().getCause(), nullValue()); + assertThat( + "Make sure the cause exception wasn't toStringed in the method", + cap.getValue().getMessage(), + not(containsString("ABC!")) + ); verifyNoMoreInteractions(auditLog, listener); } diff --git a/src/test/java/org/opensearch/security/filter/SecurityRestFilterTest.java b/src/test/java/org/opensearch/security/filter/SecurityRestFilterTest.java index 1a087887d8..692a950fb1 100644 --- a/src/test/java/org/opensearch/security/filter/SecurityRestFilterTest.java +++ b/src/test/java/org/opensearch/security/filter/SecurityRestFilterTest.java @@ -48,25 +48,29 @@ public void checkWhitelistedApisAreAccessible() throws Exception { setup(); - //ADD SOME WHITELISTED APIs + // ADD SOME WHITELISTED APIs rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - response = rh.executePutRequest("_opendistro/_security/api/whitelist", "{\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}", adminCredsHeader); + response = rh.executePutRequest( + "_opendistro/_security/api/whitelist", + "{\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}", + adminCredsHeader + ); log.warn("the response is:" + rh.executeGetRequest("_opendistro/_security/api/whitelist", adminCredsHeader)); - //NON ADMIN TRIES ACCESSING A WHITELISTED API - OK + // NON ADMIN TRIES ACCESSING A WHITELISTED API - OK rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cat/nodes", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - //ADMIN TRIES ACCESSING A WHITELISTED API - OK + // ADMIN TRIES ACCESSING A WHITELISTED API - OK rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cat/nodes", adminCredsHeader); log.warn("the second response is:{}", response); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - //SUPERADMIN TRIES ACCESSING A WHITELISTED API - OK + // SUPERADMIN TRIES ACCESSING A WHITELISTED API - OK rh.sendAdminCertificate = true; response = rh.executeGetRequest("_cat/nodes", adminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); @@ -82,25 +86,29 @@ public void checkAllowlistedApisAreAccessible() throws Exception { setup(); - //ADD SOME ALLOWLISTED APIs + // ADD SOME ALLOWLISTED APIs rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - response = rh.executePutRequest("_plugins/_security/api/allowlist", "{\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}", adminCredsHeader); + response = rh.executePutRequest( + "_plugins/_security/api/allowlist", + "{\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}", + adminCredsHeader + ); log.warn("the response is:" + rh.executeGetRequest("_plugins/_security/api/allowlist", adminCredsHeader)); - //NON ADMIN TRIES ACCESSING A ALLOWLISTED API - OK + // NON ADMIN TRIES ACCESSING A ALLOWLISTED API - OK rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cat/nodes", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - //ADMIN TRIES ACCESSING A ALLOWLISTED API - OK + // ADMIN TRIES ACCESSING A ALLOWLISTED API - OK rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cat/nodes", adminCredsHeader); log.warn("the second response is:{}", response); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - //SUPERADMIN TRIES ACCESSING A ALLOWLISTED API - OK + // SUPERADMIN TRIES ACCESSING A ALLOWLISTED API - OK rh.sendAdminCertificate = true; response = rh.executeGetRequest("_cat/nodes", adminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); @@ -115,22 +123,26 @@ public void checkAllowlistedApisAreAccessible() throws Exception { public void checkNonWhitelistedApisAccessibleOnlyBySuperAdmin() throws Exception { setup(); - //ADD SOME WHITELISTED APIs - /_cat/nodes and /_cat/indices + // ADD SOME WHITELISTED APIs - /_cat/nodes and /_cat/indices rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - response = rh.executePutRequest("_opendistro/_security/api/whitelist", "{\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}", nonAdminCredsHeader); + response = rh.executePutRequest( + "_opendistro/_security/api/whitelist", + "{\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}", + nonAdminCredsHeader + ); - //NON ADMIN TRIES ACCESSING A NON-WHITELISTED API - FORBIDDEN + // NON ADMIN TRIES ACCESSING A NON-WHITELISTED API - FORBIDDEN rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cat/plugins", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - //ADMIN TRIES ACCESSING A NON-WHITELISTED API - FORBIDDEN + // ADMIN TRIES ACCESSING A NON-WHITELISTED API - FORBIDDEN rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cat/plugins", adminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - //SUPERADMIN TRIES ACCESSING A NON-WHITELISTED API - OK + // SUPERADMIN TRIES ACCESSING A NON-WHITELISTED API - OK rh.sendAdminCertificate = true; response = rh.executeGetRequest("_cat/plugins", adminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); @@ -145,22 +157,26 @@ public void checkNonWhitelistedApisAccessibleOnlyBySuperAdmin() throws Exception public void checkNonAllowlistedApisAccessibleOnlyBySuperAdmin() throws Exception { setup(); - //ADD SOME ALLOWLISTED APIs - /_cat/nodes and /_cat/indices + // ADD SOME ALLOWLISTED APIs - /_cat/nodes and /_cat/indices rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - response = rh.executePutRequest("_plugins/_security/api/allowlist", "{\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}", nonAdminCredsHeader); + response = rh.executePutRequest( + "_plugins/_security/api/allowlist", + "{\"enabled\": true, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}", + nonAdminCredsHeader + ); - //NON ADMIN TRIES ACCESSING A NON-ALLOWLISTED API - FORBIDDEN + // NON ADMIN TRIES ACCESSING A NON-ALLOWLISTED API - FORBIDDEN rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cat/plugins", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - //ADMIN TRIES ACCESSING A NON-ALLOWLISTED API - FORBIDDEN + // ADMIN TRIES ACCESSING A NON-ALLOWLISTED API - FORBIDDEN rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cat/plugins", adminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - //SUPERADMIN TRIES ACCESSING A NON-ALLOWLISTED API - OK + // SUPERADMIN TRIES ACCESSING A NON-ALLOWLISTED API - OK rh.sendAdminCertificate = true; response = rh.executeGetRequest("_cat/plugins", adminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); @@ -173,26 +189,30 @@ public void checkNonAllowlistedApisAccessibleOnlyBySuperAdmin() throws Exception public void checkAllApisWhenWhitelistingNotEnabled() throws Exception { setup(); - //DISABLE WHITELISTING BUT ADD SOME WHITELISTED APIs - /_cat/nodes and /_cat/plugins + // DISABLE WHITELISTING BUT ADD SOME WHITELISTED APIs - /_cat/nodes and /_cat/plugins rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - response = rh.executePutRequest("_opendistro/_security/api/whitelist", "{\"enabled\": false, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}", nonAdminCredsHeader); + response = rh.executePutRequest( + "_opendistro/_security/api/whitelist", + "{\"enabled\": false, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}", + nonAdminCredsHeader + ); - //NON-ADMIN TRIES ACCESSING 2 APIs: One in the list and one outside - OK for both (Because whitelisting is off) + // NON-ADMIN TRIES ACCESSING 2 APIs: One in the list and one outside - OK for both (Because whitelisting is off) rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cat/plugins", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); response = rh.executeGetRequest("_cat/nodes", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - //ADMIN USER TRIES ACCESSING 2 APIs: One in the list and one outside - OK for both (Because whitelisting is off) + // ADMIN USER TRIES ACCESSING 2 APIs: One in the list and one outside - OK for both (Because whitelisting is off) rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cat/plugins", adminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); response = rh.executeGetRequest("_cat/nodes", adminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - //SUPERADMIN TRIES ACCESSING 2 APIS - OK (would work even if whitelisting was on) + // SUPERADMIN TRIES ACCESSING 2 APIS - OK (would work even if whitelisting was on) rh.sendAdminCertificate = true; response = rh.executeGetRequest("_cat/plugins", adminCredsHeader); @@ -208,26 +228,30 @@ public void checkAllApisWhenWhitelistingNotEnabled() throws Exception { public void checkAllApisWhenAllowlistingNotEnabled() throws Exception { setup(); - //DISABLE ALLOWLISTED BUT ADD SOME ALLOWLISTED APIs - /_cat/nodes and /_cat/plugins + // DISABLE ALLOWLISTED BUT ADD SOME ALLOWLISTED APIs - /_cat/nodes and /_cat/plugins rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - response = rh.executePutRequest("_plugins/_security/api/allowlist", "{\"enabled\": false, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}", nonAdminCredsHeader); + response = rh.executePutRequest( + "_plugins/_security/api/allowlist", + "{\"enabled\": false, \"requests\": {\"/_cat/nodes\": [\"GET\"],\"/_cat/indices\": [\"GET\"] }}", + nonAdminCredsHeader + ); - //NON-ADMIN TRIES ACCESSING 2 APIs: One in the list and one outside - OK for both (Because allowlisting is off) + // NON-ADMIN TRIES ACCESSING 2 APIs: One in the list and one outside - OK for both (Because allowlisting is off) rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cat/plugins", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); response = rh.executeGetRequest("_cat/nodes", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - //ADMIN USER TRIES ACCESSING 2 APIs: One in the list and one outside - OK for both (Because allowlisting is off) + // ADMIN USER TRIES ACCESSING 2 APIs: One in the list and one outside - OK for both (Because allowlisting is off) rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cat/plugins", adminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); response = rh.executeGetRequest("_cat/nodes", adminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - //SUPERADMIN TRIES ACCESSING 2 APIS - OK (would work even if allowlisting was on) + // SUPERADMIN TRIES ACCESSING 2 APIS - OK (would work even if allowlisting was on) rh.sendAdminCertificate = true; response = rh.executeGetRequest("_cat/plugins", adminCredsHeader); @@ -245,34 +269,50 @@ public void checkAllApisWhenAllowlistingNotEnabled() throws Exception { * */ @Test - public void checkSpecificRequestMethodWhitelisting() throws Exception{ + public void checkSpecificRequestMethodWhitelisting() throws Exception { setup(); - //WHITELIST GET /_cluster/settings + // WHITELIST GET /_cluster/settings rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - response = rh.executePutRequest("_opendistro/_security/api/whitelist", "{\"enabled\": true, \"requests\": {\"/_cluster/settings\": [\"GET\"]}}", nonAdminCredsHeader); + response = rh.executePutRequest( + "_opendistro/_security/api/whitelist", + "{\"enabled\": true, \"requests\": {\"/_cluster/settings\": [\"GET\"]}}", + nonAdminCredsHeader + ); - //NON-ADMIN TRIES ACCESSING GET - OK, PUT - FORBIDDEN + // NON-ADMIN TRIES ACCESSING GET - OK, PUT - FORBIDDEN rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cluster/settings", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - response = rh.executePutRequest("_cluster/settings","{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", nonAdminCredsHeader); + response = rh.executePutRequest( + "_cluster/settings", + "{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", + nonAdminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - //ADMIN USER TRIES ACCESSING GET - OK, PUT - FORBIDDEN + // ADMIN USER TRIES ACCESSING GET - OK, PUT - FORBIDDEN rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cluster/settings", adminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - response = rh.executePutRequest("_cluster/settings","{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", adminCredsHeader); + response = rh.executePutRequest( + "_cluster/settings", + "{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", + adminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - //SUPERADMIN TRIES ACCESSING GET - OK, PUT - OK + // SUPERADMIN TRIES ACCESSING GET - OK, PUT - OK rh.sendAdminCertificate = true; response = rh.executeGetRequest("_cluster/settings", adminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - response = rh.executePutRequest("_cluster/settings","{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", adminCredsHeader); + response = rh.executePutRequest( + "_cluster/settings", + "{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", + adminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); } @@ -285,38 +325,53 @@ public void checkSpecificRequestMethodWhitelisting() throws Exception{ * */ @Test - public void checkSpecificRequestMethodAllowlisting() throws Exception{ + public void checkSpecificRequestMethodAllowlisting() throws Exception { setup(); - //WHITELIST GET /_cluster/settings + // WHITELIST GET /_cluster/settings rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - response = rh.executePutRequest("_plugins/_security/api/allowlist", "{\"enabled\": true, \"requests\": {\"/_cluster/settings\": [\"GET\"]}}", nonAdminCredsHeader); + response = rh.executePutRequest( + "_plugins/_security/api/allowlist", + "{\"enabled\": true, \"requests\": {\"/_cluster/settings\": [\"GET\"]}}", + nonAdminCredsHeader + ); - //NON-ADMIN TRIES ACCESSING GET - OK, PUT - FORBIDDEN + // NON-ADMIN TRIES ACCESSING GET - OK, PUT - FORBIDDEN rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cluster/settings", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - response = rh.executePutRequest("_cluster/settings","{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", nonAdminCredsHeader); + response = rh.executePutRequest( + "_cluster/settings", + "{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", + nonAdminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - //ADMIN USER TRIES ACCESSING GET - OK, PUT - FORBIDDEN + // ADMIN USER TRIES ACCESSING GET - OK, PUT - FORBIDDEN rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cluster/settings", adminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - response = rh.executePutRequest("_cluster/settings","{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", adminCredsHeader); + response = rh.executePutRequest( + "_cluster/settings", + "{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", + adminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - //SUPERADMIN TRIES ACCESSING GET - OK, PUT - OK + // SUPERADMIN TRIES ACCESSING GET - OK, PUT - OK rh.sendAdminCertificate = true; response = rh.executeGetRequest("_cluster/settings", adminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - response = rh.executePutRequest("_cluster/settings","{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", adminCredsHeader); + response = rh.executePutRequest( + "_cluster/settings", + "{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", + adminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); } - /** * Tests that a whitelisted API with an extra '/' does not cause an issue * i.e if only GET /_cluster/settings/ is whitelisted, then: @@ -327,29 +382,41 @@ public void checkSpecificRequestMethodAllowlisting() throws Exception{ * @throws Exception */ @Test - public void testWhitelistedApiWithExtraSlash() throws Exception{ + public void testWhitelistedApiWithExtraSlash() throws Exception { setup(); - //WHITELIST GET /_cluster/settings/ - extra / in the request + // WHITELIST GET /_cluster/settings/ - extra / in the request rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - response = rh.executePutRequest("_opendistro/_security/api/whitelist", "{\"enabled\": true, \"requests\": {\"/_cluster/settings/\": [\"GET\"]}}", nonAdminCredsHeader); + response = rh.executePutRequest( + "_opendistro/_security/api/whitelist", + "{\"enabled\": true, \"requests\": {\"/_cluster/settings/\": [\"GET\"]}}", + nonAdminCredsHeader + ); - //NON ADMIN ACCESS GET /_cluster/settings/ - OK + // NON ADMIN ACCESS GET /_cluster/settings/ - OK rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cluster/settings/", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - //NON ADMIN ACCESS GET /_cluster/settings - OK + // NON ADMIN ACCESS GET /_cluster/settings - OK response = rh.executeGetRequest("_cluster/settings", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - //NON ADMIN ACCESS PUT /_cluster/settings/ - FORBIDDEN - response = rh.executePutRequest("_cluster/settings/","{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", adminCredsHeader); + // NON ADMIN ACCESS PUT /_cluster/settings/ - FORBIDDEN + response = rh.executePutRequest( + "_cluster/settings/", + "{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", + adminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - //NON ADMIN ACCESS PUT /_cluster/settings - FORBIDDEN - response = rh.executePutRequest("_cluster/settings","{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", adminCredsHeader); + // NON ADMIN ACCESS PUT /_cluster/settings - FORBIDDEN + response = rh.executePutRequest( + "_cluster/settings", + "{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", + adminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); } @@ -364,29 +431,41 @@ public void testWhitelistedApiWithExtraSlash() throws Exception{ * @throws Exception */ @Test - public void testAllowlistedApiWithExtraSlash() throws Exception{ + public void testAllowlistedApiWithExtraSlash() throws Exception { setup(); - //WHITELIST GET /_cluster/settings/ - extra / in the request + // WHITELIST GET /_cluster/settings/ - extra / in the request rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - response = rh.executePutRequest("_plugins/_security/api/allowlist", "{\"enabled\": true, \"requests\": {\"/_cluster/settings/\": [\"GET\"]}}", nonAdminCredsHeader); + response = rh.executePutRequest( + "_plugins/_security/api/allowlist", + "{\"enabled\": true, \"requests\": {\"/_cluster/settings/\": [\"GET\"]}}", + nonAdminCredsHeader + ); - //NON ADMIN ACCESS GET /_cluster/settings/ - OK + // NON ADMIN ACCESS GET /_cluster/settings/ - OK rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cluster/settings/", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - //NON ADMIN ACCESS GET /_cluster/settings - OK + // NON ADMIN ACCESS GET /_cluster/settings - OK response = rh.executeGetRequest("_cluster/settings", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - //NON ADMIN ACCESS PUT /_cluster/settings/ - FORBIDDEN - response = rh.executePutRequest("_cluster/settings/","{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", adminCredsHeader); + // NON ADMIN ACCESS PUT /_cluster/settings/ - FORBIDDEN + response = rh.executePutRequest( + "_cluster/settings/", + "{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", + adminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - //NON ADMIN ACCESS PUT /_cluster/settings - FORBIDDEN - response = rh.executePutRequest("_cluster/settings","{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", adminCredsHeader); + // NON ADMIN ACCESS PUT /_cluster/settings - FORBIDDEN + response = rh.executePutRequest( + "_cluster/settings", + "{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", + adminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); } @@ -401,29 +480,41 @@ public void testAllowlistedApiWithExtraSlash() throws Exception{ * @throws Exception */ @Test - public void testWhitelistedApiWithoutExtraSlash() throws Exception{ + public void testWhitelistedApiWithoutExtraSlash() throws Exception { setup(); - //WHITELIST GET /_cluster/settings (no extra / in request) + // WHITELIST GET /_cluster/settings (no extra / in request) rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - response = rh.executePutRequest("_opendistro/_security/api/whitelist", "{\"enabled\": true, \"requests\": {\"/_cluster/settings\": [\"GET\"]}}", nonAdminCredsHeader); + response = rh.executePutRequest( + "_opendistro/_security/api/whitelist", + "{\"enabled\": true, \"requests\": {\"/_cluster/settings\": [\"GET\"]}}", + nonAdminCredsHeader + ); - //NON ADMIN ACCESS GET /_cluster/settings/ - OK + // NON ADMIN ACCESS GET /_cluster/settings/ - OK rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cluster/settings/", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - //NON ADMIN ACCESS GET /_cluster/settings - OK + // NON ADMIN ACCESS GET /_cluster/settings - OK response = rh.executeGetRequest("_cluster/settings", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - //NON ADMIN ACCESS PUT /_cluster/settings/ - FORBIDDEN - response = rh.executePutRequest("_cluster/settings/","{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", adminCredsHeader); + // NON ADMIN ACCESS PUT /_cluster/settings/ - FORBIDDEN + response = rh.executePutRequest( + "_cluster/settings/", + "{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", + adminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - //NON ADMIN ACCESS PUT /_cluster/settings - FORBIDDEN - response = rh.executePutRequest("_cluster/settings","{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", adminCredsHeader); + // NON ADMIN ACCESS PUT /_cluster/settings - FORBIDDEN + response = rh.executePutRequest( + "_cluster/settings", + "{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", + adminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); } @@ -437,29 +528,41 @@ public void testWhitelistedApiWithoutExtraSlash() throws Exception{ * @throws Exception */ @Test - public void testAllowlistedApiWithoutExtraSlash() throws Exception{ + public void testAllowlistedApiWithoutExtraSlash() throws Exception { setup(); - //WHITELIST GET /_cluster/settings (no extra / in request) + // WHITELIST GET /_cluster/settings (no extra / in request) rh.keystore = "restapi/kirk-keystore.jks"; rh.sendAdminCertificate = true; - response = rh.executePutRequest("_plugins/_security/api/allowlist", "{\"enabled\": true, \"requests\": {\"/_cluster/settings\": [\"GET\"]}}", nonAdminCredsHeader); + response = rh.executePutRequest( + "_plugins/_security/api/allowlist", + "{\"enabled\": true, \"requests\": {\"/_cluster/settings\": [\"GET\"]}}", + nonAdminCredsHeader + ); - //NON ADMIN ACCESS GET /_cluster/settings/ - OK + // NON ADMIN ACCESS GET /_cluster/settings/ - OK rh.sendAdminCertificate = false; response = rh.executeGetRequest("_cluster/settings/", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - //NON ADMIN ACCESS GET /_cluster/settings - OK + // NON ADMIN ACCESS GET /_cluster/settings - OK response = rh.executeGetRequest("_cluster/settings", nonAdminCredsHeader); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - //NON ADMIN ACCESS PUT /_cluster/settings/ - FORBIDDEN - response = rh.executePutRequest("_cluster/settings/","{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", adminCredsHeader); + // NON ADMIN ACCESS PUT /_cluster/settings/ - FORBIDDEN + response = rh.executePutRequest( + "_cluster/settings/", + "{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", + adminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - //NON ADMIN ACCESS PUT /_cluster/settings - FORBIDDEN - response = rh.executePutRequest("_cluster/settings","{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", adminCredsHeader); + // NON ADMIN ACCESS PUT /_cluster/settings - FORBIDDEN + response = rh.executePutRequest( + "_cluster/settings", + "{\"persistent\": { }, \"transient\": {\"indices.recovery.max_bytes_per_sec\": \"15mb\" }}", + adminCredsHeader + ); assertThat(response.getBody(), response.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); } } diff --git a/src/test/java/org/opensearch/security/http/HTTPOnBehalfOfJwtAuthenticatorTest.java b/src/test/java/org/opensearch/security/http/HTTPOnBehalfOfJwtAuthenticatorTest.java index 5a6c5ec41c..06f19a888a 100644 --- a/src/test/java/org/opensearch/security/http/HTTPOnBehalfOfJwtAuthenticatorTest.java +++ b/src/test/java/org/opensearch/security/http/HTTPOnBehalfOfJwtAuthenticatorTest.java @@ -53,10 +53,11 @@ public class HTTPOnBehalfOfJwtAuthenticatorTest { public void testNoKey() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - null, - claimsEncryptionKey, - Jwts.builder().setSubject("Leonard McCoy"), - false); + null, + claimsEncryptionKey, + Jwts.builder().setSubject("Leonard McCoy"), + false + ); Assert.assertNull(credentials); } @@ -65,10 +66,11 @@ public void testNoKey() throws Exception { public void testEmptyKey() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - "", - claimsEncryptionKey, - Jwts.builder().setSubject("Leonard McCoy"), - false); + "", + claimsEncryptionKey, + Jwts.builder().setSubject("Leonard McCoy"), + false + ); Assert.assertNull(credentials); } @@ -77,10 +79,11 @@ public void testEmptyKey() throws Exception { public void testBadKey() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - BaseEncoding.base64().encode(new byte[]{1,3,3,4,3,6,7,8,3,10}), - claimsEncryptionKey, - Jwts.builder().setSubject("Leonard McCoy"), - false); + BaseEncoding.base64().encode(new byte[] { 1, 3, 3, 4, 3, 6, 7, 8, 3, 10 }), + claimsEncryptionKey, + Jwts.builder().setSubject("Leonard McCoy"), + false + ); Assert.assertNull(credentials); } @@ -88,7 +91,10 @@ public void testBadKey() throws Exception { @Test public void testTokenMissing() throws Exception { - HTTPOnBehalfOfJwtAuthenticator jwtAuth = new HTTPOnBehalfOfJwtAuthenticator(BaseEncoding.base64().encode(secretKeyBytes),claimsEncryptionKey); + HTTPOnBehalfOfJwtAuthenticator jwtAuth = new HTTPOnBehalfOfJwtAuthenticator( + BaseEncoding.base64().encode(secretKeyBytes), + claimsEncryptionKey + ); Map headers = new HashMap(); AuthCredentials credentials = jwtAuth.extractCredentials(new FakeRestRequest(headers, new HashMap()), null); @@ -101,9 +107,12 @@ public void testInvalid() throws Exception { String jwsToken = "123invalidtoken.."; - HTTPOnBehalfOfJwtAuthenticator jwtAuth = new HTTPOnBehalfOfJwtAuthenticator(BaseEncoding.base64().encode(secretKeyBytes), claimsEncryptionKey); + HTTPOnBehalfOfJwtAuthenticator jwtAuth = new HTTPOnBehalfOfJwtAuthenticator( + BaseEncoding.base64().encode(secretKeyBytes), + claimsEncryptionKey + ); Map headers = new HashMap(); - headers.put("Authorization", "Bearer "+jwsToken); + headers.put("Authorization", "Bearer " + jwsToken); AuthCredentials credentials = jwtAuth.extractCredentials(new FakeRestRequest(headers, new HashMap()), null); Assert.assertNull(credentials); @@ -112,11 +121,18 @@ public void testInvalid() throws Exception { @Test public void testBearer() throws Exception { - String jwsToken = Jwts.builder().setSubject("Leonard McCoy").setAudience("ext_0").signWith(secretKey, SignatureAlgorithm.HS512).compact(); + String jwsToken = Jwts.builder() + .setSubject("Leonard McCoy") + .setAudience("ext_0") + .signWith(secretKey, SignatureAlgorithm.HS512) + .compact(); - HTTPOnBehalfOfJwtAuthenticator jwtAuth = new HTTPOnBehalfOfJwtAuthenticator(BaseEncoding.base64().encode(secretKeyBytes), claimsEncryptionKey); + HTTPOnBehalfOfJwtAuthenticator jwtAuth = new HTTPOnBehalfOfJwtAuthenticator( + BaseEncoding.base64().encode(secretKeyBytes), + claimsEncryptionKey + ); Map headers = new HashMap(); - headers.put("Authorization", "Bearer "+jwsToken); + headers.put("Authorization", "Bearer " + jwsToken); AuthCredentials credentials = jwtAuth.extractCredentials(new FakeRestRequest(headers, new HashMap()), null); @@ -142,7 +158,6 @@ public void testBearerWrongPosition() throws Exception { Assert.assertNull(credentials); } - @Test public void testBasicAuthHeader() throws Exception { Settings settings = Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).build(); @@ -160,10 +175,11 @@ public void testRoles() throws Exception { List roles = List.of("IT", "HR"); final AuthCredentials credentials = extractCredentialsFromJwtHeader( - signingKey, - claimsEncryptionKey, - Jwts.builder().setSubject("Leonard McCoy").claim("dr", "role1,role2"), - true); + signingKey, + claimsEncryptionKey, + Jwts.builder().setSubject("Leonard McCoy").claim("dr", "role1,role2"), + true + ); Assert.assertNotNull(credentials); Assert.assertEquals("Leonard McCoy", credentials.getUsername()); @@ -174,10 +190,11 @@ public void testRoles() throws Exception { public void testNullClaim() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - signingKey, - claimsEncryptionKey, - Jwts.builder().setSubject("Leonard McCoy").claim("dr", null), - false); + signingKey, + claimsEncryptionKey, + Jwts.builder().setSubject("Leonard McCoy").claim("dr", null), + false + ); Assert.assertNotNull(credentials); Assert.assertEquals("Leonard McCoy", credentials.getUsername()); @@ -188,25 +205,27 @@ public void testNullClaim() throws Exception { public void testNonStringClaim() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - signingKey, - claimsEncryptionKey, - Jwts.builder().setSubject("Leonard McCoy").claim("dr", 123L), - true); + signingKey, + claimsEncryptionKey, + Jwts.builder().setSubject("Leonard McCoy").claim("dr", 123L), + true + ); Assert.assertNotNull(credentials); Assert.assertEquals("Leonard McCoy", credentials.getUsername()); Assert.assertEquals(1, credentials.getBackendRoles().size()); - Assert.assertTrue( credentials.getBackendRoles().contains("123")); + Assert.assertTrue(credentials.getBackendRoles().contains("123")); } @Test public void testRolesMissing() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - signingKey, - claimsEncryptionKey, - Jwts.builder().setSubject("Leonard McCoy"), - false); + signingKey, + claimsEncryptionKey, + Jwts.builder().setSubject("Leonard McCoy"), + false + ); Assert.assertNotNull(credentials); Assert.assertEquals("Leonard McCoy", credentials.getUsername()); @@ -217,10 +236,11 @@ public void testRolesMissing() throws Exception { public void testWrongSubjectKey() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - signingKey, - claimsEncryptionKey, - Jwts.builder().claim("roles", "role1,role2").claim("asub", "Dr. Who"), - false); + signingKey, + claimsEncryptionKey, + Jwts.builder().claim("roles", "role1,role2").claim("asub", "Dr. Who"), + false + ); Assert.assertNull(credentials); } @@ -229,10 +249,11 @@ public void testWrongSubjectKey() throws Exception { public void testExp() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - signingKey, - claimsEncryptionKey, - Jwts.builder().setSubject("Expired").setExpiration(new Date(100)), - false); + signingKey, + claimsEncryptionKey, + Jwts.builder().setSubject("Expired").setExpiration(new Date(100)), + false + ); Assert.assertNull(credentials); } @@ -241,10 +262,11 @@ public void testExp() throws Exception { public void testNbf() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - signingKey, - claimsEncryptionKey, - Jwts.builder().setSubject("Expired").setNotBefore(new Date(System.currentTimeMillis()+(1000*36000))), - false); + signingKey, + claimsEncryptionKey, + Jwts.builder().setSubject("Expired").setNotBefore(new Date(System.currentTimeMillis() + (1000 * 36000))), + false + ); Assert.assertNull(credentials); } @@ -253,17 +275,9 @@ public void testNbf() throws Exception { public void testRolesArray() throws Exception { JwtBuilder builder = Jwts.builder() - .setPayload("{"+ - "\"sub\": \"Cluster_0\","+ - "\"aud\": \"ext_0\","+ - "\"dr\": \"a,b,3rd\""+ - "}"); + .setPayload("{" + "\"sub\": \"Cluster_0\"," + "\"aud\": \"ext_0\"," + "\"dr\": \"a,b,3rd\"" + "}"); - final AuthCredentials credentials = extractCredentialsFromJwtHeader( - signingKey, - claimsEncryptionKey, - builder, - true); + final AuthCredentials credentials = extractCredentialsFromJwtHeader(signingKey, claimsEncryptionKey, builder, true); Assert.assertNotNull(credentials); Assert.assertEquals("Cluster_0", credentials.getUsername()); @@ -275,10 +289,11 @@ public void testRolesArray() throws Exception { /** extracts a default user credential from a request header */ private AuthCredentials extractCredentialsFromJwtHeader( - final String signingKey, - final String encryptionKey, - final JwtBuilder jwtBuilder, - final Boolean bwcPluginCompatibilityMode) { + final String signingKey, + final String encryptionKey, + final JwtBuilder jwtBuilder, + final Boolean bwcPluginCompatibilityMode + ) { final String jwsToken = jwtBuilder.signWith(secretKey, SignatureAlgorithm.HS512).compact(); final HTTPOnBehalfOfJwtAuthenticator jwtAuth = new HTTPOnBehalfOfJwtAuthenticator(signingKey, encryptionKey); final Map headers = Map.of("Authorization", "Bearer " + jwsToken); 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 111a07bf40..47d779cd12 100644 --- a/src/test/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticatorTest.java +++ b/src/test/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticatorTest.java @@ -65,9 +65,7 @@ public class HTTPExtendedProxyAuthenticatorTest { @Before public void setup() { context.putTransient(ConfigConstants.OPENDISTRO_SECURITY_XFF_DONE, Boolean.TRUE); - settings = Settings.builder() - .put("user_header","user") - .build(); + settings = Settings.builder().put("user_header", "user").build(); authenticator = new HTTPExtendedProxyAuthenticator(settings, null); } @@ -79,7 +77,7 @@ public void testGetType() { @Test(expected = OpenSearchSecurityException.class) public void testThrowsExceptionWhenMissingXFFDone() { authenticator = new HTTPExtendedProxyAuthenticator(Settings.EMPTY, null); - authenticator.extractCredentials(new TestRestRequest(), new ThreadContext(Settings.EMPTY)); + authenticator.extractCredentials(new TestRestRequest(), new ThreadContext(Settings.EMPTY)); } @Test @@ -90,11 +88,12 @@ public void testReturnsNullWhenUserHeaderIsUnconfigured() { @Test public void testReturnsNullWhenUserHeaderIsMissing() { - + assertNull(authenticator.extractCredentials(new TestRestRequest(), context)); } + @Test - + public void testReturnsCredentials() { headers.put("user", new ArrayList<>()); headers.put("proxy_uid", new ArrayList<>()); @@ -103,9 +102,9 @@ public void testReturnsCredentials() { headers.get("proxy_uid").add("123"); headers.get("proxy_uid").add("456"); headers.get("proxy_other").add("someothervalue"); - - settings = Settings.builder().put(settings).put("attr_header_prefix","proxy_").build(); - authenticator = new HTTPExtendedProxyAuthenticator(settings,null); + + settings = Settings.builder().put(settings).put("attr_header_prefix", "proxy_").build(); + authenticator = new HTTPExtendedProxyAuthenticator(settings, null); AuthCredentials creds = authenticator.extractCredentials(new TestRestRequest(headers), context); assertNotNull(creds); assertEquals("aValidUser", creds.getUsername()); @@ -113,19 +112,16 @@ public void testReturnsCredentials() { assertEquals("someothervalue", creds.getAttributes().get("attr.proxy.other")); assertTrue(creds.isComplete()); } - + @Test public void testTrimOnRoles() { - headers.put("user", new ArrayList<>()); + headers.put("user", new ArrayList<>()); headers.put("roles", new ArrayList<>()); headers.get("user").add("aValidUser"); headers.get("roles").add("role1, role2,\t"); - - settings = Settings.builder().put(settings) - .put("roles_header","roles") - .put("roles_separator", ",") - .build(); - authenticator = new HTTPExtendedProxyAuthenticator(settings,null); + + settings = Settings.builder().put(settings).put("roles_header", "roles").put("roles_separator", ",").build(); + authenticator = new HTTPExtendedProxyAuthenticator(settings, null); AuthCredentials creds = authenticator.extractCredentials(new TestRestRequest(headers), context); assertNotNull(creds); assertEquals("aValidUser", creds.getUsername()); @@ -134,16 +130,22 @@ public void testTrimOnRoles() { } static class TestRestRequest extends RestRequest { - + public TestRestRequest() { - super(NamedXContentRegistry.EMPTY, new HashMap<>(), "", new HashMap<>(),new HttpRequestImpl(),new HttpChannelImpl()); + super(NamedXContentRegistry.EMPTY, new HashMap<>(), "", new HashMap<>(), new HttpRequestImpl(), new HttpChannelImpl()); } + public TestRestRequest(Map> headers) { - super(NamedXContentRegistry.EMPTY, new HashMap<>(), "", headers, new HttpRequestImpl(),new HttpChannelImpl()); + super(NamedXContentRegistry.EMPTY, new HashMap<>(), "", headers, new HttpRequestImpl(), new HttpChannelImpl()); } - public TestRestRequest(NamedXContentRegistry xContentRegistry, Map params, String path, - Map> headers) { - super(xContentRegistry, params, path, headers, new HttpRequestImpl(),new HttpChannelImpl()); + + public TestRestRequest( + NamedXContentRegistry xContentRegistry, + Map params, + String path, + Map> headers + ) { + super(xContentRegistry, params, path, headers, new HttpRequestImpl(), new HttpChannelImpl()); } @Override @@ -162,7 +164,7 @@ public boolean hasContent() { } } - + static class HttpRequestImpl implements HttpRequest { @Override @@ -228,19 +230,19 @@ public Exception getInboundException() { return null; } } - + static class HttpChannelImpl implements HttpChannel { @Override public void close() { // TODO Auto-generated method stub - + } @Override public void addCloseListener(ActionListener listener) { // TODO Auto-generated method stub - + } @Override @@ -252,7 +254,7 @@ public boolean isOpen() { @Override public void sendResponse(HttpResponse response, ActionListener listener) { // TODO Auto-generated method stub - + } @Override @@ -266,6 +268,6 @@ public InetSocketAddress getRemoteAddress() { // TODO Auto-generated method stub return null; } - + } } diff --git a/src/test/java/org/opensearch/security/httpclient/HttpClientTest.java b/src/test/java/org/opensearch/security/httpclient/HttpClientTest.java index 96d41b6735..3da6ad3d7f 100644 --- a/src/test/java/org/opensearch/security/httpclient/HttpClientTest.java +++ b/src/test/java/org/opensearch/security/httpclient/HttpClientTest.java @@ -30,38 +30,44 @@ protected String getResourceFolder() { @Test public void testPlainConnection() throws Exception { - final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled", false) - .build(); + final Settings settings = Settings.builder().put("plugins.security.ssl.http.enabled", false).build(); setup(Settings.EMPTY, new DynamicSecurityConfig(), settings); Thread.sleep(1000); - try(final HttpClient httpClient = HttpClient.builder(clusterInfo.httpHost+":"+clusterInfo.httpPort) - .setBasicCredentials("admin", "admin").build()) { + try ( + final HttpClient httpClient = HttpClient.builder(clusterInfo.httpHost + ":" + clusterInfo.httpPort) + .setBasicCredentials("admin", "admin") + .build() + ) { Assert.assertTrue(httpClient.index("{\"a\":5}", "index", "type", false)); Assert.assertTrue(httpClient.index("{\"a\":5}", "index", "type", true)); Assert.assertTrue(httpClient.index("{\"a\":5}", "index", "type", true)); } - try(final HttpClient httpClient = HttpClient.builder("unknownhost:6654") - .setBasicCredentials("admin", "admin").build()) { + try (final HttpClient httpClient = HttpClient.builder("unknownhost:6654").setBasicCredentials("admin", "admin").build()) { Assert.assertFalse(httpClient.index("{\"a\":5}", "index", "type", false)); Assert.assertFalse(httpClient.index("{\"a\":5}", "index", "type", true)); Assert.assertFalse(httpClient.index("{\"a\":5}", "index", "type", true)); } - try(final HttpClient httpClient = HttpClient.builder("unknownhost:6654", clusterInfo.httpHost+":"+clusterInfo.httpPort) - .enableSsl(FileHelper.getKeystoreFromClassPath("auditlog/truststore.jks","changeit"), false) - .setBasicCredentials("admin", "admin").build()) { + try ( + final HttpClient httpClient = HttpClient.builder("unknownhost:6654", clusterInfo.httpHost + ":" + clusterInfo.httpPort) + .enableSsl(FileHelper.getKeystoreFromClassPath("auditlog/truststore.jks", "changeit"), false) + .setBasicCredentials("admin", "admin") + .build() + ) { Assert.assertFalse(httpClient.index("{\"a\":5}", "index", "type", false)); Assert.assertFalse(httpClient.index("{\"a\":5}", "index", "type", true)); Assert.assertFalse(httpClient.index("{\"a\":5}", "index", "type", true)); } - try(final HttpClient httpClient = HttpClient.builder("unknownhost:6654", clusterInfo.httpHost+":"+clusterInfo.httpPort) - .setBasicCredentials("admin", "admin").build()) { + try ( + final HttpClient httpClient = HttpClient.builder("unknownhost:6654", clusterInfo.httpHost + ":" + clusterInfo.httpPort) + .setBasicCredentials("admin", "admin") + .build() + ) { Assert.assertTrue(httpClient.index("{\"a\":5}", "index", "type", false)); Assert.assertTrue(httpClient.index("{\"a\":5}", "index", "type", true)); Assert.assertTrue(httpClient.index("{\"a\":5}", "index", "type", true)); @@ -73,27 +79,33 @@ public void testPlainConnection() throws Exception { public void testSslConnection() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled", true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, false) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .build(); + .put("plugins.security.ssl.http.enabled", true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, false) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) + .build(); setup(Settings.EMPTY, new DynamicSecurityConfig(), settings); Thread.sleep(1000); - try(final HttpClient httpClient = HttpClient.builder(clusterInfo.httpHost+":"+clusterInfo.httpPort) - .enableSsl(FileHelper.getKeystoreFromClassPath("auditlog/truststore.jks","changeit"), false) - .setBasicCredentials("admin", "admin").build()) { + try ( + final HttpClient httpClient = HttpClient.builder(clusterInfo.httpHost + ":" + clusterInfo.httpPort) + .enableSsl(FileHelper.getKeystoreFromClassPath("auditlog/truststore.jks", "changeit"), false) + .setBasicCredentials("admin", "admin") + .build() + ) { Assert.assertTrue(httpClient.index("{\"a\":5}", "index", "type", false)); Assert.assertTrue(httpClient.index("{\"a\":5}", "index", "type", true)); Assert.assertTrue(httpClient.index("{\"a\":5}", "index", "type", true)); } - try(final HttpClient httpClient = HttpClient.builder(clusterInfo.httpHost+":"+clusterInfo.httpPort) - .setBasicCredentials("admin", "admin").build()) { + try ( + final HttpClient httpClient = HttpClient.builder(clusterInfo.httpHost + ":" + clusterInfo.httpPort) + .setBasicCredentials("admin", "admin") + .build() + ) { Assert.assertFalse(httpClient.index("{\"a\":5}", "index", "type", false)); Assert.assertFalse(httpClient.index("{\"a\":5}", "index", "type", true)); Assert.assertFalse(httpClient.index("{\"a\":5}", "index", "type", true)); @@ -105,22 +117,28 @@ public void testSslConnection() throws Exception { public void testSslConnectionPKIAuth() throws Exception { final Settings settings = Settings.builder() - .put("plugins.security.ssl.http.enabled", true) - .put("plugins.security.ssl.http.clientauth_mode", "REQUIRE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, false) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) - .build(); + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.clientauth_mode", "REQUIRE") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, false) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks")) + .build(); setup(Settings.EMPTY, new DynamicSecurityConfig(), settings); Thread.sleep(1000); - try(final HttpClient httpClient = HttpClient.builder(clusterInfo.httpHost+":"+clusterInfo.httpPort) - .enableSsl(FileHelper.getKeystoreFromClassPath("auditlog/truststore.jks","changeit"), false) - .setPkiCredentials(FileHelper.getKeystoreFromClassPath("auditlog/spock-keystore.jks", "changeit"), "changeit".toCharArray(), null) - .build()) { + try ( + final HttpClient httpClient = HttpClient.builder(clusterInfo.httpHost + ":" + clusterInfo.httpPort) + .enableSsl(FileHelper.getKeystoreFromClassPath("auditlog/truststore.jks", "changeit"), false) + .setPkiCredentials( + FileHelper.getKeystoreFromClassPath("auditlog/spock-keystore.jks", "changeit"), + "changeit".toCharArray(), + null + ) + .build() + ) { Assert.assertTrue(httpClient.index("{\"a\":5}", "index", "type", false)); Assert.assertTrue(httpClient.index("{\"a\":5}", "index", "type", true)); Assert.assertTrue(httpClient.index("{\"a\":5}", "index", "type", true)); 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 5177dbae10..648f5df4a0 100644 --- a/src/test/java/org/opensearch/security/multitenancy/test/MultitenancyTests.java +++ b/src/test/java/org/opensearch/security/multitenancy/test/MultitenancyTests.java @@ -50,210 +50,321 @@ protected String getResourceFolder() { @Test public void testNoDnfof() throws Exception { - final Settings settings = Settings.builder() - .put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH") - .build(); + final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH").build(); setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_nodnfof.yml"), settings); final RestHelper rh = nonSslRestHelper(); - try (Client tc = getClient()) { - tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); - - tc.index(new IndexRequest("indexa").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":\"indexa\"}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("indexb").id("0").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":\"indexb\"}", XContentType.JSON)).actionGet(); - - - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - tc.index(new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("starfleet","starfleet_academy","starfleet_library").alias("sf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire","vulcangov").alias("nonsf"))).actionGet(); - tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))).actionGet(); - - } - - HttpResponse resc; - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("indexa,indexb/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); - System.out.println(resc.getBody()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("indexa,indexb/_search?pretty", encodeBasicHeader("user_b", "user_b"))).getStatusCode()); - System.out.println(resc.getBody()); - - String msearchBody = - "{\"index\":\"indexa\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ - "{\"index\":\"indexb\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); - System.out.println("#### msearch a"); - resc = rh.executePostRequest("_msearch?pretty", msearchBody, encodeBasicHeader("user_a", "user_a")); - Assert.assertEquals(200, resc.getStatusCode()); - System.out.println(resc.getBody()); - Assert.assertTrue(resc.getBody(), resc.getBody().contains("indexa")); - Assert.assertFalse(resc.getBody(), resc.getBody().contains("indexb")); - Assert.assertTrue(resc.getBody(), resc.getBody().contains("exception")); - Assert.assertTrue(resc.getBody(), resc.getBody().contains("permission")); - - System.out.println("#### msearch b"); - resc = rh.executePostRequest("_msearch?pretty", msearchBody, encodeBasicHeader("user_b", "user_b")); - Assert.assertEquals(200, resc.getStatusCode()); - System.out.println(resc.getBody()); - Assert.assertFalse(resc.getBody(), resc.getBody().contains("indexa")); - Assert.assertTrue(resc.getBody(), resc.getBody().contains("indexb")); - Assert.assertTrue(resc.getBody(), resc.getBody().contains("exception")); - Assert.assertTrue(resc.getBody(), resc.getBody().contains("permission")); - - msearchBody = - "{\"index\":\"indexc\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ - "{\"index\":\"indexd\", \"ignore_unavailable\": true}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); - - System.out.println("#### msearch b2"); - resc = rh.executePostRequest("_msearch?pretty", msearchBody, encodeBasicHeader("user_b", "user_b")); - System.out.println(resc.getBody()); - Assert.assertEquals(200, resc.getStatusCode()); - Assert.assertFalse(resc.getBody(), resc.getBody().contains("indexc")); - Assert.assertFalse(resc.getBody(), resc.getBody().contains("indexd")); - Assert.assertTrue(resc.getBody(), resc.getBody().contains("exception")); - Assert.assertTrue(resc.getBody(), resc.getBody().contains("permission")); - int count = resc.getBody().split("\"status\" : 403").length; - Assert.assertEquals(3, count); - - String mgetBody = "{"+ - "\"docs\" : ["+ - "{"+ - "\"_index\" : \"indexa\","+ - "\"_id\" : \"0\""+ - " },"+ - " {"+ - "\"_index\" : \"indexb\","+ - " \"_id\" : \"0\""+ - "}"+ - "]"+ - "}"; - - resc = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("user_b", "user_b")); - Assert.assertEquals(200, resc.getStatusCode()); - Assert.assertFalse(resc.getBody(), resc.getBody().contains("\"content\" : \"indexa\"")); - Assert.assertTrue(resc.getBody(), resc.getBody().contains("indexb")); - Assert.assertTrue(resc.getBody(), resc.getBody().contains("exception")); - Assert.assertTrue(resc.getBody(), resc.getBody().contains("permission")); - - mgetBody = "{"+ - "\"docs\" : ["+ - "{"+ - "\"_index\" : \"indexx\","+ - "\"_id\" : \"0\""+ - " },"+ - " {"+ - "\"_index\" : \"indexy\","+ - " \"_id\" : \"0\""+ - "}"+ - "]"+ - "}"; - - resc = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("user_b", "user_b")); - Assert.assertEquals(200, resc.getStatusCode()); - Assert.assertTrue(resc.getBody(), resc.getBody().contains("exception")); - count = resc.getBody().split("root_cause").length; - Assert.assertEquals(3, count); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("index*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); - - - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("indexa/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); - System.out.println(resc.getBody()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("indexb/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); - System.out.println(resc.getBody()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); - System.out.println(resc.getBody()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("_all/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); - System.out.println(resc.getBody()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("notexists/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); - System.out.println(resc.getBody()); - - Assert.assertEquals(HttpStatus.SC_NOT_FOUND, (resc=rh.executeGetRequest("indexanbh,indexabb*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); - System.out.println(resc.getBody()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); - System.out.println(resc.getBody()); - - Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf"))).getStatusCode()); - System.out.println(resc.getBody()); + try (Client tc = getClient()) { + tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); + + tc.index( + new IndexRequest("indexa").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":\"indexa\"}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("indexb").id("0") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source("{\"content\":\"indexb\"}", XContentType.JSON) + ).actionGet(); + + tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index( + new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + + tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON) + ).actionGet(); + + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction( + AliasActions.add().indices("starfleet", "starfleet_academy", "starfleet_library").alias("sf") + ) + ) + .actionGet(); + tc.admin() + .indices() + .aliases( + new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire", "vulcangov").alias("nonsf")) + ) + .actionGet(); + tc.admin() + .indices() + .aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))) + .actionGet(); + + } + + HttpResponse resc; + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("indexa,indexb/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); + System.out.println(resc.getBody()); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("indexa,indexb/_search?pretty", encodeBasicHeader("user_b", "user_b"))).getStatusCode() + ); + System.out.println(resc.getBody()); + + String msearchBody = "{\"index\":\"indexa\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator() + + "{\"index\":\"indexb\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); + System.out.println("#### msearch a"); + resc = rh.executePostRequest("_msearch?pretty", msearchBody, encodeBasicHeader("user_a", "user_a")); + Assert.assertEquals(200, resc.getStatusCode()); + System.out.println(resc.getBody()); + Assert.assertTrue(resc.getBody(), resc.getBody().contains("indexa")); + Assert.assertFalse(resc.getBody(), resc.getBody().contains("indexb")); + Assert.assertTrue(resc.getBody(), resc.getBody().contains("exception")); + Assert.assertTrue(resc.getBody(), resc.getBody().contains("permission")); + + System.out.println("#### msearch b"); + resc = rh.executePostRequest("_msearch?pretty", msearchBody, encodeBasicHeader("user_b", "user_b")); + Assert.assertEquals(200, resc.getStatusCode()); + System.out.println(resc.getBody()); + Assert.assertFalse(resc.getBody(), resc.getBody().contains("indexa")); + Assert.assertTrue(resc.getBody(), resc.getBody().contains("indexb")); + Assert.assertTrue(resc.getBody(), resc.getBody().contains("exception")); + Assert.assertTrue(resc.getBody(), resc.getBody().contains("permission")); + + msearchBody = "{\"index\":\"indexc\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator() + + "{\"index\":\"indexd\", \"ignore_unavailable\": true}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); + + System.out.println("#### msearch b2"); + resc = rh.executePostRequest("_msearch?pretty", msearchBody, encodeBasicHeader("user_b", "user_b")); + System.out.println(resc.getBody()); + Assert.assertEquals(200, resc.getStatusCode()); + Assert.assertFalse(resc.getBody(), resc.getBody().contains("indexc")); + Assert.assertFalse(resc.getBody(), resc.getBody().contains("indexd")); + Assert.assertTrue(resc.getBody(), resc.getBody().contains("exception")); + Assert.assertTrue(resc.getBody(), resc.getBody().contains("permission")); + int count = resc.getBody().split("\"status\" : 403").length; + Assert.assertEquals(3, count); + + String mgetBody = "{" + + "\"docs\" : [" + + "{" + + "\"_index\" : \"indexa\"," + + "\"_id\" : \"0\"" + + " }," + + " {" + + "\"_index\" : \"indexb\"," + + " \"_id\" : \"0\"" + + "}" + + "]" + + "}"; + + resc = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("user_b", "user_b")); + Assert.assertEquals(200, resc.getStatusCode()); + Assert.assertFalse(resc.getBody(), resc.getBody().contains("\"content\" : \"indexa\"")); + Assert.assertTrue(resc.getBody(), resc.getBody().contains("indexb")); + Assert.assertTrue(resc.getBody(), resc.getBody().contains("exception")); + Assert.assertTrue(resc.getBody(), resc.getBody().contains("permission")); + + mgetBody = "{" + + "\"docs\" : [" + + "{" + + "\"_index\" : \"indexx\"," + + "\"_id\" : \"0\"" + + " }," + + " {" + + "\"_index\" : \"indexy\"," + + " \"_id\" : \"0\"" + + "}" + + "]" + + "}"; + + resc = rh.executePostRequest("_mget?pretty", mgetBody, encodeBasicHeader("user_b", "user_b")); + Assert.assertEquals(200, resc.getStatusCode()); + Assert.assertTrue(resc.getBody(), resc.getBody().contains("exception")); + count = resc.getBody().split("root_cause").length; + Assert.assertEquals(3, count); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("index*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); + + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("indexa/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); + System.out.println(resc.getBody()); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("indexb/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); + System.out.println(resc.getBody()); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); + System.out.println(resc.getBody()); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("_all/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); + System.out.println(resc.getBody()); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("notexists/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); + System.out.println(resc.getBody()); + + Assert.assertEquals( + HttpStatus.SC_NOT_FOUND, + (resc = rh.executeGetRequest("indexanbh,indexabb*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); + System.out.println(resc.getBody()); + + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (resc = rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode() + ); + System.out.println(resc.getBody()); + + Assert.assertEquals( + HttpStatus.SC_OK, + (resc = rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf"))).getStatusCode() + ); + System.out.println(resc.getBody()); } @Test public void testMt() throws Exception { - final Settings settings = Settings.builder() - .build(); + final Settings settings = Settings.builder().build(); setup(settings); final RestHelper rh = nonSslRestHelper(); HttpResponse res; String body = "{\"buildNum\": 15460, \"defaultIndex\": \"humanresources\", \"tenant\": \"human_resources\"}"; - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executePutRequest(".kibana/_doc/5.6.0?pretty",body, new BasicHeader("securitytenant", "blafasel"), encodeBasicHeader("hr_employee", "hr_employee"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executePutRequest( + ".kibana/_doc/5.6.0?pretty", + body, + new BasicHeader("securitytenant", "blafasel"), + encodeBasicHeader("hr_employee", "hr_employee") + )).getStatusCode() + ); body = "{\"buildNum\": 15460, \"defaultIndex\": \"humanresources\", \"tenant\": \"human_resources\"}"; - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executePutRequest(".kibana/_doc/5.6.0?pretty",body, new BasicHeader("securitytenant", "business_intelligence"), encodeBasicHeader("hr_employee", "hr_employee"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_FORBIDDEN, + (res = rh.executePutRequest( + ".kibana/_doc/5.6.0?pretty", + body, + new BasicHeader("securitytenant", "business_intelligence"), + encodeBasicHeader("hr_employee", "hr_employee") + )).getStatusCode() + ); body = "{\"buildNum\": 15460, \"defaultIndex\": \"humanresources\", \"tenant\": \"human_resources\"}"; - Assert.assertEquals(HttpStatus.SC_CREATED, (res = rh.executePutRequest(".kibana/_doc/5.6.0?pretty",body, new BasicHeader("securitytenant", "human_resources"), encodeBasicHeader("hr_employee", "hr_employee"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_CREATED, + (res = rh.executePutRequest( + ".kibana/_doc/5.6.0?pretty", + body, + new BasicHeader("securitytenant", "human_resources"), + encodeBasicHeader("hr_employee", "hr_employee") + )).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertEquals(".kibana_1592542611_humanresources_1", DefaultObjectMapper.readTree(res.getBody()).get("_index").asText()); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest(".kibana/_doc/5.6.0?pretty",new BasicHeader("securitytenant", "human_resources"), encodeBasicHeader("hr_employee", "hr_employee"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest( + ".kibana/_doc/5.6.0?pretty", + new BasicHeader("securitytenant", "human_resources"), + encodeBasicHeader("hr_employee", "hr_employee") + )).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(WildcardMatcher.from("*human_resources*").test(res.getBody())); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest(".kibana_1592542611_humanresources_1/_alias", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest(".kibana_1592542611_humanresources_1/_alias", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); System.out.println(res.getBody()); - Assert.assertNotNull(DefaultObjectMapper.readTree(res.getBody()).get(".kibana_1592542611_humanresources_1").get("aliases").get(".kibana_1592542611_humanresources")); + Assert.assertNotNull( + DefaultObjectMapper.readTree(res.getBody()) + .get(".kibana_1592542611_humanresources_1") + .get("aliases") + .get(".kibana_1592542611_humanresources") + ); } - @Test public void testMtMulti() throws Exception { - final Settings settings = Settings.builder() - .build(); + final Settings settings = Settings.builder().build(); setup(settings); final String dashboardsIndex = ".kibana_92668751_admin_1"; try (Client tc = getClient()) { - String body = "{"+ - "\"type\" : \"index-pattern\","+ - "\"updated_at\" : \"2018-09-29T08:56:59.066Z\","+ - "\"index-pattern\" : {"+ - "\"title\" : \"humanresources\""+ - "}}"; + String body = "{" + + "\"type\" : \"index-pattern\"," + + "\"updated_at\" : \"2018-09-29T08:56:59.066Z\"," + + "\"index-pattern\" : {" + + "\"title\" : \"humanresources\"" + + "}}"; Map indexSettings = new HashMap(); indexSettings.put("number_of_shards", 1); indexSettings.put("number_of_replicas", 0); - tc.admin().indices().create(new CreateIndexRequest(dashboardsIndex) - .settings(indexSettings) - .alias(new Alias(".kibana_92668751_admin"))) + tc.admin() + .indices() + .create(new CreateIndexRequest(dashboardsIndex).settings(indexSettings).alias(new Alias(".kibana_92668751_admin"))) .actionGet(); - tc.index(new IndexRequest(dashboardsIndex) - .id("index-pattern:9fbbd1a0-c3c5-11e8-a13f-71b8ea5a4f7b") + tc.index( + new IndexRequest(dashboardsIndex).id("index-pattern:9fbbd1a0-c3c5-11e8-a13f-71b8ea5a4f7b") .setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source(body, XContentType.JSON)).actionGet(); + .source(body, XContentType.JSON) + ).actionGet(); } final RestHelper rh = nonSslRestHelper(); @@ -261,28 +372,52 @@ public void testMtMulti() throws Exception { System.out.println("#### search"); HttpResponse res; String body = "{\"query\" : {\"term\" : { \"_id\" : \"index-pattern:9fbbd1a0-c3c5-11e8-a13f-71b8ea5a4f7b\"}}}"; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest(".kibana/_search/?pretty",body, new BasicHeader("securitytenant", "__user__"), encodeBasicHeader("admin", "admin"))).getStatusCode()); - //System.out.println(res.getBody()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest( + ".kibana/_search/?pretty", + body, + new BasicHeader("securitytenant", "__user__"), + encodeBasicHeader("admin", "admin") + )).getStatusCode() + ); + // System.out.println(res.getBody()); Assert.assertFalse(res.getBody().contains("exception")); Assert.assertTrue(res.getBody().contains("humanresources")); Assert.assertTrue(res.getBody().contains("\"value\" : 1")); Assert.assertTrue(res.getBody().contains(dashboardsIndex)); System.out.println("#### msearch"); - body = - "{\"index\":\".kibana\", \"ignore_unavailable\": false}"+System.lineSeparator()+ - "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("_msearch/?pretty",body, new BasicHeader("securitytenant", "__user__"), encodeBasicHeader("admin", "admin"))).getStatusCode()); - //System.out.println(res.getBody()); + body = "{\"index\":\".kibana\", \"ignore_unavailable\": false}" + + System.lineSeparator() + + "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}" + + System.lineSeparator(); + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest( + "_msearch/?pretty", + body, + new BasicHeader("securitytenant", "__user__"), + encodeBasicHeader("admin", "admin") + )).getStatusCode() + ); + // System.out.println(res.getBody()); Assert.assertFalse(res.getBody().contains("exception")); Assert.assertTrue(res.getBody().contains("humanresources")); Assert.assertTrue(res.getBody().contains("\"value\" : 1")); Assert.assertTrue(res.getBody().contains(dashboardsIndex)); System.out.println("#### get"); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest(".kibana/_doc/index-pattern:9fbbd1a0-c3c5-11e8-a13f-71b8ea5a4f7b?pretty", new BasicHeader("securitytenant", "__user__"), encodeBasicHeader("admin", "admin"))).getStatusCode()); - //System.out.println(res.getBody()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest( + ".kibana/_doc/index-pattern:9fbbd1a0-c3c5-11e8-a13f-71b8ea5a4f7b?pretty", + new BasicHeader("securitytenant", "__user__"), + encodeBasicHeader("admin", "admin") + )).getStatusCode() + ); + // System.out.println(res.getBody()); Assert.assertFalse(res.getBody().contains("exception")); Assert.assertTrue(res.getBody().contains("humanresources")); Assert.assertTrue(res.getBody().contains("\"found\" : true")); @@ -290,40 +425,70 @@ public void testMtMulti() throws Exception { System.out.println("#### mget"); body = "{\"docs\" : [{\"_index\" : \".kibana\",\"_id\" : \"index-pattern:9fbbd1a0-c3c5-11e8-a13f-71b8ea5a4f7b\"}]}"; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("_mget/?pretty",body, new BasicHeader("securitytenant", "__user__"), encodeBasicHeader("admin", "admin"))).getStatusCode()); - //System.out.println(res.getBody()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePostRequest( + "_mget/?pretty", + body, + new BasicHeader("securitytenant", "__user__"), + encodeBasicHeader("admin", "admin") + )).getStatusCode() + ); + // System.out.println(res.getBody()); Assert.assertFalse(res.getBody().contains("exception")); Assert.assertTrue(res.getBody().contains("humanresources")); Assert.assertTrue(res.getBody().contains(dashboardsIndex)); System.out.println("#### index"); - body = "{"+ - "\"type\" : \"index-pattern\","+ - "\"updated_at\" : \"2017-09-29T08:56:59.066Z\","+ - "\"index-pattern\" : {"+ - "\"title\" : \"xyz\""+ - "}}"; - Assert.assertEquals(HttpStatus.SC_CREATED, (res = rh.executePutRequest(".kibana/_doc/abc?pretty",body, new BasicHeader("securitytenant", "__user__"), encodeBasicHeader("admin", "admin"))).getStatusCode()); - //System.out.println(res.getBody()); + body = "{" + + "\"type\" : \"index-pattern\"," + + "\"updated_at\" : \"2017-09-29T08:56:59.066Z\"," + + "\"index-pattern\" : {" + + "\"title\" : \"xyz\"" + + "}}"; + Assert.assertEquals( + HttpStatus.SC_CREATED, + (res = rh.executePutRequest( + ".kibana/_doc/abc?pretty", + body, + new BasicHeader("securitytenant", "__user__"), + encodeBasicHeader("admin", "admin") + )).getStatusCode() + ); + // System.out.println(res.getBody()); Assert.assertFalse(res.getBody().contains("exception")); Assert.assertTrue(res.getBody().contains("\"result\" : \"created\"")); Assert.assertTrue(res.getBody().contains(dashboardsIndex)); System.out.println("#### bulk"); - body = - "{ \"index\" : { \"_index\" : \".kibana\", \"_id\" : \"b1\" } }"+System.lineSeparator()+ - "{ \"field1\" : \"value1\" }" +System.lineSeparator()+ - "{ \"index\" : { \"_index\" : \".kibana\", \"_id\" : \"b2\" } }"+System.lineSeparator()+ - "{ \"field2\" : \"value2\" }"+System.lineSeparator(); - - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePutRequest("_bulk?pretty",body, new BasicHeader("securitytenant", "__user__"), encodeBasicHeader("admin", "admin"))).getStatusCode()); - //System.out.println(res.getBody()); + body = "{ \"index\" : { \"_index\" : \".kibana\", \"_id\" : \"b1\" } }" + + System.lineSeparator() + + "{ \"field1\" : \"value1\" }" + + System.lineSeparator() + + "{ \"index\" : { \"_index\" : \".kibana\", \"_id\" : \"b2\" } }" + + System.lineSeparator() + + "{ \"field2\" : \"value2\" }" + + System.lineSeparator(); + + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executePutRequest( + "_bulk?pretty", + body, + new BasicHeader("securitytenant", "__user__"), + encodeBasicHeader("admin", "admin") + )).getStatusCode() + ); + // System.out.println(res.getBody()); Assert.assertFalse(res.getBody().contains("exception")); Assert.assertTrue(res.getBody().contains(dashboardsIndex)); Assert.assertTrue(res.getBody().contains("\"errors\" : false")); Assert.assertTrue(res.getBody().contains("\"result\" : \"created\"")); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_cat/indices", encodeBasicHeader("admin", "admin"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest("_cat/indices", encodeBasicHeader("admin", "admin"))).getStatusCode() + ); Assert.assertEquals(2, res.getBody().split(".kibana").length); Assert.assertTrue(res.getBody().contains(dashboardsIndex)); @@ -331,8 +496,7 @@ public void testMtMulti() throws Exception { @Test public void testDashboardsAlias() throws Exception { - final Settings settings = Settings.builder() - .build(); + final Settings settings = Settings.builder().build(); setup(settings); try (Client tc = getClient()) { @@ -340,19 +504,26 @@ public void testDashboardsAlias() throws Exception { Map indexSettings = new HashMap(); indexSettings.put("number_of_shards", 1); indexSettings.put("number_of_replicas", 0); - tc.admin().indices().create(new CreateIndexRequest(".kibana-6") - .alias(new Alias(".kibana")) - .settings(indexSettings)) + tc.admin() + .indices() + .create(new CreateIndexRequest(".kibana-6").alias(new Alias(".kibana")).settings(indexSettings)) .actionGet(); - tc.index(new IndexRequest(".kibana-6").id("6.2.2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source(body, XContentType.JSON)).actionGet(); + tc.index(new IndexRequest(".kibana-6").id("6.2.2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source(body, XContentType.JSON)) + .actionGet(); } final RestHelper rh = nonSslRestHelper(); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest(".kibana-6/_doc/6.2.2?pretty", encodeBasicHeader("kibanaro", "kibanaro"))).getStatusCode()); - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest(".kibana/_doc/6.2.2?pretty", encodeBasicHeader("kibanaro", "kibanaro"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest(".kibana-6/_doc/6.2.2?pretty", encodeBasicHeader("kibanaro", "kibanaro"))).getStatusCode() + ); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest(".kibana/_doc/6.2.2?pretty", encodeBasicHeader("kibanaro", "kibanaro"))).getStatusCode() + ); System.out.println(res.getBody()); @@ -360,8 +531,7 @@ public void testDashboardsAlias() throws Exception { @Test public void testDashboardsAlias65() throws Exception { - final Settings settings = Settings.builder() - .build(); + final Settings settings = Settings.builder().build(); setup(settings); try (Client tc = getClient()) { @@ -369,29 +539,39 @@ public void testDashboardsAlias65() throws Exception { Map indexSettings = new HashMap(); indexSettings.put("number_of_shards", 1); indexSettings.put("number_of_replicas", 0); - tc.admin().indices().create(new CreateIndexRequest(".kibana_1") - .alias(new Alias(".kibana")) - .settings(indexSettings)) + tc.admin() + .indices() + .create(new CreateIndexRequest(".kibana_1").alias(new Alias(".kibana")).settings(indexSettings)) .actionGet(); - tc.index(new IndexRequest(".kibana_1").id("6.2.2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source(body, XContentType.JSON)).actionGet(); - tc.index(new IndexRequest(".kibana_-900636979_kibanaro").id("6.2.2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source(body, XContentType.JSON)).actionGet(); + tc.index(new IndexRequest(".kibana_1").id("6.2.2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source(body, XContentType.JSON)) + .actionGet(); + tc.index( + new IndexRequest(".kibana_-900636979_kibanaro").id("6.2.2") + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source(body, XContentType.JSON) + ).actionGet(); } final RestHelper rh = nonSslRestHelper(); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest(".kibana/_doc/6.2.2?pretty", new BasicHeader("securitytenant", "__user__"), encodeBasicHeader("kibanaro", "kibanaro"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest( + ".kibana/_doc/6.2.2?pretty", + new BasicHeader("securitytenant", "__user__"), + encodeBasicHeader("kibanaro", "kibanaro") + )).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains(".kibana_-900636979_kibanaro")); } - @Test public void testTenantParametersSubstitution() throws Exception { - final Settings settings = Settings.builder() - .build(); + final Settings settings = Settings.builder().build(); setup(settings); final RestHelper rh = nonSslRestHelper(); @@ -419,9 +599,10 @@ public void testTenantParametersSubstitution() throws Exception { assertThat(res.getStatusCode(), equalTo(HttpStatus.SC_OK)); assertThat(res.findValueInJson("_source.tenant"), equalTo(tenantName)); - final String tenantNameAppended = "tenant_parameters_substitution_1"; - final String createTenantAppendedBody = "{\"buildNum\": 15460, \"defaultIndex\": \"plop\", \"tenant\": \"" + tenantNameAppended + "\"}"; + final String createTenantAppendedBody = "{\"buildNum\": 15460, \"defaultIndex\": \"plop\", \"tenant\": \"" + + tenantNameAppended + + "\"}"; final Header userTenantAppended = new BasicHeader("securitytenant", tenantNameAppended); res = rh.executeGetRequest(url, asNoAccessUser, userTenantAppended); @@ -440,8 +621,7 @@ public void testTenantParametersSubstitution() throws Exception { @Test public void testMultitenancyAnonymousUser() throws Exception { - final Settings settings = Settings.builder() - .build(); + final Settings settings = Settings.builder().build(); setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_anonymous.yml"), settings); final RestHelper rh = nonSslRestHelper(); diff --git a/src/test/java/org/opensearch/security/multitenancy/test/TenancyMultitenancyEnabledTests.java b/src/test/java/org/opensearch/security/multitenancy/test/TenancyMultitenancyEnabledTests.java index bd9664a84c..b25a50d934 100644 --- a/src/test/java/org/opensearch/security/multitenancy/test/TenancyMultitenancyEnabledTests.java +++ b/src/test/java/org/opensearch/security/multitenancy/test/TenancyMultitenancyEnabledTests.java @@ -29,15 +29,17 @@ public class TenancyMultitenancyEnabledTests extends SingleClusterTest { private static final Header AS_REST_API_USER = encodeBasicHeader("user_rest_api_access", "user_rest_api_access"); private static final Header AS_USER = encodeBasicHeader("admin", "admin"); private static final Header ON_USER_TENANT = new BasicHeader("securitytenant", "__user__"); - + private static String createIndexPatternDoc(final String title) { - return "{"+ - "\"type\" : \"index-pattern\","+ - "\"updated_at\" : \"2018-09-29T08:56:59.066Z\","+ - "\"index-pattern\" : {"+ - "\"title\" : \"" + title + "\""+ - "}}"; - } + return "{" + + "\"type\" : \"index-pattern\"," + + "\"updated_at\" : \"2018-09-29T08:56:59.066Z\"," + + "\"index-pattern\" : {" + + "\"title\" : \"" + + title + + "\"" + + "}}"; + } @Override protected String getResourceFolder() { @@ -46,37 +48,69 @@ protected String getResourceFolder() { @Test public void testMultitenancyDisabled_endToEndTest() throws Exception { - setup(Settings.EMPTY, - new DynamicSecurityConfig(), - Settings.builder().put("plugins.security.restapi.roles_enabled.0", "security_rest_api_access").build(), - true); - - final HttpResponse getSettingResponse = nonSslRestHelper().executeGetRequest("/_plugins/_security/api/tenancy/config", AS_REST_API_USER); + setup( + Settings.EMPTY, + new DynamicSecurityConfig(), + Settings.builder().put("plugins.security.restapi.roles_enabled.0", "security_rest_api_access").build(), + true + ); + + final HttpResponse getSettingResponse = nonSslRestHelper().executeGetRequest( + "/_plugins/_security/api/tenancy/config", + AS_REST_API_USER + ); assertThat(getSettingResponse.getStatusCode(), equalTo(HttpStatus.SC_OK)); assertThat(getSettingResponse.findValueInJson("multitenancy_enabled"), equalTo("true")); HttpResponse getDashboardsinfoResponse = nonSslRestHelper().executeGetRequest("/_plugins/_security/dashboardsinfo", AS_USER); - assertThat(getDashboardsinfoResponse.findValueInJson("multitenancy_enabled"),equalTo("true")); + assertThat(getDashboardsinfoResponse.findValueInJson("multitenancy_enabled"), equalTo("true")); - final HttpResponse createDocInGlobalTenantResponse = nonSslRestHelper().executePostRequest(".kibana/_doc?refresh=true", createIndexPatternDoc("globalIndex"), AS_USER); + final HttpResponse createDocInGlobalTenantResponse = nonSslRestHelper().executePostRequest( + ".kibana/_doc?refresh=true", + createIndexPatternDoc("globalIndex"), + AS_USER + ); assertThat(createDocInGlobalTenantResponse.getStatusCode(), equalTo(HttpStatus.SC_CREATED)); - final HttpResponse createDocInUserTenantResponse = nonSslRestHelper().executePostRequest(".kibana/_doc?refresh=true", createIndexPatternDoc("userIndex"), ON_USER_TENANT, AS_USER); + final HttpResponse createDocInUserTenantResponse = nonSslRestHelper().executePostRequest( + ".kibana/_doc?refresh=true", + createIndexPatternDoc("userIndex"), + ON_USER_TENANT, + AS_USER + ); assertThat(createDocInUserTenantResponse.getStatusCode(), equalTo(HttpStatus.SC_CREATED)); - final HttpResponse searchInUserTenantWithMutlitenancyEnabled = nonSslRestHelper().executeGetRequest(".kibana/_search", ON_USER_TENANT, AS_USER); + final HttpResponse searchInUserTenantWithMutlitenancyEnabled = nonSslRestHelper().executeGetRequest( + ".kibana/_search", + ON_USER_TENANT, + AS_USER + ); assertThat(searchInUserTenantWithMutlitenancyEnabled.getStatusCode(), equalTo(HttpStatus.SC_OK)); - assertThat(searchInUserTenantWithMutlitenancyEnabled.findValueInJson("hits.hits[0]._source.index-pattern.title"), equalTo("userIndex")); - - final HttpResponse updateMutlitenancyToDisabled = nonSslRestHelper().executePutRequest("/_plugins/_security/api/tenancy/config", "{\"multitenancy_enabled\": \"false\"}", AS_REST_API_USER); + assertThat( + searchInUserTenantWithMutlitenancyEnabled.findValueInJson("hits.hits[0]._source.index-pattern.title"), + equalTo("userIndex") + ); + + final HttpResponse updateMutlitenancyToDisabled = nonSslRestHelper().executePutRequest( + "/_plugins/_security/api/tenancy/config", + "{\"multitenancy_enabled\": \"false\"}", + AS_REST_API_USER + ); assertThat(updateMutlitenancyToDisabled.getStatusCode(), equalTo(HttpStatus.SC_OK)); assertThat(updateMutlitenancyToDisabled.findValueInJson("multitenancy_enabled"), equalTo("false")); getDashboardsinfoResponse = nonSslRestHelper().executeGetRequest("/_plugins/_security/dashboardsinfo", AS_USER); - assertThat(getDashboardsinfoResponse.findValueInJson("multitenancy_enabled"),equalTo("false")); + assertThat(getDashboardsinfoResponse.findValueInJson("multitenancy_enabled"), equalTo("false")); - final HttpResponse searchInUserTenantWithMutlitenancyDisabled = nonSslRestHelper().executeGetRequest(".kibana/_search", ON_USER_TENANT, AS_USER); + final HttpResponse searchInUserTenantWithMutlitenancyDisabled = nonSslRestHelper().executeGetRequest( + ".kibana/_search", + ON_USER_TENANT, + AS_USER + ); assertThat(searchInUserTenantWithMutlitenancyDisabled.getStatusCode(), equalTo(HttpStatus.SC_OK)); - assertThat(searchInUserTenantWithMutlitenancyDisabled.findValueInJson("hits.hits[0]._source.index-pattern.title"), equalTo("globalIndex")); + assertThat( + searchInUserTenantWithMutlitenancyDisabled.findValueInJson("hits.hits[0]._source.index-pattern.title"), + equalTo("globalIndex") + ); } } diff --git a/src/test/java/org/opensearch/security/multitenancy/test/TenancyPrivateTenantEnabledTests.java b/src/test/java/org/opensearch/security/multitenancy/test/TenancyPrivateTenantEnabledTests.java index 599586239c..1af102802f 100644 --- a/src/test/java/org/opensearch/security/multitenancy/test/TenancyPrivateTenantEnabledTests.java +++ b/src/test/java/org/opensearch/security/multitenancy/test/TenancyPrivateTenantEnabledTests.java @@ -32,12 +32,14 @@ public class TenancyPrivateTenantEnabledTests extends SingleClusterTest { private static final Header ON_USER_TENANT = new BasicHeader("securitytenant", "__user__"); private static String createIndexPatternDoc(final String title) { - return "{"+ - "\"type\" : \"index-pattern\","+ - "\"updated_at\" : \"2018-09-29T08:56:59.066Z\","+ - "\"index-pattern\" : {"+ - "\"title\" : \"" + title + "\""+ - "}}"; + return "{" + + "\"type\" : \"index-pattern\"," + + "\"updated_at\" : \"2018-09-29T08:56:59.066Z\"," + + "\"index-pattern\" : {" + + "\"title\" : \"" + + title + + "\"" + + "}}"; } @Override @@ -47,37 +49,69 @@ protected String getResourceFolder() { @Test public void testPrivateTenantDisabled_Update_EndToEnd() throws Exception { - setup(Settings.EMPTY, - new DynamicSecurityConfig(), - Settings.builder().put("plugins.security.restapi.roles_enabled.0", "security_rest_api_access").build(), - true); - - final HttpResponse getSettingResponse = nonSslRestHelper().executeGetRequest("/_plugins/_security/api/tenancy/config", AS_REST_API_USER); + setup( + Settings.EMPTY, + new DynamicSecurityConfig(), + Settings.builder().put("plugins.security.restapi.roles_enabled.0", "security_rest_api_access").build(), + true + ); + + final HttpResponse getSettingResponse = nonSslRestHelper().executeGetRequest( + "/_plugins/_security/api/tenancy/config", + AS_REST_API_USER + ); assertThat(getSettingResponse.getStatusCode(), equalTo(HttpStatus.SC_OK)); assertThat(getSettingResponse.findValueInJson("private_tenant_enabled"), equalTo("true")); HttpResponse getDashboardsinfoResponse = nonSslRestHelper().executeGetRequest("/_plugins/_security/dashboardsinfo", AS_ADMIN_USER); assertThat(getDashboardsinfoResponse.findValueInJson("private_tenant_enabled"), equalTo("true")); - final HttpResponse createDocInGlobalTenantResponse = nonSslRestHelper().executePostRequest(".kibana/_doc?refresh=true", createIndexPatternDoc("globalIndex"), AS_ADMIN_USER); + final HttpResponse createDocInGlobalTenantResponse = nonSslRestHelper().executePostRequest( + ".kibana/_doc?refresh=true", + createIndexPatternDoc("globalIndex"), + AS_ADMIN_USER + ); assertThat(createDocInGlobalTenantResponse.getStatusCode(), equalTo(HttpStatus.SC_CREATED)); - final HttpResponse createDocInUserTenantResponse = nonSslRestHelper().executePostRequest(".kibana/_doc?refresh=true", createIndexPatternDoc("userIndex"), ON_USER_TENANT, AS_USER); + final HttpResponse createDocInUserTenantResponse = nonSslRestHelper().executePostRequest( + ".kibana/_doc?refresh=true", + createIndexPatternDoc("userIndex"), + ON_USER_TENANT, + AS_USER + ); assertThat(createDocInUserTenantResponse.getStatusCode(), equalTo(HttpStatus.SC_CREATED)); - final HttpResponse searchInUserTenantWithPrivateTenantEnabled = nonSslRestHelper().executeGetRequest(".kibana/_search", ON_USER_TENANT, AS_USER); + final HttpResponse searchInUserTenantWithPrivateTenantEnabled = nonSslRestHelper().executeGetRequest( + ".kibana/_search", + ON_USER_TENANT, + AS_USER + ); assertThat(searchInUserTenantWithPrivateTenantEnabled.getStatusCode(), equalTo(HttpStatus.SC_OK)); - assertThat(searchInUserTenantWithPrivateTenantEnabled.findValueInJson("hits.hits[0]._source.index-pattern.title"), equalTo("userIndex")); - - final HttpResponse disablePrivateTenantResponse = nonSslRestHelper().executePutRequest("/_plugins/_security/api/tenancy/config", "{\"private_tenant_enabled\": \"false\"}", AS_REST_API_USER); + assertThat( + searchInUserTenantWithPrivateTenantEnabled.findValueInJson("hits.hits[0]._source.index-pattern.title"), + equalTo("userIndex") + ); + + final HttpResponse disablePrivateTenantResponse = nonSslRestHelper().executePutRequest( + "/_plugins/_security/api/tenancy/config", + "{\"private_tenant_enabled\": \"false\"}", + AS_REST_API_USER + ); assertThat(disablePrivateTenantResponse.getStatusCode(), equalTo(HttpStatus.SC_OK)); assertThat(disablePrivateTenantResponse.findValueInJson("private_tenant_enabled"), equalTo("false")); getDashboardsinfoResponse = nonSslRestHelper().executeGetRequest("/_plugins/_security/dashboardsinfo", AS_ADMIN_USER); - assertThat(getDashboardsinfoResponse.findValueInJson("private_tenant_enabled"),equalTo("false")); + assertThat(getDashboardsinfoResponse.findValueInJson("private_tenant_enabled"), equalTo("false")); - final HttpResponse searchInUserTenantWithPrivateTenantDisabled = nonSslRestHelper().executeGetRequest(".kibana/_search", ON_USER_TENANT, AS_USER); + final HttpResponse searchInUserTenantWithPrivateTenantDisabled = nonSslRestHelper().executeGetRequest( + ".kibana/_search", + ON_USER_TENANT, + AS_USER + ); assertThat(searchInUserTenantWithPrivateTenantDisabled.getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - assertThat(searchInUserTenantWithPrivateTenantDisabled.findValueInJson("error.reason"), containsString("no permissions for [indices:data/read/search] and User")); + assertThat( + searchInUserTenantWithPrivateTenantDisabled.findValueInJson("error.reason"), + containsString("no permissions for [indices:data/read/search] and User") + ); } diff --git a/src/test/java/org/opensearch/security/privileges/PrivilegesEvaluatorTest.java b/src/test/java/org/opensearch/security/privileges/PrivilegesEvaluatorTest.java index ba265bcf2e..b953ac8ddb 100644 --- a/src/test/java/org/opensearch/security/privileges/PrivilegesEvaluatorTest.java +++ b/src/test/java/org/opensearch/security/privileges/PrivilegesEvaluatorTest.java @@ -26,15 +26,15 @@ public class PrivilegesEvaluatorTest extends SingleClusterTest { private static final Header NegatedRegexUserHeader = encodeBasicHeader("negated_regex_user", "negated_regex_user"); public void setupSettingsIndexPattern() throws Exception { - Settings settings = Settings.builder() - .build(); - setup(Settings.EMPTY, - new DynamicSecurityConfig() - .setSecurityRoles("roles_index_patterns.yml") - .setSecurityInternalUsers("internal_users_index_patterns.yml") - .setSecurityRolesMapping("roles_mapping_index_patterns.yml"), - settings, - true); + Settings settings = Settings.builder().build(); + setup( + Settings.EMPTY, + new DynamicSecurityConfig().setSecurityRoles("roles_index_patterns.yml") + .setSecurityInternalUsers("internal_users_index_patterns.yml") + .setSecurityRolesMapping("roles_mapping_index_patterns.yml"), + settings, + true + ); } @Test @@ -42,9 +42,9 @@ public void testNegativeLookaheadPattern() throws Exception { setupSettingsIndexPattern(); RestHelper rh = nonSslRestHelper(); - RestHelper.HttpResponse response = rh.executeGetRequest( "*/_search", NegativeLookaheadUserHeader); + RestHelper.HttpResponse response = rh.executeGetRequest("*/_search", NegativeLookaheadUserHeader); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); - response = rh.executeGetRequest( "r*/_search", NegativeLookaheadUserHeader); + response = rh.executeGetRequest("r*/_search", NegativeLookaheadUserHeader); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); } @@ -53,9 +53,9 @@ public void testRegexPattern() throws Exception { setupSettingsIndexPattern(); RestHelper rh = nonSslRestHelper(); - RestHelper.HttpResponse response = rh.executeGetRequest( "*/_search", NegatedRegexUserHeader); + RestHelper.HttpResponse response = rh.executeGetRequest("*/_search", NegatedRegexUserHeader); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, response.getStatusCode()); - response = rh.executeGetRequest( "r*/_search", NegatedRegexUserHeader); + response = rh.executeGetRequest("r*/_search", NegatedRegexUserHeader); Assert.assertEquals(HttpStatus.SC_OK, response.getStatusCode()); } } diff --git a/src/test/java/org/opensearch/security/privileges/SecurityIndexAccessEvaluatorTest.java b/src/test/java/org/opensearch/security/privileges/SecurityIndexAccessEvaluatorTest.java index 6d81c3b1da..14c5eabb73 100644 --- a/src/test/java/org/opensearch/security/privileges/SecurityIndexAccessEvaluatorTest.java +++ b/src/test/java/org/opensearch/security/privileges/SecurityIndexAccessEvaluatorTest.java @@ -55,11 +55,10 @@ public class SecurityIndexAccessEvaluatorTest { @Mock private Logger log; - private SecurityIndexAccessEvaluator evaluator; - private static final String UNPROTECTED_ACTION = "indices:data/read"; - private static final String PROTECTED_ACTION = "indices:data/write"; + private static final String UNPROTECTED_ACTION = "indices:data/read"; + private static final String PROTECTED_ACTION = "indices:data/write"; @Before public void before() { @@ -69,7 +68,8 @@ public void before() { .put("plugins.security.system_indices.enabled", true) .build(), auditLog, - irr); + irr + ); evaluator.log = log; when(log.isDebugEnabled()).thenReturn(true); @@ -79,7 +79,7 @@ public void before() { public void after() { verifyNoMoreInteractions(auditLog, irr, request, task, presponse, log); } - + @Test public void actionIsNotProtected_noSystemIndexInvolved() { final Resolved resolved = createResolved(".test"); @@ -140,13 +140,16 @@ public void protectedActionSystemIndex() { verify(presponse).markComplete(); verify(log).isDebugEnabled(); - verify(log).warn( - "{} for '{}' index is not allowed for a regular user", - "indices:data/write", - ".opendistro_security, .test"); + verify(log).warn("{} for '{}' index is not allowed for a regular user", "indices:data/write", ".opendistro_security, .test"); } private Resolved createResolved(final String... indexes) { - return new Resolved(ImmutableSet.of(), ImmutableSet.copyOf(indexes), ImmutableSet.copyOf(indexes), ImmutableSet.of(), IndicesOptions.STRICT_EXPAND_OPEN); + return new Resolved( + ImmutableSet.of(), + ImmutableSet.copyOf(indexes), + ImmutableSet.copyOf(indexes), + ImmutableSet.of(), + IndicesOptions.STRICT_EXPAND_OPEN + ); } } 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 52f66f3462..0ff7d64de9 100644 --- a/src/test/java/org/opensearch/security/protected_indices/ProtectedIndicesTests.java +++ b/src/test/java/org/opensearch/security/protected_indices/ProtectedIndicesTests.java @@ -66,7 +66,10 @@ public class ProtectedIndicesTests extends SingleClusterTest { // This user is mapped to all_access, but is not mapped to any protectedIndexRoles private static final String indexAccessNoRoleUser = "indexAccessNoRoleUser"; private static final Header indexAccessNoRoleUserHeader = encodeBasicHeader(indexAccessNoRoleUser, indexAccessNoRoleUser); - private static final String generalErrorMessage = String.format("no permissions for [] and User [name=%s, backend_roles=[], requestedTenant=null]", indexAccessNoRoleUser); + private static final String generalErrorMessage = String.format( + "no permissions for [] and User [name=%s, backend_roles=[], requestedTenant=null]", + indexAccessNoRoleUser + ); // This user is mapped to all_access and protected_index_role1 private static final String protectedIndexUser = "protectedIndexUser"; private static final Header protectedIndexUserHeader = encodeBasicHeader(protectedIndexUser, protectedIndexUser); @@ -81,35 +84,37 @@ public class ProtectedIndicesTests extends SingleClusterTest { public void setupSettingsEnabled() throws Exception { // Setup settings Settings protectedIndexSettings = Settings.builder() - .put(ConfigConstants.SECURITY_PROTECTED_INDICES_ENABLED_KEY, true) - .putList(ConfigConstants.SECURITY_PROTECTED_INDICES_KEY, listOfIndexesToTest) - .putList(ConfigConstants.SECURITY_PROTECTED_INDICES_ROLES_KEY, protectedIndexRoles) - .build(); - setup(Settings.EMPTY, - new DynamicSecurityConfig() - .setConfig("config_protected_indices.yml") - .setSecurityRoles("roles_protected_indices.yml") - .setSecurityInternalUsers("internal_users_protected_indices.yml") - .setSecurityRolesMapping("roles_mapping_protected_indices.yml"), - protectedIndexSettings, - true); + .put(ConfigConstants.SECURITY_PROTECTED_INDICES_ENABLED_KEY, true) + .putList(ConfigConstants.SECURITY_PROTECTED_INDICES_KEY, listOfIndexesToTest) + .putList(ConfigConstants.SECURITY_PROTECTED_INDICES_ROLES_KEY, protectedIndexRoles) + .build(); + setup( + Settings.EMPTY, + new DynamicSecurityConfig().setConfig("config_protected_indices.yml") + .setSecurityRoles("roles_protected_indices.yml") + .setSecurityInternalUsers("internal_users_protected_indices.yml") + .setSecurityRolesMapping("roles_mapping_protected_indices.yml"), + protectedIndexSettings, + true + ); } public void setupSettingsIndexPatterns() throws Exception { // Setup settings Settings protectedIndexSettings = Settings.builder() - .put(ConfigConstants.SECURITY_PROTECTED_INDICES_ENABLED_KEY, true) - .putList(ConfigConstants.SECURITY_PROTECTED_INDICES_KEY, listOfIndexPatternsToTest) - .putList(ConfigConstants.SECURITY_PROTECTED_INDICES_ROLES_KEY, protectedIndexRoles) - .build(); - setup(Settings.EMPTY, - new DynamicSecurityConfig() - .setConfig("config_protected_indices.yml") - .setSecurityRoles("roles_protected_indices.yml") - .setSecurityInternalUsers("internal_users_protected_indices.yml") - .setSecurityRolesMapping("roles_mapping_protected_indices.yml"), - protectedIndexSettings, - true); + .put(ConfigConstants.SECURITY_PROTECTED_INDICES_ENABLED_KEY, true) + .putList(ConfigConstants.SECURITY_PROTECTED_INDICES_KEY, listOfIndexPatternsToTest) + .putList(ConfigConstants.SECURITY_PROTECTED_INDICES_ROLES_KEY, protectedIndexRoles) + .build(); + setup( + Settings.EMPTY, + new DynamicSecurityConfig().setConfig("config_protected_indices.yml") + .setSecurityRoles("roles_protected_indices.yml") + .setSecurityInternalUsers("internal_users_protected_indices.yml") + .setSecurityRolesMapping("roles_mapping_protected_indices.yml"), + protectedIndexSettings, + true + ); } /** @@ -122,35 +127,38 @@ public void setupSettingsIndexPatterns() throws Exception { public void setupSettingsDisabled() throws Exception { // Setup settings Settings protectedIndexSettings = Settings.builder() - .put(ConfigConstants.SECURITY_PROTECTED_INDICES_ENABLED_KEY, false) - .putList(ConfigConstants.SECURITY_PROTECTED_INDICES_KEY, listOfIndexesToTest) - .putList(ConfigConstants.SECURITY_PROTECTED_INDICES_ROLES_KEY, protectedIndexRoles) - .build(); - setup(Settings.EMPTY, - new DynamicSecurityConfig() - .setConfig("config_protected_indices.yml") - .setSecurityRoles("roles_protected_indices.yml") - .setSecurityInternalUsers("internal_users_protected_indices.yml") - .setSecurityRolesMapping("roles_mapping_protected_indices.yml"), - protectedIndexSettings, - true); + .put(ConfigConstants.SECURITY_PROTECTED_INDICES_ENABLED_KEY, false) + .putList(ConfigConstants.SECURITY_PROTECTED_INDICES_KEY, listOfIndexesToTest) + .putList(ConfigConstants.SECURITY_PROTECTED_INDICES_ROLES_KEY, protectedIndexRoles) + .build(); + setup( + Settings.EMPTY, + new DynamicSecurityConfig().setConfig("config_protected_indices.yml") + .setSecurityRoles("roles_protected_indices.yml") + .setSecurityInternalUsers("internal_users_protected_indices.yml") + .setSecurityRolesMapping("roles_mapping_protected_indices.yml"), + protectedIndexSettings, + true + ); } public void setupSettingsEnabledSnapshot() throws Exception { final Settings settings = Settings.builder() - .putList("path.repo", repositoryPath.getRoot().getAbsolutePath()) - .put(ConfigConstants.SECURITY_PROTECTED_INDICES_ENABLED_KEY, true) - .putList(ConfigConstants.SECURITY_PROTECTED_INDICES_KEY, listOfIndexesToTest) - .putList(ConfigConstants.SECURITY_PROTECTED_INDICES_ROLES_KEY, protectedIndexRoles) - .build(); - - setup(Settings.EMPTY, new DynamicSecurityConfig() - .setConfig("config_protected_indices.yml") + .putList("path.repo", repositoryPath.getRoot().getAbsolutePath()) + .put(ConfigConstants.SECURITY_PROTECTED_INDICES_ENABLED_KEY, true) + .putList(ConfigConstants.SECURITY_PROTECTED_INDICES_KEY, listOfIndexesToTest) + .putList(ConfigConstants.SECURITY_PROTECTED_INDICES_ROLES_KEY, protectedIndexRoles) + .build(); + + setup( + Settings.EMPTY, + new DynamicSecurityConfig().setConfig("config_protected_indices.yml") .setSecurityRoles("roles_protected_indices.yml") .setSecurityInternalUsers("internal_users_protected_indices.yml") .setSecurityRolesMapping("roles_mapping_protected_indices.yml"), - settings, - true); + settings, + true + ); } /** @@ -162,7 +170,11 @@ public void createTestIndicesAndDocs() { try (Client tc = getClient()) { for (String index : listOfIndexesToTest) { tc.admin().indices().create(new CreateIndexRequest(index)).actionGet(); - tc.index(new IndexRequest(index).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).id("document1").source("{ \"foo\": \"bar\" }", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest(index).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .id("document1") + .source("{ \"foo\": \"bar\" }", XContentType.JSON) + ).actionGet(); } } } @@ -170,8 +182,19 @@ public void createTestIndicesAndDocs() { public void createSnapshots() { try (Client tc = getClient()) { for (String index : listOfIndexesToTest) { - tc.admin().cluster().putRepository(new PutRepositoryRequest(index).type("fs").settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/" + index))).actionGet(); - tc.admin().cluster().createSnapshot(new CreateSnapshotRequest(index, index + "_1").indices(index).includeGlobalState(true).waitForCompletion(true)).actionGet(); + tc.admin() + .cluster() + .putRepository( + new PutRepositoryRequest(index).type("fs") + .settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/" + index)) + ) + .actionGet(); + tc.admin() + .cluster() + .createSnapshot( + new CreateSnapshotRequest(index, index + "_1").indices(index).includeGlobalState(true).waitForCompletion(true) + ) + .actionGet(); } } } @@ -192,7 +215,8 @@ public void testNoSearchResults() throws Exception { // Test direct index query. for (String index : listOfIndexesToTest) { RestHelper.HttpResponse response = rh.executePostRequest(index + "/_search", matchAllQuery, indexAccessNoRoleUserHeader); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); SearchResponse searchResponse = SearchResponse.fromXContent(xcp); // confirm good response. assertTrue(searchResponse.status() == RestStatus.OK); @@ -207,7 +231,8 @@ public void testNoSearchResults() throws Exception { // Test index pattern for (String indexPattern : listOfIndexPatternsToTest) { RestHelper.HttpResponse response = rh.executePostRequest(indexPattern + "/_search", matchAllQuery, indexAccessNoRoleUserHeader); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); SearchResponse searchResponse = SearchResponse.fromXContent(xcp); // confirm good response. assertTrue(searchResponse.status() == RestStatus.OK); @@ -231,7 +256,8 @@ public void testSearchWithSettingDisabled() throws Exception { // Test direct index query. for (String index : listOfIndexesToTest) { RestHelper.HttpResponse response = rh.executePostRequest(index + "/_search", matchAllQuery, protectedIndexUserHeader); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); SearchResponse searchResponse = SearchResponse.fromXContent(xcp); // confirm good response. assertTrue(searchResponse.status() == RestStatus.OK); @@ -246,7 +272,8 @@ public void testSearchWithSettingDisabled() throws Exception { // Test index pattern for (String indexPattern : listOfIndexPatternsToTest) { RestHelper.HttpResponse response = rh.executePostRequest(indexPattern + "/_search", matchAllQuery, protectedIndexUserHeader); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); SearchResponse searchResponse = SearchResponse.fromXContent(xcp); // confirm good response. assertTrue(searchResponse.status() == RestStatus.OK); @@ -268,10 +295,9 @@ public void testNoResultsAlias() throws Exception { try (Client tc = getClient()) { for (String index : listOfIndexesToTest) { IndicesAliasesRequest request = new IndicesAliasesRequest(); - IndicesAliasesRequest.AliasActions aliasAction = - new IndicesAliasesRequest.AliasActions(IndicesAliasesRequest.AliasActions.Type.ADD) - .index(index) - .alias("alias" + i); + IndicesAliasesRequest.AliasActions aliasAction = new IndicesAliasesRequest.AliasActions( + IndicesAliasesRequest.AliasActions.Type.ADD + ).index(index).alias("alias" + i); request.addAliasAction(aliasAction); tc.admin().indices().aliases(request).actionGet(); i++; @@ -282,8 +308,13 @@ public void testNoResultsAlias() throws Exception { RestHelper rh = nonSslRestHelper(); for (int aliasNumber = 0; aliasNumber < i; aliasNumber++) { - RestHelper.HttpResponse response = rh.executePostRequest("alias" + aliasNumber + "/_search", matchAllQuery, indexAccessNoRoleUserHeader); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + RestHelper.HttpResponse response = rh.executePostRequest( + "alias" + aliasNumber + "/_search", + matchAllQuery, + indexAccessNoRoleUserHeader + ); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); SearchResponse searchResponse = SearchResponse.fromXContent(xcp); // confirm good response. assertTrue(searchResponse.status() == RestStatus.OK); @@ -303,14 +334,14 @@ public void testNoAccessCreateIndexDisabled() throws Exception { // Create rest client RestHelper rh = nonSslRestHelper(); - String indexSettings = "{\n" + - " \"settings\" : {\n" + - " \"index\" : {\n" + - " \"number_of_shards\" : 3, \n" + - " \"number_of_replicas\" : 2 \n" + - " }\n" + - " }\n" + - "}"; + String indexSettings = "{\n" + + " \"settings\" : {\n" + + " \"index\" : {\n" + + " \"number_of_shards\" : 3, \n" + + " \"number_of_replicas\" : 2 \n" + + " }\n" + + " }\n" + + "}"; for (String index : listOfIndexesToTest) { RestHelper.HttpResponse response = rh.executePutRequest(index, indexSettings, indexAccessNoRoleUserHeader); assertTrue(response.getStatusCode() == RestStatus.OK.getStatus()); @@ -446,10 +477,7 @@ public void testNonAccessUpdateMappings() throws Exception { setupSettingsEnabled(); createTestIndicesAndDocs(); - String newMappings = "{\"properties\": {" + - "\"user_name\": {" + - "\"type\": \"text\"" + - "}}}"; + String newMappings = "{\"properties\": {" + "\"user_name\": {" + "\"type\": \"text\"" + "}}}"; // Create rest client RestHelper rh = nonSslRestHelper(); @@ -467,10 +495,7 @@ public void testNonAccessUpdateMappingsDisabled() throws Exception { setupSettingsDisabled(); createTestIndicesAndDocs(); - String newMappings = "{\"properties\": {" + - "\"user_name\": {" + - "\"type\": \"text\"" + - "}}}"; + String newMappings = "{\"properties\": {" + "\"user_name\": {" + "\"type\": \"text\"" + "}}}"; // Create rest client RestHelper rh = nonSslRestHelper(); @@ -510,7 +535,11 @@ public void testNonAccessAliasOperations() throws Exception { String aliasTemplate = "{\"actions\" : [{ \"add\" : { \"index\" : \"%s\", \"alias\" : \"foobar\" } }]}"; for (String index : listOfIndexesToTest) { - RestHelper.HttpResponse response = rh.executePostRequest("_aliases", String.format(aliasTemplate, index), indexAccessNoRoleUserHeader); + RestHelper.HttpResponse response = rh.executePostRequest( + "_aliases", + String.format(aliasTemplate, index), + indexAccessNoRoleUserHeader + ); assertTrue(response.getStatusCode() == RestStatus.FORBIDDEN.getStatus()); assertTrue(response.getBody().contains(generalErrorMessage)); } @@ -519,7 +548,11 @@ public void testNonAccessAliasOperations() throws Exception { aliasTemplate = "{\"actions\" : [{ \"remove\" : { \"index\" : \"%s\", \"alias\" : \"foobar\" } }]}"; for (String index : listOfIndexesToTest) { - RestHelper.HttpResponse response = rh.executePostRequest("_aliases", String.format(aliasTemplate, index), indexAccessNoRoleUserHeader); + RestHelper.HttpResponse response = rh.executePostRequest( + "_aliases", + String.format(aliasTemplate, index), + indexAccessNoRoleUserHeader + ); assertTrue(response.getStatusCode() == RestStatus.FORBIDDEN.getStatus()); assertTrue(response.getBody().contains(generalErrorMessage)); } @@ -528,7 +561,11 @@ public void testNonAccessAliasOperations() throws Exception { aliasTemplate = "{\"actions\" : [{ \"remove_index\" : { \"index\" : \"%s\"} }]}"; for (String index : listOfIndexesToTest) { - RestHelper.HttpResponse response = rh.executePostRequest("_aliases", String.format(aliasTemplate, index), indexAccessNoRoleUserHeader); + RestHelper.HttpResponse response = rh.executePostRequest( + "_aliases", + String.format(aliasTemplate, index), + indexAccessNoRoleUserHeader + ); assertTrue(response.getStatusCode() == RestStatus.FORBIDDEN.getStatus()); assertTrue(response.getBody().contains(generalErrorMessage)); } @@ -543,14 +580,14 @@ public void testNonAccessUpdateIndexSettings() throws Exception { // Create rest client RestHelper rh = nonSslRestHelper(); - String indexSettings = "{\n" + - " \"settings\" : {\n" + - " \"index\" : {\n" + - " \"number_of_shards\" : 30, \n" + - " \"number_of_replicas\" : 20 \n" + - " }\n" + - " }\n" + - "}"; + String indexSettings = "{\n" + + " \"settings\" : {\n" + + " \"index\" : {\n" + + " \"number_of_shards\" : 30, \n" + + " \"number_of_replicas\" : 20 \n" + + " }\n" + + " }\n" + + "}"; for (String index : listOfIndexesToTest) { RestHelper.HttpResponse response = rh.executePutRequest(index + "/_settings", indexSettings, indexAccessNoRoleUserHeader); @@ -575,7 +612,8 @@ public void testSearchResults() throws Exception { // Test direct index query. for (String index : listOfIndexesToTest) { RestHelper.HttpResponse response = rh.executePostRequest(index + "/_search", matchAllQuery, protectedIndexUserHeader); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); SearchResponse searchResponse = SearchResponse.fromXContent(xcp); // confirm good response. assertTrue(searchResponse.status() == RestStatus.OK); @@ -590,7 +628,8 @@ public void testSearchResults() throws Exception { // Test index pattern for (String indexPattern : listOfIndexPatternsToTest) { RestHelper.HttpResponse response = rh.executePostRequest(indexPattern + "/_search", matchAllQuery, protectedIndexUserHeader); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); SearchResponse searchResponse = SearchResponse.fromXContent(xcp); // confirm good response. assertTrue(searchResponse.status() == RestStatus.OK); @@ -612,10 +651,9 @@ public void testResultsAlias() throws Exception { try (Client tc = getClient()) { for (String index : listOfIndexesToTest) { IndicesAliasesRequest request = new IndicesAliasesRequest(); - IndicesAliasesRequest.AliasActions aliasAction = - new IndicesAliasesRequest.AliasActions(IndicesAliasesRequest.AliasActions.Type.ADD) - .index(index) - .alias("alias" + i); + IndicesAliasesRequest.AliasActions aliasAction = new IndicesAliasesRequest.AliasActions( + IndicesAliasesRequest.AliasActions.Type.ADD + ).index(index).alias("alias" + i); request.addAliasAction(aliasAction); tc.admin().indices().aliases(request).actionGet(); i++; @@ -626,9 +664,14 @@ public void testResultsAlias() throws Exception { RestHelper rh = nonSslRestHelper(); for (int aliasNumber = 0; aliasNumber < i; aliasNumber++) { - RestHelper.HttpResponse response = rh.executePostRequest("alias" + aliasNumber + "/_search", matchAllQuery, protectedIndexUserHeader); - - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + RestHelper.HttpResponse response = rh.executePostRequest( + "alias" + aliasNumber + "/_search", + matchAllQuery, + protectedIndexUserHeader + ); + + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); SearchResponse searchResponse = SearchResponse.fromXContent(xcp); // confirm good response. assertTrue(searchResponse.status() == RestStatus.OK); @@ -648,14 +691,14 @@ public void testCreateIndex() throws Exception { // Create rest client RestHelper rh = nonSslRestHelper(); - String indexSettings = "{\n" + - " \"settings\" : {\n" + - " \"index\" : {\n" + - " \"number_of_shards\" : 3, \n" + - " \"number_of_replicas\" : 2 \n" + - " }\n" + - " }\n" + - "}"; + String indexSettings = "{\n" + + " \"settings\" : {\n" + + " \"index\" : {\n" + + " \"number_of_shards\" : 3, \n" + + " \"number_of_replicas\" : 2 \n" + + " }\n" + + " }\n" + + "}"; for (String index : listOfIndexesToTest) { RestHelper.HttpResponse response = rh.executePutRequest(index, indexSettings, protectedIndexUserHeader); assertTrue(response.getStatusCode() == RestStatus.OK.getStatus()); @@ -716,10 +759,7 @@ public void testUpdateMappings() throws Exception { setupSettingsEnabled(); createTestIndicesAndDocs(); - String newMappings = "{\"properties\": {" + - "\"user_name\": {" + - "\"type\": \"text\"" + - "}}}"; + String newMappings = "{\"properties\": {" + "\"user_name\": {" + "\"type\": \"text\"" + "}}}"; // Create rest client RestHelper rh = nonSslRestHelper(); @@ -775,7 +815,11 @@ public void testAliasOperations() throws Exception { String aliasTemplate = "{\"actions\" : [{ \"add\" : { \"index\" : \"%s\", \"alias\" : \"foobar\" } }]}"; for (String index : listOfIndexesToTest) { - RestHelper.HttpResponse response = rh.executePostRequest("_aliases", String.format(aliasTemplate, index), protectedIndexUserHeader); + RestHelper.HttpResponse response = rh.executePostRequest( + "_aliases", + String.format(aliasTemplate, index), + protectedIndexUserHeader + ); assertTrue(response.getStatusCode() == RestStatus.OK.getStatus()); } @@ -783,7 +827,11 @@ public void testAliasOperations() throws Exception { aliasTemplate = "{\"actions\" : [{ \"remove\" : { \"index\" : \"%s\", \"alias\" : \"foobar\" } }]}"; for (String index : listOfIndexesToTest) { - RestHelper.HttpResponse response = rh.executePostRequest("_aliases", String.format(aliasTemplate, index), protectedIndexUserHeader); + RestHelper.HttpResponse response = rh.executePostRequest( + "_aliases", + String.format(aliasTemplate, index), + protectedIndexUserHeader + ); assertTrue(response.getStatusCode() == RestStatus.OK.getStatus()); } @@ -791,7 +839,11 @@ public void testAliasOperations() throws Exception { aliasTemplate = "{\"actions\" : [{ \"remove_index\" : { \"index\" : \"%s\"} }]}"; for (String index : listOfIndexesToTest) { - RestHelper.HttpResponse response = rh.executePostRequest("_aliases", String.format(aliasTemplate, index), protectedIndexUserHeader); + RestHelper.HttpResponse response = rh.executePostRequest( + "_aliases", + String.format(aliasTemplate, index), + protectedIndexUserHeader + ); assertTrue(response.getStatusCode() == RestStatus.OK.getStatus()); } } @@ -805,11 +857,7 @@ public void testUpdateIndexSettings() throws Exception { // Create rest client RestHelper rh = nonSslRestHelper(); - String indexSettings = "{\n" + - " \"index\" : {\n" + - " \"refresh_interval\" : null\n" + - " }\n" + - "}"; + String indexSettings = "{\n" + " \"index\" : {\n" + " \"refresh_interval\" : null\n" + " }\n" + "}"; for (String index : listOfIndexesToTest) { RestHelper.HttpResponse response = rh.executePutRequest(index + "/_settings", indexSettings, protectedIndexUserHeader); @@ -833,21 +881,48 @@ public void testAccessSnapshot() throws Exception { } } - String putSnapshot = "{"+ - "\"indices\": \"%s\"," + - "\"ignore_unavailable\": false," + - "\"include_global_state\": false" + - "}"; + String putSnapshot = "{" + "\"indices\": \"%s\"," + "\"ignore_unavailable\": false," + "\"include_global_state\": false" + "}"; // Create rest client RestHelper rh = nonSslRestHelper(); for (String index : listOfIndexesToTest) { - assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_snapshot/" + index + "/" + index + "_1", protectedIndexUserHeader).getStatusCode()); - assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/" + index + "/" + index + "_1/_restore?wait_for_completion=true","{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_with_global_state_$1\" }", protectedIndexUserHeader).getStatusCode()); - assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/" + index + "/" + index + "_1/_restore?wait_for_completion=true", "", protectedIndexUserHeader).getStatusCode()); - assertEquals(HttpStatus.SC_OK, rh.executePostRequest("_snapshot/" + index + "/" + index + "_1/_restore?wait_for_completion=true","{ \"indices\": \"" + index + "\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"" + index + "_1\" }", protectedIndexUserHeader).getStatusCode()); - assertEquals(HttpStatus.SC_OK, rh.executePutRequest("_snapshot/" + index + "/" + index + "_2?wait_for_completion=true", String.format(putSnapshot, index), protectedIndexUserHeader).getStatusCode()); + assertEquals( + HttpStatus.SC_OK, + rh.executeGetRequest("_snapshot/" + index + "/" + index + "_1", protectedIndexUserHeader).getStatusCode() + ); + assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/" + index + "/" + index + "_1/_restore?wait_for_completion=true", + "{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_with_global_state_$1\" }", + protectedIndexUserHeader + ).getStatusCode() + ); + assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/" + index + "/" + index + "_1/_restore?wait_for_completion=true", + "", + protectedIndexUserHeader + ).getStatusCode() + ); + assertEquals( + HttpStatus.SC_OK, + rh.executePostRequest( + "_snapshot/" + index + "/" + index + "_1/_restore?wait_for_completion=true", + "{ \"indices\": \"" + index + "\", \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"" + index + "_1\" }", + protectedIndexUserHeader + ).getStatusCode() + ); + assertEquals( + HttpStatus.SC_OK, + rh.executePutRequest( + "_snapshot/" + index + "/" + index + "_2?wait_for_completion=true", + String.format(putSnapshot, index), + protectedIndexUserHeader + ).getStatusCode() + ); } } } diff --git a/src/test/java/org/opensearch/security/sanity/tests/SecurityRestTestCase.java b/src/test/java/org/opensearch/security/sanity/tests/SecurityRestTestCase.java index 51c4ddb984..b0d53deaa8 100644 --- a/src/test/java/org/opensearch/security/sanity/tests/SecurityRestTestCase.java +++ b/src/test/java/org/opensearch/security/sanity/tests/SecurityRestTestCase.java @@ -45,54 +45,52 @@ public class SecurityRestTestCase extends OpenSearchRestTestCase { private static final String CERT_FILE_DIRECTORY = "sanity-tests/"; + private boolean isHttps() { return System.getProperty("https").equals("true"); } + private boolean securityEnabled() { return System.getProperty("security.enabled").equals("true"); } @Override - protected Settings restAdminSettings(){ - return Settings - .builder() - .put("http.port", 9200) - .put(SECURITY_SSL_HTTP_ENABLED, isHttps()) - .put(SECURITY_SSL_HTTP_PEMCERT_FILEPATH, CERT_FILE_DIRECTORY + "opensearch-node.pem") - .put(SECURITY_SSL_HTTP_PEMKEY_FILEPATH, CERT_FILE_DIRECTORY + "opensearch-node-key.pem") - .put(SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH, CERT_FILE_DIRECTORY + "root-ca.pem") - .put(SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, CERT_FILE_DIRECTORY + "test-kirk.jks") - .put(SECURITY_SSL_HTTP_KEYSTORE_PASSWORD.insecurePropertyName, "changeit") - .put(SECURITY_SSL_HTTP_KEYSTORE_KEYPASSWORD.insecurePropertyName, "changeit") - .build(); + protected Settings restAdminSettings() { + return Settings.builder() + .put("http.port", 9200) + .put(SECURITY_SSL_HTTP_ENABLED, isHttps()) + .put(SECURITY_SSL_HTTP_PEMCERT_FILEPATH, CERT_FILE_DIRECTORY + "opensearch-node.pem") + .put(SECURITY_SSL_HTTP_PEMKEY_FILEPATH, CERT_FILE_DIRECTORY + "opensearch-node-key.pem") + .put(SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH, CERT_FILE_DIRECTORY + "root-ca.pem") + .put(SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, CERT_FILE_DIRECTORY + "test-kirk.jks") + .put(SECURITY_SSL_HTTP_KEYSTORE_PASSWORD.insecurePropertyName, "changeit") + .put(SECURITY_SSL_HTTP_KEYSTORE_KEYPASSWORD.insecurePropertyName, "changeit") + .build(); } @Override protected RestClient buildClient(Settings settings, HttpHost[] hosts) throws IOException { - if(securityEnabled()){ + if (securityEnabled()) { String keystore = settings.get(SECURITY_SSL_HTTP_KEYSTORE_FILEPATH); - if(keystore != null){ + if (keystore != null) { // create adminDN (super-admin) client File file = new File(getClass().getClassLoader().getResource(CERT_FILE_DIRECTORY).getFile()); Path configPath = PathUtils.get(file.toURI()).getParent().toAbsolutePath(); - return new SecureRestClientBuilder(settings, configPath) - .setSocketTimeout(60000) - .setConnectionRequestTimeout(180000) - .build(); + return new SecureRestClientBuilder(settings, configPath).setSocketTimeout(60000) + .setConnectionRequestTimeout(180000) + .build(); } // create client with passed user String userName = System.getProperty("user"); String password = System.getProperty("password"); - return new SecureRestClientBuilder(hosts, isHttps(), userName, password) - .setSocketTimeout(60000) - .setConnectionRequestTimeout(180000) - .build(); - } - else { + return new SecureRestClientBuilder(hosts, isHttps(), userName, password).setSocketTimeout(60000) + .setConnectionRequestTimeout(180000) + .build(); + } else { RestClientBuilder builder = RestClient.builder(hosts); configureClient(builder, settings); builder.setStrictDeprecationMode(true); diff --git a/src/test/java/org/opensearch/security/sanity/tests/SingleClusterSanityIT.java b/src/test/java/org/opensearch/security/sanity/tests/SingleClusterSanityIT.java index 55d4a6ea0b..8987744d58 100644 --- a/src/test/java/org/opensearch/security/sanity/tests/SingleClusterSanityIT.java +++ b/src/test/java/org/opensearch/security/sanity/tests/SingleClusterSanityIT.java @@ -24,7 +24,6 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; - @SuppressWarnings("unchecked") public class SingleClusterSanityIT extends SecurityRestTestCase { diff --git a/src/test/java/org/opensearch/security/securityconf/SecurityRolesPermissionsTest.java b/src/test/java/org/opensearch/security/securityconf/SecurityRolesPermissionsTest.java index 010b453b85..49a9be8a91 100644 --- a/src/test/java/org/opensearch/security/securityconf/SecurityRolesPermissionsTest.java +++ b/src/test/java/org/opensearch/security/securityconf/SecurityRolesPermissionsTest.java @@ -56,90 +56,62 @@ public class SecurityRolesPermissionsTest { - static final Map NO_REST_ADMIN_PERMISSIONS_ROLES = - ImmutableMap.builder() - .put( - "all_access", - role("*")) - .put( - "all_cluster_and_indices", - role("custer:*", "indices:*") - ).build(); - - static final Map REST_ADMIN_PERMISSIONS_FULL_ACCESS_ROLES = - ImmutableMap.builder() - .put( - "security_rest_api_full_access", - role(allRestApiPermissions())) - .put( - "security_rest_api_full_access_with_star", - role("restapi:admin/*")) - .build(); + static final Map NO_REST_ADMIN_PERMISSIONS_ROLES = ImmutableMap.builder() + .put("all_access", role("*")) + .put("all_cluster_and_indices", role("custer:*", "indices:*")) + .build(); + static final Map REST_ADMIN_PERMISSIONS_FULL_ACCESS_ROLES = ImmutableMap.builder() + .put("security_rest_api_full_access", role(allRestApiPermissions())) + .put("security_rest_api_full_access_with_star", role("restapi:admin/*")) + .build(); static String restAdminApiRoleName(final String endpoint) { return String.format("security_rest_api_%s_only", endpoint); } - static final Map REST_ADMIN_PERMISSIONS_ROLES = - ENDPOINTS_WITH_PERMISSIONS - .entrySet() - .stream() - .flatMap(e -> { - final String endpoint = e.getKey().name().toLowerCase(Locale.ROOT); - final PermissionBuilder pb = e.getValue(); - if (e.getKey() == Endpoint.SSL) { - return Stream.of( - new SimpleEntry<>( - restAdminApiRoleName(CERTS_INFO_ACTION), - role(pb.build(CERTS_INFO_ACTION)) - ), - new SimpleEntry<>( - restAdminApiRoleName(RELOAD_CERTS_ACTION), - role(pb.build(RELOAD_CERTS_ACTION)) - ) - ); - } else { - return Stream.of( - new SimpleEntry<>(restAdminApiRoleName(endpoint), role(pb.build())) - ); - } - }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + static final Map REST_ADMIN_PERMISSIONS_ROLES = ENDPOINTS_WITH_PERMISSIONS.entrySet().stream().flatMap(e -> { + final String endpoint = e.getKey().name().toLowerCase(Locale.ROOT); + final PermissionBuilder pb = e.getValue(); + if (e.getKey() == Endpoint.SSL) { + return Stream.of( + new SimpleEntry<>(restAdminApiRoleName(CERTS_INFO_ACTION), role(pb.build(CERTS_INFO_ACTION))), + new SimpleEntry<>(restAdminApiRoleName(RELOAD_CERTS_ACTION), role(pb.build(RELOAD_CERTS_ACTION))) + ); + } else { + return Stream.of(new SimpleEntry<>(restAdminApiRoleName(endpoint), role(pb.build()))); + } + }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); static ObjectNode role(final String... clusterPermissions) { final ArrayNode clusterPermissionsArrayNode = DefaultObjectMapper.objectMapper.createArrayNode(); Arrays.stream(clusterPermissions).forEach(clusterPermissionsArrayNode::add); - return DefaultObjectMapper.objectMapper - .createObjectNode() - .put("reserved", true) - .set("cluster_permissions", clusterPermissionsArrayNode); + return DefaultObjectMapper.objectMapper.createObjectNode() + .put("reserved", true) + .set("cluster_permissions", clusterPermissionsArrayNode); } static String[] allRestApiPermissions() { - return ENDPOINTS_WITH_PERMISSIONS - .entrySet() - .stream() - .flatMap(entry -> { - if (entry.getKey() == Endpoint.SSL) { - return Stream.of(entry.getValue().build(CERTS_INFO_ACTION), entry.getValue().build(RELOAD_CERTS_ACTION)); - } else { - return Stream.of(entry.getValue().build()); - } - }).toArray(String[]::new); + return ENDPOINTS_WITH_PERMISSIONS.entrySet().stream().flatMap(entry -> { + if (entry.getKey() == Endpoint.SSL) { + return Stream.of(entry.getValue().build(CERTS_INFO_ACTION), entry.getValue().build(RELOAD_CERTS_ACTION)); + } else { + return Stream.of(entry.getValue().build()); + } + }).toArray(String[]::new); } final ConfigModel configModel; public SecurityRolesPermissionsTest() throws IOException { - this.configModel = - new ConfigModelV7( - createRolesConfig(), - createRoleMappingsConfig(), - createActionGroupsConfig(), - createTenantsConfig(), - Mockito.mock(DynamicConfigModel.class), - Settings.EMPTY - ); + this.configModel = new ConfigModelV7( + createRolesConfig(), + createRoleMappingsConfig(), + createActionGroupsConfig(), + createTenantsConfig(), + Mockito.mock(DynamicConfigModel.class), + Settings.EMPTY + ); } @Test @@ -151,17 +123,17 @@ public void hasNoExplicitClusterPermissionPermissionForRestAdmin() { final PermissionBuilder permissionBuilder = entry.getValue(); if (endpoint == Endpoint.SSL) { Assert.assertFalse( - endpoint.name(), - securityRolesForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build(CERTS_INFO_ACTION)) + endpoint.name(), + securityRolesForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build(CERTS_INFO_ACTION)) ); Assert.assertFalse( - endpoint.name(), - securityRolesForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build(RELOAD_CERTS_ACTION)) + endpoint.name(), + securityRolesForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build(RELOAD_CERTS_ACTION)) ); } else { Assert.assertFalse( - endpoint.name(), - securityRolesForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build()) + endpoint.name(), + securityRolesForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build()) ); } } @@ -176,10 +148,19 @@ public void hasExplicitClusterPermissionPermissionForRestAdminWitFullAccess() { final Endpoint endpoint = entry.getKey(); final PermissionBuilder permissionBuilder = entry.getValue(); if (endpoint == Endpoint.SSL) { - Assert.assertTrue(endpoint.name() + "/" + CERTS_INFO_ACTION, securityRolesForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build(CERTS_INFO_ACTION))); - Assert.assertTrue(endpoint.name() + "/" + CERTS_INFO_ACTION, securityRolesForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build(RELOAD_CERTS_ACTION))); + Assert.assertTrue( + endpoint.name() + "/" + CERTS_INFO_ACTION, + securityRolesForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build(CERTS_INFO_ACTION)) + ); + Assert.assertTrue( + endpoint.name() + "/" + CERTS_INFO_ACTION, + securityRolesForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build(RELOAD_CERTS_ACTION)) + ); } else { - Assert.assertTrue(endpoint.name(), securityRolesForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build())); + Assert.assertTrue( + endpoint.name(), + securityRolesForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build()) + ); } } } @@ -188,60 +169,53 @@ public void hasExplicitClusterPermissionPermissionForRestAdminWitFullAccess() { @Test public void hasExplicitClusterPermissionPermissionForRestAdmin() { // verify all endpoint except SSL - final Collection noSslEndpoints = - ENDPOINTS_WITH_PERMISSIONS.keySet().stream() - .filter(e -> e != Endpoint.SSL).collect(Collectors.toList()); + final Collection noSslEndpoints = ENDPOINTS_WITH_PERMISSIONS.keySet() + .stream() + .filter(e -> e != Endpoint.SSL) + .collect(Collectors.toList()); for (final Endpoint endpoint : noSslEndpoints) { final String permission = ENDPOINTS_WITH_PERMISSIONS.get(endpoint).build(); - final SecurityRoles allowOnePermissionRole = - configModel.getSecurityRoles().filter( - ImmutableSet.of(restAdminApiRoleName(endpoint.name().toLowerCase(Locale.ROOT)))); + final SecurityRoles allowOnePermissionRole = configModel.getSecurityRoles() + .filter(ImmutableSet.of(restAdminApiRoleName(endpoint.name().toLowerCase(Locale.ROOT)))); Assert.assertTrue(endpoint.name(), allowOnePermissionRole.hasExplicitClusterPermissionPermission(permission)); - assertHasNoPermissionsForRestApiAdminOnePermissionRole( - endpoint, - allowOnePermissionRole - ); + assertHasNoPermissionsForRestApiAdminOnePermissionRole(endpoint, allowOnePermissionRole); } // verify SSL endpoint with 2 actions for (final String sslAction : ImmutableSet.of(CERTS_INFO_ACTION, RELOAD_CERTS_ACTION)) { - final SecurityRoles sslAllowRole = - configModel.getSecurityRoles().filter(ImmutableSet.of(restAdminApiRoleName(sslAction))); + final SecurityRoles sslAllowRole = configModel.getSecurityRoles().filter(ImmutableSet.of(restAdminApiRoleName(sslAction))); final PermissionBuilder permissionBuilder = ENDPOINTS_WITH_PERMISSIONS.get(Endpoint.SSL); Assert.assertTrue( - Endpoint.SSL + "/" + sslAction, - sslAllowRole.hasExplicitClusterPermissionPermission(permissionBuilder.build(sslAction)) + Endpoint.SSL + "/" + sslAction, + sslAllowRole.hasExplicitClusterPermissionPermission(permissionBuilder.build(sslAction)) ); assertHasNoPermissionsForRestApiAdminOnePermissionRole(Endpoint.SSL, sslAllowRole); } } void assertHasNoPermissionsForRestApiAdminOnePermissionRole(final Endpoint allowEndpoint, final SecurityRoles allowOnlyRoleForRole) { - final Collection noPermissionEndpoints = - ENDPOINTS_WITH_PERMISSIONS.keySet().stream() - .filter(e -> e != allowEndpoint) - .collect(Collectors.toList()); + final Collection noPermissionEndpoints = ENDPOINTS_WITH_PERMISSIONS.keySet() + .stream() + .filter(e -> e != allowEndpoint) + .collect(Collectors.toList()); for (final Endpoint endpoint : noPermissionEndpoints) { final PermissionBuilder permissionBuilder = ENDPOINTS_WITH_PERMISSIONS.get(endpoint); if (endpoint == Endpoint.SSL) { Assert.assertFalse( - endpoint.name(), - allowOnlyRoleForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build(CERTS_INFO_ACTION))); + endpoint.name(), + allowOnlyRoleForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build(CERTS_INFO_ACTION)) + ); Assert.assertFalse( - endpoint.name(), - allowOnlyRoleForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build(RELOAD_CERTS_ACTION))); + endpoint.name(), + allowOnlyRoleForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build(RELOAD_CERTS_ACTION)) + ); } else { - Assert.assertFalse( - endpoint.name(), - allowOnlyRoleForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build())); + Assert.assertFalse(endpoint.name(), allowOnlyRoleForRole.hasExplicitClusterPermissionPermission(permissionBuilder.build())); } } } static ObjectNode meta(final String type) { - return DefaultObjectMapper.objectMapper - .createObjectNode() - .put("type", type) - .put("config_version", 2); + return DefaultObjectMapper.objectMapper.createObjectNode().put("type", type).put("config_version", 2); } static SecurityDynamicConfiguration createRolesConfig() throws IOException { diff --git a/src/test/java/org/opensearch/security/securityconf/impl/v7/IndexPatternTests.java b/src/test/java/org/opensearch/security/securityconf/impl/v7/IndexPatternTests.java index be7c2da7b0..2b95a6e84c 100644 --- a/src/test/java/org/opensearch/security/securityconf/impl/v7/IndexPatternTests.java +++ b/src/test/java/org/opensearch/security/securityconf/impl/v7/IndexPatternTests.java @@ -68,7 +68,7 @@ public void before() { @After public void after() { verifyNoMoreInteractions(user, resolver, clusterService); - } + } @Test public void testCtor() { @@ -78,7 +78,7 @@ public void testCtor() { /** Ensure that concreteIndexNames sends correct parameters are sent to getResolvedIndexPattern */ @Test public void testConcreteIndexNamesOverload() { - doReturn(ImmutableSet.of("darn")).when(ip).getResolvedIndexPattern(user, resolver, clusterService, false); + doReturn(ImmutableSet.of("darn")).when(ip).getResolvedIndexPattern(user, resolver, clusterService, false); final Set results = ip.concreteIndexNames(user, resolver, clusterService); @@ -93,7 +93,7 @@ public void testConcreteIndexNamesOverload() { @Test public void testAttemptResolveIndexNamesOverload() { doReturn(ImmutableSet.of("yarn")).when(ip).getResolvedIndexPattern(user, resolver, clusterService, true); - + final Set results = ip.attemptResolveIndexNames(user, resolver, clusterService); assertThat(results, contains("yarn")); @@ -108,7 +108,9 @@ public void testAttemptResolveIndexNamesOverload() { public void testExactNameWithNoMatches() { doReturn("index-17").when(ip).getUnresolvedIndexPattern(user); when(clusterService.state()).thenReturn(mock(ClusterState.class)); - when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-17"))).thenReturn(new String[]{}); + when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-17"))).thenReturn( + new String[] {} + ); final Set results = ip.concreteIndexNames(user, resolver, clusterService); @@ -124,7 +126,9 @@ public void testExactNameWithNoMatches() { public void testExactName() { doReturn("index-17").when(ip).getUnresolvedIndexPattern(user); when(clusterService.state()).thenReturn(mock(ClusterState.class)); - when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-17"))).thenReturn(new String[]{"resolved-index-17"}); + when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-17"))).thenReturn( + new String[] { "resolved-index-17" } + ); final Set results = ip.concreteIndexNames(user, resolver, clusterService); @@ -140,7 +144,9 @@ public void testExactName() { public void testMultipleConcreteIndices() { doReturn("index-1*").when(ip).getUnresolvedIndexPattern(user); doReturn(createClusterState()).when(clusterService).state(); - when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-1*"))).thenReturn(new String[]{"resolved-index-17", "resolved-index-18"}); + when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-1*"))).thenReturn( + new String[] { "resolved-index-17", "resolved-index-18" } + ); final Set results = ip.concreteIndexNames(user, resolver, clusterService); @@ -156,12 +162,18 @@ public void testMultipleConcreteIndices() { public void testMultipleConcreteIndicesWithOneAlias() { doReturn("index-1*").when(ip).getUnresolvedIndexPattern(user); - doReturn(createClusterState( - new IndexShorthand("index-100", Type.ALIAS), // Name and type match - new IndexShorthand("19", Type.ALIAS) // Type matches/wrong name - )).when(clusterService).state(); - when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-100"))).thenReturn(new String[]{"resolved-index-100"}); - when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-1*"))).thenReturn(new String[]{"resolved-index-17", "resolved-index-18"}); + doReturn( + createClusterState( + new IndexShorthand("index-100", Type.ALIAS), // Name and type match + new IndexShorthand("19", Type.ALIAS) // Type matches/wrong name + ) + ).when(clusterService).state(); + when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-100"))).thenReturn( + new String[] { "resolved-index-100" } + ); + when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-1*"))).thenReturn( + new String[] { "resolved-index-17", "resolved-index-18" } + ); final Set results = ip.concreteIndexNames(user, resolver, clusterService); @@ -172,18 +184,23 @@ public void testMultipleConcreteIndicesWithOneAlias() { verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-100")); verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-1*")); } - + /** Verify attemptResolveIndexNames with multiple aliases */ @Test public void testMultipleConcreteAliasedAndUnresolved() { doReturn("index-1*").when(ip).getUnresolvedIndexPattern(user); - doReturn(createClusterState( - new IndexShorthand("index-100", Type.ALIAS), // Name and type match - new IndexShorthand("index-101", Type.ALIAS), // Name and type match - new IndexShorthand("19", Type.ALIAS) // Type matches/wrong name - )).when(clusterService).state(); - when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-100"), eq("index-101"))).thenReturn(new String[]{"resolved-index-100", "resolved-index-101"}); - when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-1*"))).thenReturn(new String[]{"resolved-index-17", "resolved-index-18"}); + doReturn( + createClusterState( + new IndexShorthand("index-100", Type.ALIAS), // Name and type match + new IndexShorthand("index-101", Type.ALIAS), // Name and type match + new IndexShorthand("19", Type.ALIAS) // Type matches/wrong name + ) + ).when(clusterService).state(); + when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-100"), eq("index-101"))) + .thenReturn(new String[] { "resolved-index-100", "resolved-index-101" }); + when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-1*"))).thenReturn( + new String[] { "resolved-index-17", "resolved-index-18" } + ); final Set results = ip.attemptResolveIndexNames(user, resolver, clusterService); @@ -200,7 +217,7 @@ private ClusterState createClusterState(final IndexShorthand... indices) { Arrays.stream(indices).forEach(indexShorthand -> { final IndexAbstraction indexAbstraction = mock(IndexAbstraction.class); when(indexAbstraction.getType()).thenReturn(indexShorthand.type); - indexMap.put(indexShorthand.name, indexAbstraction); + indexMap.put(indexShorthand.name, indexAbstraction); }); final Metadata mockMetadata = mock(Metadata.class, withSettings().strictness(Strictness.LENIENT)); @@ -215,6 +232,7 @@ private ClusterState createClusterState(final IndexShorthand... indices) { private class IndexShorthand { public final String name; public final Type type; + public IndexShorthand(final String name, final Type type) { this.name = name; this.type = type; diff --git a/src/test/java/org/opensearch/security/setting/DeprecatedSettingsTest.java b/src/test/java/org/opensearch/security/setting/DeprecatedSettingsTest.java index 72c1bc3741..143efe9b11 100644 --- a/src/test/java/org/opensearch/security/setting/DeprecatedSettingsTest.java +++ b/src/test/java/org/opensearch/security/setting/DeprecatedSettingsTest.java @@ -29,7 +29,7 @@ public class DeprecatedSettingsTest { @Mock private DeprecationLogger logger; - private DeprecationLogger original; + private DeprecationLogger original; @Before public void before() { diff --git a/src/test/java/org/opensearch/security/ssl/CertificateValidatorTest.java b/src/test/java/org/opensearch/security/ssl/CertificateValidatorTest.java index f1f7f9ea84..ce614a17ca 100644 --- a/src/test/java/org/opensearch/security/ssl/CertificateValidatorTest.java +++ b/src/test/java/org/opensearch/security/ssl/CertificateValidatorTest.java @@ -1,10 +1,10 @@ /* * Copyright 2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl; @@ -41,39 +41,39 @@ import org.opensearch.security.test.helper.file.FileHelper; public class CertificateValidatorTest { - + public static final Date CRL_DATE = new Date(1525546426000L); protected final Logger log = LogManager.getLogger(this.getClass()); - + @Test public void testStaticCRL() throws Exception { - + File staticCrl = FileHelper.getAbsoluteFilePathFromClassPath("ssl/crl/revoked.crl").toFile(); Collection crls = null; - try(FileInputStream crlin = new FileInputStream(staticCrl)) { + try (FileInputStream crlin = new FileInputStream(staticCrl)) { crls = CertificateFactory.getInstance("X.509").generateCRLs(crlin); } - + Assert.assertEquals(crls.size(), 1); - - //trust chain incl intermediate certificates (root + intermediates) + + // trust chain incl intermediate certificates (root + intermediates) Collection rootCas; final File trustedCas = FileHelper.getAbsoluteFilePathFromClassPath("ssl/chain-ca.pem").toFile(); - try(FileInputStream trin = new FileInputStream(trustedCas)) { - rootCas = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); + try (FileInputStream trin = new FileInputStream(trustedCas)) { + rootCas = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); } - + Assert.assertEquals(rootCas.size(), 2); - //certificate chain to validate (client cert + intermediates but without root) + // certificate chain to validate (client cert + intermediates but without root) Collection certsToValidate; final File certs = FileHelper.getAbsoluteFilePathFromClassPath("ssl/crl/revoked.crt.pem").toFile(); - try(FileInputStream trin = new FileInputStream(certs)) { - certsToValidate = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); + try (FileInputStream trin = new FileInputStream(certs)) { + certsToValidate = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); } - + Assert.assertEquals(certsToValidate.size(), 2); - + CertificateValidator validator = new CertificateValidator(rootCas.toArray(new X509Certificate[0]), crls); validator.setDate(CRL_DATE); try { @@ -83,36 +83,36 @@ public void testStaticCRL() throws Exception { Assert.assertTrue(ExceptionUtils.getRootCause(e) instanceof CertificateRevokedException); } } - + @Test public void testStaticCRLOk() throws Exception { - + File staticCrl = FileHelper.getAbsoluteFilePathFromClassPath("ssl/crl/revoked.crl").toFile(); Collection crls = null; - try(FileInputStream crlin = new FileInputStream(staticCrl)) { + try (FileInputStream crlin = new FileInputStream(staticCrl)) { crls = CertificateFactory.getInstance("X.509").generateCRLs(crlin); } - + Assert.assertEquals(crls.size(), 1); - - //trust chain incl intermediate certificates (root + intermediates) + + // trust chain incl intermediate certificates (root + intermediates) Collection rootCas; final File trustedCas = FileHelper.getAbsoluteFilePathFromClassPath("ssl/chain-ca.pem").toFile(); - try(FileInputStream trin = new FileInputStream(trustedCas)) { - rootCas = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); + try (FileInputStream trin = new FileInputStream(trustedCas)) { + rootCas = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); } - + Assert.assertEquals(rootCas.size(), 2); - //certificate chain to validate (client cert + intermediates but without root) + // certificate chain to validate (client cert + intermediates but without root) Collection certsToValidate; final File certs = FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem").toFile(); - try(FileInputStream trin = new FileInputStream(certs)) { - certsToValidate = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); + try (FileInputStream trin = new FileInputStream(certs)) { + certsToValidate = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); } - + Assert.assertEquals(certsToValidate.size(), 3); - + CertificateValidator validator = new CertificateValidator(rootCas.toArray(new X509Certificate[0]), crls); validator.setDate(CRL_DATE); try { @@ -121,26 +121,26 @@ public void testStaticCRLOk() throws Exception { Assert.fail(ExceptionsHelper.stackTrace(ExceptionUtils.getRootCause(e))); } } - + @Test public void testNoValidationPossible() throws Exception { - //trust chain incl intermediate certificates (root + intermediates) + // trust chain incl intermediate certificates (root + intermediates) Collection rootCas; final File trustedCas = FileHelper.getAbsoluteFilePathFromClassPath("ssl/chain-ca.pem").toFile(); - try(FileInputStream trin = new FileInputStream(trustedCas)) { - rootCas = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); + try (FileInputStream trin = new FileInputStream(trustedCas)) { + rootCas = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); } - + Assert.assertEquals(rootCas.size(), 2); - //certificate chain to validate (client cert + intermediates but without root) + // certificate chain to validate (client cert + intermediates but without root) Collection certsToValidate; final File certs = FileHelper.getAbsoluteFilePathFromClassPath("ssl/crl/revoked.crt.pem").toFile(); - try(FileInputStream trin = new FileInputStream(certs)) { - certsToValidate = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); + try (FileInputStream trin = new FileInputStream(certs)) { + certsToValidate = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); } - + Assert.assertEquals(certsToValidate.size(), 2); CertificateValidator validator = new CertificateValidator(rootCas.toArray(new X509Certificate[0]), Collections.emptyList()); @@ -153,29 +153,29 @@ public void testNoValidationPossible() throws Exception { Assert.assertTrue(e.getCause().getMessage().contains("unable to find valid certification path to requested target")); } } - + @Test public void testCRLDP() throws Exception { - //trust chain incl intermediate certificates (root + intermediates) + // trust chain incl intermediate certificates (root + intermediates) Collection rootCas; final File trustedCas = FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem").toFile(); - try(FileInputStream trin = new FileInputStream(trustedCas)) { - rootCas = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); + try (FileInputStream trin = new FileInputStream(trustedCas)) { + rootCas = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); } - + Assert.assertEquals(rootCas.size(), 1); - //certificate chain to validate (client cert + intermediates but without root) + // certificate chain to validate (client cert + intermediates but without root) Collection certsToValidate; final File certs = FileHelper.getAbsoluteFilePathFromClassPath("ssl/crl/revoked.crt.pem").toFile(); - //final File certs = getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem"); - try(FileInputStream trin = new FileInputStream(certs)) { - certsToValidate = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); + // final File certs = getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem"); + try (FileInputStream trin = new FileInputStream(certs)) { + certsToValidate = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); } - + Assert.assertEquals(certsToValidate.size(), 2); - + CertificateValidator validator = new CertificateValidator(rootCas.toArray(new X509Certificate[0]), Collections.emptyList()); validator.setEnableCRLDP(true); validator.setEnableOCSP(true); diff --git a/src/test/java/org/opensearch/security/ssl/OpenSSLTest.java b/src/test/java/org/opensearch/security/ssl/OpenSSLTest.java index 6d473c0160..f205f5fff9 100644 --- a/src/test/java/org/opensearch/security/ssl/OpenSSLTest.java +++ b/src/test/java/org/opensearch/security/ssl/OpenSSLTest.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl; @@ -104,21 +104,20 @@ public void testHttpsV3Fail() throws Exception { super.testHttpsV3Fail(); } - @Override - @Test(timeout=40000) + @Test(timeout = 40000) public void testNodeClientSSL() throws Exception { Assume.assumeTrue(OpenSearchSecuritySSLPlugin.OPENSSL_SUPPORTED && OpenSsl.isAvailable()); super.testNodeClientSSL(); } - + @Override @Test public void testHttpsOptionalAuth() throws Exception { Assume.assumeTrue(OpenSearchSecuritySSLPlugin.OPENSSL_SUPPORTED && OpenSsl.isAvailable()); super.testHttpsOptionalAuth(); } - + @Test public void testAvailCiphersOpenSSL() throws Exception { Assume.assumeTrue(OpenSearchSecuritySSLPlugin.OPENSSL_SUPPORTED && OpenSsl.isAvailable()); @@ -139,7 +138,7 @@ public void testAvailCiphersOpenSSL() throws Exception { System.out.println("OpenSSL secure ciphers: " + openSSLSecureCiphers); Assert.assertTrue(openSSLSecureCiphers.size() > 0); } - + @Test public void testHttpsEnforceFail() throws Exception { Assume.assumeTrue(OpenSearchSecuritySSLPlugin.OPENSSL_SUPPORTED && OpenSsl.isAvailable()); @@ -157,55 +156,64 @@ public void testHttpsAndNodeSSLFailedCipher() throws Exception { Assume.assumeTrue(OpenSearchSecuritySSLPlugin.OPENSSL_SUPPORTED && OpenSsl.isAvailable()); super.testHttpsAndNodeSSLFailedCipher(); } - + @Test public void testHttpsAndNodeSSLPem() throws Exception { Assume.assumeTrue(OpenSearchSecuritySSLPlugin.OPENSSL_SUPPORTED && OpenSsl.isAvailable()); super.testHttpsAndNodeSSLPKCS8Pem(); } - + @Test public void testHttpsAndNodeSSLPemEnc() throws Exception { Assume.assumeTrue(OpenSearchSecuritySSLPlugin.OPENSSL_SUPPORTED && OpenSsl.isAvailable()); super.testHttpsAndNodeSSLPemEnc(); } - + @Test public void testNodeClientSSLwithOpenSslTLSv13() throws Exception { - + Assume.assumeTrue(OpenSearchSecuritySSLPlugin.OPENSSL_SUPPORTED && OpenSsl.isAvailable() && OpenSsl.version() > 0x10101009L); - final Settings settings = Settings.builder().put("plugins.security.ssl.transport.enabled", true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") - .put("plugins.security.ssl.transport.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - .put("plugins.security.ssl.transport.enforce_hostname_verification", false) - .put("plugins.security.ssl.transport.resolve_hostname", false) - .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_PROTOCOLS, "TLSv1.3") - .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_CIPHERS, "TLS_CHACHA20_POLY1305_SHA256") - .put("node.max_local_storage_nodes",4) - .build(); + final Settings settings = Settings.builder() + .put("plugins.security.ssl.transport.enabled", true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") + .put("plugins.security.ssl.transport.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .put("plugins.security.ssl.transport.enforce_hostname_verification", false) + .put("plugins.security.ssl.transport.resolve_hostname", false) + .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_PROTOCOLS, "TLSv1.3") + .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_CIPHERS, "TLS_CHACHA20_POLY1305_SHA256") + .put("node.max_local_storage_nodes", 4) + .build(); setupSslOnlyMode(settings); - + RestHelper rh = nonSslRestHelper(); - final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) - .put("cluster.name", clusterInfo.clustername).put("path.home", "/tmp") - .put("node.name", "client_node_" + new Random().nextInt()) - .put("path.data", "./target/data/" + clusterInfo.clustername + "/ssl/data") - .put("path.logs", "./target/data/" + clusterInfo.clustername + "/ssl/logs") - .put("path.home", "./target") - .put("discovery.initial_state_timeout","8s") - .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost+":"+clusterInfo.nodePort) - .put(settings)// ----- - .build(); + final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) + .put("cluster.name", clusterInfo.clustername) + .put("path.home", "/tmp") + .put("node.name", "client_node_" + new Random().nextInt()) + .put("path.data", "./target/data/" + clusterInfo.clustername + "/ssl/data") + .put("path.logs", "./target/data/" + clusterInfo.clustername + "/ssl/logs") + .put("path.home", "./target") + .put("discovery.initial_state_timeout", "8s") + .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost + ":" + clusterInfo.nodePort) + .put(settings)// ----- + .build(); try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class).start()) { - ClusterHealthResponse res = node.client().admin().cluster().health(new ClusterHealthRequest().waitForNodes("4").timeout(TimeValue.timeValueSeconds(5))).actionGet(); + ClusterHealthResponse res = node.client() + .admin() + .cluster() + .health(new ClusterHealthRequest().waitForNodes("4").timeout(TimeValue.timeValueSeconds(5))) + .actionGet(); Assert.assertFalse(res.isTimedOut()); Assert.assertEquals(4, res.getNumberOfNodes()); Assert.assertEquals(4, node.client().admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); diff --git a/src/test/java/org/opensearch/security/ssl/SSLTest.java b/src/test/java/org/opensearch/security/ssl/SSLTest.java index 65181d66b9..72ad6d5d16 100644 --- a/src/test/java/org/opensearch/security/ssl/SSLTest.java +++ b/src/test/java/org/opensearch/security/ssl/SSLTest.java @@ -70,7 +70,7 @@ import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_TRANSPORT_PEMKEY_PASSWORD; import static org.opensearch.security.ssl.SecureSSLSettings.SSLSetting.SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD; -@SuppressWarnings({"resource", "unchecked"}) +@SuppressWarnings({ "resource", "unchecked" }) public class SSLTest extends SingleClusterTest { @Rule @@ -82,19 +82,25 @@ public class SSLTest extends SingleClusterTest { public void testHttps() throws Exception { final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, false) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .putList(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_PROTOCOLS, "TLSv1.1", "TLSv1.2") - .putList(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_CIPHERS, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256") - .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_PROTOCOLS, "TLSv1.1", "TLSv1.2") - .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_CIPHERS, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, false) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .putList(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_PROTOCOLS, "TLSv1.1", "TLSv1.2") + .putList(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_CIPHERS, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256") + .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_PROTOCOLS, "TLSv1.1", "TLSv1.2") + .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_CIPHERS, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256") + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .build(); setupSslOnlyMode(settings); @@ -105,14 +111,18 @@ public void testHttps() throws Exception { rh.keystore = "node-untspec5-keystore.p12"; System.out.println(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty&show_dn=true")); - Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty&show_dn=true").contains("EMAILADDRESS=unt@tst.com")); + Assert.assertTrue( + rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty&show_dn=true").contains("EMAILADDRESS=unt@tst.com") + ); Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty&show_dn=true").contains("local_certificates_list")); - Assert.assertFalse(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty&show_dn=false").contains("local_certificates_list")); + Assert.assertFalse( + rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty&show_dn=false").contains("local_certificates_list") + ); Assert.assertFalse(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("local_certificates_list")); Assert.assertTrue(rh.executeSimpleRequest("_nodes/settings?pretty").contains(clusterInfo.clustername)); Assert.assertFalse(rh.executeSimpleRequest("_nodes/settings?pretty").contains("\"opendistro_security\"")); Assert.assertFalse(rh.executeSimpleRequest("_nodes/settings?pretty").contains("keystore_filepath")); - //Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE")); + // Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE")); } @@ -124,28 +134,35 @@ public void testCipherAndProtocols() throws Exception { System.out.println("allowOpenSSL: " + allowOpenSSL); Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, false) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0").put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - //WEAK and insecure cipher, do NOT use this, its here for unittesting only!!! - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_CIPHERS, "SSL_RSA_EXPORT_WITH_RC4_40_MD5") - //WEAK and insecure protocol, do NOT use this, its here for unittesting only!!! - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_PROTOCOLS, "SSLv3") - .put("client.type", "node") - .put("path.home", ".") - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, false) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + // WEAK and insecure cipher, do NOT use this, its here for unittesting only!!! + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_CIPHERS, "SSL_RSA_EXPORT_WITH_RC4_40_MD5") + // WEAK and insecure protocol, do NOT use this, its here for unittesting only!!! + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_PROTOCOLS, "SSLv3") + .put("client.type", "node") + .put("path.home", ".") + .build(); try { String[] enabledCiphers = new DefaultSecurityKeyStore(settings, Paths.get(".")).createHTTPSSLEngine().getEnabledCipherSuites(); String[] enabledProtocols = new DefaultSecurityKeyStore(settings, Paths.get(".")).createHTTPSSLEngine().getEnabledProtocols(); if (allowOpenSSL) { - Assert.assertEquals(2, enabledProtocols.length); //SSLv2Hello is always enabled when using openssl + Assert.assertEquals(2, enabledProtocols.length); // SSLv2Hello is always enabled when using openssl Assert.assertTrue("Check SSLv3", "SSLv3".equals(enabledProtocols[0]) || "SSLv3".equals(enabledProtocols[1])); Assert.assertEquals(1, enabledCiphers.length); Assert.assertEquals("TLS_RSA_EXPORT_WITH_RC4_40_MD5", enabledCiphers[0]); @@ -157,25 +174,32 @@ public void testCipherAndProtocols() throws Exception { } settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - //WEAK and insecure cipher, do NOT use this, its here for unittesting only!!! - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_CIPHERS, "SSL_RSA_EXPORT_WITH_RC4_40_MD5") - //WEAK and insecure protocol, do NOT use this, its here for unittesting only!!! - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_PROTOCOLS, "SSLv3") - .put("client.type", "node") - .put("path.home", ".") - .build(); - - enabledCiphers = new DefaultSecurityKeyStore(settings, Paths.get(".")).createServerTransportSSLEngine().getEnabledCipherSuites(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + // WEAK and insecure cipher, do NOT use this, its here for unittesting only!!! + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_CIPHERS, "SSL_RSA_EXPORT_WITH_RC4_40_MD5") + // WEAK and insecure protocol, do NOT use this, its here for unittesting only!!! + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_PROTOCOLS, "SSLv3") + .put("client.type", "node") + .put("path.home", ".") + .build(); + + enabledCiphers = new DefaultSecurityKeyStore(settings, Paths.get(".")).createServerTransportSSLEngine() + .getEnabledCipherSuites(); enabledProtocols = new DefaultSecurityKeyStore(settings, Paths.get(".")).createServerTransportSSLEngine().getEnabledProtocols(); if (allowOpenSSL) { - Assert.assertEquals(2, enabledProtocols.length); //SSLv2Hello is always enabled when using openssl + Assert.assertEquals(2, enabledProtocols.length); // SSLv2Hello is always enabled when using openssl Assert.assertTrue("Check SSLv3", "SSLv3".equals(enabledProtocols[0]) || "SSLv3".equals(enabledProtocols[1])); Assert.assertEquals(1, enabledCiphers.length); Assert.assertEquals("TLS_RSA_EXPORT_WITH_RC4_40_MD5", enabledCiphers[0]); @@ -185,11 +209,13 @@ public void testCipherAndProtocols() throws Exception { Assert.assertEquals(1, enabledCiphers.length); Assert.assertEquals("SSL_RSA_EXPORT_WITH_RC4_40_MD5", enabledCiphers[0]); } - enabledCiphers = new DefaultSecurityKeyStore(settings, Paths.get(".")).createClientTransportSSLEngine(null, -1).getEnabledCipherSuites(); - enabledProtocols = new DefaultSecurityKeyStore(settings, Paths.get(".")).createClientTransportSSLEngine(null, -1).getEnabledProtocols(); + enabledCiphers = new DefaultSecurityKeyStore(settings, Paths.get(".")).createClientTransportSSLEngine(null, -1) + .getEnabledCipherSuites(); + enabledProtocols = new DefaultSecurityKeyStore(settings, Paths.get(".")).createClientTransportSSLEngine(null, -1) + .getEnabledProtocols(); if (allowOpenSSL) { - Assert.assertEquals(2, enabledProtocols.length); //SSLv2Hello is always enabled when using openssl + Assert.assertEquals(2, enabledProtocols.length); // SSLv2Hello is always enabled when using openssl Assert.assertTrue("Check SSLv3", "SSLv3".equals(enabledProtocols[0]) || "SSLv3".equals(enabledProtocols[1])); Assert.assertEquals(1, enabledCiphers.length); Assert.assertEquals("TLS_RSA_EXPORT_WITH_RC4_40_MD5", enabledCiphers[0]); @@ -200,9 +226,18 @@ public void testCipherAndProtocols() throws Exception { Assert.assertEquals("SSL_RSA_EXPORT_WITH_RC4_40_MD5", enabledCiphers[0]); } } catch (OpenSearchSecurityException e) { - System.out.println("EXPECTED " + e.getClass().getSimpleName() + " for " + System.getProperty("java.specification.version") + ": " + e.toString()); + System.out.println( + "EXPECTED " + + e.getClass().getSimpleName() + + " for " + + System.getProperty("java.specification.version") + + ": " + + e.toString() + ); e.printStackTrace(); - Assert.assertTrue("Check if error contains 'no valid cipher suites' -> " + e.toString(), e.toString().contains("no valid cipher suites") + Assert.assertTrue( + "Check if error contains 'no valid cipher suites' -> " + e.toString(), + e.toString().contains("no valid cipher suites") || e.toString().contains("failed to set cipher suite") || e.toString().contains("Unable to configure permitted SSL ciphers") || e.toString().contains("OPENSSL_internal:NO_CIPHER_MATCH") @@ -215,13 +250,21 @@ public void testCipherAndProtocols() throws Exception { public void testHttpsOptionalAuth() throws Exception { final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, false) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0").put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")).build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, false) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .build(); setupSslOnlyMode(settings); @@ -234,29 +277,44 @@ public void testHttpsOptionalAuth() throws Exception { Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("TLS")); Assert.assertTrue(rh.executeSimpleRequest("_nodes/settings?pretty").contains(clusterInfo.clustername)); Assert.assertFalse(rh.executeSimpleRequest("_nodes/settings?pretty").contains("\"opendistro_security\"")); - Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE")); + Assert.assertTrue( + rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE") + ); } @Test public void testHttpsAndNodeSSL() throws Exception { final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) - - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true).put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) + + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + + .build(); setupSslOnlyMode(settings); @@ -269,7 +327,9 @@ public void testHttpsAndNodeSSL() throws Exception { Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("TLS")); Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").length() > 0); Assert.assertTrue(rh.executeSimpleRequest("_nodes/settings?pretty").contains(clusterInfo.clustername)); - Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE")); + Assert.assertTrue( + rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE") + ); Assert.assertFalse(rh.executeSimpleRequest("_nodes/stats?pretty").contains("\"tx_size_in_bytes\" : 0")); Assert.assertFalse(rh.executeSimpleRequest("_nodes/stats?pretty").contains("\"rx_count\" : 0")); Assert.assertFalse(rh.executeSimpleRequest("_nodes/stats?pretty").contains("\"rx_size_in_bytes\" : 0")); @@ -281,22 +341,34 @@ public void testHttpsAndNodeSSL() throws Exception { public void testHttpsAndNodeSSLPKCS8Pem() throws Exception { final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.key.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) - - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.key.pem")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem")) - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMKEY_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.key.pem") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) + + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem")) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.key.pem")) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem") + ) + .build(); setupSslOnlyMode(settings); @@ -309,30 +381,47 @@ public void testHttpsAndNodeSSLPKCS8Pem() throws Exception { Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("TLS")); Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").length() > 0); Assert.assertTrue(rh.executeSimpleRequest("_nodes/settings?pretty").contains(clusterInfo.clustername)); - //Assert.assertTrue(!executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("null")); - Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE")); + // Assert.assertTrue(!executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("null")); + Assert.assertTrue( + rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE") + ); } @Test public void testHttpsAndNodeSSLPKCS1Pem() throws Exception { final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-pkcs1.key.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) - - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-pkcs1.key.pem")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem")) - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMKEY_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-pkcs1.key.pem") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) + + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem")) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_PEMKEY_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-pkcs1.key.pem") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem") + ) + .build(); setupSslOnlyMode(settings); @@ -344,7 +433,9 @@ public void testHttpsAndNodeSSLPKCS1Pem() throws Exception { Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("TLS")); Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").length() > 0); Assert.assertTrue(rh.executeSimpleRequest("_nodes/settings?pretty").contains(clusterInfo.clustername)); - Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE")); + Assert.assertTrue( + rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE") + ); } @Test @@ -354,23 +445,38 @@ public void testHttpsAndNodeSSLPemEnc() throws Exception { mockSecureSettings.setString(SECURITY_SSL_TRANSPORT_PEMKEY_PASSWORD.propertyName, "changeit"); final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/pem/node-4.crt.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/pem/node-4.key")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) - - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/pem/node-4.crt.pem")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/pem/node-4.key")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem")) - .setSecureSettings(mockSecureSettings) - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/pem/node-4.crt.pem") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMKEY_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/pem/node-4.key") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) + + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_PEMCERT_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/pem/node-4.crt.pem") + ) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/pem/node-4.key")) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem") + ) + .setSecureSettings(mockSecureSettings) + .build(); setupSslOnlyMode(settings); @@ -383,32 +489,49 @@ public void testHttpsAndNodeSSLPemEnc() throws Exception { Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("TLS")); Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").length() > 0); Assert.assertTrue(rh.executeSimpleRequest("_nodes/settings?pretty").contains(clusterInfo.clustername)); - //Assert.assertTrue(!executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("null")); - Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE")); + // Assert.assertTrue(!executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("null")); + Assert.assertTrue( + rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE") + ); } @Test public void testSSLPemEncWithInsecureSettings() throws Exception { final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/pem/node-4.crt.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/pem/node-4.key")) - // legacy insecure passwords - .put(SECURITY_SSL_TRANSPORT_PEMKEY_PASSWORD.insecurePropertyName, "changeit") - .put(SECURITY_SSL_HTTP_PEMKEY_PASSWORD.insecurePropertyName, "changeit") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) - - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/pem/node-4.crt.pem")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/pem/node-4.key")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem")) - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/pem/node-4.crt.pem") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMKEY_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/pem/node-4.key") + ) + // legacy insecure passwords + .put(SECURITY_SSL_TRANSPORT_PEMKEY_PASSWORD.insecurePropertyName, "changeit") + .put(SECURITY_SSL_HTTP_PEMKEY_PASSWORD.insecurePropertyName, "changeit") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) + + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_PEMCERT_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/pem/node-4.crt.pem") + ) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/pem/node-4.key")) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem") + ) + .build(); setupSslOnlyMode(settings); @@ -417,33 +540,46 @@ public void testSSLPemEncWithInsecureSettings() throws Exception { rh.trustHTTPServerCertificate = true; rh.sendAdminCertificate = true; - Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE")); + Assert.assertTrue( + rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE") + ); } - @Test public void testHttpsAndNodeSSLFailedCipher() throws Exception { final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) - - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_CIPHERS, "INVALID_CIPHER") - - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) + + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_CIPHERS, "INVALID_CIPHER") + + .build(); try { setupSslOnlyMode(settings); @@ -461,18 +597,25 @@ public void testHttpPlainFail() throws Exception { thrown.expect(NoHttpResponseException.class); final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, false) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0").put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "OPTIONAL") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")).build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, false) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "OPTIONAL") + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .build(); setupSslOnlyMode(settings); - RestHelper rh = restHelper(); rh.enableHTTPClientSSL = false; rh.trustHTTPServerCertificate = true; @@ -480,21 +623,31 @@ public void testHttpPlainFail() throws Exception { Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").length() > 0); Assert.assertTrue(rh.executeSimpleRequest("_nodes/settings?pretty").contains(clusterInfo.clustername)); - Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE")); + Assert.assertTrue( + rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE") + ); } @Test public void testHttpsNoEnforce() throws Exception { final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, false) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0").put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "NONE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")).build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, false) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "NONE") + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .build(); setupSslOnlyMode(settings); @@ -505,21 +658,31 @@ public void testHttpsNoEnforce() throws Exception { Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").length() > 0); Assert.assertTrue(rh.executeSimpleRequest("_nodes/settings?pretty").contains(clusterInfo.clustername)); - Assert.assertFalse(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE")); + Assert.assertFalse( + rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE") + ); } @Test public void testHttpsEnforceFail() throws Exception { final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, false) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0").put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")).build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, false) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .build(); setupSslOnlyMode(settings); @@ -532,7 +695,7 @@ public void testHttpsEnforceFail() throws Exception { rh.executeSimpleRequest(""); Assert.fail(); } catch (SocketException | SSLException e) { - //expected + // expected System.out.println("Expected SSLHandshakeException " + e.toString()); } catch (Exception e) { e.printStackTrace(); @@ -545,14 +708,22 @@ public void testHttpsV3Fail() throws Exception { thrown.expect(SSLHandshakeException.class); final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, false) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0").put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "NONE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")).build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, false) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "NONE") + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .build(); setupSslOnlyMode(settings); @@ -570,34 +741,45 @@ public void testHttpsV3Fail() throws Exception { public void testNodeClientSSL() throws Exception { final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) + .build(); setupSslOnlyMode(settings); RestHelper rh = nonSslRestHelper(); final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) - .put("cluster.name", clusterInfo.clustername).put("path.home", ".") - .put("node.name", "client_node_" + new Random().nextInt()) - .put("path.data", "./target/data/" + clusterInfo.clustername + "/ssl/data") - .put("path.logs", "./target/data/" + clusterInfo.clustername + "/ssl/logs") - .put("path.home", "./target") - .put("discovery.initial_state_timeout", "8s") - .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost + ":" + clusterInfo.nodePort) - .put(settings)// ----- - .build(); + .put("cluster.name", clusterInfo.clustername) + .put("path.home", ".") + .put("node.name", "client_node_" + new Random().nextInt()) + .put("path.data", "./target/data/" + clusterInfo.clustername + "/ssl/data") + .put("path.logs", "./target/data/" + clusterInfo.clustername + "/ssl/logs") + .put("path.home", "./target") + .put("discovery.initial_state_timeout", "8s") + .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost + ":" + clusterInfo.nodePort) + .put(settings)// ----- + .build(); try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class).start()) { - ClusterHealthResponse res = node.client().admin().cluster().health(new ClusterHealthRequest().waitForNodes("4").timeout(TimeValue.timeValueSeconds(15))).actionGet(); + ClusterHealthResponse res = node.client() + .admin() + .cluster() + .health(new ClusterHealthRequest().waitForNodes("4").timeout(TimeValue.timeValueSeconds(15))) + .actionGet(); Assert.assertFalse(res.isTimedOut()); Assert.assertEquals(4, res.getNumberOfNodes()); Assert.assertEquals(4, node.client().admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); @@ -635,7 +817,7 @@ public void testUnmodifieableCipherProtocolConfig() throws Exception { SSLConfigConstants.getSecureSSLCiphers(Settings.EMPTY, false).set(0, "bogus"); Assert.fail(); } catch (UnsupportedOperationException e) { - //expected + // expected } } @@ -643,20 +825,33 @@ public void testUnmodifieableCipherProtocolConfig() throws Exception { public void testCustomPrincipalExtractor() throws Exception { final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PRINCIPAL_EXTRACTOR_CLASS, "org.opensearch.security.ssl.TestPrincipalExtractor") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")).build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PRINCIPAL_EXTRACTOR_CLASS, "org.opensearch.security.ssl.TestPrincipalExtractor") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .build(); setupSslOnlyMode(settings); @@ -667,7 +862,11 @@ public void testCustomPrincipalExtractor() throws Exception { log.debug("OpenSearch started"); - final Settings tcSettings = Settings.builder().put("cluster.name", clusterInfo.clustername).put("path.home", ".").put(settings).build(); + final Settings tcSettings = Settings.builder() + .put("cluster.name", clusterInfo.clustername) + .put("path.home", ".") + .put(settings) + .build(); try (Client tc = getClient()) { @@ -676,7 +875,12 @@ public void testCustomPrincipalExtractor() throws Exception { Assert.assertEquals(3, tc.admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); log.debug("Client connected"); TestPrincipalExtractor.reset(); - Assert.assertEquals("test", tc.index(new IndexRequest("test").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"a\":5}", XContentType.JSON)).actionGet().getIndex()); + Assert.assertEquals( + "test", + tc.index(new IndexRequest("test").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"a\":5}", XContentType.JSON)) + .actionGet() + .getIndex() + ); log.debug("Index created"); Assert.assertEquals(1L, tc.search(new SearchRequest("test")).actionGet().getHits().getTotalHits().value); log.debug("Search done"); @@ -688,8 +892,8 @@ public void testCustomPrincipalExtractor() throws Exception { rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty"); - //we need to test this in SG itself because in the SSL only plugin the info is not longer propagated - //Assert.assertTrue(TestPrincipalExtractor.getTransportCount() > 0); + // we need to test this in SG itself because in the SSL only plugin the info is not longer propagated + // Assert.assertTrue(TestPrincipalExtractor.getTransportCount() > 0); Assert.assertTrue(TestPrincipalExtractor.getHttpCount() > 0); } @@ -697,24 +901,36 @@ public void testCustomPrincipalExtractor() throws Exception { public void testCRLPem() throws Exception { final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.key.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) - - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.key.pem")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/chain-ca.pem")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CRL_VALIDATE, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CRL_VALIDATION_DATE, CertificateValidatorTest.CRL_DATE.getTime()) - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMKEY_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.key.pem") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) + + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem")) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.key.pem")) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/chain-ca.pem") + ) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CRL_VALIDATE, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CRL_VALIDATION_DATE, CertificateValidatorTest.CRL_DATE.getTime()) + .build(); setupSslOnlyMode(settings); @@ -730,19 +946,25 @@ public void testCRLPem() throws Exception { public void testCRL() throws Exception { final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, false) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CRL_VALIDATE, true) - .put(SSLConfigConstants.SSECURITY_SSL_HTTP_CRL_FILE, FileHelper.getAbsoluteFilePathFromClassPath("ssl/crl/revoked.crl")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CRL_VALIDATION_DATE, CertificateValidatorTest.CRL_DATE.getTime()) - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, false) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CRL_VALIDATE, true) + .put(SSLConfigConstants.SSECURITY_SSL_HTTP_CRL_FILE, FileHelper.getAbsoluteFilePathFromClassPath("ssl/crl/revoked.crl")) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CRL_VALIDATION_DATE, CertificateValidatorTest.CRL_DATE.getTime()) + .build(); setupSslOnlyMode(settings); @@ -758,40 +980,50 @@ public void testCRL() throws Exception { @Test public void testNodeClientSSLwithJavaTLSv13() throws Exception { - //Java TLS 1.3 is available since Java 11 + // Java TLS 1.3 is available since Java 11 Assume.assumeTrue(!allowOpenSSL && PlatformDependent.javaVersion() >= 11); final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) - .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_PROTOCOLS, "TLSv1.3") - .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_CIPHERS, "TLS_AES_128_GCM_SHA256") - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) + .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_PROTOCOLS, "TLSv1.3") + .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_CIPHERS, "TLS_AES_128_GCM_SHA256") + .build(); setupSslOnlyMode(settings); RestHelper rh = nonSslRestHelper(); final Settings tcSettings = Settings.builder() - .put("cluster.name", clusterInfo.clustername) - .put("path.data", "./target/data/" + clusterInfo.clustername + "/ssl/data") - .put("path.logs", "./target/data/" + clusterInfo.clustername + "/ssl/logs") - .put("path.home", "./target") - .put("node.name", "client_node_" + new Random().nextInt()) - .put("discovery.initial_state_timeout", "8s") - .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost + ":" + clusterInfo.nodePort) - .put(settings)// ----- - .build(); + .put("cluster.name", clusterInfo.clustername) + .put("path.data", "./target/data/" + clusterInfo.clustername + "/ssl/data") + .put("path.logs", "./target/data/" + clusterInfo.clustername + "/ssl/logs") + .put("path.home", "./target") + .put("node.name", "client_node_" + new Random().nextInt()) + .put("discovery.initial_state_timeout", "8s") + .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost + ":" + clusterInfo.nodePort) + .put(settings)// ----- + .build(); try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class).start()) { - ClusterHealthResponse res = node.client().admin().cluster().health(new ClusterHealthRequest().waitForNodes("4").timeout(TimeValue.timeValueSeconds(5))).actionGet(); + ClusterHealthResponse res = node.client() + .admin() + .cluster() + .health(new ClusterHealthRequest().waitForNodes("4").timeout(TimeValue.timeValueSeconds(5))) + .actionGet(); Assert.assertFalse(res.isTimedOut()); Assert.assertEquals(4, res.getNumberOfNodes()); Assert.assertEquals(4, node.client().admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); @@ -807,20 +1039,32 @@ public void testNodeClientSSLwithJavaTLSv13() throws Exception { public void testTLSv12() throws Exception { final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_PROTOCOLS, "TLSv1.2") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_PROTOCOLS, "TLSv1.2") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .build(); setupSslOnlyMode(settings); @@ -831,7 +1075,6 @@ public void testTLSv12() throws Exception { Assert.assertTrue(rh.executeSimpleRequest("_nodes/stats?pretty").contains("\"tx_size_in_bytes\"")); } - @Test public void testHttpsAndNodeSSLKeyPass() throws Exception { final MockSecureSettings mockSecureSettings = new MockSecureSettings(); @@ -839,24 +1082,36 @@ public void testHttpsAndNodeSSLKeyPass() throws Exception { mockSecureSettings.setString(SECURITY_SSL_TRANSPORT_KEYSTORE_KEYPASSWORD.propertyName, "changeit"); final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) - - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - .setSecureSettings(mockSecureSettings) - - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) + + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .setSecureSettings(mockSecureSettings) + + .build(); setupSslOnlyMode(settings); @@ -869,7 +1124,9 @@ public void testHttpsAndNodeSSLKeyPass() throws Exception { Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("TLS")); Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").length() > 0); Assert.assertTrue(rh.executeSimpleRequest("_nodes/settings?pretty").contains(clusterInfo.clustername)); - Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE")); + Assert.assertTrue( + rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE") + ); Assert.assertFalse(rh.executeSimpleRequest("_nodes/stats?pretty").contains("\"tx_size_in_bytes\" : 0")); Assert.assertFalse(rh.executeSimpleRequest("_nodes/stats?pretty").contains("\"rx_count\" : 0")); Assert.assertFalse(rh.executeSimpleRequest("_nodes/stats?pretty").contains("\"rx_size_in_bytes\" : 0")); @@ -885,30 +1142,43 @@ public void testHttpsAndNodeSSLKeyStoreExtendedUsageEnabled() throws Exception { mockSecureSettings.setString(SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD.propertyName, "changeit"); final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_EXTENDED_KEY_USAGE_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_CLIENT_KEYSTORE_ALIAS, "node-0-client") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_SERVER_KEYSTORE_ALIAS, "node-0-server") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_CLIENT_TRUSTSTORE_ALIAS, "root-ca") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_SERVER_TRUSTSTORE_ALIAS, "root-ca") - - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/truststore.jks")) - - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) - - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true).put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - .setSecureSettings(mockSecureSettings) - - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_EXTENDED_KEY_USAGE_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_CLIENT_KEYSTORE_ALIAS, "node-0-client") + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_SERVER_KEYSTORE_ALIAS, "node-0-server") + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_CLIENT_TRUSTSTORE_ALIAS, "root-ca") + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_SERVER_TRUSTSTORE_ALIAS, "root-ca") + + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/truststore.jks") + ) + + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) + + .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .setSecureSettings(mockSecureSettings) + + .build(); setupSslOnlyMode(settings); @@ -921,7 +1191,9 @@ public void testHttpsAndNodeSSLKeyStoreExtendedUsageEnabled() throws Exception { Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("TLS")); Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").length() > 0); Assert.assertTrue(rh.executeSimpleRequest("_nodes/settings?pretty").contains(clusterInfo.clustername)); - Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE")); + Assert.assertTrue( + rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE") + ); Assert.assertFalse(rh.executeSimpleRequest("_nodes/stats?pretty").contains("\"tx_size_in_bytes\" : 0")); Assert.assertFalse(rh.executeSimpleRequest("_nodes/stats?pretty").contains("\"rx_count\" : 0")); Assert.assertFalse(rh.executeSimpleRequest("_nodes/stats?pretty").contains("\"rx_size_in_bytes\" : 0")); @@ -936,25 +1208,36 @@ public void testHttpsAndNodeSSLKeyPassFail() throws Exception { mockSecureSettings.setString(SECURITY_SSL_TRANSPORT_KEYSTORE_KEYPASSWORD.propertyName, "wrongpass"); final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) - - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks")) - .setSecureSettings(mockSecureSettings) - - - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) + + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/truststore.jks") + ) + .setSecureSettings(mockSecureSettings) + + .build(); setupSslOnlyMode(settings); @@ -971,26 +1254,47 @@ public void testHttpsAndNodeSSLKeyPassFail() throws Exception { public void testHttpsAndNodeSSLPemExtendedUsageEnabled() throws Exception { final Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) - .put(ConfigConstants.SECURITY_SSL_ONLY, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_EXTENDED_KEY_USAGE_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_CLIENT_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-client.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_CLIENT_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-key-client.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_CLIENT_PEMTRUSTEDCAS_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/root-ca.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_SERVER_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-server.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_SERVER_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-key-server.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_SERVER_PEMTRUSTEDCAS_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/root-ca.pem")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) - - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.key.pem")) - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem")) - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, true) + .put(ConfigConstants.SECURITY_SSL_ONLY, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_EXTENDED_KEY_USAGE_ENABLED, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_CLIENT_PEMCERT_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-client.pem") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_CLIENT_PEMKEY_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-key-client.pem") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_CLIENT_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/root-ca.pem") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_SERVER_PEMCERT_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-server.pem") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_SERVER_PEMKEY_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-key-server.pem") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_SERVER_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/root-ca.pem") + ) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) + + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, true) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") + .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMCERT_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem")) + .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMKEY_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.key.pem")) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem") + ) + .build(); setupSslOnlyMode(settings); @@ -1003,6 +1307,8 @@ public void testHttpsAndNodeSSLPemExtendedUsageEnabled() throws Exception { Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("TLS")); Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").length() > 0); Assert.assertTrue(rh.executeSimpleRequest("_nodes/settings?pretty").contains(clusterInfo.clustername)); - Assert.assertTrue(rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE")); + Assert.assertTrue( + rh.executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE") + ); } } diff --git a/src/test/java/org/opensearch/security/ssl/SecureSSLSettingsTest.java b/src/test/java/org/opensearch/security/ssl/SecureSSLSettingsTest.java index d60c2cfcc5..beb170a31a 100644 --- a/src/test/java/org/opensearch/security/ssl/SecureSSLSettingsTest.java +++ b/src/test/java/org/opensearch/security/ssl/SecureSSLSettingsTest.java @@ -31,9 +31,7 @@ public void testGetSecureSetting() { @Test public void testGetInsecureSetting() { - final var settings = Settings.builder() - .put(SECURITY_SSL_HTTP_PEMKEY_PASSWORD.insecurePropertyName, "test-password") - .build(); + final var settings = Settings.builder().put(SECURITY_SSL_HTTP_PEMKEY_PASSWORD.insecurePropertyName, "test-password").build(); final var password = SECURITY_SSL_HTTP_PEMKEY_PASSWORD.getSetting(settings); Assert.assertEquals("test-password", password); } @@ -43,9 +41,9 @@ public void testShouldFavorSecureOverInsecureSetting() { final var mockSecureSettings = new MockSecureSettings(); mockSecureSettings.setString(SECURITY_SSL_HTTP_PEMKEY_PASSWORD.propertyName, "secure-password"); final var settings = Settings.builder() - .setSecureSettings(mockSecureSettings) - .put(SECURITY_SSL_HTTP_PEMKEY_PASSWORD.insecurePropertyName, "insecure-password") - .build(); + .setSecureSettings(mockSecureSettings) + .put(SECURITY_SSL_HTTP_PEMKEY_PASSWORD.insecurePropertyName, "insecure-password") + .build(); final var password = SECURITY_SSL_HTTP_PEMKEY_PASSWORD.getSetting(settings); Assert.assertEquals("secure-password", password); } diff --git a/src/test/java/org/opensearch/security/ssl/SecuritySSLReloadCertsActionTests.java b/src/test/java/org/opensearch/security/ssl/SecuritySSLReloadCertsActionTests.java index e1c8ec7282..ee1cd585f7 100644 --- a/src/test/java/org/opensearch/security/ssl/SecuritySSLReloadCertsActionTests.java +++ b/src/test/java/org/opensearch/security/ssl/SecuritySSLReloadCertsActionTests.java @@ -50,20 +50,31 @@ public class SecuritySSLReloadCertsActionTests extends SingleClusterTest { private final List> NODE_CERT_DETAILS = ImmutableList.of( ImmutableMap.of( - "issuer_dn", "CN=Example Com Inc. Signing CA,OU=Example Com Inc. Signing CA,O=Example Com Inc.,DC=example,DC=com", - "subject_dn", "CN=node-1.example.com,OU=SSL,O=Test,L=Test,C=DE", - "san", "[[8, 1.2.3.4.5.5], [0, [2.5.4.3, node-1.example.com]], [2, node-1.example.com], [2, localhost], [7, 127.0.0.1]]", - "not_before", "2023-04-14T13:22:53Z", - "not_after", "2033-04-11T13:22:53Z" - )); + "issuer_dn", + "CN=Example Com Inc. Signing CA,OU=Example Com Inc. Signing CA,O=Example Com Inc.,DC=example,DC=com", + "subject_dn", + "CN=node-1.example.com,OU=SSL,O=Test,L=Test,C=DE", + "san", + "[[8, 1.2.3.4.5.5], [0, [2.5.4.3, node-1.example.com]], [2, node-1.example.com], [2, localhost], [7, 127.0.0.1]]", + "not_before", + "2023-04-14T13:22:53Z", + "not_after", + "2033-04-11T13:22:53Z" + ) + ); private final List> NEW_NODE_CERT_DETAILS = ImmutableList.of( ImmutableMap.of( - "issuer_dn", "CN=Example Com Inc. Signing CA,OU=Example Com Inc. Signing CA,O=Example Com Inc.,DC=example,DC=com", - "subject_dn", "CN=node-1.example.com,OU=SSL,O=Test,L=Test,C=DE", - "san", "[[8, 1.2.3.4.5.5], [0, [2.5.4.3, node-1.example.com]], [2, node-1.example.com], [2, localhost], [7, 127.0.0.1]]", - "not_before", "2023-04-14T13:23:00Z", - "not_after", "2033-04-11T13:23:00Z" + "issuer_dn", + "CN=Example Com Inc. Signing CA,OU=Example Com Inc. Signing CA,O=Example Com Inc.,DC=example,DC=com", + "subject_dn", + "CN=node-1.example.com,OU=SSL,O=Test,L=Test,C=DE", + "san", + "[[8, 1.2.3.4.5.5], [0, [2.5.4.3, node-1.example.com]], [2, node-1.example.com], [2, localhost], [7, 127.0.0.1]]", + "not_before", + "2023-04-14T13:23:00Z", + "not_after", + "2033-04-11T13:23:00Z" ) ); @@ -71,7 +82,7 @@ public class SecuritySSLReloadCertsActionTests extends SingleClusterTest { private String pemKeyFilePath; private final String defaultCertFilePath = "ssl/reload/node.crt.pem"; private final String defaultKeyFilePath = "ssl/reload/node.key.pem"; - private final String newCertFilePath = "ssl/reload/node-new.crt.pem"; + private final String newCertFilePath = "ssl/reload/node-new.crt.pem"; private final String newKeyFilePath = "ssl/reload/node-new.key.pem"; @Before @@ -138,8 +149,11 @@ public void testSSLReloadFail_InvalidDNAndDate() throws Exception { RestHelper.HttpResponse reloadCertsResponse = rh.executePutRequest(RELOAD_TRANSPORT_CERTS_ENDPOINT, null); Assert.assertEquals(500, reloadCertsResponse.getStatusCode()); JSONObject expectedResponse = new JSONObject(); - expectedResponse.appendField("error", "OpenSearchSecurityException[Error while initializing transport SSL layer from PEM: java.lang.Exception: " + - "New Certs do not have valid Issuer DN, Subject DN or SAN.]; nested: Exception[New Certs do not have valid Issuer DN, Subject DN or SAN.];"); + expectedResponse.appendField( + "error", + "OpenSearchSecurityException[Error while initializing transport SSL layer from PEM: java.lang.Exception: " + + "New Certs do not have valid Issuer DN, Subject DN or SAN.]; nested: Exception[New Certs do not have valid Issuer DN, Subject DN or SAN.];" + ); Assert.assertEquals(expectedResponse.toString(), reloadCertsResponse.getBody()); } @@ -261,7 +275,13 @@ private void initClusterWithTestCerts() throws Exception { * @param httpPemKeyFilePath Absolute Path to transport pem key file * @param sslCertReload Sets the ssl cert reload flag */ - private void initTestCluster(final String transportPemCertFilePath, final String transportPemKeyFilePath, final String httpPemCertFilePath, final String httpPemKeyFilePath, final boolean sslCertReload) throws Exception { + private void initTestCluster( + final String transportPemCertFilePath, + final String transportPemKeyFilePath, + final String httpPemCertFilePath, + final String httpPemKeyFilePath, + final boolean sslCertReload + ) throws Exception { final Settings settings = Settings.builder() .putList(ConfigConstants.SECURITY_AUTHCZ_ADMIN_DN, "CN=kirk,OU=client,O=client,L=Test,C=DE") .putList(ConfigConstants.SECURITY_NODES_DN, "CN=node-1.example.com,OU=SSL,O=Test,L=Test,C=DE") @@ -271,19 +291,29 @@ private void initTestCluster(final String transportPemCertFilePath, final String .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, false) .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH, transportPemCertFilePath) .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMKEY_FILEPATH, transportPemKeyFilePath) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/reload/root-ca.pem")) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/reload/root-ca.pem") + ) .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMCERT_FILEPATH, httpPemCertFilePath) // "ssl/reload/node.crt.pem" .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMKEY_FILEPATH, httpPemKeyFilePath) // "ssl/reload/node.key.pem" - .put(SSLConfigConstants.SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ssl/reload/root-ca.pem")) + .put( + SSLConfigConstants.SECURITY_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/reload/root-ca.pem") + ) .put(ConfigConstants.SECURITY_SSL_CERT_RELOAD_ENABLED, sslCertReload) .build(); final Settings initTransportClientSettings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ssl/reload/truststore.jks")) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/reload/truststore.jks") + ) .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ssl/reload/kirk-keystore.jks")) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ssl/reload/kirk-keystore.jks") + ) .build(); setup(initTransportClientSettings, new DynamicSecurityConfig(), settings, true, clusterConfiguration); diff --git a/src/test/java/org/opensearch/security/ssl/TestPrincipalExtractor.java b/src/test/java/org/opensearch/security/ssl/TestPrincipalExtractor.java index 6102327fe4..886df37b91 100644 --- a/src/test/java/org/opensearch/security/ssl/TestPrincipalExtractor.java +++ b/src/test/java/org/opensearch/security/ssl/TestPrincipalExtractor.java @@ -1,10 +1,10 @@ /* * Copyright 2017 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 @@ -12,7 +12,7 @@ * 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. - * + * */ package org.opensearch.security.ssl; @@ -25,20 +25,19 @@ public class TestPrincipalExtractor implements PrincipalExtractor { private static int transportCount = 0; private static int httpCount = 0; - - public TestPrincipalExtractor() { - } + + public TestPrincipalExtractor() {} @Override public String extractPrincipal(X509Certificate x509Certificate, Type type) { - if(type == Type.HTTP) { + if (type == Type.HTTP) { httpCount++; } - - if(type == Type.TRANSPORT) { + + if (type == Type.TRANSPORT) { transportCount++; } - + return "testdn"; } @@ -49,10 +48,10 @@ public static int getTransportCount() { public static int getHttpCount() { return httpCount; } - + public static void reset() { - httpCount = 0; - transportCount = 0; + httpCount = 0; + transportCount = 0; } } diff --git a/src/test/java/org/opensearch/security/ssl/transport/DualModeSSLHandlerTests.java b/src/test/java/org/opensearch/security/ssl/transport/DualModeSSLHandlerTests.java index 9016a8a3db..79d53f4d7b 100644 --- a/src/test/java/org/opensearch/security/ssl/transport/DualModeSSLHandlerTests.java +++ b/src/test/java/org/opensearch/security/ssl/transport/DualModeSSLHandlerTests.java @@ -76,10 +76,8 @@ public void testValidTLSMessage() throws Exception { handler.decode(ctx, buffer, null); // ensure ssl handler is added Mockito.verify(ctx, Mockito.times(1)).pipeline(); - Mockito.verify(pipeline, Mockito.times(1)) - .addAfter("port_unification_handler", "ssl_server", sslHandler); - Mockito.verify(pipeline, - Mockito.times(1)).remove(handler); + Mockito.verify(pipeline, Mockito.times(1)).addAfter("port_unification_handler", "ssl_server", sslHandler); + Mockito.verify(pipeline, Mockito.times(1)).remove(handler); } @Test @@ -95,10 +93,8 @@ public void testNonTLSMessage() throws Exception { handler.decode(ctx, buffer, null); // ensure ssl handler is added Mockito.verify(ctx, Mockito.times(1)).pipeline(); - Mockito.verify(pipeline, Mockito.times(0)) - .addAfter("port_unification_handler", "ssl_server", sslHandler); - Mockito.verify(pipeline, - Mockito.times(1)).remove(handler); + Mockito.verify(pipeline, Mockito.times(0)).addAfter("port_unification_handler", "ssl_server", sslHandler); + Mockito.verify(pipeline, Mockito.times(1)).remove(handler); } @Test diff --git a/src/test/java/org/opensearch/security/ssl/util/CertFromFileTests.java b/src/test/java/org/opensearch/security/ssl/util/CertFromFileTests.java index 383c60147c..097d65472c 100644 --- a/src/test/java/org/opensearch/security/ssl/util/CertFromFileTests.java +++ b/src/test/java/org/opensearch/security/ssl/util/CertFromFileTests.java @@ -22,60 +22,65 @@ public class CertFromFileTests { @Test public void testLoadSameCertForClientServerUsage() throws Exception { - CertFileProps certProps = new CertFileProps( - FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem").toString(), - FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.key.pem").toString(), - FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem").toString(), - null); - - CertFromFile cert = new CertFromFile(certProps); - - Assert.assertEquals(1, cert.getCerts().length); - Assert.assertNotNull(cert.getClientPemCert()); - Assert.assertNotNull(cert.getClientPemKey()); - Assert.assertNotNull(cert.getClientTrustedCas()); + CertFileProps certProps = new CertFileProps( + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem").toString(), + FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.key.pem").toString(), + FileHelper.getAbsoluteFilePathFromClassPath("ssl/root-ca.pem").toString(), + null + ); + + CertFromFile cert = new CertFromFile(certProps); + + Assert.assertEquals(1, cert.getCerts().length); + Assert.assertNotNull(cert.getClientPemCert()); + Assert.assertNotNull(cert.getClientPemKey()); + Assert.assertNotNull(cert.getClientTrustedCas()); } - @Test - public void testLoadCertWithoutCA() throws Exception { + @Test + public void testLoadCertWithoutCA() throws Exception { CertFileProps certProps = new CertFileProps( FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.crt.pem").toString(), FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.key.pem").toString(), null, - null); + null + ); CertFromFile cert = new CertFromFile(certProps); Assert.assertNull(cert.getClientTrustedCas()); } - @Test(expected= FileNotFoundException.class) + @Test(expected = FileNotFoundException.class) public void testLoadCertWithMissingFiles() throws Exception { CertFileProps certProps = new CertFileProps( "missing.pem", FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0.key.pem").toString(), null, - null); + null + ); CertFromFile cert = new CertFromFile(certProps); } @Test public void testLoadDifferentCertsForClientServerUsage() throws Exception { - CertFileProps clientCertProps = new CertFileProps( - FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-client.pem").toString(), - FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-key-client.pem").toString(), - FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/root-ca.pem").toString(), - null); - CertFileProps servertCertProps = new CertFileProps( - FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-server.pem").toString(), - FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-key-server.pem").toString(), - FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/root-ca.pem").toString(), - null); - - CertFromFile cert = new CertFromFile(clientCertProps, servertCertProps); - - Assert.assertEquals(2, cert.getCerts().length); + CertFileProps clientCertProps = new CertFileProps( + FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-client.pem").toString(), + FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-key-client.pem").toString(), + FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/root-ca.pem").toString(), + null + ); + CertFileProps servertCertProps = new CertFileProps( + FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-server.pem").toString(), + FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-key-server.pem").toString(), + FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/root-ca.pem").toString(), + null + ); + + CertFromFile cert = new CertFromFile(clientCertProps, servertCertProps); + + Assert.assertEquals(2, cert.getCerts().length); } } diff --git a/src/test/java/org/opensearch/security/ssl/util/CertFromKeystoreTests.java b/src/test/java/org/opensearch/security/ssl/util/CertFromKeystoreTests.java index 0a2cac18b5..fb97fdcfd1 100644 --- a/src/test/java/org/opensearch/security/ssl/util/CertFromKeystoreTests.java +++ b/src/test/java/org/opensearch/security/ssl/util/CertFromKeystoreTests.java @@ -25,7 +25,8 @@ public class CertFromKeystoreTests { @Test - public void testLoadSameCertForClientServerUsage() throws UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException { + public void testLoadSameCertForClientServerUsage() throws UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, + KeyStoreException, IOException { KeystoreProps props = new KeystoreProps( FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks").toString(), "JKS", @@ -43,7 +44,8 @@ public void testLoadSameCertForClientServerUsage() throws UnrecoverableKeyExcept } @Test - public void testLoadSameCertWithoutAlias() throws UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException { + public void testLoadSameCertWithoutAlias() throws UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, + KeyStoreException, IOException { KeystoreProps props = new KeystoreProps( FileHelper.getAbsoluteFilePathFromClassPath("ssl/node-0-keystore.jks").toString(), "JKS", @@ -58,7 +60,8 @@ public void testLoadSameCertWithoutAlias() throws UnrecoverableKeyException, Cer } @Test - public void testLoadDifferentCertsForClientServerUsage() throws UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException { + public void testLoadDifferentCertsForClientServerUsage() throws UnrecoverableKeyException, CertificateException, + NoSuchAlgorithmException, KeyStoreException, IOException { KeystoreProps props = new KeystoreProps( FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/node-0-keystore.jks").toString(), "JKS", diff --git a/src/test/java/org/opensearch/security/ssl/util/CertFromTruststoreTests.java b/src/test/java/org/opensearch/security/ssl/util/CertFromTruststoreTests.java index ed0f0ac252..e4ab860759 100644 --- a/src/test/java/org/opensearch/security/ssl/util/CertFromTruststoreTests.java +++ b/src/test/java/org/opensearch/security/ssl/util/CertFromTruststoreTests.java @@ -24,7 +24,8 @@ public class CertFromTruststoreTests { @Test - public void testLoadSameCertForClientServerUsage() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException { + public void testLoadSameCertForClientServerUsage() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, + IOException { KeystoreProps props = new KeystoreProps( FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/truststore.jks").toString(), "JKS", @@ -50,7 +51,8 @@ public void testLoadSameCertWithoutAlias() throws CertificateException, NoSuchAl Assert.assertEquals(1, cert.getClientTrustedCerts().length); } - public void testLoadDifferentCertsForClientServerUsage() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException { + public void testLoadDifferentCertsForClientServerUsage() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, + IOException { KeystoreProps props = new KeystoreProps( FileHelper.getAbsoluteFilePathFromClassPath("ssl/extended_key_usage/truststore.jks").toString(), "JKS", diff --git a/src/test/java/org/opensearch/security/ssl/util/SSLConnectionTestUtilTests.java b/src/test/java/org/opensearch/security/ssl/util/SSLConnectionTestUtilTests.java index 1400b0d401..98ee95a90b 100644 --- a/src/test/java/org/opensearch/security/ssl/util/SSLConnectionTestUtilTests.java +++ b/src/test/java/org/opensearch/security/ssl/util/SSLConnectionTestUtilTests.java @@ -43,16 +43,22 @@ public void setup() { public void testConnectionSSLAvailable() throws Exception { Mockito.doNothing().when(outputStreamWriter).write(Mockito.anyString()); Mockito.when(inputStreamReader.read()) - .thenReturn((int)'D') - .thenReturn((int)'U') - .thenReturn((int)'A') - .thenReturn((int)'L') - .thenReturn((int)'S') - .thenReturn((int)'M') + .thenReturn((int) 'D') + .thenReturn((int) 'U') + .thenReturn((int) 'A') + .thenReturn((int) 'L') + .thenReturn((int) 'S') + .thenReturn((int) 'M') .thenReturn(-1); Mockito.doNothing().when(socket).close(); - SSLConnectionTestUtil connectionTestUtil = new SSLConnectionTestUtil("127.0.0.1", 443, socket, outputStreamWriter, inputStreamReader); + SSLConnectionTestUtil connectionTestUtil = new SSLConnectionTestUtil( + "127.0.0.1", + 443, + socket, + outputStreamWriter, + inputStreamReader + ); SSLConnectionTestResult result = connectionTestUtil.testConnection(); verifyClientHelloSend(); @@ -66,7 +72,13 @@ public void testConnectionSSLNotAvailable() throws Exception { setupMocksForOpenSearchPingSuccess(); Mockito.doNothing().when(socket).close(); - SSLConnectionTestUtil connectionTestUtil = new SSLConnectionTestUtil("127.0.0.1", 443, socket, outputStreamWriter, inputStreamReader); + SSLConnectionTestUtil connectionTestUtil = new SSLConnectionTestUtil( + "127.0.0.1", + 443, + socket, + outputStreamWriter, + inputStreamReader + ); SSLConnectionTestResult result = connectionTestUtil.testConnection(); verifyClientHelloSend(); @@ -77,13 +89,17 @@ public void testConnectionSSLNotAvailable() throws Exception { @Test public void testConnectionSSLNotAvailableIOException() throws Exception { - Mockito.doThrow(new IOException("Error while writing bytes to output stream")) - .when(outputStreamWriter) - .write(Mockito.anyString()); + Mockito.doThrow(new IOException("Error while writing bytes to output stream")).when(outputStreamWriter).write(Mockito.anyString()); setupMocksForOpenSearchPingSuccess(); Mockito.doNothing().when(socket).close(); - SSLConnectionTestUtil connectionTestUtil = new SSLConnectionTestUtil("127.0.0.1", 443, socket, outputStreamWriter, inputStreamReader); + SSLConnectionTestUtil connectionTestUtil = new SSLConnectionTestUtil( + "127.0.0.1", + 443, + socket, + outputStreamWriter, + inputStreamReader + ); SSLConnectionTestResult result = connectionTestUtil.testConnection(); verifyClientHelloSend(); @@ -99,11 +115,16 @@ public void testConnectionOpenSearchPingFailed() throws Exception { Mockito.when(socket.getOutputStream()).thenReturn(outputStream); Mockito.when(socket.getInputStream()).thenReturn(inputStream); Mockito.doNothing().when(outputStream).write(Mockito.any(byte[].class)); - Mockito.when(inputStream.read()) - .thenReturn(-1); + Mockito.when(inputStream.read()).thenReturn(-1); Mockito.doNothing().when(socket).close(); - SSLConnectionTestUtil connectionTestUtil = new SSLConnectionTestUtil("127.0.0.1", 443, socket, outputStreamWriter, inputStreamReader); + SSLConnectionTestUtil connectionTestUtil = new SSLConnectionTestUtil( + "127.0.0.1", + 443, + socket, + outputStreamWriter, + inputStreamReader + ); SSLConnectionTestResult result = connectionTestUtil.testConnection(); verifyClientHelloSend(); @@ -119,15 +140,21 @@ public void testConnectionOpenSearchPingFailedInvalidReply() throws Exception { Mockito.when(socket.getInputStream()).thenReturn(inputStream); Mockito.doNothing().when(outputStream).write(Mockito.any(byte[].class)); Mockito.when(inputStream.read()) - .thenReturn((int)'E') - .thenReturn((int)'E') + .thenReturn((int) 'E') + .thenReturn((int) 'E') .thenReturn(0xFF) .thenReturn(0xFF) .thenReturn(0xFF) .thenReturn(0xFF); Mockito.doNothing().when(socket).close(); - SSLConnectionTestUtil connectionTestUtil = new SSLConnectionTestUtil("127.0.0.1", 443, socket, outputStreamWriter, inputStreamReader); + SSLConnectionTestUtil connectionTestUtil = new SSLConnectionTestUtil( + "127.0.0.1", + 443, + socket, + outputStreamWriter, + inputStreamReader + ); SSLConnectionTestResult result = connectionTestUtil.testConnection(); verifyClientHelloSend(); @@ -144,7 +171,13 @@ public void testConnectionOpenSearchPingFailedIOException() throws Exception { Mockito.doThrow(new IOException("Error while writing bytes to output stream")).when(outputStream).write(Mockito.any(byte[].class)); Mockito.doNothing().when(socket).close(); - SSLConnectionTestUtil connectionTestUtil = new SSLConnectionTestUtil("127.0.0.1", 443, socket, outputStreamWriter, inputStreamReader); + SSLConnectionTestUtil connectionTestUtil = new SSLConnectionTestUtil( + "127.0.0.1", + 443, + socket, + outputStreamWriter, + inputStreamReader + ); SSLConnectionTestResult result = connectionTestUtil.testConnection(); verifyClientHelloSend(); @@ -156,9 +189,7 @@ public void testConnectionOpenSearchPingFailedIOException() throws Exception { private void verifyClientHelloSend() throws IOException { ArgumentCaptor clientHelloMsgArgCaptor = ArgumentCaptor.forClass(String.class); - Mockito.verify(outputStreamWriter, - Mockito.times(1)) - .write(clientHelloMsgArgCaptor.capture()); + Mockito.verify(outputStreamWriter, Mockito.times(1)).write(clientHelloMsgArgCaptor.capture()); String msgWritten = clientHelloMsgArgCaptor.getValue(); String expectedMsg = "DUALCM"; Assert.assertEquals("Unexpected Dual SSL Client Hello message written to socket", expectedMsg, msgWritten); @@ -166,20 +197,17 @@ private void verifyClientHelloSend() throws IOException { private void verifyOpenSearchPingSend() throws IOException { ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(byte[].class); - Mockito.verify(outputStream, - Mockito.times(1)) - .write(argumentCaptor.capture()); + Mockito.verify(outputStream, Mockito.times(1)).write(argumentCaptor.capture()); byte[] bytesWritten = argumentCaptor.getValue(); - byte[] expectedBytes = new byte[]{'E','S',(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF}; - for(int i = 0; i < bytesWritten.length; i++) { + byte[] expectedBytes = new byte[] { 'E', 'S', (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF }; + for (int i = 0; i < bytesWritten.length; i++) { Assert.assertEquals("Unexpected OpenSearch Ping bytes written to socket", expectedBytes[i], bytesWritten[i]); } } private void setupMocksForClientHelloFailure() throws IOException { Mockito.doNothing().when(outputStreamWriter).write(Mockito.anyString()); - Mockito.when(inputStreamReader.read()) - .thenReturn(-1); + Mockito.when(inputStreamReader.read()).thenReturn(-1); } private void setupMocksForOpenSearchPingSuccess() throws IOException { @@ -187,8 +215,8 @@ private void setupMocksForOpenSearchPingSuccess() throws IOException { Mockito.when(socket.getInputStream()).thenReturn(inputStream); Mockito.doNothing().when(outputStream).write(Mockito.any(byte[].class)); Mockito.when(inputStream.read()) - .thenReturn((int)'E') - .thenReturn((int)'S') + .thenReturn((int) 'E') + .thenReturn((int) 'S') .thenReturn(0xFF) .thenReturn(0xFF) .thenReturn(0xFF) diff --git a/src/test/java/org/opensearch/security/ssl/util/TLSUtilTests.java b/src/test/java/org/opensearch/security/ssl/util/TLSUtilTests.java index 83ef5668ac..c77f05b39f 100644 --- a/src/test/java/org/opensearch/security/ssl/util/TLSUtilTests.java +++ b/src/test/java/org/opensearch/security/ssl/util/TLSUtilTests.java @@ -49,7 +49,7 @@ public void testSSLUtilWrongTLSVersion() { for (int byteToSend = 20; byteToSend <= 24; byteToSend++) { ByteBuf buffer = ALLOCATOR.buffer(5); buffer.writeByte(byteToSend); - //setting invalid TLS version 100 + // setting invalid TLS version 100 buffer.writeByte(100); buffer.writeByte(TLS_MINOR_VERSION); buffer.writeByte(100); @@ -66,7 +66,7 @@ public void testSSLUtilInvalidContentLength() { buffer.writeByte(byteToSend); buffer.writeByte(TLS_MAJOR_VERSION); buffer.writeByte(TLS_MINOR_VERSION); - //setting content length as 0 + // setting content length as 0 buffer.writeShort(0); Assert.assertFalse(TLSUtil.isTLS(buffer)); } diff --git a/src/test/java/org/opensearch/security/support/GuardedSearchOperationWrapperTest.java b/src/test/java/org/opensearch/security/support/GuardedSearchOperationWrapperTest.java index 982d1108ad..67090e9b3d 100644 --- a/src/test/java/org/opensearch/security/support/GuardedSearchOperationWrapperTest.java +++ b/src/test/java/org/opensearch/security/support/GuardedSearchOperationWrapperTest.java @@ -26,7 +26,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; - public class GuardedSearchOperationWrapperTest { @Test @@ -115,26 +114,21 @@ public void onQueryPhase(SearchContext context, long tookInNanos) { private static class DefaultingGuardedSearchOperationWrapper implements GuardedSearchOperationWrapper { @Override - public void onNewReaderContext(ReaderContext readerContext) { - } + public void onNewReaderContext(ReaderContext readerContext) {} @Override - public void onNewScrollContext(ReaderContext readerContext) { - } + public void onNewScrollContext(ReaderContext readerContext) {} @Override - public void onPreQueryPhase(SearchContext context) { - } + public void onPreQueryPhase(SearchContext context) {} @Override - public void onQueryPhase(SearchContext searchContext, long tookInNanos) { - } + public void onQueryPhase(SearchContext searchContext, long tookInNanos) {} @Override - public void validateReaderContext(ReaderContext readerContext, TransportRequest transportRequest) { - } + public void validateReaderContext(ReaderContext readerContext, TransportRequest transportRequest) {} - void exerciseAllMethods(){ + void exerciseAllMethods() { final SearchOperationListener sol = this.toListener(); sol.onNewReaderContext(mock(ReaderContext.class)); sol.onNewScrollContext(mock(ReaderContext.class)); diff --git a/src/test/java/org/opensearch/security/support/SecurityUtilsTest.java b/src/test/java/org/opensearch/security/support/SecurityUtilsTest.java index ed6a471421..f0645d4958 100644 --- a/src/test/java/org/opensearch/security/support/SecurityUtilsTest.java +++ b/src/test/java/org/opensearch/security/support/SecurityUtilsTest.java @@ -60,14 +60,14 @@ private void checkKeysWithPredicate(Collection keys, String predicateNam final String prefixWithKeyName = "${" + predicateName + "." + envKeyName; final String baseKeyName = prefixWithKeyName + "}"; - assertThat("Testing " + envKeyName + ", " + baseKeyName, - predicate.test(baseKeyName), - equalTo(true)); + assertThat("Testing " + envKeyName + ", " + baseKeyName, predicate.test(baseKeyName), equalTo(true)); final String baseKeyNameWithDefault = prefixWithKeyName + ":-tTt}"; - assertThat("Testing " + envKeyName + " with defaultValue, " + baseKeyNameWithDefault, + assertThat( + "Testing " + envKeyName + " with defaultValue, " + baseKeyNameWithDefault, predicate.test(baseKeyNameWithDefault), - equalTo(true)); + equalTo(true) + ); }); } } diff --git a/src/test/java/org/opensearch/security/system_indices/SystemIndicesTests.java b/src/test/java/org/opensearch/security/system_indices/SystemIndicesTests.java index 273214b0fe..e298ae45c7 100644 --- a/src/test/java/org/opensearch/security/system_indices/SystemIndicesTests.java +++ b/src/test/java/org/opensearch/security/system_indices/SystemIndicesTests.java @@ -53,46 +53,51 @@ public class SystemIndicesTests extends SingleClusterTest { private static final String matchAllQuery = "{\n\"query\": {\"match_all\": {}}}"; private static final String allAccessUser = "admin_all_access"; private static final Header allAccessUserHeader = encodeBasicHeader(allAccessUser, allAccessUser); - private static final String generalErrorMessage = String.format("no permissions for [] and User [name=%s, backend_roles=[], requestedTenant=null]", allAccessUser); + private static final String generalErrorMessage = String.format( + "no permissions for [] and User [name=%s, backend_roles=[], requestedTenant=null]", + allAccessUser + ); private void setupSystemIndicesDisabledWithSsl() throws Exception { Settings systemIndexSettings = Settings.builder() - .put(ConfigConstants.SECURITY_SYSTEM_INDICES_ENABLED_KEY, false) - .putList(ConfigConstants.SECURITY_SYSTEM_INDICES_KEY, listOfIndexesToTest) - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .put("path.repo", repositoryPath.getRoot().getAbsolutePath()) - .build(); - setup(Settings.EMPTY, - new DynamicSecurityConfig() - .setConfig("config_system_indices.yml") - .setSecurityRoles("roles_system_indices.yml") - .setSecurityInternalUsers("internal_users_system_indices.yml") - .setSecurityRolesMapping("roles_mapping_system_indices.yml"), - systemIndexSettings, - true); + .put(ConfigConstants.SECURITY_SYSTEM_INDICES_ENABLED_KEY, false) + .putList(ConfigConstants.SECURITY_SYSTEM_INDICES_KEY, listOfIndexesToTest) + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .put("path.repo", repositoryPath.getRoot().getAbsolutePath()) + .build(); + setup( + Settings.EMPTY, + new DynamicSecurityConfig().setConfig("config_system_indices.yml") + .setSecurityRoles("roles_system_indices.yml") + .setSecurityInternalUsers("internal_users_system_indices.yml") + .setSecurityRolesMapping("roles_mapping_system_indices.yml"), + systemIndexSettings, + true + ); } private void setupSystemIndicesEnabledWithSsl() throws Exception { Settings systemIndexSettings = Settings.builder() - .put(ConfigConstants.SECURITY_SYSTEM_INDICES_ENABLED_KEY, true) - .putList(ConfigConstants.SECURITY_SYSTEM_INDICES_KEY, listOfIndexesToTest) - .put("plugins.security.ssl.http.enabled",true) - .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) - .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) - .put("path.repo", repositoryPath.getRoot().getAbsolutePath()) - .build(); - setup(Settings.EMPTY, - new DynamicSecurityConfig() - .setConfig("config_system_indices.yml") - .setSecurityRoles("roles_system_indices.yml") - .setSecurityInternalUsers("internal_users_system_indices.yml") - .setSecurityRolesMapping("roles_mapping_system_indices.yml"), - systemIndexSettings, - true); + .put(ConfigConstants.SECURITY_SYSTEM_INDICES_ENABLED_KEY, true) + .putList(ConfigConstants.SECURITY_SYSTEM_INDICES_KEY, listOfIndexesToTest) + .put("plugins.security.ssl.http.enabled", true) + .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) + .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) + .put("path.repo", repositoryPath.getRoot().getAbsolutePath()) + .build(); + setup( + Settings.EMPTY, + new DynamicSecurityConfig().setConfig("config_system_indices.yml") + .setSecurityRoles("roles_system_indices.yml") + .setSecurityInternalUsers("internal_users_system_indices.yml") + .setSecurityRolesMapping("roles_mapping_system_indices.yml"), + systemIndexSettings, + true + ); } /** @@ -104,7 +109,11 @@ private void createTestIndicesAndDocs() { try (Client tc = getClient()) { for (String index : listOfIndexesToTest) { tc.admin().indices().create(new CreateIndexRequest(index)).actionGet(); - tc.index(new IndexRequest(index).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).id("document1").source("{ \"foo\": \"bar\" }", XContentType.JSON)).actionGet(); + tc.index( + new IndexRequest(index).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .id("document1") + .source("{ \"foo\": \"bar\" }", XContentType.JSON) + ).actionGet(); } } } @@ -112,8 +121,19 @@ private void createTestIndicesAndDocs() { private void createSnapshots() { try (Client tc = getClient()) { for (String index : listOfIndexesToTest) { - tc.admin().cluster().putRepository(new PutRepositoryRequest(index).type("fs").settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/" + index))).actionGet(); - tc.admin().cluster().createSnapshot(new CreateSnapshotRequest(index, index + "_1").indices(index).includeGlobalState(true).waitForCompletion(true)).actionGet(); + tc.admin() + .cluster() + .putRepository( + new PutRepositoryRequest(index).type("fs") + .settings(Settings.builder().put("location", repositoryPath.getRoot().getAbsolutePath() + "/" + index)) + ) + .actionGet(); + tc.admin() + .cluster() + .createSnapshot( + new CreateSnapshotRequest(index, index + "_1").indices(index).includeGlobalState(true).waitForCompletion(true) + ) + .actionGet(); } } } @@ -140,7 +160,8 @@ private RestHelper sslRestHelper() { private void validateSearchResponse(RestHelper.HttpResponse response, int expectecdHits) throws IOException { assertEquals(RestStatus.OK.getStatus(), response.getStatusCode()); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); SearchResponse searchResponse = SearchResponse.fromXContent(xcp); assertEquals(RestStatus.OK, searchResponse.status()); assertEquals(expectecdHits, searchResponse.getHits().getHits().length); @@ -154,12 +175,12 @@ public void testSearchAsSuperAdmin() throws Exception { createTestIndicesAndDocs(); RestHelper restHelper = keyStoreRestHelper(); - //search system indices + // search system indices for (String index : listOfIndexesToTest) { validateSearchResponse(restHelper.executePostRequest(index + "/_search", matchAllQuery), 1); } - //search all indices + // search all indices RestHelper.HttpResponse response = restHelper.executePostRequest("/_search", matchAllQuery); assertEquals(RestStatus.OK.getStatus(), response.getStatusCode()); } @@ -170,12 +191,12 @@ public void testSearchAsAdmin() throws Exception { createTestIndicesAndDocs(); RestHelper restHelper = sslRestHelper(); - //search system indices + // search system indices for (String index : listOfIndexesToTest) { validateSearchResponse(restHelper.executePostRequest(index + "/_search", matchAllQuery, allAccessUserHeader), 1); } - //search all indices + // search all indices RestHelper.HttpResponse response = restHelper.executePostRequest("/_search", matchAllQuery, allAccessUserHeader); assertEquals(RestStatus.OK.getStatus(), response.getStatusCode()); } @@ -186,17 +207,16 @@ public void testSearchWithSystemIndicesAsSuperAdmin() throws Exception { createTestIndicesAndDocs(); RestHelper restHelper = keyStoreRestHelper(); - //search system indices + // search system indices for (String index : listOfIndexesToTest) { validateSearchResponse(restHelper.executePostRequest(index + "/_search", matchAllQuery), 1); } - //search all indices + // search all indices RestHelper.HttpResponse response = restHelper.executePostRequest("/_search", matchAllQuery); assertEquals(RestStatus.OK.getStatus(), response.getStatusCode()); } - @Test public void testSearchWithSystemIndicesAsAdmin() throws Exception { setupSystemIndicesEnabledWithSsl(); @@ -207,10 +227,11 @@ public void testSearchWithSystemIndicesAsAdmin() throws Exception { validateSearchResponse(restHelper.executePostRequest(index + "/_search", matchAllQuery, allAccessUserHeader), 0); } - //search all indices + // search all indices RestHelper.HttpResponse response = restHelper.executePostRequest("/_search", matchAllQuery, allAccessUserHeader); assertEquals(RestStatus.OK.getStatus(), response.getStatusCode()); - XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); + XContentParser xcp = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, response.getBody()); SearchResponse searchResponse = SearchResponse.fromXContent(xcp); assertEquals(RestStatus.OK, searchResponse.status()); assertEquals(0, searchResponse.getHits().getHits().length); @@ -227,7 +248,7 @@ public void testDelete() throws Exception { RestHelper keyStoreRestHelper = keyStoreRestHelper(); RestHelper sslRestHelper = sslRestHelper(); - //as super-admin + // as super-admin for (String index : listOfIndexesToTest) { RestHelper.HttpResponse responseDoc = keyStoreRestHelper.executeDeleteRequest(index + "/_doc/document1"); assertEquals(RestStatus.OK.getStatus(), responseDoc.getStatusCode()); @@ -237,7 +258,7 @@ public void testDelete() throws Exception { } createTestIndicesAndDocs(); - //as admin + // as admin for (String index : listOfIndexesToTest) { RestHelper.HttpResponse responseDoc = sslRestHelper.executeDeleteRequest(index + "/_doc/document1", allAccessUserHeader); assertEquals(RestStatus.OK.getStatus(), responseDoc.getStatusCode()); @@ -254,7 +275,7 @@ public void testDeleteWithSystemIndices() throws Exception { RestHelper keyStoreRestHelper = keyStoreRestHelper(); RestHelper sslRestHelper = sslRestHelper(); - //as super-admin + // as super-admin for (String index : listOfIndexesToTest) { RestHelper.HttpResponse responseDoc = keyStoreRestHelper.executeDeleteRequest(index + "/_doc/document1"); assertEquals(RestStatus.OK.getStatus(), responseDoc.getStatusCode()); @@ -264,7 +285,7 @@ public void testDeleteWithSystemIndices() throws Exception { } createTestIndicesAndDocs(); - //as admin + // as admin for (String index : listOfIndexesToTest) { RestHelper.HttpResponse responseDoc = sslRestHelper.executeDeleteRequest(index + "/_doc/document1", allAccessUserHeader); assertEquals(RestStatus.FORBIDDEN.getStatus(), responseDoc.getStatusCode()); @@ -285,18 +306,18 @@ public void testCloseOpen() throws Exception { RestHelper keyStoreRestHelper = keyStoreRestHelper(); RestHelper sslRestHelper = sslRestHelper(); - //as super-admin + // as super-admin for (String index : listOfIndexesToTest) { - RestHelper.HttpResponse responseClose = keyStoreRestHelper.executePostRequest(index + "/_close",""); + RestHelper.HttpResponse responseClose = keyStoreRestHelper.executePostRequest(index + "/_close", ""); assertEquals(RestStatus.OK.getStatus(), responseClose.getStatusCode()); RestHelper.HttpResponse responseOpen = keyStoreRestHelper.executePostRequest(index + "/_open", ""); assertEquals(RestStatus.OK.getStatus(), responseOpen.getStatusCode()); } - //as admin + // as admin for (String index : listOfIndexesToTest) { - RestHelper.HttpResponse responseClose = sslRestHelper.executePostRequest(index + "/_close","", allAccessUserHeader); + RestHelper.HttpResponse responseClose = sslRestHelper.executePostRequest(index + "/_close", "", allAccessUserHeader); assertEquals(RestStatus.OK.getStatus(), responseClose.getStatusCode()); RestHelper.HttpResponse responseOpen = sslRestHelper.executePostRequest(index + "/_open", "", allAccessUserHeader); @@ -311,18 +332,18 @@ public void testCloseOpenWithSystemIndices() throws Exception { RestHelper keyStoreRestHelper = keyStoreRestHelper(); RestHelper sslRestHelper = sslRestHelper(); - //as super-admin + // as super-admin for (String index : listOfIndexesToTest) { - RestHelper.HttpResponse responseClose = keyStoreRestHelper.executePostRequest(index + "/_close",""); + RestHelper.HttpResponse responseClose = keyStoreRestHelper.executePostRequest(index + "/_close", ""); assertEquals(RestStatus.OK.getStatus(), responseClose.getStatusCode()); RestHelper.HttpResponse responseOpen = keyStoreRestHelper.executePostRequest(index + "/_open", ""); assertEquals(RestStatus.OK.getStatus(), responseOpen.getStatusCode()); } - //as admin + // as admin for (String index : listOfIndexesToTest) { - RestHelper.HttpResponse responseClose = sslRestHelper.executePostRequest(index + "/_close","", allAccessUserHeader); + RestHelper.HttpResponse responseClose = sslRestHelper.executePostRequest(index + "/_close", "", allAccessUserHeader); assertEquals(RestStatus.FORBIDDEN.getStatus(), responseClose.getStatusCode()); RestHelper.HttpResponse responseOpen = sslRestHelper.executePostRequest(index + "/_open", "", allAccessUserHeader); @@ -341,18 +362,14 @@ public void testUpdateIndexSettings() throws Exception { RestHelper keyStoreRestHelper = keyStoreRestHelper(); RestHelper sslRestHelper = sslRestHelper(); - String indexSettings = "{\n" + - " \"index\" : {\n" + - " \"refresh_interval\" : null\n" + - " }\n" + - "}"; + String indexSettings = "{\n" + " \"index\" : {\n" + " \"refresh_interval\" : null\n" + " }\n" + "}"; - //as super-admin + // as super-admin for (String index : listOfIndexesToTest) { RestHelper.HttpResponse response = keyStoreRestHelper.executePutRequest(index + "/_settings", indexSettings); assertEquals(RestStatus.OK.getStatus(), response.getStatusCode()); } - //as admin + // as admin for (String index : listOfIndexesToTest) { RestHelper.HttpResponse response = sslRestHelper.executePutRequest(index + "/_settings", indexSettings, allAccessUserHeader); assertEquals(RestStatus.OK.getStatus(), response.getStatusCode()); @@ -366,23 +383,20 @@ public void testUpdateIndexSettingsWithSystemIndices() throws Exception { RestHelper keyStoreRestHelper = keyStoreRestHelper(); RestHelper sslRestHelper = sslRestHelper(); - String indexSettings = "{\n" + - " \"index\" : {\n" + - " \"refresh_interval\" : null\n" + - " }\n" + - "}"; + String indexSettings = "{\n" + " \"index\" : {\n" + " \"refresh_interval\" : null\n" + " }\n" + "}"; - //as super-admin + // as super-admin for (String index : listOfIndexesToTest) { RestHelper.HttpResponse response = keyStoreRestHelper.executePutRequest(index + "/_settings", indexSettings); assertEquals(RestStatus.OK.getStatus(), response.getStatusCode()); } - //as admin + // as admin for (String index : listOfIndexesToTest) { RestHelper.HttpResponse response = sslRestHelper.executePutRequest(index + "/_settings", indexSettings, allAccessUserHeader); assertEquals(RestStatus.FORBIDDEN.getStatus(), response.getStatusCode()); } } + /*************************************************************************************************************************** * Index mappings. indices:admin/mapping/put ************************************************************************************************************************** */ @@ -394,18 +408,15 @@ public void testUpdateMappings() throws Exception { RestHelper keyStoreRestHelper = keyStoreRestHelper(); RestHelper sslRestHelper = sslRestHelper(); - String newMappings = "{\"properties\": {" + - "\"user_name\": {" + - "\"type\": \"text\"" + - "}}}"; + String newMappings = "{\"properties\": {" + "\"user_name\": {" + "\"type\": \"text\"" + "}}}"; - //as super-admin + // as super-admin for (String index : listOfIndexesToTest) { RestHelper.HttpResponse response = keyStoreRestHelper.executePutRequest(index + "/_mapping", newMappings); assertEquals(RestStatus.OK.getStatus(), response.getStatusCode()); } - //as admin + // as admin for (String index : listOfIndexesToTest) { RestHelper.HttpResponse response = sslRestHelper.executePutRequest(index + "/_mapping", newMappings, allAccessUserHeader); assertEquals(RestStatus.OK.getStatus(), response.getStatusCode()); @@ -419,18 +430,15 @@ public void testUpdateMappingsWithSystemIndices() throws Exception { RestHelper keyStoreRestHelper = keyStoreRestHelper(); RestHelper sslRestHelper = sslRestHelper(); - String newMappings = "{\"properties\": {" + - "\"user_name\": {" + - "\"type\": \"text\"" + - "}}}"; + String newMappings = "{\"properties\": {" + "\"user_name\": {" + "\"type\": \"text\"" + "}}}"; - //as super-admin + // as super-admin for (String index : listOfIndexesToTest) { RestHelper.HttpResponse response = keyStoreRestHelper.executePutRequest(index + "/_mapping", newMappings); assertEquals(RestStatus.OK.getStatus(), response.getStatusCode()); } - //as admin + // as admin for (String index : listOfIndexesToTest) { RestHelper.HttpResponse response = sslRestHelper.executePutRequest(index + "/_mapping", newMappings, allAccessUserHeader); assertEquals(RestStatus.FORBIDDEN.getStatus(), response.getStatusCode()); @@ -448,16 +456,16 @@ public void testCreate() throws Exception { RestHelper keyStoreRestHelper = keyStoreRestHelper(); RestHelper sslRestHelper = sslRestHelper(); - String indexSettings = "{\n" + - " \"settings\" : {\n" + - " \"index\" : {\n" + - " \"number_of_shards\" : 3, \n" + - " \"number_of_replicas\" : 2 \n" + - " }\n" + - " }\n" + - "}"; + String indexSettings = "{\n" + + " \"settings\" : {\n" + + " \"index\" : {\n" + + " \"number_of_shards\" : 3, \n" + + " \"number_of_replicas\" : 2 \n" + + " }\n" + + " }\n" + + "}"; - //as super-admin + // as super-admin for (String index : listOfIndexesToTest) { RestHelper.HttpResponse responseIndex = keyStoreRestHelper.executePutRequest(index, indexSettings); assertEquals(RestStatus.OK.getStatus(), responseIndex.getStatusCode()); @@ -470,7 +478,7 @@ public void testCreate() throws Exception { keyStoreRestHelper.executeDeleteRequest(index); } - //as admin + // as admin for (String index : listOfIndexesToTest) { RestHelper.HttpResponse responseIndex = sslRestHelper.executePutRequest(index, indexSettings, allAccessUserHeader); assertEquals(RestStatus.OK.getStatus(), responseIndex.getStatusCode()); @@ -486,16 +494,16 @@ public void testCreateWithSystemIndices() throws Exception { RestHelper keyStoreRestHelper = keyStoreRestHelper(); RestHelper sslRestHelper = sslRestHelper(); - String indexSettings = "{\n" + - " \"settings\" : {\n" + - " \"index\" : {\n" + - " \"number_of_shards\" : 3, \n" + - " \"number_of_replicas\" : 2 \n" + - " }\n" + - " }\n" + - "}"; + String indexSettings = "{\n" + + " \"settings\" : {\n" + + " \"index\" : {\n" + + " \"number_of_shards\" : 3, \n" + + " \"number_of_replicas\" : 2 \n" + + " }\n" + + " }\n" + + "}"; - //as super-admin + // as super-admin for (String index : listOfIndexesToTest) { RestHelper.HttpResponse responseIndex = keyStoreRestHelper.executePutRequest(index, indexSettings); assertEquals(RestStatus.OK.getStatus(), responseIndex.getStatusCode()); @@ -508,7 +516,7 @@ public void testCreateWithSystemIndices() throws Exception { keyStoreRestHelper.executeDeleteRequest(index); } - //as admin + // as admin for (String index : listOfIndexesToTest) { RestHelper.HttpResponse responseIndex = sslRestHelper.executePutRequest(index, indexSettings, allAccessUserHeader); assertEquals(RestStatus.OK.getStatus(), responseIndex.getStatusCode()); @@ -536,9 +544,26 @@ public void testSnapshotWithSystemIndices() throws Exception { RestHelper sslRestHelper = sslRestHelper(); // as admin for (String index : listOfIndexesToTest) { - assertEquals(HttpStatus.SC_OK, sslRestHelper.executeGetRequest("_snapshot/" + index + "/" + index + "_1", allAccessUserHeader).getStatusCode()); - assertEquals(HttpStatus.SC_OK, sslRestHelper.executePostRequest("_snapshot/" + index + "/" + index + "_1/_restore?wait_for_completion=true","{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_with_global_state_$1\" }", allAccessUserHeader).getStatusCode()); - assertEquals(HttpStatus.SC_FORBIDDEN, sslRestHelper.executePostRequest("_snapshot/" + index + "/" + index + "_1/_restore?wait_for_completion=true", "", allAccessUserHeader).getStatusCode()); + assertEquals( + HttpStatus.SC_OK, + sslRestHelper.executeGetRequest("_snapshot/" + index + "/" + index + "_1", allAccessUserHeader).getStatusCode() + ); + assertEquals( + HttpStatus.SC_OK, + sslRestHelper.executePostRequest( + "_snapshot/" + index + "/" + index + "_1/_restore?wait_for_completion=true", + "{ \"rename_pattern\": \"(.+)\", \"rename_replacement\": \"restored_index_with_global_state_$1\" }", + allAccessUserHeader + ).getStatusCode() + ); + assertEquals( + HttpStatus.SC_FORBIDDEN, + sslRestHelper.executePostRequest( + "_snapshot/" + index + "/" + index + "_1/_restore?wait_for_completion=true", + "", + allAccessUserHeader + ).getStatusCode() + ); } } } diff --git a/src/test/java/org/opensearch/security/test/AbstractSecurityUnitTest.java b/src/test/java/org/opensearch/security/test/AbstractSecurityUnitTest.java index 72b05abb91..975db57701 100644 --- a/src/test/java/org/opensearch/security/test/AbstractSecurityUnitTest.java +++ b/src/test/java/org/opensearch/security/test/AbstractSecurityUnitTest.java @@ -95,11 +95,11 @@ import org.opensearch.threadpool.ThreadPool; /* - * There are real thread leaks during test execution, not all threads are + * There are real thread leaks during test execution, not all threads are * properly waited on or interrupted. While this normally doesn't create test * failures, retries mitigate this. Remove this attribute to explore these * issues. - */ + */ @ThreadLeakScope(Scope.NONE) public abstract class AbstractSecurityUnitTest extends RandomizedTest { @@ -109,26 +109,32 @@ public abstract class AbstractSecurityUnitTest extends RandomizedTest { static { - System.out.println("OS: " + System.getProperty("os.name") + " " + System.getProperty("os.arch") + " " - + System.getProperty("os.version")); System.out.println( - "Java Version: " + System.getProperty("java.version") + " " + System.getProperty("java.vendor")); - System.out.println("JVM Impl.: " + System.getProperty("java.vm.version") + " " - + System.getProperty("java.vm.vendor") + " " + System.getProperty("java.vm.name")); + "OS: " + System.getProperty("os.name") + " " + System.getProperty("os.arch") + " " + System.getProperty("os.version") + ); + System.out.println("Java Version: " + System.getProperty("java.version") + " " + System.getProperty("java.vendor")); + System.out.println( + "JVM Impl.: " + + System.getProperty("java.vm.version") + + " " + + System.getProperty("java.vm.vendor") + + " " + + System.getProperty("java.vm.name") + ); System.out.println("Open SSL available: " + OpenSsl.isAvailable()); System.out.println("Open SSL version: " + OpenSsl.versionString()); withRemoteCluster = Boolean.parseBoolean(System.getenv("TESTARG_unittests_with_remote_cluster")); System.out.println("With remote cluster: " + withRemoteCluster); - //System.setProperty("security.display_lic_none","true"); + // System.setProperty("security.display_lic_none","true"); } protected final Logger log = LogManager.getLogger(this.getClass()); - public static final ThreadPool MOCK_POOL = new ThreadPool(Settings.builder().put("node.name", "mock").build()); + public static final ThreadPool MOCK_POOL = new ThreadPool(Settings.builder().put("node.name", "mock").build()); - //TODO Test Matrix - protected boolean allowOpenSSL = false; //disabled, we test this already in SSL Plugin - //enable//disable enterprise modules - //1node and 3 node + // TODO Test Matrix + protected boolean allowOpenSSL = false; // disabled, we test this already in SSL Plugin + // enable//disable enterprise modules + // 1node and 3 node @Rule public TestName name = new TestName(); @@ -136,63 +142,68 @@ public abstract class AbstractSecurityUnitTest extends RandomizedTest { @Rule public final TemporaryFolder repositoryPath = new TemporaryFolder(); - @Rule - public final TestWatcher testWatcher = new SecurityTestWatcher(); + @Rule + public final TestWatcher testWatcher = new SecurityTestWatcher(); public static Header encodeBasicHeader(final String username, final String password) { - return new BasicHeader("Authorization", "Basic "+Base64.getEncoder().encodeToString( - (username + ":" + Objects.requireNonNull(password)).getBytes(StandardCharsets.UTF_8))); + return new BasicHeader( + "Authorization", + "Basic " + + Base64.getEncoder().encodeToString((username + ":" + Objects.requireNonNull(password)).getBytes(StandardCharsets.UTF_8)) + ); } protected RestHighLevelClient getRestClient(ClusterInfo info, String keyStoreName, String trustStoreName) { return getRestClient(info, keyStoreName, trustStoreName, null); } - protected RestHighLevelClient getRestClient(ClusterInfo info, String keyStoreName, String trustStoreName, HttpVersionPolicy httpVersionPolicy) { - final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; + protected RestHighLevelClient getRestClient( + ClusterInfo info, + String keyStoreName, + String trustStoreName, + HttpVersionPolicy httpVersionPolicy + ) { + final String prefix = getResourceFolder() == null ? "" : getResourceFolder() + "/"; try { SSLContextBuilder sslContextBuilder = SSLContexts.custom(); File keyStoreFile = FileHelper.getAbsoluteFilePathFromClassPath(prefix + keyStoreName).toFile(); - KeyStore keyStore = KeyStore.getInstance(keyStoreName.endsWith(".jks")?"JKS":"PKCS12"); + KeyStore keyStore = KeyStore.getInstance(keyStoreName.endsWith(".jks") ? "JKS" : "PKCS12"); keyStore.load(new FileInputStream(keyStoreFile), null); sslContextBuilder.loadKeyMaterial(keyStore, "changeit".toCharArray()); - KeyStore trustStore = KeyStore.getInstance(trustStoreName.endsWith(".jks")?"JKS":"PKCS12"); + KeyStore trustStore = KeyStore.getInstance(trustStoreName.endsWith(".jks") ? "JKS" : "PKCS12"); File trustStoreFile = FileHelper.getAbsoluteFilePathFromClassPath(prefix + trustStoreName).toFile(); - trustStore.load(new FileInputStream(trustStoreFile), - "changeit".toCharArray()); + trustStore.load(new FileInputStream(trustStoreFile), "changeit".toCharArray()); sslContextBuilder.loadTrustMaterial(trustStore, null); SSLContext sslContext = sslContextBuilder.build(); HttpHost httpHost = new HttpHost("https", info.httpHost, info.httpPort); - RestClientBuilder restClientBuilder = RestClient.builder(httpHost) - .setHttpClientConfigCallback( - builder -> { - TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create() - .setSslContext(sslContext) - .setTlsVersions(new String[] { "TLSv1", "TLSv1.1", "TLSv1.2", "SSLv3"}) - .setHostnameVerifier(NoopHostnameVerifier.INSTANCE) - // See please https://issues.apache.org/jira/browse/HTTPCLIENT-2219 - .setTlsDetailsFactory(new Factory() { - @Override - public TlsDetails create(final SSLEngine sslEngine) { - return new TlsDetails(sslEngine.getSession(), sslEngine.getApplicationProtocol()); - } - }) - .build(); - - final AsyncClientConnectionManager cm = PoolingAsyncClientConnectionManagerBuilder.create() - .setTlsStrategy(tlsStrategy) - .build(); - builder.setConnectionManager(cm); - if (httpVersionPolicy != null) { - builder.setVersionPolicy(httpVersionPolicy); - } - return builder; - }); + RestClientBuilder restClientBuilder = RestClient.builder(httpHost).setHttpClientConfigCallback(builder -> { + TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create() + .setSslContext(sslContext) + .setTlsVersions(new String[] { "TLSv1", "TLSv1.1", "TLSv1.2", "SSLv3" }) + .setHostnameVerifier(NoopHostnameVerifier.INSTANCE) + // See please https://issues.apache.org/jira/browse/HTTPCLIENT-2219 + .setTlsDetailsFactory(new Factory() { + @Override + public TlsDetails create(final SSLEngine sslEngine) { + return new TlsDetails(sslEngine.getSession(), sslEngine.getApplicationProtocol()); + } + }) + .build(); + + final AsyncClientConnectionManager cm = PoolingAsyncClientConnectionManagerBuilder.create() + .setTlsStrategy(tlsStrategy) + .build(); + builder.setConnectionManager(cm); + if (httpVersionPolicy != null) { + builder.setVersionPolicy(httpVersionPolicy); + } + return builder; + }); return new RestHighLevelClient(restClientBuilder); } catch (Exception e) { log.error("Cannot create client", e); @@ -210,7 +221,7 @@ public void waitForInit(Client client) { retainedException = Optional.empty(); return; } catch (OpenSearchSecurityException ex) { - if(ex.getMessage().contains("OpenSearch Security not initialized")) { + if (ex.getMessage().contains("OpenSearch Security not initialized")) { retainedException = Optional.of(ex); try { Thread.sleep(500); @@ -227,7 +238,11 @@ public void waitForInit(Client client) { } } - public static Settings.Builder nodeRolesSettings(final Settings.Builder settingsBuilder, final boolean isClusterManager, final boolean isDataNode) { + public static Settings.Builder nodeRolesSettings( + final Settings.Builder settingsBuilder, + final boolean isClusterManager, + final boolean isDataNode + ) { final ImmutableList.Builder nodeRolesBuilder = ImmutableList.builder(); if (isDataNode) { nodeRolesBuilder.add(DiscoveryNodeRole.DATA_ROLE.roleName()); @@ -245,29 +260,29 @@ public static Settings.Builder mergeNodeRolesAndSettings(final Settings.Builder .addAll(settingsBuilder.build().getAsList(NODE_ROLE_KEY, ImmutableList.of())) .addAll(otherSettings.getAsList(NODE_ROLE_KEY, ImmutableList.of())); - return settingsBuilder.put(otherSettings) - .putList(NODE_ROLE_KEY, originalRoles.build().asList()); + return settingsBuilder.put(otherSettings).putList(NODE_ROLE_KEY, originalRoles.build().asList()); } - protected void initialize(ClusterHelper clusterHelper, ClusterInfo clusterInfo, DynamicSecurityConfig securityConfig) throws IOException { + protected void initialize(ClusterHelper clusterHelper, ClusterInfo clusterInfo, DynamicSecurityConfig securityConfig) + throws IOException { try (Client tc = clusterHelper.nodeClient()) { - Assert.assertEquals(clusterInfo.numNodes, - tc.admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); + Assert.assertEquals(clusterInfo.numNodes, tc.admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); try { tc.admin().indices().create(new CreateIndexRequest(".opendistro_security")).actionGet(); } catch (Exception e) { - //ignore + // ignore } List indexRequests = securityConfig.getDynamicConfig(getResourceFolder()); - for(IndexRequest ir: indexRequests) { + for (IndexRequest ir : indexRequests) { tc.index(ir).actionGet(); } - ConfigUpdateResponse cur = tc - .execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(CType.lcStringValues().toArray(new String[0]))) - .actionGet(); + ConfigUpdateResponse cur = tc.execute( + ConfigUpdateAction.INSTANCE, + new ConfigUpdateRequest(CType.lcStringValues().toArray(new String[0])) + ).actionGet(); Assert.assertFalse(cur.failures().toString(), cur.hasFailures()); Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); @@ -278,22 +293,27 @@ protected void initialize(ClusterHelper clusterHelper, ClusterInfo clusterInfo, protected Settings.Builder minimumSecuritySettingsBuilder(int node, boolean sslOnly, Settings other) { - final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; + final String prefix = getResourceFolder() == null ? "" : getResourceFolder() + "/"; Settings.Builder builder = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL); + .put(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL) + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL); // If custom transport settings are not defined use defaults if (!hasCustomTransportSettings(other)) { builder.put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "node-0") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath(prefix+"node-0-keystore.jks")) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks")) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath(prefix + "node-0-keystore.jks") + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath(prefix + "truststore.jks") + ) .put("plugins.security.ssl.transport.enforce_hostname_verification", false); } - if(!sslOnly) { + if (!sslOnly) { builder.putList("plugins.security.authcz.admin_dn", "CN=kirk,OU=client,O=client,l=tEst, C=De"); builder.put(ConfigConstants.SECURITY_BACKGROUND_INIT_IF_SECURITYINDEX_NOT_EXIST, false); } @@ -340,8 +360,8 @@ protected NodeSettingsSupplier genericMinimumSecuritySettings(List oth assert i > 0; // i is 1-indexed // Set to default if input does not have value at (i-1) index - boolean sslOnlyFlag = i > sslOnly.size() ? false : sslOnly.get(i-1); - Settings settings = i > others.size() ? Settings.EMPTY : others.get(i-1); + boolean sslOnlyFlag = i > sslOnly.size() ? false : sslOnly.get(i - 1); + Settings settings = i > others.size() ? Settings.EMPTY : others.get(i - 1); return minimumSecuritySettingsBuilder(i, sslOnlyFlag, settings).build(); }; @@ -363,7 +383,6 @@ protected String getResourceFolder() { return null; } - /** * Check if transport certs are is mentioned in the custom settings * @param customSettings custom settings from the test class @@ -371,7 +390,7 @@ protected String getResourceFolder() { */ protected boolean hasCustomTransportSettings(Settings customSettings) { // If Transport key extended usage is enabled this is true - return Boolean.parseBoolean(customSettings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_EXTENDED_KEY_USAGE_ENABLED)) || - customSettings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH) != null; + return Boolean.parseBoolean(customSettings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_EXTENDED_KEY_USAGE_ENABLED)) + || customSettings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PEMCERT_FILEPATH) != null; } } diff --git a/src/test/java/org/opensearch/security/test/DynamicSecurityConfig.java b/src/test/java/org/opensearch/security/test/DynamicSecurityConfig.java index 3573c7c274..9213d36070 100644 --- a/src/test/java/org/opensearch/security/test/DynamicSecurityConfig.java +++ b/src/test/java/org/opensearch/security/test/DynamicSecurityConfig.java @@ -45,8 +45,8 @@ public class DynamicSecurityConfig { private String securityInternalUsers = "internal_users.yml"; private String securityActionGroups = "action_groups.yml"; private String securityNodesDn = "nodes_dn.yml"; - private String securityWhitelist= "whitelist.yml"; - private String securityAllowlist= "allowlist.yml"; + private String securityWhitelist = "whitelist.yml"; + private String securityAllowlist = "allowlist.yml"; private String securityAudit = "audit.yml"; private String securityConfigAsYamlString = null; private String legacyConfigFolder = ""; @@ -95,12 +95,12 @@ public DynamicSecurityConfig setSecurityNodesDn(String nodesDn) { return this; } - public DynamicSecurityConfig setSecurityWhitelist(String whitelist){ + public DynamicSecurityConfig setSecurityWhitelist(String whitelist) { this.securityWhitelist = whitelist; return this; } - public DynamicSecurityConfig setSecurityAllowlist(String allowlist){ + public DynamicSecurityConfig setSecurityAllowlist(String allowlist) { this.securityAllowlist = allowlist; return this; } @@ -117,71 +117,86 @@ public DynamicSecurityConfig setLegacy() { public List getDynamicConfig(String folder) { - final String prefix = legacyConfigFolder+(folder == null?"":folder+"/"); + final String prefix = legacyConfigFolder + (folder == null ? "" : folder + "/"); List ret = new ArrayList(); - ret.add(new IndexRequest(securityIndexName) - .id(CType.CONFIG.toLCString()) + ret.add( + new IndexRequest(securityIndexName).id(CType.CONFIG.toLCString()) .setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source(CType.CONFIG.toLCString(), securityConfigAsYamlString==null? FileHelper.readYamlContent(prefix+securityConfig):FileHelper.readYamlContentFromString(securityConfigAsYamlString))); - - ret.add(new IndexRequest(securityIndexName) - .id(CType.ACTIONGROUPS.toLCString()) + .source( + CType.CONFIG.toLCString(), + securityConfigAsYamlString == null + ? FileHelper.readYamlContent(prefix + securityConfig) + : FileHelper.readYamlContentFromString(securityConfigAsYamlString) + ) + ); + + ret.add( + new IndexRequest(securityIndexName).id(CType.ACTIONGROUPS.toLCString()) .setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source(CType.ACTIONGROUPS.toLCString(), FileHelper.readYamlContent(prefix+securityActionGroups))); + .source(CType.ACTIONGROUPS.toLCString(), FileHelper.readYamlContent(prefix + securityActionGroups)) + ); - ret.add(new IndexRequest(securityIndexName) - .id(CType.INTERNALUSERS.toLCString()) + ret.add( + new IndexRequest(securityIndexName).id(CType.INTERNALUSERS.toLCString()) .setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source(CType.INTERNALUSERS.toLCString(), FileHelper.readYamlContent(prefix+securityInternalUsers))); + .source(CType.INTERNALUSERS.toLCString(), FileHelper.readYamlContent(prefix + securityInternalUsers)) + ); - ret.add(new IndexRequest(securityIndexName) - .id(CType.ROLES.toLCString()) + ret.add( + new IndexRequest(securityIndexName).id(CType.ROLES.toLCString()) .setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source(CType.ROLES.toLCString(), FileHelper.readYamlContent(prefix+securityRoles))); + .source(CType.ROLES.toLCString(), FileHelper.readYamlContent(prefix + securityRoles)) + ); - ret.add(new IndexRequest(securityIndexName) - .id(CType.ROLESMAPPING.toLCString()) + ret.add( + new IndexRequest(securityIndexName).id(CType.ROLESMAPPING.toLCString()) .setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source(CType.ROLESMAPPING.toLCString(), FileHelper.readYamlContent(prefix+securityRolesMapping))); - if("".equals(legacyConfigFolder)) { - ret.add(new IndexRequest(securityIndexName) - .id(CType.TENANTS.toLCString()) + .source(CType.ROLESMAPPING.toLCString(), FileHelper.readYamlContent(prefix + securityRolesMapping)) + ); + if ("".equals(legacyConfigFolder)) { + ret.add( + new IndexRequest(securityIndexName).id(CType.TENANTS.toLCString()) .setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source(CType.TENANTS.toLCString(), FileHelper.readYamlContent(prefix+securityTenants))); + .source(CType.TENANTS.toLCString(), FileHelper.readYamlContent(prefix + securityTenants)) + ); } if (null != FileHelper.getAbsoluteFilePathFromClassPath(prefix + securityNodesDn)) { - ret.add(new IndexRequest(securityIndexName) - .id(CType.NODESDN.toLCString()) + ret.add( + new IndexRequest(securityIndexName).id(CType.NODESDN.toLCString()) .setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source(CType.NODESDN.toLCString(), FileHelper.readYamlContent(prefix + securityNodesDn))); + .source(CType.NODESDN.toLCString(), FileHelper.readYamlContent(prefix + securityNodesDn)) + ); } final String whitelistYmlFile = prefix + securityWhitelist; if (null != FileHelper.getAbsoluteFilePathFromClassPath(whitelistYmlFile)) { - ret.add(new IndexRequest(securityIndexName) - .id(CType.WHITELIST.toLCString()) + ret.add( + new IndexRequest(securityIndexName).id(CType.WHITELIST.toLCString()) .setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source(CType.WHITELIST.toLCString(), FileHelper.readYamlContent(whitelistYmlFile))); + .source(CType.WHITELIST.toLCString(), FileHelper.readYamlContent(whitelistYmlFile)) + ); } final String allowlistYmlFile = prefix + securityAllowlist; if (null != FileHelper.getAbsoluteFilePathFromClassPath(allowlistYmlFile)) { - ret.add(new IndexRequest(securityIndexName) - .id(CType.ALLOWLIST.toLCString()) + ret.add( + new IndexRequest(securityIndexName).id(CType.ALLOWLIST.toLCString()) .setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source(CType.ALLOWLIST.toLCString(), FileHelper.readYamlContent(allowlistYmlFile))); + .source(CType.ALLOWLIST.toLCString(), FileHelper.readYamlContent(allowlistYmlFile)) + ); } final String auditYmlFile = prefix + securityAudit; if (null != FileHelper.getAbsoluteFilePathFromClassPath(auditYmlFile)) { - ret.add(new IndexRequest(securityIndexName) - .id(CType.AUDIT.toLCString()) + ret.add( + new IndexRequest(securityIndexName).id(CType.AUDIT.toLCString()) .setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source(CType.AUDIT.toLCString(), FileHelper.readYamlContent(auditYmlFile))); + .source(CType.AUDIT.toLCString(), FileHelper.readYamlContent(auditYmlFile)) + ); } return Collections.unmodifiableList(ret); diff --git a/src/test/java/org/opensearch/security/test/SingleClusterTest.java b/src/test/java/org/opensearch/security/test/SingleClusterTest.java index 0c2f3bfc07..2839e1e283 100644 --- a/src/test/java/org/opensearch/security/test/SingleClusterTest.java +++ b/src/test/java/org/opensearch/security/test/SingleClusterTest.java @@ -48,10 +48,13 @@ public abstract class SingleClusterTest extends AbstractSecurityUnitTest { private static final int DEFAULT_CLUSTER_MANAGER_NODE_NUM = 3; private static final int DEFAULT_FIRST_DATA_NODE_NUM = 2; - protected ClusterHelper clusterHelper = new ClusterHelper("utest_n"+num.incrementAndGet()+"_f"+System.getProperty("forkno")+"_t"+System.nanoTime()); + protected ClusterHelper clusterHelper = new ClusterHelper( + "utest_n" + num.incrementAndGet() + "_f" + System.getProperty("forkno") + "_t" + System.nanoTime() + ); protected ClusterInfo clusterInfo; - private ClusterHelper remoteClusterHelper = withRemoteCluster ? - new ClusterHelper("crl2_n"+num.incrementAndGet()+"_f"+System.getProperty("forkno")+"_t"+System.nanoTime()) : null; + private ClusterHelper remoteClusterHelper = withRemoteCluster + ? new ClusterHelper("crl2_n" + num.incrementAndGet() + "_f" + System.getProperty("forkno") + "_t" + System.nanoTime()) + : null; private ClusterInfo remoteClusterInfo; protected void setup(Settings nodeOverride) throws Exception { @@ -66,48 +69,71 @@ protected void setup() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig(), Settings.EMPTY, true); } - protected void setup(Settings initTransportClientSettings, DynamicSecurityConfig dynamicSecuritySettings, Settings nodeOverride) throws Exception { + protected void setup(Settings initTransportClientSettings, DynamicSecurityConfig dynamicSecuritySettings, Settings nodeOverride) + throws Exception { setup(initTransportClientSettings, dynamicSecuritySettings, nodeOverride, true); } - protected void setup(Settings initTransportClientSettings, DynamicSecurityConfig dynamicSecuritySettings, Settings nodeOverride, boolean initSecurityIndex) throws Exception { + protected void setup( + Settings initTransportClientSettings, + DynamicSecurityConfig dynamicSecuritySettings, + Settings nodeOverride, + boolean initSecurityIndex + ) throws Exception { setup(initTransportClientSettings, dynamicSecuritySettings, nodeOverride, initSecurityIndex, ClusterConfiguration.DEFAULT); } - protected void restart(Settings initTransportClientSettings, DynamicSecurityConfig dynamicSecuritySettings, Settings nodeOverride, boolean initOpendistroSecurityIndex) throws Exception { + protected void restart( + Settings initTransportClientSettings, + DynamicSecurityConfig dynamicSecuritySettings, + Settings nodeOverride, + boolean initOpendistroSecurityIndex + ) throws Exception { clusterInfo = clusterHelper.startCluster(minimumSecuritySettings(ccs(nodeOverride)), ClusterConfiguration.DEFAULT); - if(initOpendistroSecurityIndex && dynamicSecuritySettings != null) { + if (initOpendistroSecurityIndex && dynamicSecuritySettings != null) { initialize(clusterHelper, clusterInfo, dynamicSecuritySettings); } } private Settings ccs(Settings nodeOverride) throws Exception { - if(remoteClusterHelper != null) { + if (remoteClusterHelper != null) { Assert.assertNull("No remote clusters", remoteClusterInfo); remoteClusterInfo = remoteClusterHelper.startCluster(minimumSecuritySettings(Settings.EMPTY), ClusterConfiguration.SINGLENODE); Settings.Builder builder = Settings.builder() - .put(nodeOverride) - .putList("cluster.remote.cross_cluster_two.seeds", remoteClusterInfo.nodeHost+":"+remoteClusterInfo.nodePort); + .put(nodeOverride) + .putList("cluster.remote.cross_cluster_two.seeds", remoteClusterInfo.nodeHost + ":" + remoteClusterInfo.nodePort); return builder.build(); } else { return nodeOverride; } } - - protected void setup(Settings initTransportClientSettings, DynamicSecurityConfig dynamicSecuritySettings, Settings nodeOverride, boolean initSecurityIndex, ClusterConfiguration clusterConfiguration) throws Exception { + protected void setup( + Settings initTransportClientSettings, + DynamicSecurityConfig dynamicSecuritySettings, + Settings nodeOverride, + boolean initSecurityIndex, + ClusterConfiguration clusterConfiguration + ) throws Exception { Assert.assertNull("No cluster", clusterInfo); clusterInfo = clusterHelper.startCluster(minimumSecuritySettings(ccs(nodeOverride)), clusterConfiguration); - if(initSecurityIndex && dynamicSecuritySettings != null) { + if (initSecurityIndex && dynamicSecuritySettings != null) { initialize(clusterHelper, clusterInfo, dynamicSecuritySettings); } } - protected void setup(Settings initTransportClientSettings, DynamicSecurityConfig dynamicSecuritySettings, Settings nodeOverride - , boolean initSecurityIndex, ClusterConfiguration clusterConfiguration, int timeout, Integer nodes) throws Exception { + protected void setup( + Settings initTransportClientSettings, + DynamicSecurityConfig dynamicSecuritySettings, + Settings nodeOverride, + boolean initSecurityIndex, + ClusterConfiguration clusterConfiguration, + int timeout, + Integer nodes + ) throws Exception { Assert.assertNull("No cluster", clusterInfo); clusterInfo = clusterHelper.startCluster(minimumSecuritySettings(ccs(nodeOverride)), clusterConfiguration, timeout, nodes); - if(initSecurityIndex) { + if (initSecurityIndex) { initialize(clusterHelper, clusterInfo, dynamicSecuritySettings); } } @@ -119,20 +145,24 @@ protected void setupSslOnlyMode(Settings nodeOverride) throws Exception { protected void setupSslOnlyModeWithClusterManagerNodeWithoutSSL(Settings nodeOverride) throws Exception { Assert.assertNull("No cluster", clusterInfo); - clusterInfo = clusterHelper.startCluster(minimumSecuritySettingsSslOnlyWithOneNodeNonSSL(nodeOverride, - DEFAULT_CLUSTER_MANAGER_NODE_NUM), ClusterConfiguration.DEFAULT_CLUSTER_MANAGER_WITHOUT_SECURITY_PLUGIN); + clusterInfo = clusterHelper.startCluster( + minimumSecuritySettingsSslOnlyWithOneNodeNonSSL(nodeOverride, DEFAULT_CLUSTER_MANAGER_NODE_NUM), + ClusterConfiguration.DEFAULT_CLUSTER_MANAGER_WITHOUT_SECURITY_PLUGIN + ); } protected void setupSslOnlyModeWithDataNodeWithoutSSL(Settings nodeOverride) throws Exception { Assert.assertNull("No cluster", clusterInfo); - clusterInfo = clusterHelper.startCluster(minimumSecuritySettingsSslOnlyWithOneNodeNonSSL(nodeOverride, - DEFAULT_FIRST_DATA_NODE_NUM), ClusterConfiguration.DEFAULT_ONE_DATA_NODE_WITHOUT_SECURITY_PLUGIN); + clusterInfo = clusterHelper.startCluster( + minimumSecuritySettingsSslOnlyWithOneNodeNonSSL(nodeOverride, DEFAULT_FIRST_DATA_NODE_NUM), + ClusterConfiguration.DEFAULT_ONE_DATA_NODE_WITHOUT_SECURITY_PLUGIN + ); } - protected void setupGenericNodes(List nodeOverride, List sslOnly, ClusterConfiguration clusterConfiguration) throws Exception { + protected void setupGenericNodes(List nodeOverride, List sslOnly, ClusterConfiguration clusterConfiguration) + throws Exception { Assert.assertNull("No cluster", clusterInfo); - clusterInfo = clusterHelper.startCluster(genericMinimumSecuritySettings(nodeOverride, sslOnly), - clusterConfiguration); + clusterInfo = clusterHelper.startCluster(genericMinimumSecuritySettings(nodeOverride, sslOnly), clusterConfiguration); } protected RestHelper restHelper() { @@ -147,11 +177,10 @@ protected Client getClient() { return clusterHelper.nodeClient(); } - @After public void tearDown() { - if(remoteClusterInfo != null) { + if (remoteClusterInfo != null) { try { remoteClusterHelper.stopCluster(); } catch (Exception e) { @@ -161,7 +190,7 @@ public void tearDown() { remoteClusterInfo = null; } - if(clusterInfo != null) { + if (clusterInfo != null) { try { clusterHelper.stopCluster(); } catch (Exception e) { diff --git a/src/test/java/org/opensearch/security/test/helper/cluster/ClusterConfiguration.java b/src/test/java/org/opensearch/security/test/helper/cluster/ClusterConfiguration.java index 871cf5a59d..e9b503e669 100644 --- a/src/test/java/org/opensearch/security/test/helper/cluster/ClusterConfiguration.java +++ b/src/test/java/org/opensearch/security/test/helper/cluster/ClusterConfiguration.java @@ -45,90 +45,111 @@ import org.opensearch.transport.Netty4ModulePlugin; public enum ClusterConfiguration { - //first one needs to be a cluster manager - //HUGE(new NodeSettings(true, false, false), new NodeSettings(true, false, false), new NodeSettings(true, false, false), new NodeSettings(false, true,false), new NodeSettings(false, true, false)), - - //3 nodes (1m, 2d) + // first one needs to be a cluster manager + // HUGE(new NodeSettings(true, false, false), new NodeSettings(true, false, false), new NodeSettings(true, false, false), new + // NodeSettings(false, true,false), new NodeSettings(false, true, false)), + + // 3 nodes (1m, 2d) DEFAULT(new NodeSettings(true, false), new NodeSettings(false, true), new NodeSettings(false, true)), - //2 nodes (1m, 3d) - ONE_CLUSTER_MANAGER_THREE_DATA(new NodeSettings(true, false), new NodeSettings(false, true), new NodeSettings(false, true), new NodeSettings(false, true)), - - DEFAULT_CLUSTER_MANAGER_WITHOUT_SECURITY_PLUGIN(new NodeSettings(true, false) - .removePluginIfPresent(OpenSearchSecurityPlugin.class) - , new NodeSettings(false, true) - , new NodeSettings(false, true)), - - DEFAULT_ONE_DATA_NODE_WITHOUT_SECURITY_PLUGIN(new NodeSettings(true, false) - , new NodeSettings(false, true).removePluginIfPresent(OpenSearchSecurityPlugin.class) - , new NodeSettings(false, true)), - - //1 node (1md) - SINGLENODE(new NodeSettings(true, true)), - - //4 node (1m, 2d, 1c) - CLIENTNODE(new NodeSettings(true, false), new NodeSettings(false, true), new NodeSettings(false, true), new NodeSettings(false, false)), - - //3 nodes (1m, 2d) plus additional UserInjectorPlugin - USERINJECTOR(new NodeSettings(true, false, Lists.newArrayList(UserInjectorPlugin.class)), new NodeSettings(false, true, Lists.newArrayList(UserInjectorPlugin.class)), new NodeSettings(false, true, Lists.newArrayList(UserInjectorPlugin.class))); - - private List nodeSettings = new LinkedList<>(); - - private ClusterConfiguration(NodeSettings ... settings) { - nodeSettings.addAll(Arrays.asList(settings)); - } - - public List getNodeSettings() { - return Collections.unmodifiableList(nodeSettings); - } - - public List getClusterManagerNodeSettings() { - return Collections.unmodifiableList(nodeSettings.stream().filter(a->a.clusterManagerNode).collect(Collectors.toList())); + // 2 nodes (1m, 3d) + ONE_CLUSTER_MANAGER_THREE_DATA( + new NodeSettings(true, false), + new NodeSettings(false, true), + new NodeSettings(false, true), + new NodeSettings(false, true) + ), + + DEFAULT_CLUSTER_MANAGER_WITHOUT_SECURITY_PLUGIN( + new NodeSettings(true, false).removePluginIfPresent(OpenSearchSecurityPlugin.class), + new NodeSettings(false, true), + new NodeSettings(false, true) + ), + + DEFAULT_ONE_DATA_NODE_WITHOUT_SECURITY_PLUGIN( + new NodeSettings(true, false), + new NodeSettings(false, true).removePluginIfPresent(OpenSearchSecurityPlugin.class), + new NodeSettings(false, true) + ), + + // 1 node (1md) + SINGLENODE(new NodeSettings(true, true)), + + // 4 node (1m, 2d, 1c) + CLIENTNODE(new NodeSettings(true, false), new NodeSettings(false, true), new NodeSettings(false, true), new NodeSettings(false, false)), + + // 3 nodes (1m, 2d) plus additional UserInjectorPlugin + USERINJECTOR( + new NodeSettings(true, false, Lists.newArrayList(UserInjectorPlugin.class)), + new NodeSettings(false, true, Lists.newArrayList(UserInjectorPlugin.class)), + new NodeSettings(false, true, Lists.newArrayList(UserInjectorPlugin.class)) + ); + + private List nodeSettings = new LinkedList<>(); + + private ClusterConfiguration(NodeSettings... settings) { + nodeSettings.addAll(Arrays.asList(settings)); + } + + public List getNodeSettings() { + return Collections.unmodifiableList(nodeSettings); } - - public List getNonClusterManagerNodeSettings() { - return Collections.unmodifiableList(nodeSettings.stream().filter(a->!a.clusterManagerNode).collect(Collectors.toList())); + + public List getClusterManagerNodeSettings() { + return Collections.unmodifiableList(nodeSettings.stream().filter(a -> a.clusterManagerNode).collect(Collectors.toList())); + } + + public List getNonClusterManagerNodeSettings() { + return Collections.unmodifiableList(nodeSettings.stream().filter(a -> !a.clusterManagerNode).collect(Collectors.toList())); } - - public int getNodes() { + + public int getNodes() { return nodeSettings.size(); } - - public int getClusterManagerNodes() { - return (int) nodeSettings.stream().filter(a->a.clusterManagerNode).count(); + + public int getClusterManagerNodes() { + return (int) nodeSettings.stream().filter(a -> a.clusterManagerNode).count(); } - - public int getDataNodes() { - return (int) nodeSettings.stream().filter(a->a.dataNode).count(); + + public int getDataNodes() { + return (int) nodeSettings.stream().filter(a -> a.dataNode).count(); } - - public int getClientNodes() { - return (int) nodeSettings.stream().filter(a->!a.clusterManagerNode && !a.dataNode).count(); + + public int getClientNodes() { + return (int) nodeSettings.stream().filter(a -> !a.clusterManagerNode && !a.dataNode).count(); } - - public static class NodeSettings { - public boolean clusterManagerNode; - public boolean dataNode; - public List> plugins = Lists.newArrayList(Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class, MatrixAggregationModulePlugin.class, MustacheModulePlugin.class, ParentJoinModulePlugin.class, PercolatorModulePlugin.class, ReindexModulePlugin.class); - - public NodeSettings(boolean clusterManagerNode, boolean dataNode) { - super(); - this.clusterManagerNode = clusterManagerNode; - this.dataNode = dataNode; - } - - public NodeSettings(boolean clusterManagerNode, boolean dataNode, List> additionalPlugins) { + + public static class NodeSettings { + public boolean clusterManagerNode; + public boolean dataNode; + public List> plugins = Lists.newArrayList( + Netty4ModulePlugin.class, + OpenSearchSecurityPlugin.class, + MatrixAggregationModulePlugin.class, + MustacheModulePlugin.class, + ParentJoinModulePlugin.class, + PercolatorModulePlugin.class, + ReindexModulePlugin.class + ); + + public NodeSettings(boolean clusterManagerNode, boolean dataNode) { + super(); + this.clusterManagerNode = clusterManagerNode; + this.dataNode = dataNode; + } + + public NodeSettings(boolean clusterManagerNode, boolean dataNode, List> additionalPlugins) { this(clusterManagerNode, dataNode); this.plugins.addAll(additionalPlugins); } - public NodeSettings removePluginIfPresent(Class pluginToRemove){ - this.plugins.remove(pluginToRemove); - return this; - } - - public Class[] getPlugins() { - return plugins.toArray(new Class[0] ); - } - } + public NodeSettings removePluginIfPresent(Class pluginToRemove) { + this.plugins.remove(pluginToRemove); + return this; + } + + public Class[] getPlugins() { + return plugins.toArray(new Class[0]); + } + } } diff --git a/src/test/java/org/opensearch/security/test/helper/cluster/ClusterHelper.java b/src/test/java/org/opensearch/security/test/helper/cluster/ClusterHelper.java index 5aea8f7dfe..e60fab8e48 100644 --- a/src/test/java/org/opensearch/security/test/helper/cluster/ClusterHelper.java +++ b/src/test/java/org/opensearch/security/test/helper/cluster/ClusterHelper.java @@ -74,17 +74,17 @@ public final class ClusterHelper { static { resetSystemProperties(); } - + /** Resets all system properties associated with a cluster */ public static void resetSystemProperties() { System.setProperty("opensearch.enforce.bootstrap.checks", "true"); - updateDefaultDirectory(new File( SingleClusterTest.PROJECT_ROOT_RELATIVE_PATH + "config").getAbsolutePath()); + updateDefaultDirectory(new File(SingleClusterTest.PROJECT_ROOT_RELATIVE_PATH + "config").getAbsolutePath()); } /** * Update the default directory used by the security plugin * NOTE: this setting is system wide, use ClusterHelper.resetSystemProperties() to restore the original state - * + * * @return the previous value if one was set, otherwise null */ public static String updateDefaultDirectory(final String newValue) { @@ -115,12 +115,17 @@ public String getClusterName() { * @throws Exception */ - public final ClusterInfo startCluster(final NodeSettingsSupplier nodeSettingsSupplier, ClusterConfiguration clusterConfiguration) throws Exception { + public final ClusterInfo startCluster(final NodeSettingsSupplier nodeSettingsSupplier, ClusterConfiguration clusterConfiguration) + throws Exception { return startCluster(nodeSettingsSupplier, clusterConfiguration, 10, null); } - public final synchronized ClusterInfo startCluster(final NodeSettingsSupplier nodeSettingsSupplier, ClusterConfiguration clusterConfiguration, int timeout, Integer nodes) - throws Exception { + public final synchronized ClusterInfo startCluster( + final NodeSettingsSupplier nodeSettingsSupplier, + ClusterConfiguration clusterConfiguration, + int timeout, + Integer nodes + ) throws Exception { switch (clusterState) { case UNINITIALIZED: @@ -140,27 +145,40 @@ public final synchronized ClusterInfo startCluster(final NodeSettingsSupplier no final String forkno = System.getProperty("forkno"); int forkNumber = 1; - if(forkno != null && forkno.length() > 0) { + if (forkno != null && forkno.length() > 0) { forkNumber = Integer.parseInt(forkno.split("_")[1]); } - final int min = SocketUtils.PORT_RANGE_MIN+(forkNumber*5000); - final int max = SocketUtils.PORT_RANGE_MIN+((forkNumber+1)*5000)-1; + final int min = SocketUtils.PORT_RANGE_MIN + (forkNumber * 5000); + final int max = SocketUtils.PORT_RANGE_MIN + ((forkNumber + 1) * 5000) - 1; - final SortedSet freePorts = SocketUtils.findAvailableTcpPorts(internalNodeSettings.size()*2, min, max); - assert freePorts.size() == internalNodeSettings.size()*2; + final SortedSet freePorts = SocketUtils.findAvailableTcpPorts(internalNodeSettings.size() * 2, min, max); + assert freePorts.size() == internalNodeSettings.size() * 2; final SortedSet tcpClusterManagerPortsOnly = new TreeSet(); final SortedSet tcpAllPorts = new TreeSet(); - freePorts.stream().limit(clusterConfiguration.getClusterManagerNodes()).forEach(el->tcpClusterManagerPortsOnly.add(el)); - freePorts.stream().limit(internalNodeSettings.size()).forEach(el->tcpAllPorts.add(el)); + freePorts.stream().limit(clusterConfiguration.getClusterManagerNodes()).forEach(el -> tcpClusterManagerPortsOnly.add(el)); + freePorts.stream().limit(internalNodeSettings.size()).forEach(el -> tcpAllPorts.add(el)); final Iterator tcpPortsAllIt = tcpAllPorts.iterator(); final SortedSet httpPorts = new TreeSet(); - freePorts.stream().skip(internalNodeSettings.size()).limit(internalNodeSettings.size()).forEach(el->httpPorts.add(el)); + freePorts.stream().skip(internalNodeSettings.size()).limit(internalNodeSettings.size()).forEach(el -> httpPorts.add(el)); final Iterator httpPortsIt = httpPorts.iterator(); - System.out.println("tcpClusterManagerPorts: "+tcpClusterManagerPortsOnly+"/tcpAllPorts: "+tcpAllPorts+"/httpPorts: "+httpPorts+" for ("+min+"-"+max+") fork "+forkNumber); + System.out.println( + "tcpClusterManagerPorts: " + + tcpClusterManagerPortsOnly + + "/tcpAllPorts: " + + tcpAllPorts + + "/httpPorts: " + + httpPorts + + " for (" + + min + + "-" + + max + + ") fork " + + forkNumber + ); final CountDownLatch latch = new CountDownLatch(internalNodeSettings.size()); @@ -174,7 +192,15 @@ public final synchronized ClusterInfo startCluster(final NodeSettingsSupplier no for (int i = 0; i < internalClusterManagerNodeSettings.size(); i++) { NodeSettings setting = internalClusterManagerNodeSettings.get(i); int nodeNum = nodeNumCounter--; - final Settings.Builder nodeSettingsBuilder = getMinimumNonSecurityNodeSettingsBuilder(nodeNum, setting.clusterManagerNode, setting.dataNode, internalNodeSettings.size(), tcpClusterManagerPortsOnly, tcpPortsAllIt.next(), httpPortsIt.next()); + final Settings.Builder nodeSettingsBuilder = getMinimumNonSecurityNodeSettingsBuilder( + nodeNum, + setting.clusterManagerNode, + setting.dataNode, + internalNodeSettings.size(), + tcpClusterManagerPortsOnly, + tcpPortsAllIt.next(), + httpPortsIt.next() + ); final Settings settingsForNode; if (nodeSettingsSupplier != null) { final Settings suppliedSettings = nodeSettingsSupplier.get(nodeNum); @@ -206,7 +232,15 @@ public void run() { for (int i = 0; i < internalNonClusterManagerNodeSettings.size(); i++) { NodeSettings setting = internalNonClusterManagerNodeSettings.get(i); int nodeNum = nodeNumCounter--; - final Settings.Builder nodeSettingsBuilder = getMinimumNonSecurityNodeSettingsBuilder(nodeNum, setting.clusterManagerNode, setting.dataNode, internalNodeSettings.size(), tcpClusterManagerPortsOnly, tcpPortsAllIt.next(), httpPortsIt.next()); + final Settings.Builder nodeSettingsBuilder = getMinimumNonSecurityNodeSettingsBuilder( + nodeNum, + setting.clusterManagerNode, + setting.dataNode, + internalNodeSettings.size(), + tcpClusterManagerPortsOnly, + tcpPortsAllIt.next(), + httpPortsIt.next() + ); final Settings settingsForNode; if (nodeSettingsSupplier != null) { final Settings suppliedSettings = nodeSettingsSupplier.get(nodeNum); @@ -239,27 +273,34 @@ public void run() { latch.await(); - if(err.get() != null) { - throw new RuntimeException("Could not start all nodes "+err.get(),err.get()); + if (err.get() != null) { + throw new RuntimeException("Could not start all nodes " + err.get(), err.get()); } - ClusterInfo cInfo = waitForCluster(ClusterHealthStatus.GREEN, TimeValue.timeValueSeconds(timeout), nodes == null?opensearchNodes.size():nodes.intValue()); + ClusterInfo cInfo = waitForCluster( + ClusterHealthStatus.GREEN, + TimeValue.timeValueSeconds(timeout), + nodes == null ? opensearchNodes.size() : nodes.intValue() + ); cInfo.numNodes = internalNodeSettings.size(); cInfo.clustername = clustername; - cInfo.tcpClusterManagerPortsOnly = tcpClusterManagerPortsOnly.stream().map(s->"127.0.0.1:"+s).collect(Collectors.toList()); - - final String defaultTemplate = "{\n" + - " \"index_patterns\": [\"*\"],\n" + - " \"order\": -1,\n" + - " \"settings\": {\n" + - " \"number_of_shards\": \"5\",\n" + - " \"number_of_replicas\": \"1\"\n" + - " }\n" + - " }"; - - final AcknowledgedResponse templateAck = nodeClient().admin().indices().putTemplate(new PutIndexTemplateRequest("default").source(defaultTemplate, XContentType.JSON)).actionGet(); - - if(!templateAck.isAcknowledged()) { + cInfo.tcpClusterManagerPortsOnly = tcpClusterManagerPortsOnly.stream().map(s -> "127.0.0.1:" + s).collect(Collectors.toList()); + + final String defaultTemplate = "{\n" + + " \"index_patterns\": [\"*\"],\n" + + " \"order\": -1,\n" + + " \"settings\": {\n" + + " \"number_of_shards\": \"5\",\n" + + " \"number_of_replicas\": \"1\"\n" + + " }\n" + + " }"; + + final AcknowledgedResponse templateAck = nodeClient().admin() + .indices() + .putTemplate(new PutIndexTemplateRequest("default").source(defaultTemplate, XContentType.JSON)) + .actionGet(); + + if (!templateAck.isAcknowledged()) { throw new RuntimeException("Default template could not be created"); } @@ -269,15 +310,15 @@ public void run() { public final void stopCluster() throws Exception { closeAllNodes(); - FileUtils.deleteDirectory(new File("./target/data/"+clustername)); + FileUtils.deleteDirectory(new File("./target/data/" + clustername)); } - private void closeAllNodes() throws Exception { - //close non cluster manager nodes - opensearchNodes.stream().filter(n->!n.isClusterManagerEligible()).forEach(ClusterHelper::closeNode); + private void closeAllNodes() throws Exception { + // close non cluster manager nodes + opensearchNodes.stream().filter(n -> !n.isClusterManagerEligible()).forEach(ClusterHelper::closeNode); - //close cluster manager nodes - opensearchNodes.stream().filter(n->n.isClusterManagerEligible()).forEach(ClusterHelper::closeNode); + // close cluster manager nodes + opensearchNodes.stream().filter(n -> n.isClusterManagerEligible()).forEach(ClusterHelper::closeNode); opensearchNodes.clear(); clusterState = ClusterState.STOPPED; } @@ -287,16 +328,16 @@ private static void closeNode(Node node) { node.close(); node.awaitClose(250, TimeUnit.MILLISECONDS); } catch (Throwable e) { - //ignore + // ignore } } - public Client nodeClient() { return opensearchNodes.get(0).client(); } - public ClusterInfo waitForCluster(final ClusterHealthStatus status, final TimeValue timeout, final int expectedNodeCount) throws IOException { + public ClusterInfo waitForCluster(final ClusterHealthStatus status, final TimeValue timeout, final int expectedNodeCount) + throws IOException { if (opensearchNodes.isEmpty()) { throw new RuntimeException("List of nodes was empty."); } @@ -307,12 +348,19 @@ public ClusterInfo waitForCluster(final ClusterHealthStatus status, final TimeVa Client client = node.client(); try { log.debug("waiting for cluster state {} and {} nodes", status.name(), expectedNodeCount); - final ClusterHealthResponse healthResponse = client.admin().cluster().prepareHealth() - .setWaitForStatus(status).setTimeout(timeout).setClusterManagerNodeTimeout(timeout).setWaitForNodes("" + expectedNodeCount).execute() - .actionGet(); + final ClusterHealthResponse healthResponse = client.admin() + .cluster() + .prepareHealth() + .setWaitForStatus(status) + .setTimeout(timeout) + .setClusterManagerNodeTimeout(timeout) + .setWaitForNodes("" + expectedNodeCount) + .execute() + .actionGet(); if (healthResponse.isTimedOut()) { - throw new IOException("cluster state is " + healthResponse.getStatus().name() + " with " - + healthResponse.getNumberOfNodes() + " nodes"); + throw new IOException( + "cluster state is " + healthResponse.getStatus().name() + " with " + healthResponse.getNumberOfNodes() + " nodes" + ); } else { log.debug("... cluster state ok {} with {} nodes", healthResponse.getStatus().name(), healthResponse.getNumberOfNodes()); } @@ -323,21 +371,32 @@ public ClusterInfo waitForCluster(final ClusterHealthStatus status, final TimeVa final List nodes = res.getNodes(); - final List clusterManagerNodes = nodes.stream().filter(n->n.getNode().getRoles().contains(DiscoveryNodeRole.CLUSTER_MANAGER_ROLE)).collect(Collectors.toList()); - final List dataNodes = nodes.stream().filter(n->n.getNode().getRoles().contains(DiscoveryNodeRole.DATA_ROLE) && !n.getNode().getRoles().contains(DiscoveryNodeRole.CLUSTER_MANAGER_ROLE)).collect(Collectors.toList()); + final List clusterManagerNodes = nodes.stream() + .filter(n -> n.getNode().getRoles().contains(DiscoveryNodeRole.CLUSTER_MANAGER_ROLE)) + .collect(Collectors.toList()); + final List dataNodes = nodes.stream() + .filter( + n -> n.getNode().getRoles().contains(DiscoveryNodeRole.DATA_ROLE) + && !n.getNode().getRoles().contains(DiscoveryNodeRole.CLUSTER_MANAGER_ROLE) + ) + .collect(Collectors.toList()); // Sorting the nodes so that the node receiving the http requests is always deterministic dataNodes.sort(Comparator.comparing(nodeInfo -> nodeInfo.getNode().getName())); - final List clientNodes = nodes.stream().filter(n->!n.getNode().getRoles().contains(DiscoveryNodeRole.CLUSTER_MANAGER_ROLE) && !n.getNode().getRoles().contains(DiscoveryNodeRole.DATA_ROLE)).collect(Collectors.toList()); - - - for (NodeInfo nodeInfo: clusterManagerNodes) { + final List clientNodes = nodes.stream() + .filter( + n -> !n.getNode().getRoles().contains(DiscoveryNodeRole.CLUSTER_MANAGER_ROLE) + && !n.getNode().getRoles().contains(DiscoveryNodeRole.DATA_ROLE) + ) + .collect(Collectors.toList()); + + for (NodeInfo nodeInfo : clusterManagerNodes) { final TransportInfo transportInfo = nodeInfo.getInfo(TransportInfo.class); final TransportAddress transportAddress = transportInfo.getAddress().publishAddress(); clusterInfo.nodePort = transportAddress.getPort(); clusterInfo.nodeHost = transportAddress.getAddress(); } - if(!clientNodes.isEmpty()) { + if (!clientNodes.isEmpty()) { NodeInfo nodeInfo = clientNodes.get(0); final HttpInfo httpInfo = nodeInfo.getInfo(HttpInfo.class); if (httpInfo != null && httpInfo.address() != null) { @@ -348,9 +407,9 @@ public ClusterInfo waitForCluster(final ClusterHealthStatus status, final TimeVa } else { throw new RuntimeException("no http host/port for client node"); } - } else if(!dataNodes.isEmpty()) { + } else if (!dataNodes.isEmpty()) { - for (NodeInfo nodeInfo: dataNodes) { + for (NodeInfo nodeInfo : dataNodes) { final HttpInfo httpInfo = nodeInfo.getInfo(HttpInfo.class); if (httpInfo != null && httpInfo.address() != null) { final TransportAddress transportAddress = httpInfo.address().publishAddress(); @@ -360,9 +419,9 @@ public ClusterInfo waitForCluster(final ClusterHealthStatus status, final TimeVa break; } } - } else { + } else { - for (NodeInfo nodeInfo: nodes) { + for (NodeInfo nodeInfo : nodes) { final HttpInfo httpInfo = nodeInfo.getInfo(HttpInfo.class); if (httpInfo != null && httpInfo.address() != null) { final TransportAddress transportAddress = httpInfo.address().publishAddress(); @@ -374,32 +433,41 @@ public ClusterInfo waitForCluster(final ClusterHealthStatus status, final TimeVa } } } catch (final OpenSearchTimeoutException e) { - throw new IOException( - "timeout, cluster does not respond to health request, cowardly refusing to continue with operations"); + throw new IOException("timeout, cluster does not respond to health request, cowardly refusing to continue with operations"); } return clusterInfo; } // @formatter:off - private Settings.Builder getMinimumNonSecurityNodeSettingsBuilder(final int nodenum, final boolean isClusterManagerNode, - final boolean isDataNode, int nodeCount, SortedSet clusterManagerTcpPorts, int tcpPort, int httpPort) { + private Settings.Builder getMinimumNonSecurityNodeSettingsBuilder( + final int nodenum, + final boolean isClusterManagerNode, + final boolean isDataNode, + int nodeCount, + SortedSet clusterManagerTcpPorts, + int tcpPort, + int httpPort + ) { return AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), isClusterManagerNode, isDataNode) - .put("node.name", "node_"+clustername+ "_num" + nodenum) - .put("cluster.name", clustername) - .put("path.data", "./target/data/"+clustername+"/data") - .put("path.logs", "./target/data/"+clustername+"/logs") - .put("node.max_local_storage_nodes", nodeCount) - .putList("cluster.initial_cluster_manager_nodes", clusterManagerTcpPorts.stream().map(s->"127.0.0.1:"+s).collect(Collectors.toList())) - .put("discovery.initial_state_timeout","8s") - .putList("discovery.seed_hosts", clusterManagerTcpPorts.stream().map(s->"127.0.0.1:"+s).collect(Collectors.toList())) - .put("transport.tcp.port", tcpPort) - .put("http.port", httpPort) - .put("http.cors.enabled", true) - .put("path.home", "./target"); + .put("node.name", "node_" + clustername + "_num" + nodenum) + .put("cluster.name", clustername) + .put("path.data", "./target/data/" + clustername + "/data") + .put("path.logs", "./target/data/" + clustername + "/logs") + .put("node.max_local_storage_nodes", nodeCount) + .putList( + "cluster.initial_cluster_manager_nodes", + clusterManagerTcpPorts.stream().map(s -> "127.0.0.1:" + s).collect(Collectors.toList()) + ) + .put("discovery.initial_state_timeout", "8s") + .putList("discovery.seed_hosts", clusterManagerTcpPorts.stream().map(s -> "127.0.0.1:" + s).collect(Collectors.toList())) + .put("transport.tcp.port", tcpPort) + .put("http.port", httpPort) + .put("http.cors.enabled", true) + .put("path.home", "./target"); } - private enum ClusterState{ + private enum ClusterState { UNINITIALIZED, STARTED, STOPPED diff --git a/src/test/java/org/opensearch/security/test/helper/cluster/ClusterInfo.java b/src/test/java/org/opensearch/security/test/helper/cluster/ClusterInfo.java index bb59450752..d50274e0e0 100644 --- a/src/test/java/org/opensearch/security/test/helper/cluster/ClusterInfo.java +++ b/src/test/java/org/opensearch/security/test/helper/cluster/ClusterInfo.java @@ -33,12 +33,12 @@ import org.opensearch.common.transport.TransportAddress; public class ClusterInfo { - public int numNodes; - public String httpHost = null; - public int httpPort = -1; - public Set httpAdresses = new HashSet(); - public String nodeHost; - public int nodePort; - public String clustername; + public int numNodes; + public String httpHost = null; + public int httpPort = -1; + public Set httpAdresses = new HashSet(); + public String nodeHost; + public int nodePort; + public String clustername; public List tcpClusterManagerPortsOnly; } diff --git a/src/test/java/org/opensearch/security/test/helper/file/FileHelper.java b/src/test/java/org/opensearch/security/test/helper/file/FileHelper.java index 6aadd2acbb..acb4a7d217 100644 --- a/src/test/java/org/opensearch/security/test/helper/file/FileHelper.java +++ b/src/test/java/org/opensearch/security/test/helper/file/FileHelper.java @@ -57,90 +57,90 @@ public class FileHelper { - protected final static Logger log = LogManager.getLogger(FileHelper.class); - - public static KeyStore getKeystoreFromClassPath(final String fileNameFromClasspath, String password) throws Exception { - Path path = getAbsoluteFilePathFromClassPath(fileNameFromClasspath); - if(path==null) { - return null; - } - - KeyStore ks = KeyStore.getInstance("JKS"); - try (FileInputStream fin = new FileInputStream(path.toFile())) { - ks.load(fin, password==null||password.isEmpty()?null:password.toCharArray()); - } - return ks; - } - - public static Path getAbsoluteFilePathFromClassPath(final String fileNameFromClasspath) { - File file = null; - final URL fileUrl = FileHelper.class.getClassLoader().getResource(fileNameFromClasspath); - if (fileUrl != null) { - try { - file = new File(URLDecoder.decode(fileUrl.getFile(), "UTF-8")); - } catch (final UnsupportedEncodingException e) { - return null; - } - - if (file.exists() && file.canRead()) { - return Paths.get(file.getAbsolutePath()); - } else { - log.error("Cannot read from {}, maybe the file does not exists? ", file.getAbsolutePath()); - } - - } else { - log.error("Failed to load {}", fileNameFromClasspath); - } - return null; - } - - public static final String loadFile(final String file) throws IOException { - final StringWriter sw = new StringWriter(); - IOUtils.copy(FileHelper.class.getResourceAsStream("/" + file), sw, StandardCharsets.UTF_8); - return sw.toString(); - } - + protected final static Logger log = LogManager.getLogger(FileHelper.class); + + public static KeyStore getKeystoreFromClassPath(final String fileNameFromClasspath, String password) throws Exception { + Path path = getAbsoluteFilePathFromClassPath(fileNameFromClasspath); + if (path == null) { + return null; + } + + KeyStore ks = KeyStore.getInstance("JKS"); + try (FileInputStream fin = new FileInputStream(path.toFile())) { + ks.load(fin, password == null || password.isEmpty() ? null : password.toCharArray()); + } + return ks; + } + + public static Path getAbsoluteFilePathFromClassPath(final String fileNameFromClasspath) { + File file = null; + final URL fileUrl = FileHelper.class.getClassLoader().getResource(fileNameFromClasspath); + if (fileUrl != null) { + try { + file = new File(URLDecoder.decode(fileUrl.getFile(), "UTF-8")); + } catch (final UnsupportedEncodingException e) { + return null; + } + + if (file.exists() && file.canRead()) { + return Paths.get(file.getAbsolutePath()); + } else { + log.error("Cannot read from {}, maybe the file does not exists? ", file.getAbsolutePath()); + } + + } else { + log.error("Failed to load {}", fileNameFromClasspath); + } + return null; + } + + public static final String loadFile(final String file) throws IOException { + final StringWriter sw = new StringWriter(); + IOUtils.copy(FileHelper.class.getResourceAsStream("/" + file), sw, StandardCharsets.UTF_8); + return sw.toString(); + } + public static BytesReference readYamlContent(final String file) { - + XContentParser parser = null; try { - parser = XContentFactory.xContent(XContentType.YAML).createParser(NamedXContentRegistry.EMPTY, THROW_UNSUPPORTED_OPERATION, new StringReader(loadFile(file))); + parser = XContentFactory.xContent(XContentType.YAML) + .createParser(NamedXContentRegistry.EMPTY, THROW_UNSUPPORTED_OPERATION, new StringReader(loadFile(file))); parser.nextToken(); final XContentBuilder builder = XContentFactory.jsonBuilder(); builder.copyCurrentStructure(parser); return BytesReference.bytes(builder); } catch (Exception e) { throw new RuntimeException(e); - } - finally { + } finally { if (parser != null) { try { parser.close(); } catch (IOException e) { - //ignore + // ignore } } } - } - + } + public static BytesReference readYamlContentFromString(final String yaml) { - + XContentParser parser = null; try { - parser = XContentFactory.xContent(XContentType.YAML).createParser(NamedXContentRegistry.EMPTY, THROW_UNSUPPORTED_OPERATION, new StringReader(yaml)); + parser = XContentFactory.xContent(XContentType.YAML) + .createParser(NamedXContentRegistry.EMPTY, THROW_UNSUPPORTED_OPERATION, new StringReader(yaml)); parser.nextToken(); final XContentBuilder builder = XContentFactory.jsonBuilder(); builder.copyCurrentStructure(parser); return BytesReference.bytes(builder); } catch (Exception e) { throw new RuntimeException(e); - } - finally { + } finally { if (parser != null) { try { parser.close(); } catch (IOException e) { - //ignore + // ignore } } } diff --git a/src/test/java/org/opensearch/security/test/helper/network/SocketUtils.java b/src/test/java/org/opensearch/security/test/helper/network/SocketUtils.java index 1d264025e0..b9f014960c 100644 --- a/src/test/java/org/opensearch/security/test/helper/network/SocketUtils.java +++ b/src/test/java/org/opensearch/security/test/helper/network/SocketUtils.java @@ -79,10 +79,8 @@ public class SocketUtils { */ public static final int PORT_RANGE_MAX = 65535; - private static final Random random = new Random(System.currentTimeMillis()); - /** * Although {@code SocketUtils} consists solely of static utility methods, * this constructor is intentionally {@code public}. @@ -103,7 +101,6 @@ public SocketUtils() { /* no-op */ } - /** * Find an available TCP port randomly selected from the range * [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}]. @@ -218,19 +215,17 @@ public static SortedSet findAvailableUdpPorts(int numRequested, int min return SocketType.UDP.findAvailablePorts(numRequested, minPort, maxPort); } - private enum SocketType { TCP { @Override protected boolean isPortAvailable(int port) { try { - ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket( - port, 1, InetAddress.getByName("localhost")); + ServerSocket serverSocket = ServerSocketFactory.getDefault() + .createServerSocket(port, 1, InetAddress.getByName("localhost")); serverSocket.close(); return true; - } - catch (Exception ex) { + } catch (Exception ex) { return false; } } @@ -243,8 +238,7 @@ protected boolean isPortAvailable(int port) { DatagramSocket socket = new DatagramSocket(port, InetAddress.getByName("localhost")); socket.close(); return true; - } - catch (Exception ex) { + } catch (Exception ex) { return false; } } @@ -277,23 +271,28 @@ private int findRandomPort(int minPort, int maxPort) { * @throws IllegalStateException if no available port could be found */ int findAvailablePort(int minPort, int maxPort) { - //Assert.assertTrue(minPort > 0, "'minPort' must be greater than 0"); - //Assert.isTrue(maxPort >= minPort, "'maxPort' must be greater than or equal to 'minPort'"); - //Assert.isTrue(maxPort <= PORT_RANGE_MAX, "'maxPort' must be less than or equal to " + PORT_RANGE_MAX); + // Assert.assertTrue(minPort > 0, "'minPort' must be greater than 0"); + // Assert.isTrue(maxPort >= minPort, "'maxPort' must be greater than or equal to 'minPort'"); + // Assert.isTrue(maxPort <= PORT_RANGE_MAX, "'maxPort' must be less than or equal to " + PORT_RANGE_MAX); int portRange = maxPort - minPort; int candidatePort; int searchCounter = 0; do { if (searchCounter > portRange) { - throw new IllegalStateException(String.format( + throw new IllegalStateException( + String.format( "Could not find an available %s port in the range [%d, %d] after %d attempts", - name(), minPort, maxPort, searchCounter)); + name(), + minPort, + maxPort, + searchCounter + ) + ); } candidatePort = findRandomPort(minPort, maxPort); searchCounter++; - } - while (!isPortAvailable(candidatePort)); + } while (!isPortAvailable(candidatePort)); return candidatePort; } @@ -308,12 +307,12 @@ int findAvailablePort(int minPort, int maxPort) { * @throws IllegalStateException if the requested number of available ports could not be found */ SortedSet findAvailablePorts(int numRequested, int minPort, int maxPort) { - //Assert.isTrue(minPort > 0, "'minPort' must be greater than 0"); - //Assert.isTrue(maxPort > minPort, "'maxPort' must be greater than 'minPort'"); - //Assert.isTrue(maxPort <= PORT_RANGE_MAX, "'maxPort' must be less than or equal to " + PORT_RANGE_MAX); - //Assert.isTrue(numRequested > 0, "'numRequested' must be greater than 0"); - //Assert.isTrue((maxPort - minPort) >= numRequested, - // "'numRequested' must not be greater than 'maxPort' - 'minPort'"); + // Assert.isTrue(minPort > 0, "'minPort' must be greater than 0"); + // Assert.isTrue(maxPort > minPort, "'maxPort' must be greater than 'minPort'"); + // Assert.isTrue(maxPort <= PORT_RANGE_MAX, "'maxPort' must be less than or equal to " + PORT_RANGE_MAX); + // Assert.isTrue(numRequested > 0, "'numRequested' must be greater than 0"); + // Assert.isTrue((maxPort - minPort) >= numRequested, + // "'numRequested' must not be greater than 'maxPort' - 'minPort'"); SortedSet availablePorts = new TreeSet<>(); int attemptCount = 0; @@ -322,9 +321,9 @@ SortedSet findAvailablePorts(int numRequested, int minPort, int maxPort } if (availablePorts.size() != numRequested) { - throw new IllegalStateException(String.format( - "Could not find %d available %s ports in the range [%d, %d]", - numRequested, name(), minPort, maxPort)); + throw new IllegalStateException( + String.format("Could not find %d available %s ports in the range [%d, %d]", numRequested, name(), minPort, maxPort) + ); } return availablePorts; 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 367332f160..730a22f18f 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 @@ -94,450 +94,479 @@ public class RestHelper { - protected final Logger log = LogManager.getLogger(RestHelper.class); - - public boolean enableHTTPClientSSL = true; - public boolean enableHTTPClientSSLv3Only = false; - public boolean sendAdminCertificate = false; - public boolean trustHTTPServerCertificate = true; - public boolean sendHTTPClientCredentials = false; - public String keystore = "node-0-keystore.jks"; - public final String prefix; - //public String truststore = "truststore.jks"; - private ClusterInfo clusterInfo; - - public RestHelper(ClusterInfo clusterInfo, String prefix) { - this.clusterInfo = clusterInfo; - this.prefix = prefix; - } - - public RestHelper(ClusterInfo clusterInfo, boolean enableHTTPClientSSL, boolean trustHTTPServerCertificate, String prefix) { - this.clusterInfo = clusterInfo; - this.enableHTTPClientSSL = enableHTTPClientSSL; - this.trustHTTPServerCertificate = trustHTTPServerCertificate; - this.prefix = prefix; - } - public String executeSimpleRequest(final String request) throws Exception { - - CloseableHttpAsyncClient httpClient = null; - - try { - httpClient = getHTTPClient(); - httpClient.start(); - - final CompletableFuture future = new CompletableFuture<>(); - final SimpleHttpRequest simpleRequest = SimpleRequestBuilder.copy(new HttpGet(getRequestUri(request))).build(); - httpClient.execute(simpleRequest, new FutureCallback() { - @Override - public void completed(SimpleHttpResponse result) { - future.complete(result); - } - - @Override - public void failed(Exception ex) { - future.completeExceptionally(ex); - } - - @Override - public void cancelled() { - future.cancel(true); - } - }); - - final SimpleHttpResponse response = future.join(); - if (response.getCode() >= 300) { - throw new Exception("Statuscode " + response.getCode()); - } - - if (enableHTTPClientSSL && !response.getVersion().equals(HttpVersion.HTTP_2)) { - throw new IllegalStateException("HTTP/2 expected for HTTPS communication but " + response.getVersion() + " was used"); - } - - return response.getBodyText(); - } catch (final CompletionException e) { - final Throwable cause = e.getCause(); - // Make it compatible with DefaultHttpResponseParser::createConnectionClosedException() - if (cause instanceof ConnectionClosedException) { - throw new NoHttpResponseException(cause.getMessage(), cause); - } else { - throw (Exception)cause; - } - } finally { - if (httpClient != null) { - httpClient.close(); - } - } - } - - public HttpResponse[] executeMultipleAsyncPutRequest(final int numOfRequests, final String request, String body) throws Exception { - final ExecutorService executorService = Executors.newFixedThreadPool(numOfRequests); - Future[] futures = new Future[numOfRequests]; - for (int i = 0; i < numOfRequests; i++) { - futures[i] = executorService.submit(() -> executePutRequest(request, body, new Header[0])); - } - executorService.shutdown(); - return Arrays.stream(futures) - .map(HttpResponse::from) - .toArray(s -> new HttpResponse[s]); - } - - public HttpResponse executeGetRequest(final String request, Header... header) { - return executeRequest(new HttpGet(getRequestUri(request)), header); - } - - public HttpResponse executeGetRequest(final String request, String body, Header... header) { - HttpGet getRequest = new HttpGet(getRequestUri(request)); - getRequest.setEntity(createStringEntity(body)); - getRequest.addHeader(HttpHeaders.CONTENT_TYPE, "application/json"); - return executeRequest(getRequest, header); - } - - public HttpResponse executeHeadRequest(final String request, Header... header) { - return executeRequest(new HttpHead(getRequestUri(request)), header); - } - - public HttpResponse executeOptionsRequest(final String request) { - return executeRequest(new HttpOptions(getRequestUri(request))); - } - - public HttpResponse executePutRequest(final String request, String body, Header... header) { - HttpPut uriRequest = new HttpPut(getRequestUri(request)); - if (body != null && !body.isEmpty()) { - uriRequest.setEntity(createStringEntity(body)); - } - return executeRequest(uriRequest, header); - } - - public HttpResponse executeDeleteRequest(final String request, Header... header) { - return executeRequest(new HttpDelete(getRequestUri(request)), header); - } - - public HttpResponse executeDeleteRequest(final String request, String body, Header... header) { - HttpDelete delRequest = new HttpDelete(getRequestUri(request)); - delRequest.setEntity(createStringEntity(body)); - delRequest.setHeader(HttpHeaders.CONTENT_TYPE, "application/json"); - return executeRequest(delRequest, header); - } - - - public HttpResponse executePostRequest(final String request, String body, Header... header) { - HttpPost uriRequest = new HttpPost(getRequestUri(request)); - if (body != null && !body.isEmpty()) { - uriRequest.setEntity(createStringEntity(body)); - } - - return executeRequest(uriRequest, header); - } - - public HttpResponse executePatchRequest(final String request, String body, Header... header) { - HttpPatch uriRequest = new HttpPatch(getRequestUri(request)); - if (body != null && !body.isEmpty()) { - uriRequest.setEntity(createStringEntity(body)); - } - return executeRequest(uriRequest, header); - } - - public HttpResponse executeRequest(HttpUriRequest uriRequest, Header... header) { - - CloseableHttpAsyncClient httpClient = null; - try { - - httpClient = getHTTPClient(); - httpClient.start(); - - if (header != null && header.length > 0) { - for (int i = 0; i < header.length; i++) { - Header h = header[i]; - uriRequest.addHeader(h); - } - } - - if (!uriRequest.containsHeader("Content-Type")) { - uriRequest.addHeader("Content-Type","application/json"); - } - - final CompletableFuture future = new CompletableFuture<>(); - final SimpleHttpRequest simpleRequest = SimpleRequestBuilder.copy(uriRequest).build(); - if (uriRequest.getEntity() != null) { - simpleRequest.setBody(EntityUtils.toByteArray(uriRequest.getEntity()), - ContentType.parse(uriRequest.getEntity().getContentType())); - } - httpClient.execute(simpleRequest, new FutureCallback() { - @Override - public void completed(SimpleHttpResponse result) { - future.complete(result); - } - - @Override - public void failed(Exception ex) { - future.completeExceptionally(ex); - } - - @Override - public void cancelled() { - future.cancel(true); - } - }); - - final HttpResponse res = new HttpResponse(future.join()); - if (enableHTTPClientSSL && !res.getProtocolVersion().equals(HttpVersion.HTTP_2)) { - throw new IllegalStateException("HTTP/2 expected for HTTPS communication but " + res.getProtocolVersion() + " was used"); - } - - log.debug(res.getBody()); - return res; - } catch (final CompletionException e) { - final Throwable cause = e.getCause(); - // Make it compatible with DefaultHttpResponseParser::createConnectionClosedException() - if (cause instanceof ConnectionClosedException) { - throw new RuntimeException(new NoHttpResponseException(cause.getMessage(), cause)); - } else if (cause instanceof RuntimeException) { - throw (RuntimeException)cause; - } else { - throw new RuntimeException(cause); - } - } catch (final Exception e) { - throw new RuntimeException(e); - } finally { - - if (httpClient != null) { - try { - httpClient.close(); - } catch (final Exception e) { - throw new RuntimeException(e); - } - } - } - } - - private HttpEntity createStringEntity(String body) { - return new StringEntity(body); - } - - protected final String getHttpServerUri() { - final String address = "http" + (enableHTTPClientSSL ? "s" : "") + "://" + clusterInfo.httpHost + ":" + clusterInfo.httpPort; - log.debug("Connect to {}", address); - return address; - } - - protected final String getRequestUri(String request) { - return getHttpServerUri() + "/" + StringUtils.strip(request, "/"); - } - - protected final CloseableHttpAsyncClient getHTTPClient() throws Exception { - - final HttpAsyncClientBuilder hcb = HttpAsyncClients.custom(); - - if (sendHTTPClientCredentials) { - UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("sarek", "sarek".toCharArray()); - BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); - credentialsProvider.setCredentials(new AuthScope(null, -1), credentials); - hcb.setDefaultCredentialsProvider(credentialsProvider); - } - - if (enableHTTPClientSSL) { - - log.debug("Configure HTTP client with SSL"); - - if(prefix != null && !keystore.contains("/")) { - keystore = prefix+"/"+keystore; - } - - final String keyStorePath = FileHelper.getAbsoluteFilePathFromClassPath(keystore).toFile().getParent(); - - final KeyStore myTrustStore = KeyStore.getInstance("JKS"); - myTrustStore.load(new FileInputStream(keyStorePath+"/truststore.jks"), - "changeit".toCharArray()); - - final KeyStore keyStore = KeyStore.getInstance("JKS"); - keyStore.load(new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath(keystore).toFile()), "changeit".toCharArray()); - - final SSLContextBuilder sslContextbBuilder = SSLContexts.custom(); - - if (trustHTTPServerCertificate) { - sslContextbBuilder.loadTrustMaterial(myTrustStore, null); - } - - if (sendAdminCertificate) { - sslContextbBuilder.loadKeyMaterial(keyStore, "changeit".toCharArray()); - } - - final SSLContext sslContext = sslContextbBuilder.build(); - - String[] protocols = null; - - if (enableHTTPClientSSLv3Only) { - protocols = new String[] { "SSLv3" }; - } else { - protocols = new String[] { "TLSv1", "TLSv1.1", "TLSv1.2" }; - } - - final TlsStrategy tlsStrategy = ClientTlsStrategyBuilder - .create() - .setSslContext(sslContext) - .setTlsVersions(protocols) - .setHostnameVerifier(NoopHostnameVerifier.INSTANCE) - // See please https://issues.apache.org/jira/browse/HTTPCLIENT-2219 - .setTlsDetailsFactory(new Factory() { - @Override - public TlsDetails create(final SSLEngine sslEngine) { - return new TlsDetails(sslEngine.getSession(), sslEngine.getApplicationProtocol()); - } - }) - .build(); - - final AsyncClientConnectionManager cm = PoolingAsyncClientConnectionManagerBuilder.create() - .setTlsStrategy(tlsStrategy) - .build(); - - hcb.setConnectionManager(cm); - } - - final RequestConfig.Builder requestConfigBuilder = RequestConfig.custom() - .setResponseTimeout(Timeout.ofSeconds(60)); - - return hcb.setDefaultRequestConfig(requestConfigBuilder.build()).disableAutomaticRetries().build(); - } - - - public static class HttpResponse { - private final SimpleHttpResponse inner; - private final String body; - private final Header[] header; - private final int statusCode; - private final String statusReason; - private final ProtocolVersion protocolVersion; - - public HttpResponse(SimpleHttpResponse inner) throws IllegalStateException, IOException { - super(); - this.inner = inner; - if(inner.getBody() == null) { //head request does not have a entity - this.body = ""; - } else { - this.body = inner.getBodyText(); - } - this.header = inner.getHeaders(); - this.statusCode = inner.getCode(); - this.statusReason = inner.getReasonPhrase(); - this.protocolVersion = inner.getVersion(); - } - - public String getContentType() { - Header h = getInner().getFirstHeader("content-type"); - if(h!= null) { - return h.getValue(); - } - return null; - } - - public boolean isJsonContentType() { - String ct = getContentType(); - if(ct == null) { - return false; - } - return ct.contains("application/json"); - } - - public SimpleHttpResponse getInner() { - return inner; - } - - public String getBody() { - return body; - } - - public Header[] getHeader() { - return header; - } - - public int getStatusCode() { - return statusCode; - } - - public String getStatusReason() { - return statusReason; - } - - public List
getHeaders() { - return header==null?Collections.emptyList():Arrays.asList(header); - } - - public ProtocolVersion getProtocolVersion() { - return protocolVersion; - } - - @Override - public String toString() { - return "HttpResponse [inner=" + inner + ", body=" + body + ", header=" + Arrays.toString(header) + ", statusCode=" + statusCode - + ", statusReason=" + statusReason + "]"; - } - - /** - * Given a json path with dots delimiated returns the object at the leaf - */ - public String findValueInJson(final String jsonDotPath) { - // Make sure its json / then parse it - if (!isJsonContentType()) { - throw new RuntimeException("Response was expected to be JSON, body was: \n" + body); - } - JsonNode currentNode = null; - try { - currentNode = DefaultObjectMapper.readTree(body); - } catch (final Exception e) { - throw new RuntimeException(e); - } - - // Break the path into parts, and scan into the json object - try (final Scanner jsonPathScanner = new Scanner(jsonDotPath).useDelimiter("\\.")) { - if (!jsonPathScanner.hasNext()) { - throw new RuntimeException("Invalid json dot path '" + jsonDotPath + "', rewrite with '.' characters between path elements."); - } - do { - String pathEntry = jsonPathScanner.next(); - // if pathEntry is an array lookup - int arrayEntryIdx = -1; - - // Looks for an array-lookup pattern in the path - // e.g. root_cause[1] -> will match - // e.g. root_cause[2aasd] -> won't match - final Pattern r = Pattern.compile("(.+?)\\[(\\d+)\\]"); - final Matcher m = r.matcher(pathEntry); - if(m.find()) { - pathEntry = m.group(1); - arrayEntryIdx = Integer.parseInt(m.group(2)); - } - - if (!currentNode.has(pathEntry)) { - throw new RuntimeException("Unable to resolve '" + jsonDotPath + "', on path entry '" + pathEntry + "' from available fields " + currentNode.toPrettyString()); - } - currentNode = currentNode.get(pathEntry); - - // if it's an Array lookup we get the requested index item - if (arrayEntryIdx > -1) { - if(!currentNode.isArray()) { - throw new RuntimeException("Unable to resolve '" + jsonDotPath + "', the '" + pathEntry + "' field is not an array " + currentNode.toPrettyString()); - } else if (!currentNode.has(arrayEntryIdx)) { - throw new RuntimeException("Unable to resolve '" + jsonDotPath + "', index '" + arrayEntryIdx + "' is out of bounds for array '" + pathEntry + "' \n" + currentNode.toPrettyString()); - } - currentNode = currentNode.get(arrayEntryIdx); - } - } while (jsonPathScanner.hasNext()); - - if (!currentNode.isValueNode()) { - throw new RuntimeException("Unexpected value note, index directly to the object to reference, object\n" + currentNode.toPrettyString()); - } - return currentNode.asText(); - } - } - - private static HttpResponse from(Future future) { - try { - return future.get(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - + protected final Logger log = LogManager.getLogger(RestHelper.class); + + public boolean enableHTTPClientSSL = true; + public boolean enableHTTPClientSSLv3Only = false; + public boolean sendAdminCertificate = false; + public boolean trustHTTPServerCertificate = true; + public boolean sendHTTPClientCredentials = false; + public String keystore = "node-0-keystore.jks"; + public final String prefix; + // public String truststore = "truststore.jks"; + private ClusterInfo clusterInfo; + + public RestHelper(ClusterInfo clusterInfo, String prefix) { + this.clusterInfo = clusterInfo; + this.prefix = prefix; + } + + public RestHelper(ClusterInfo clusterInfo, boolean enableHTTPClientSSL, boolean trustHTTPServerCertificate, String prefix) { + this.clusterInfo = clusterInfo; + this.enableHTTPClientSSL = enableHTTPClientSSL; + this.trustHTTPServerCertificate = trustHTTPServerCertificate; + this.prefix = prefix; + } + + public String executeSimpleRequest(final String request) throws Exception { + + CloseableHttpAsyncClient httpClient = null; + + try { + httpClient = getHTTPClient(); + httpClient.start(); + + final CompletableFuture future = new CompletableFuture<>(); + final SimpleHttpRequest simpleRequest = SimpleRequestBuilder.copy(new HttpGet(getRequestUri(request))).build(); + httpClient.execute(simpleRequest, new FutureCallback() { + @Override + public void completed(SimpleHttpResponse result) { + future.complete(result); + } + + @Override + public void failed(Exception ex) { + future.completeExceptionally(ex); + } + + @Override + public void cancelled() { + future.cancel(true); + } + }); + + final SimpleHttpResponse response = future.join(); + if (response.getCode() >= 300) { + throw new Exception("Statuscode " + response.getCode()); + } + + if (enableHTTPClientSSL && !response.getVersion().equals(HttpVersion.HTTP_2)) { + throw new IllegalStateException("HTTP/2 expected for HTTPS communication but " + response.getVersion() + " was used"); + } + + return response.getBodyText(); + } catch (final CompletionException e) { + final Throwable cause = e.getCause(); + // Make it compatible with DefaultHttpResponseParser::createConnectionClosedException() + if (cause instanceof ConnectionClosedException) { + throw new NoHttpResponseException(cause.getMessage(), cause); + } else { + throw (Exception) cause; + } + } finally { + if (httpClient != null) { + httpClient.close(); + } + } + } + + public HttpResponse[] executeMultipleAsyncPutRequest(final int numOfRequests, final String request, String body) throws Exception { + final ExecutorService executorService = Executors.newFixedThreadPool(numOfRequests); + Future[] futures = new Future[numOfRequests]; + for (int i = 0; i < numOfRequests; i++) { + futures[i] = executorService.submit(() -> executePutRequest(request, body, new Header[0])); + } + executorService.shutdown(); + return Arrays.stream(futures).map(HttpResponse::from).toArray(s -> new HttpResponse[s]); + } + + public HttpResponse executeGetRequest(final String request, Header... header) { + return executeRequest(new HttpGet(getRequestUri(request)), header); + } + + public HttpResponse executeGetRequest(final String request, String body, Header... header) { + HttpGet getRequest = new HttpGet(getRequestUri(request)); + getRequest.setEntity(createStringEntity(body)); + getRequest.addHeader(HttpHeaders.CONTENT_TYPE, "application/json"); + return executeRequest(getRequest, header); + } + + public HttpResponse executeHeadRequest(final String request, Header... header) { + return executeRequest(new HttpHead(getRequestUri(request)), header); + } + + public HttpResponse executeOptionsRequest(final String request) { + return executeRequest(new HttpOptions(getRequestUri(request))); + } + + public HttpResponse executePutRequest(final String request, String body, Header... header) { + HttpPut uriRequest = new HttpPut(getRequestUri(request)); + if (body != null && !body.isEmpty()) { + uriRequest.setEntity(createStringEntity(body)); + } + return executeRequest(uriRequest, header); + } + + public HttpResponse executeDeleteRequest(final String request, Header... header) { + return executeRequest(new HttpDelete(getRequestUri(request)), header); + } + + public HttpResponse executeDeleteRequest(final String request, String body, Header... header) { + HttpDelete delRequest = new HttpDelete(getRequestUri(request)); + delRequest.setEntity(createStringEntity(body)); + delRequest.setHeader(HttpHeaders.CONTENT_TYPE, "application/json"); + return executeRequest(delRequest, header); + } + + public HttpResponse executePostRequest(final String request, String body, Header... header) { + HttpPost uriRequest = new HttpPost(getRequestUri(request)); + if (body != null && !body.isEmpty()) { + uriRequest.setEntity(createStringEntity(body)); + } + + return executeRequest(uriRequest, header); + } + + public HttpResponse executePatchRequest(final String request, String body, Header... header) { + HttpPatch uriRequest = new HttpPatch(getRequestUri(request)); + if (body != null && !body.isEmpty()) { + uriRequest.setEntity(createStringEntity(body)); + } + return executeRequest(uriRequest, header); + } + + public HttpResponse executeRequest(HttpUriRequest uriRequest, Header... header) { + + CloseableHttpAsyncClient httpClient = null; + try { + + httpClient = getHTTPClient(); + httpClient.start(); + + if (header != null && header.length > 0) { + for (int i = 0; i < header.length; i++) { + Header h = header[i]; + uriRequest.addHeader(h); + } + } + + if (!uriRequest.containsHeader("Content-Type")) { + uriRequest.addHeader("Content-Type", "application/json"); + } + + final CompletableFuture future = new CompletableFuture<>(); + final SimpleHttpRequest simpleRequest = SimpleRequestBuilder.copy(uriRequest).build(); + if (uriRequest.getEntity() != null) { + simpleRequest.setBody( + EntityUtils.toByteArray(uriRequest.getEntity()), + ContentType.parse(uriRequest.getEntity().getContentType()) + ); + } + httpClient.execute(simpleRequest, new FutureCallback() { + @Override + public void completed(SimpleHttpResponse result) { + future.complete(result); + } + + @Override + public void failed(Exception ex) { + future.completeExceptionally(ex); + } + + @Override + public void cancelled() { + future.cancel(true); + } + }); + + final HttpResponse res = new HttpResponse(future.join()); + if (enableHTTPClientSSL && !res.getProtocolVersion().equals(HttpVersion.HTTP_2)) { + throw new IllegalStateException("HTTP/2 expected for HTTPS communication but " + res.getProtocolVersion() + " was used"); + } + + log.debug(res.getBody()); + return res; + } catch (final CompletionException e) { + final Throwable cause = e.getCause(); + // Make it compatible with DefaultHttpResponseParser::createConnectionClosedException() + if (cause instanceof ConnectionClosedException) { + throw new RuntimeException(new NoHttpResponseException(cause.getMessage(), cause)); + } else if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } else { + throw new RuntimeException(cause); + } + } catch (final Exception e) { + throw new RuntimeException(e); + } finally { + + if (httpClient != null) { + try { + httpClient.close(); + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + } + } + + private HttpEntity createStringEntity(String body) { + return new StringEntity(body); + } + + protected final String getHttpServerUri() { + final String address = "http" + (enableHTTPClientSSL ? "s" : "") + "://" + clusterInfo.httpHost + ":" + clusterInfo.httpPort; + log.debug("Connect to {}", address); + return address; + } + + protected final String getRequestUri(String request) { + return getHttpServerUri() + "/" + StringUtils.strip(request, "/"); + } + + protected final CloseableHttpAsyncClient getHTTPClient() throws Exception { + + final HttpAsyncClientBuilder hcb = HttpAsyncClients.custom(); + + if (sendHTTPClientCredentials) { + UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("sarek", "sarek".toCharArray()); + BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(new AuthScope(null, -1), credentials); + hcb.setDefaultCredentialsProvider(credentialsProvider); + } + + if (enableHTTPClientSSL) { + + log.debug("Configure HTTP client with SSL"); + + if (prefix != null && !keystore.contains("/")) { + keystore = prefix + "/" + keystore; + } + + final String keyStorePath = FileHelper.getAbsoluteFilePathFromClassPath(keystore).toFile().getParent(); + + final KeyStore myTrustStore = KeyStore.getInstance("JKS"); + myTrustStore.load(new FileInputStream(keyStorePath + "/truststore.jks"), "changeit".toCharArray()); + + final KeyStore keyStore = KeyStore.getInstance("JKS"); + keyStore.load(new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath(keystore).toFile()), "changeit".toCharArray()); + + final SSLContextBuilder sslContextbBuilder = SSLContexts.custom(); + + if (trustHTTPServerCertificate) { + sslContextbBuilder.loadTrustMaterial(myTrustStore, null); + } + + if (sendAdminCertificate) { + sslContextbBuilder.loadKeyMaterial(keyStore, "changeit".toCharArray()); + } + + final SSLContext sslContext = sslContextbBuilder.build(); + + String[] protocols = null; + + if (enableHTTPClientSSLv3Only) { + protocols = new String[] { "SSLv3" }; + } else { + protocols = new String[] { "TLSv1", "TLSv1.1", "TLSv1.2" }; + } + + final TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create() + .setSslContext(sslContext) + .setTlsVersions(protocols) + .setHostnameVerifier(NoopHostnameVerifier.INSTANCE) + // See please https://issues.apache.org/jira/browse/HTTPCLIENT-2219 + .setTlsDetailsFactory(new Factory() { + @Override + public TlsDetails create(final SSLEngine sslEngine) { + return new TlsDetails(sslEngine.getSession(), sslEngine.getApplicationProtocol()); + } + }) + .build(); + + final AsyncClientConnectionManager cm = PoolingAsyncClientConnectionManagerBuilder.create().setTlsStrategy(tlsStrategy).build(); + + hcb.setConnectionManager(cm); + } + + final RequestConfig.Builder requestConfigBuilder = RequestConfig.custom().setResponseTimeout(Timeout.ofSeconds(60)); + + return hcb.setDefaultRequestConfig(requestConfigBuilder.build()).disableAutomaticRetries().build(); + } + + public static class HttpResponse { + private final SimpleHttpResponse inner; + private final String body; + private final Header[] header; + private final int statusCode; + private final String statusReason; + private final ProtocolVersion protocolVersion; + + public HttpResponse(SimpleHttpResponse inner) throws IllegalStateException, IOException { + super(); + this.inner = inner; + if (inner.getBody() == null) { // head request does not have a entity + this.body = ""; + } else { + this.body = inner.getBodyText(); + } + this.header = inner.getHeaders(); + this.statusCode = inner.getCode(); + this.statusReason = inner.getReasonPhrase(); + this.protocolVersion = inner.getVersion(); + } + + public String getContentType() { + Header h = getInner().getFirstHeader("content-type"); + if (h != null) { + return h.getValue(); + } + return null; + } + + public boolean isJsonContentType() { + String ct = getContentType(); + if (ct == null) { + return false; + } + return ct.contains("application/json"); + } + + public SimpleHttpResponse getInner() { + return inner; + } + + public String getBody() { + return body; + } + + public Header[] getHeader() { + return header; + } + + public int getStatusCode() { + return statusCode; + } + + public String getStatusReason() { + return statusReason; + } + + public List
getHeaders() { + return header == null ? Collections.emptyList() : Arrays.asList(header); + } + + public ProtocolVersion getProtocolVersion() { + return protocolVersion; + } + + @Override + public String toString() { + return "HttpResponse [inner=" + + inner + + ", body=" + + body + + ", header=" + + Arrays.toString(header) + + ", statusCode=" + + statusCode + + ", statusReason=" + + statusReason + + "]"; + } + + /** + * Given a json path with dots delimiated returns the object at the leaf + */ + public String findValueInJson(final String jsonDotPath) { + // Make sure its json / then parse it + if (!isJsonContentType()) { + throw new RuntimeException("Response was expected to be JSON, body was: \n" + body); + } + JsonNode currentNode = null; + try { + currentNode = DefaultObjectMapper.readTree(body); + } catch (final Exception e) { + throw new RuntimeException(e); + } + + // Break the path into parts, and scan into the json object + try (final Scanner jsonPathScanner = new Scanner(jsonDotPath).useDelimiter("\\.")) { + if (!jsonPathScanner.hasNext()) { + throw new RuntimeException( + "Invalid json dot path '" + jsonDotPath + "', rewrite with '.' characters between path elements." + ); + } + do { + String pathEntry = jsonPathScanner.next(); + // if pathEntry is an array lookup + int arrayEntryIdx = -1; + + // Looks for an array-lookup pattern in the path + // e.g. root_cause[1] -> will match + // e.g. root_cause[2aasd] -> won't match + final Pattern r = Pattern.compile("(.+?)\\[(\\d+)\\]"); + final Matcher m = r.matcher(pathEntry); + if (m.find()) { + pathEntry = m.group(1); + arrayEntryIdx = Integer.parseInt(m.group(2)); + } + + if (!currentNode.has(pathEntry)) { + throw new RuntimeException( + "Unable to resolve '" + + jsonDotPath + + "', on path entry '" + + pathEntry + + "' from available fields " + + currentNode.toPrettyString() + ); + } + currentNode = currentNode.get(pathEntry); + + // if it's an Array lookup we get the requested index item + if (arrayEntryIdx > -1) { + if (!currentNode.isArray()) { + throw new RuntimeException( + "Unable to resolve '" + + jsonDotPath + + "', the '" + + pathEntry + + "' field is not an array " + + currentNode.toPrettyString() + ); + } else if (!currentNode.has(arrayEntryIdx)) { + throw new RuntimeException( + "Unable to resolve '" + + jsonDotPath + + "', index '" + + arrayEntryIdx + + "' is out of bounds for array '" + + pathEntry + + "' \n" + + currentNode.toPrettyString() + ); + } + currentNode = currentNode.get(arrayEntryIdx); + } + } while (jsonPathScanner.hasNext()); + + if (!currentNode.isValueNode()) { + throw new RuntimeException( + "Unexpected value note, index directly to the object to reference, object\n" + currentNode.toPrettyString() + ); + } + return currentNode.asText(); + } + } + + private static HttpResponse from(Future future) { + try { + return future.get(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + } diff --git a/src/test/java/org/opensearch/security/test/helper/rules/SecurityTestWatcher.java b/src/test/java/org/opensearch/security/test/helper/rules/SecurityTestWatcher.java index b0ee40384d..b888bfbc35 100644 --- a/src/test/java/org/opensearch/security/test/helper/rules/SecurityTestWatcher.java +++ b/src/test/java/org/opensearch/security/test/helper/rules/SecurityTestWatcher.java @@ -29,27 +29,27 @@ import org.junit.rules.TestWatcher; import org.junit.runner.Description; -public class SecurityTestWatcher extends TestWatcher{ - - @Override - protected void starting(final Description description) { - final String methodName = description.getMethodName(); - String className = description.getClassName(); - className = className.substring(className.lastIndexOf('.') + 1); - System.out.println("---------------- Starting JUnit-test: " + className + " " + methodName + " ----------------"); - } - - @Override - protected void failed(final Throwable e, final Description description) { - final String methodName = description.getMethodName(); - String className = description.getClassName(); - className = className.substring(className.lastIndexOf('.') + 1); - System.out.println(">>>> " + className + " " + methodName + " FAILED due to " + e); - } - - @Override - protected void finished(final Description description) { - // System.out.println("-----------------------------------------------------------------------------------------"); - } +public class SecurityTestWatcher extends TestWatcher { + + @Override + protected void starting(final Description description) { + final String methodName = description.getMethodName(); + String className = description.getClassName(); + className = className.substring(className.lastIndexOf('.') + 1); + System.out.println("---------------- Starting JUnit-test: " + className + " " + methodName + " ----------------"); + } + + @Override + protected void failed(final Throwable e, final Description description) { + final String methodName = description.getMethodName(); + String className = description.getClassName(); + className = className.substring(className.lastIndexOf('.') + 1); + System.out.println(">>>> " + className + " " + methodName + " FAILED due to " + e); + } + + @Override + protected void finished(final Description description) { + // System.out.println("-----------------------------------------------------------------------------------------"); + } } diff --git a/src/test/java/org/opensearch/security/test/plugin/UserInjectorPlugin.java b/src/test/java/org/opensearch/security/test/plugin/UserInjectorPlugin.java index ae6f5116a1..227dd6699d 100644 --- a/src/test/java/org/opensearch/security/test/plugin/UserInjectorPlugin.java +++ b/src/test/java/org/opensearch/security/test/plugin/UserInjectorPlugin.java @@ -58,36 +58,63 @@ * @author jkressin */ public class UserInjectorPlugin extends Plugin implements NetworkPlugin { - + Settings settings; private final SharedGroupFactory sharedGroupFactory; ThreadPool threadPool; - - public UserInjectorPlugin(final Settings settings, final Path configPath) { + + public UserInjectorPlugin(final Settings settings, final Path configPath) { this.settings = settings; sharedGroupFactory = new SharedGroupFactory(settings); } @Override - public Map> getHttpTransports(Settings settings, ThreadPool threadPool, BigArrays bigArrays, - PageCacheRecycler pageCacheRecycler, CircuitBreakerService circuitBreakerService, NamedXContentRegistry xContentRegistry, - NetworkService networkService, Dispatcher dispatcher, ClusterSettings clusterSettings) { + public Map> getHttpTransports( + Settings settings, + ThreadPool threadPool, + BigArrays bigArrays, + PageCacheRecycler pageCacheRecycler, + CircuitBreakerService circuitBreakerService, + NamedXContentRegistry xContentRegistry, + NetworkService networkService, + Dispatcher dispatcher, + ClusterSettings clusterSettings + ) { final UserInjectingDispatcher validatingDispatcher = new UserInjectingDispatcher(dispatcher); - return ImmutableMap.of("org.opensearch.security.http.UserInjectingServerTransport", - () -> new UserInjectingServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, validatingDispatcher, clusterSettings, sharedGroupFactory)); + return ImmutableMap.of( + "org.opensearch.security.http.UserInjectingServerTransport", + () -> new UserInjectingServerTransport( + settings, + networkService, + bigArrays, + threadPool, + xContentRegistry, + validatingDispatcher, + clusterSettings, + sharedGroupFactory + ) + ); } - + class UserInjectingServerTransport extends Netty4HttpServerTransport { - - public UserInjectingServerTransport(final Settings settings, final NetworkService networkService, final BigArrays bigArrays, - final ThreadPool threadPool, final NamedXContentRegistry namedXContentRegistry, final Dispatcher dispatcher, ClusterSettings clusterSettings, SharedGroupFactory sharedGroupFactory) { + + public UserInjectingServerTransport( + final Settings settings, + final NetworkService networkService, + final BigArrays bigArrays, + final ThreadPool threadPool, + final NamedXContentRegistry namedXContentRegistry, + final Dispatcher dispatcher, + ClusterSettings clusterSettings, + SharedGroupFactory sharedGroupFactory + ) { super(settings, networkService, bigArrays, threadPool, namedXContentRegistry, dispatcher, clusterSettings, sharedGroupFactory); } } - + class UserInjectingDispatcher implements Dispatcher { - + private Dispatcher originalDispatcher; public UserInjectingDispatcher(final Dispatcher originalDispatcher) { @@ -97,14 +124,20 @@ public UserInjectingDispatcher(final Dispatcher originalDispatcher) { @Override public void dispatchRequest(RestRequest request, RestChannel channel, ThreadContext threadContext) { - threadContext.putTransient(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, request.header(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER)); + threadContext.putTransient( + ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, + request.header(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER) + ); originalDispatcher.dispatchRequest(request, channel, threadContext); - + } @Override public void dispatchBadRequest(RestChannel channel, ThreadContext threadContext, Throwable cause) { - threadContext.putTransient(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, channel.request().header(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER)); + threadContext.putTransient( + ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, + channel.request().header(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER) + ); originalDispatcher.dispatchBadRequest(channel, threadContext, cause); } } diff --git a/src/test/java/org/opensearch/security/util/FakeRestRequest.java b/src/test/java/org/opensearch/security/util/FakeRestRequest.java index 989b775709..05e69ef614 100644 --- a/src/test/java/org/opensearch/security/util/FakeRestRequest.java +++ b/src/test/java/org/opensearch/security/util/FakeRestRequest.java @@ -21,11 +21,10 @@ public class FakeRestRequest extends RestRequest { - //private final Map headers; + // private final Map headers; private final BytesReference content; private final Method method; - public FakeRestRequest() { this(new HashMap<>(), new HashMap<>(), null, Method.GET, "/"); } @@ -35,10 +34,10 @@ public FakeRestRequest(Map headers, Map params) } private FakeRestRequest(Map headers, Map params, BytesReference content, Method method, String path) { - //NamedXContentRegistry xContentRegistry, Map params, String path, - //Map> headers, HttpRequest httpRequest, HttpChannel httpChannel + // NamedXContentRegistry xContentRegistry, Map params, String path, + // Map> headers, HttpRequest httpRequest, HttpChannel httpChannel super(null, params, path, convert(headers), null, null); - //this.headers = headers; + // this.headers = headers; this.content = content; this.method = method; } @@ -108,7 +107,7 @@ public FakeRestRequest build() { private static Map> convert(Map headers) { Map> ret = new HashMap>(); - for (String h:headers.keySet()) { + for (String h : headers.keySet()) { ret.put(h, Collections.singletonList(headers.get(h))); } return ret; diff --git a/src/test/java/org/opensearch/security/util/SettingsBasedSSLConfiguratorV4Test.java b/src/test/java/org/opensearch/security/util/SettingsBasedSSLConfiguratorV4Test.java index cc75ec6eb0..976f085ce4 100644 --- a/src/test/java/org/opensearch/security/util/SettingsBasedSSLConfiguratorV4Test.java +++ b/src/test/java/org/opensearch/security/util/SettingsBasedSSLConfiguratorV4Test.java @@ -84,25 +84,32 @@ public class SettingsBasedSSLConfiguratorV4Test { @Test public void testPemTrust() throws Exception { - try (TestServer testServer = new TestServer("sslConfigurator/pem/truststore.jks", - "sslConfigurator/pem/node1-keystore.jks", "secret", false)) { + try ( + TestServer testServer = new TestServer( + "sslConfigurator/pem/truststore.jks", + "sslConfigurator/pem/node1-keystore.jks", + "secret", + false + ) + ) { Path rootCaPemPath = FileHelper.getAbsoluteFilePathFromClassPath("sslConfigurator/pem/root-ca.pem"); Assert.assertTrue(rootCaPemPath.toFile().exists()); Settings settings = Settings.builder() - .put("prefix.pemtrustedcas_filepath", rootCaPemPath.getFileName().toString()) - .put("prefix.enable_ssl", "true") - .put("path.home", rootCaPemPath.getParent().toString()) - .build(); + .put("prefix.pemtrustedcas_filepath", rootCaPemPath.getFileName().toString()) + .put("prefix.enable_ssl", "true") + .put("path.home", rootCaPemPath.getParent().toString()) + .build(); Path configPath = rootCaPemPath.getParent(); SettingsBasedSSLConfiguratorV4 sbsc = new SettingsBasedSSLConfiguratorV4(settings, configPath, "prefix"); SSLConfig sslConfig = sbsc.buildSSLConfig(); - try (CloseableHttpClient httpClient = HttpClients.custom() - .setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build()) { + try ( + CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build() + ) { try (CloseableHttpResponse response = httpClient.execute(new HttpGet(testServer.getUri()))) { // Success @@ -115,23 +122,30 @@ public void testPemTrust() throws Exception { @Test public void testPemWrongTrust() throws Exception { - try (TestServer testServer = new TestServer("sslConfigurator/pem/truststore.jks", - "sslConfigurator/pem/node1-keystore.jks", "secret", false)) { + try ( + TestServer testServer = new TestServer( + "sslConfigurator/pem/truststore.jks", + "sslConfigurator/pem/node1-keystore.jks", + "secret", + false + ) + ) { Path rootCaPemPath = FileHelper.getAbsoluteFilePathFromClassPath("sslConfigurator/pem/other-root-ca.pem"); Settings settings = Settings.builder() - .put("prefix.pemtrustedcas_filepath", rootCaPemPath.getFileName().toString()) - .put("prefix.enable_ssl", "true") - .put("path.home", rootCaPemPath.getParent().toString()) - .build(); + .put("prefix.pemtrustedcas_filepath", rootCaPemPath.getFileName().toString()) + .put("prefix.enable_ssl", "true") + .put("path.home", rootCaPemPath.getParent().toString()) + .build(); Path configPath = rootCaPemPath.getParent(); SettingsBasedSSLConfiguratorV4 sbsc = new SettingsBasedSSLConfiguratorV4(settings, configPath, "prefix"); SSLConfig sslConfig = sbsc.buildSSLConfig(); - try (CloseableHttpClient httpClient = HttpClients.custom() - .setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build()) { + try ( + CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build() + ) { thrown.expect(SSLHandshakeException.class); @@ -146,27 +160,34 @@ public void testPemWrongTrust() throws Exception { @Test public void testPemClientAuth() throws Exception { - try (TestServer testServer = new TestServer("sslConfigurator/pem/truststore.jks", - "sslConfigurator/pem/node1-keystore.jks", "secret", true)) { + try ( + TestServer testServer = new TestServer( + "sslConfigurator/pem/truststore.jks", + "sslConfigurator/pem/node1-keystore.jks", + "secret", + true + ) + ) { Path rootCaPemPath = FileHelper.getAbsoluteFilePathFromClassPath("sslConfigurator/pem/root-ca.pem"); Settings settings = Settings.builder() - .put("prefix.pemtrustedcas_filepath", rootCaPemPath.getFileName().toString()) - .put("prefix.enable_ssl", "true") - .put("path.home", rootCaPemPath.getParent().toString()) - .put("prefix.enable_ssl_client_auth", "true") - .put("prefix.pemcert_filepath", "kirk.pem") - .put("prefix.pemkey_filepath", "kirk.key") - .put("prefix.pemkey_password", "secret") - .build(); + .put("prefix.pemtrustedcas_filepath", rootCaPemPath.getFileName().toString()) + .put("prefix.enable_ssl", "true") + .put("path.home", rootCaPemPath.getParent().toString()) + .put("prefix.enable_ssl_client_auth", "true") + .put("prefix.pemcert_filepath", "kirk.pem") + .put("prefix.pemkey_filepath", "kirk.key") + .put("prefix.pemkey_password", "secret") + .build(); Path configPath = rootCaPemPath.getParent(); SettingsBasedSSLConfiguratorV4 sbsc = new SettingsBasedSSLConfiguratorV4(settings, configPath, "prefix"); SSLConfig sslConfig = sbsc.buildSSLConfig(); - try (CloseableHttpClient httpClient = HttpClients.custom() - .setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build()) { + try ( + CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build() + ) { try (CloseableHttpResponse response = httpClient.execute(new HttpGet(testServer.getUri()))) { // Success @@ -179,33 +200,43 @@ public void testPemClientAuth() throws Exception { @Test public void testPemClientAuthFailure() throws Exception { - try (TestServer testServer = new TestServer("sslConfigurator/pem/truststore.jks", - "sslConfigurator/pem/node1-keystore.jks", "secret", true)) { + try ( + TestServer testServer = new TestServer( + "sslConfigurator/pem/truststore.jks", + "sslConfigurator/pem/node1-keystore.jks", + "secret", + true + ) + ) { Path rootCaPemPath = FileHelper.getAbsoluteFilePathFromClassPath("sslConfigurator/pem/root-ca.pem"); Settings settings = Settings.builder() - .put("prefix.pemtrustedcas_filepath", rootCaPemPath.getFileName().toString()) - .put("prefix.enable_ssl", "true") - .put("path.home", rootCaPemPath.getParent().toString()) - .put("prefix.enable_ssl_client_auth", "true") - .put("prefix.pemcert_filepath", "wrong-kirk.pem") - .put("prefix.pemkey_filepath", "wrong-kirk.key") - .put("prefix.pemkey_password", "G0CVtComen4a") - .build(); + .put("prefix.pemtrustedcas_filepath", rootCaPemPath.getFileName().toString()) + .put("prefix.enable_ssl", "true") + .put("path.home", rootCaPemPath.getParent().toString()) + .put("prefix.enable_ssl_client_auth", "true") + .put("prefix.pemcert_filepath", "wrong-kirk.pem") + .put("prefix.pemkey_filepath", "wrong-kirk.key") + .put("prefix.pemkey_password", "G0CVtComen4a") + .build(); Path configPath = rootCaPemPath.getParent(); SettingsBasedSSLConfiguratorV4 sbsc = new SettingsBasedSSLConfiguratorV4(settings, configPath, "prefix"); SSLConfig sslConfig = sbsc.buildSSLConfig(); - try (CloseableHttpClient httpClient = HttpClients.custom() - .setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build()) { + try ( + CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build() + ) { // Due to some race condition in Java's internal network stack, this can be one // of the following exceptions - thrown.expect(either(instanceOf(SocketException.class)).or(instanceOf(SSLHandshakeException.class)) - .or(instanceOf(SSLException.class)) // Java 11: javax.net.ssl.SSLException: readHandshakeRecord + thrown.expect( + either(instanceOf(SocketException.class)).or(instanceOf(SSLHandshakeException.class)).or(instanceOf(SSLException.class)) // Java + // 11: + // javax.net.ssl.SSLException: + // readHandshakeRecord ); try (CloseableHttpResponse response = httpClient.execute(new HttpGet(testServer.getUri()))) { @@ -218,24 +249,31 @@ public void testPemClientAuthFailure() throws Exception { @Test public void testPemHostnameVerificationFailure() throws Exception { - try (TestServer testServer = new TestServer("sslConfigurator/pem/truststore.jks", - "sslConfigurator/pem/node-wrong-hostname-keystore.jks", "secret", false)) { + try ( + TestServer testServer = new TestServer( + "sslConfigurator/pem/truststore.jks", + "sslConfigurator/pem/node-wrong-hostname-keystore.jks", + "secret", + false + ) + ) { Path rootCaPemPath = FileHelper.getAbsoluteFilePathFromClassPath("sslConfigurator/pem/root-ca.pem"); Settings settings = Settings.builder() - .put("prefix.pemtrustedcas_filepath", rootCaPemPath.getFileName().toString()) - .put("prefix.enable_ssl", "true") - .put("prefix.verify_hostnames", "true") - .put("path.home", rootCaPemPath.getParent().toString()) - .build(); + .put("prefix.pemtrustedcas_filepath", rootCaPemPath.getFileName().toString()) + .put("prefix.enable_ssl", "true") + .put("prefix.verify_hostnames", "true") + .put("path.home", rootCaPemPath.getParent().toString()) + .build(); Path configPath = rootCaPemPath.getParent(); SettingsBasedSSLConfiguratorV4 sbsc = new SettingsBasedSSLConfiguratorV4(settings, configPath, "prefix"); SSLConfig sslConfig = sbsc.buildSSLConfig(); - try (CloseableHttpClient httpClient = HttpClients.custom() - .setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build()) { + try ( + CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build() + ) { thrown.expect(SSLPeerUnverifiedException.class); @@ -249,24 +287,31 @@ public void testPemHostnameVerificationFailure() throws Exception { @Test public void testPemHostnameVerificationOff() throws Exception { - try (TestServer testServer = new TestServer("sslConfigurator/pem/truststore.jks", - "sslConfigurator/pem/node-wrong-hostname-keystore.jks", "secret", false)) { + try ( + TestServer testServer = new TestServer( + "sslConfigurator/pem/truststore.jks", + "sslConfigurator/pem/node-wrong-hostname-keystore.jks", + "secret", + false + ) + ) { Path rootCaPemPath = FileHelper.getAbsoluteFilePathFromClassPath("sslConfigurator/pem/root-ca.pem"); Settings settings = Settings.builder() - .put("prefix.pemtrustedcas_filepath", rootCaPemPath.getFileName().toString()) - .put("prefix.enable_ssl", "true") - .put("prefix.verify_hostnames", "false") - .put("path.home", rootCaPemPath.getParent().toString()) - .build(); + .put("prefix.pemtrustedcas_filepath", rootCaPemPath.getFileName().toString()) + .put("prefix.enable_ssl", "true") + .put("prefix.verify_hostnames", "false") + .put("path.home", rootCaPemPath.getParent().toString()) + .build(); Path configPath = rootCaPemPath.getParent(); SettingsBasedSSLConfiguratorV4 sbsc = new SettingsBasedSSLConfiguratorV4(settings, configPath, "prefix"); SSLConfig sslConfig = sbsc.buildSSLConfig(); - try (CloseableHttpClient httpClient = HttpClients.custom() - .setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build()) { + try ( + CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build() + ) { try (CloseableHttpResponse response = httpClient.execute(new HttpGet(testServer.getUri()))) { // Success @@ -278,26 +323,33 @@ public void testPemHostnameVerificationOff() throws Exception { @Test public void testJksTrust() throws Exception { - try (TestServer testServer = new TestServer("sslConfigurator/jks/truststore.jks", - "sslConfigurator/jks/node1-keystore.jks", "secret", false)) { + try ( + TestServer testServer = new TestServer( + "sslConfigurator/jks/truststore.jks", + "sslConfigurator/jks/node1-keystore.jks", + "secret", + false + ) + ) { Path rootCaJksPath = FileHelper.getAbsoluteFilePathFromClassPath("sslConfigurator/jks/truststore.jks"); MockSecureSettings mockSecureSettings = new MockSecureSettings(); mockSecureSettings.setString(SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD.propertyName, "secret"); Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, rootCaJksPath.getFileName().toString()) - .put("prefix.enable_ssl", "true") - .put("path.home", rootCaJksPath.getParent().toString()) - .setSecureSettings(mockSecureSettings) - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, rootCaJksPath.getFileName().toString()) + .put("prefix.enable_ssl", "true") + .put("path.home", rootCaJksPath.getParent().toString()) + .setSecureSettings(mockSecureSettings) + .build(); Path configPath = rootCaJksPath.getParent(); SettingsBasedSSLConfiguratorV4 sbsc = new SettingsBasedSSLConfiguratorV4(settings, configPath, "prefix"); SSLConfig sslConfig = sbsc.buildSSLConfig(); - try (CloseableHttpClient httpClient = HttpClients.custom() - .setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build()) { + try ( + CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build() + ) { try (CloseableHttpResponse response = httpClient.execute(new HttpGet(testServer.getUri()))) { // Success @@ -310,26 +362,33 @@ public void testJksTrust() throws Exception { @Test public void testJksWrongTrust() throws Exception { - try (TestServer testServer = new TestServer("sslConfigurator/jks/truststore.jks", - "sslConfigurator/jks/node1-keystore.jks", "secret", false)) { + try ( + TestServer testServer = new TestServer( + "sslConfigurator/jks/truststore.jks", + "sslConfigurator/jks/node1-keystore.jks", + "secret", + false + ) + ) { Path rootCaJksPath = FileHelper.getAbsoluteFilePathFromClassPath("sslConfigurator/jks/other-root-ca.jks"); MockSecureSettings mockSecureSettings = new MockSecureSettings(); mockSecureSettings.setString(SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD.propertyName, "secret"); Settings settings = Settings.builder() - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, rootCaJksPath.getFileName().toString()) - .put("prefix.enable_ssl", "true") - .put("path.home", rootCaJksPath.getParent().toString()) - .setSecureSettings(mockSecureSettings) - .build(); + .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, rootCaJksPath.getFileName().toString()) + .put("prefix.enable_ssl", "true") + .put("path.home", rootCaJksPath.getParent().toString()) + .setSecureSettings(mockSecureSettings) + .build(); Path configPath = rootCaJksPath.getParent(); SettingsBasedSSLConfiguratorV4 sbsc = new SettingsBasedSSLConfiguratorV4(settings, configPath, "prefix"); SSLConfig sslConfig = sbsc.buildSSLConfig(); - try (CloseableHttpClient httpClient = HttpClients.custom() - .setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build()) { + try ( + CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build() + ) { thrown.expect(SSLHandshakeException.class); @@ -342,23 +401,30 @@ public void testJksWrongTrust() throws Exception { @Test public void testTrustAll() throws Exception { - try (TestServer testServer = new TestServer("sslConfigurator/jks/truststore.jks", - "sslConfigurator/jks/node1-keystore.jks", "secret", false)) { + try ( + TestServer testServer = new TestServer( + "sslConfigurator/jks/truststore.jks", + "sslConfigurator/jks/node1-keystore.jks", + "secret", + false + ) + ) { Path rootCaJksPath = FileHelper.getAbsoluteFilePathFromClassPath("sslConfigurator/jks/other-root-ca.jks"); Settings settings = Settings.builder() - .put("prefix.enable_ssl", "true") - .put("prefix.trust_all", "true") - .put("path.home", rootCaJksPath.getParent().toString()) - .build(); + .put("prefix.enable_ssl", "true") + .put("prefix.trust_all", "true") + .put("path.home", rootCaJksPath.getParent().toString()) + .build(); Path configPath = rootCaJksPath.getParent(); SettingsBasedSSLConfiguratorV4 sbsc = new SettingsBasedSSLConfiguratorV4(settings, configPath, "prefix"); SSLConfig sslConfig = sbsc.buildSSLConfig(); - try (CloseableHttpClient httpClient = HttpClients.custom() - .setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build()) { + try ( + CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()).build() + ) { try (CloseableHttpResponse response = httpClient.execute(new HttpGet(testServer.getUri()))) { // Success @@ -379,43 +445,50 @@ String getUri() { return "https://localhost:" + port + "/test"; } - private void createHttpServer(String trustStore, String keyStore, String password, boolean clientAuth) - throws IOException { + private void createHttpServer(String trustStore, String keyStore, String password, boolean clientAuth) throws IOException { this.port = SocketUtils.findAvailableTcpPort(); - ServerBootstrap serverBootstrap = ServerBootstrap.bootstrap().setListenerPort(port).registerHandler("test", - new HttpRequestHandler() { + ServerBootstrap serverBootstrap = ServerBootstrap.bootstrap() + .setListenerPort(port) + .registerHandler("test", new HttpRequestHandler() { - @Override - public void handle(HttpRequest request, HttpResponse response, HttpContext context) - throws HttpException, IOException { + @Override + public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { - } - }); + } + }); serverBootstrap = serverBootstrap.setSslContext(createSSLContext(trustStore, keyStore, password)) - .setSslSetupHandler(new SSLServerSetupHandler() { + .setSslSetupHandler(new SSLServerSetupHandler() { - @Override - public void initialize(SSLServerSocket socket) throws SSLException { - if (clientAuth) { - socket.setNeedClientAuth(true); - } - } - }).setConnectionFactory(new HttpConnectionFactory() { - - private ConnectionConfig cconfig = ConnectionConfig.DEFAULT; - - @Override - public DefaultBHttpServerConnection createConnection(final Socket socket) throws IOException { - final SSLTestHttpServerConnection conn = new SSLTestHttpServerConnection( - this.cconfig.getBufferSize(), this.cconfig.getFragmentSizeHint(), - ConnSupport.createDecoder(this.cconfig), ConnSupport.createEncoder(this.cconfig), - this.cconfig.getMessageConstraints(), null, null, null, null); - conn.bind(socket); - return conn; + @Override + public void initialize(SSLServerSocket socket) throws SSLException { + if (clientAuth) { + socket.setNeedClientAuth(true); } - }); + } + }) + .setConnectionFactory(new HttpConnectionFactory() { + + private ConnectionConfig cconfig = ConnectionConfig.DEFAULT; + + @Override + public DefaultBHttpServerConnection createConnection(final Socket socket) throws IOException { + final SSLTestHttpServerConnection conn = new SSLTestHttpServerConnection( + this.cconfig.getBufferSize(), + this.cconfig.getFragmentSizeHint(), + ConnSupport.createDecoder(this.cconfig), + ConnSupport.createEncoder(this.cconfig), + this.cconfig.getMessageConstraints(), + null, + null, + null, + null + ); + conn.bind(socket); + return conn; + } + }); this.httpServer = serverBootstrap.create(); @@ -434,8 +507,7 @@ private SSLContext createSSLContext(String trustStorePath, String keyStorePath, try { TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); KeyStore trustStore = KeyStore.getInstance("JKS"); - InputStream trustStream = new FileInputStream( - FileHelper.getAbsoluteFilePathFromClassPath(trustStorePath).toFile()); + InputStream trustStream = new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath(trustStorePath).toFile()); trustStore.load(trustStream, password.toCharArray()); tmf.init(trustStore); @@ -472,14 +544,28 @@ public String chooseAlias(Map aliases, Socket socket) } static class SSLTestHttpServerConnection extends DefaultBHttpServerConnection { - public SSLTestHttpServerConnection(final int buffersize, final int fragmentSizeHint, - final CharsetDecoder chardecoder, final CharsetEncoder charencoder, - final MessageConstraints constraints, final ContentLengthStrategy incomingContentStrategy, - final ContentLengthStrategy outgoingContentStrategy, - final HttpMessageParserFactory requestParserFactory, - final HttpMessageWriterFactory responseWriterFactory) { - super(buffersize, fragmentSizeHint, chardecoder, charencoder, constraints, incomingContentStrategy, - outgoingContentStrategy, requestParserFactory, responseWriterFactory); + public SSLTestHttpServerConnection( + final int buffersize, + final int fragmentSizeHint, + final CharsetDecoder chardecoder, + final CharsetEncoder charencoder, + final MessageConstraints constraints, + final ContentLengthStrategy incomingContentStrategy, + final ContentLengthStrategy outgoingContentStrategy, + final HttpMessageParserFactory requestParserFactory, + final HttpMessageWriterFactory responseWriterFactory + ) { + super( + buffersize, + fragmentSizeHint, + chardecoder, + charencoder, + constraints, + incomingContentStrategy, + outgoingContentStrategy, + requestParserFactory, + responseWriterFactory + ); } public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { diff --git a/src/test/resources/auditlog/data2.json b/src/test/resources/auditlog/data2.json index 1d37b6abc2..cc4748ed82 100644 --- a/src/test/resources/auditlog/data2.json +++ b/src/test/resources/auditlog/data2.json @@ -1,6 +1,6 @@ { "text": "text question value", "joinfield": { - "name": "question" + "name": "question" } } diff --git a/src/test/resources/auditlog/data3.json b/src/test/resources/auditlog/data3.json index 05c678b114..6846fe0f68 100644 --- a/src/test/resources/auditlog/data3.json +++ b/src/test/resources/auditlog/data3.json @@ -1,7 +1,7 @@ { "text": "text answer value", "joinfield": { - "name": "answer", - "parent": "1" + "name": "answer", + "parent": "1" } } diff --git a/src/test/resources/auditlog/endpoints/configuration_wrong_endpoint_names.yml b/src/test/resources/auditlog/endpoints/configuration_wrong_endpoint_names.yml index 24fb5dcae5..dee8c95641 100644 --- a/src/test/resources/auditlog/endpoints/configuration_wrong_endpoint_names.yml +++ b/src/test/resources/auditlog/endpoints/configuration_wrong_endpoint_names.yml @@ -7,7 +7,7 @@ plugins.security: type: external_opensearch config: http_endpoints: ['localhost:9200','localhost:9201','localhost:9202'] - index: auditlog + index: auditlog username: auditloguser password: auditlogpassword enable_ssl: false diff --git a/src/test/resources/auditlog/endpoints/routing/configuration_valid.yml b/src/test/resources/auditlog/endpoints/routing/configuration_valid.yml index 75df18aac7..046e4d6ee5 100644 --- a/src/test/resources/auditlog/endpoints/routing/configuration_valid.yml +++ b/src/test/resources/auditlog/endpoints/routing/configuration_valid.yml @@ -3,7 +3,7 @@ plugins.security: type: external_opensearch config: http_endpoints: ['localhost:9200','localhost:9201','localhost:9202'] - index: auditlog + index: auditlog username: auditloguser password: auditlogpassword enable_ssl: false @@ -16,7 +16,7 @@ plugins.security: type: external_opensearch config: http_endpoints: ['localhost:9200','localhost:9201','localhost:9202'] - index: auditlog + index: auditlog username: auditloguser password: auditlogpassword enable_ssl: false diff --git a/src/test/resources/auditlog/endpoints/routing/configuration_wrong_endpoint_names.yml b/src/test/resources/auditlog/endpoints/routing/configuration_wrong_endpoint_names.yml index 2361b6049b..2b96265492 100644 --- a/src/test/resources/auditlog/endpoints/routing/configuration_wrong_endpoint_names.yml +++ b/src/test/resources/auditlog/endpoints/routing/configuration_wrong_endpoint_names.yml @@ -8,7 +8,7 @@ plugins.security: type: external_opensearch config: http_endpoints: ['localhost:9200','localhost:9201','localhost:9202'] - index: auditlog + index: auditlog username: auditloguser password: auditlogpassword enable_ssl: false diff --git a/src/test/resources/auditlog/endpoints/routing/configuration_wrong_endpoint_types.yml b/src/test/resources/auditlog/endpoints/routing/configuration_wrong_endpoint_types.yml index 6b6929b2c7..c59adc4ee1 100644 --- a/src/test/resources/auditlog/endpoints/routing/configuration_wrong_endpoint_types.yml +++ b/src/test/resources/auditlog/endpoints/routing/configuration_wrong_endpoint_types.yml @@ -8,7 +8,7 @@ plugins.security: type: external_opensearch config: http_endpoints: ['localhost:9200','localhost:9201','localhost:9202'] - index: auditlog + index: auditlog username: auditloguser password: auditlogpassword enable_ssl: false diff --git a/src/test/resources/auditlog/endpoints/routing/routing.yml b/src/test/resources/auditlog/endpoints/routing/routing.yml index ac6596424e..4135b800e2 100644 --- a/src/test/resources/auditlog/endpoints/routing/routing.yml +++ b/src/test/resources/auditlog/endpoints/routing/routing.yml @@ -19,4 +19,4 @@ plugins.security: - endpoint3 COMPLIANCE_DOC_WRITE: endpoints: - - default + - default diff --git a/src/test/resources/auditlog/endpoints/sink/configuration_all_variants.yml b/src/test/resources/auditlog/endpoints/sink/configuration_all_variants.yml index e441322c17..f1c8620e88 100644 --- a/src/test/resources/auditlog/endpoints/sink/configuration_all_variants.yml +++ b/src/test/resources/auditlog/endpoints/sink/configuration_all_variants.yml @@ -17,10 +17,10 @@ plugins.security: type: external_opensearch something: key: value - endpoint6: + endpoint6: something: key: value - endpoint7: + endpoint7: config: key: value endpoint8: diff --git a/src/test/resources/auditlog/endpoints/sink/configuration_no_default.yml b/src/test/resources/auditlog/endpoints/sink/configuration_no_default.yml index f81b37dde2..013410ea77 100644 --- a/src/test/resources/auditlog/endpoints/sink/configuration_no_default.yml +++ b/src/test/resources/auditlog/endpoints/sink/configuration_no_default.yml @@ -16,10 +16,10 @@ plugins.security: type: external_opensearch something: key: value - endpoint6: + endpoint6: something: key: value - endpoint7: + endpoint7: config: key: value endpoint8: diff --git a/src/test/resources/config_auth_ratelimiting.yml b/src/test/resources/config_auth_ratelimiting.yml index 3675afc33e..a55ad0b5d3 100644 --- a/src/test/resources/config_auth_ratelimiting.yml +++ b/src/test/resources/config_auth_ratelimiting.yml @@ -23,5 +23,5 @@ config: allowed_tries: 10 internal_authentication_backend_limiting: type: username - authentication_backend: intern + authentication_backend: intern allowed_tries: 3 diff --git a/src/test/resources/config_ldap.yml b/src/test/resources/config_ldap.yml index c2aebf869b..5dc0895d8d 100644 --- a/src/test/resources/config_ldap.yml +++ b/src/test/resources/config_ldap.yml @@ -7,7 +7,7 @@ plugins.security: remoteIpHeader: "x-forwarded-for" proxiesHeader: "x-forwarded-by" trustedProxies: "proxy1|proxy2" - authenticator: + authenticator: type: org.opensearch.security.http.HTTPBasicAuthenticator authcz: authentication_domain_basic_internal: diff --git a/src/test/resources/data2.json b/src/test/resources/data2.json index 1d37b6abc2..cc4748ed82 100644 --- a/src/test/resources/data2.json +++ b/src/test/resources/data2.json @@ -1,6 +1,6 @@ { "text": "text question value", "joinfield": { - "name": "question" + "name": "question" } } diff --git a/src/test/resources/data3.json b/src/test/resources/data3.json index 05c678b114..6846fe0f68 100644 --- a/src/test/resources/data3.json +++ b/src/test/resources/data3.json @@ -1,7 +1,7 @@ { "text": "text answer value", "joinfield": { - "name": "answer", - "parent": "1" + "name": "answer", + "parent": "1" } } diff --git a/src/test/resources/dlsfls/doc1.json b/src/test/resources/dlsfls/doc1.json index 6067eedc9a..7dccde9b93 100644 --- a/src/test/resources/dlsfls/doc1.json +++ b/src/test/resources/dlsfls/doc1.json @@ -1,5 +1,5 @@ { - + "customer": { "name": "", "type": "normal", @@ -9,8 +9,8 @@ "street": "street1", "zip": "12345", "city": "mycity" - - } + + } }, "secret": "a secret value", @@ -34,7 +34,7 @@ "boolfield5": true, "boolfield6": false, "nullfield": null, - + "@timestamp": "", "timestamp": "" diff --git a/src/test/resources/dlsfls/flsquery.json b/src/test/resources/dlsfls/flsquery.json index 9418e8721b..19d3897971 100644 --- a/src/test/resources/dlsfls/flsquery.json +++ b/src/test/resources/dlsfls/flsquery.json @@ -34,9 +34,9 @@ } }, "query":{ - - - + + + "bool":{ "must":[ { @@ -53,8 +53,8 @@ ] } - - + + }, "stored_fields":[ "*", diff --git a/src/test/resources/dlsfls/flsquery2.json b/src/test/resources/dlsfls/flsquery2.json index a5ad1da20e..26fce316db 100644 --- a/src/test/resources/dlsfls/flsquery2.json +++ b/src/test/resources/dlsfls/flsquery2.json @@ -38,8 +38,8 @@ "match_all":{ - - + + } }, "stored_fields":[ diff --git a/src/test/resources/dlsfls/internal_users_tlq.yml b/src/test/resources/dlsfls/internal_users_tlq.yml index 5bbec586f0..dff0a67633 100644 --- a/src/test/resources/dlsfls/internal_users_tlq.yml +++ b/src/test/resources/dlsfls/internal_users_tlq.yml @@ -2,7 +2,7 @@ _meta: type: "internalusers" config_version: 2 - + tlq_1337: hash: "$2y$12$SP9z.rBgEHTlueKkiqSK/OxqB2PLJN/eRoNJ8WOPoHWIpirvbFAAy" # "password" backend_roles: ["os_dls_tlq_lookup"] diff --git a/src/test/resources/dlsfls/masked_field_mapping.json b/src/test/resources/dlsfls/masked_field_mapping.json index f3629282fd..56863f546c 100644 --- a/src/test/resources/dlsfls/masked_field_mapping.json +++ b/src/test/resources/dlsfls/masked_field_mapping.json @@ -1,5 +1,5 @@ { - + "_doc": { "properties": { @@ -142,6 +142,6 @@ } } } - - + + } diff --git a/src/test/resources/dlsfls/roles_tlq.yml b/src/test/resources/dlsfls/roles_tlq.yml index c2d08ca948..1420a7a965 100644 --- a/src/test/resources/dlsfls/roles_tlq.yml +++ b/src/test/resources/dlsfls/roles_tlq.yml @@ -2,7 +2,7 @@ _meta: type: "roles" config_version: 2 - + os_dls_tlq_lookup: cluster_permissions: - "*" diff --git a/src/test/resources/ldap/test1.yml b/src/test/resources/ldap/test1.yml index e1e396ba01..e0ad96ceea 100644 --- a/src/test/resources/ldap/test1.yml +++ b/src/test/resources/ldap/test1.yml @@ -1,8 +1,8 @@ ---- +--- enable_ssl: true enable_ssl_client_auth: false enable_start_tls: false -#hosts: +#hosts: # - "localhost:${ldapport}" path.home: "." pemcert_content: | diff --git a/src/test/resources/legacy/securityconfig_v6/action_groups.yml b/src/test/resources/legacy/securityconfig_v6/action_groups.yml index 5acbe1aea8..ac564e7421 100644 --- a/src/test/resources/legacy/securityconfig_v6/action_groups.yml +++ b/src/test/resources/legacy/securityconfig_v6/action_groups.yml @@ -128,7 +128,7 @@ OPENDISTRO_SECURITY_CLUSTER_COMPOSITE_OPS: - "indices:admin/aliases*" - "indices:data/write/reindex" - CLUSTER_COMPOSITE_OPS_RO - + OPENDISTRO_SECURITY_MANAGE_SNAPSHOTS: readonly: true permissions: diff --git a/src/test/resources/legacy/securityconfig_v6/config.yml b/src/test/resources/legacy/securityconfig_v6/config.yml index 031be9bb15..19b1fd76cd 100644 --- a/src/test/resources/legacy/securityconfig_v6/config.yml +++ b/src/test/resources/legacy/securityconfig_v6/config.yml @@ -1,14 +1,14 @@ # This is the main OpenSearch Security configuration file where authentication # and authorization is defined. -# +# # You need to configure at least one authentication domain in the authc of this file. -# An authentication domain is responsible for extracting the user credentials from -# the request and for validating them against an authentication backend like Active Directory for example. +# An authentication domain is responsible for extracting the user credentials from +# the request and for validating them against an authentication backend like Active Directory for example. # -# If more than one authentication domain is configured the first one which succeeds wins. +# If more than one authentication domain is configured the first one which succeeds wins. # If all authentication domains fail then the request is unauthenticated. # In this case an exception is thrown and/or the HTTP status is set to 401. -# +# # After authentication authorization (authz) will be applied. There can be zero or more authorizers which collect # the roles from a given backend for the authenticated user. # @@ -21,18 +21,18 @@ # For HTTP it is possible to allow anonymous authentication. If that is the case then the HTTP authenticators try to # find user credentials in the HTTP request. If credentials are found then the user gets regularly authenticated. # If none can be found the user will be authenticated as an "anonymous" user. This user has always the username "opendistro_security_anonymous" -# and one role named "opendistro_security_anonymous_backendrole". +# and one role named "opendistro_security_anonymous_backendrole". # If you enable anonymous authentication all HTTP authenticators will not challenge. -# +# # # Note: If you define more than one HTTP authenticators make sure to put non-challenging authenticators like "proxy" or "clientcert" -# first and the challenging one last. +# first and the challenging one last. # Because it's not possible to challenge a client with two different authentication methods (for example # Kerberos and Basic) only one can have the challenge flag set to true. You can cope with this situation # by using pre-authentication, e.g. sending a HTTP Basic authentication header in the request. # # Default value of the challenge flag is true. -# +# # # HTTP # basic (challenging) @@ -77,7 +77,7 @@ opendistro_security: ###### and here https://tools.ietf.org/html/rfc7239 ###### and https://tomcat.apache.org/tomcat-8.0-doc/config/valve.html#Remote_IP_Valve authc: - kerberos_auth_domain: + kerberos_auth_domain: http_enabled: false transport_enabled: false order: 6 @@ -91,7 +91,7 @@ opendistro_security: strip_realm_from_principal: true authentication_backend: type: noop - basic_internal_auth_domain: + basic_internal_auth_domain: http_enabled: true transport_enabled: true order: 4 @@ -163,11 +163,11 @@ opendistro_security: password: null userbase: 'ou=people,dc=example,dc=com' # Filter to search for users (currently in the whole subtree beneath userbase) - # {0} is substituted with the username + # {0} is substituted with the username usersearch: '(sAMAccountName={0})' # Use this attribute from the user as username (if not set then DN is used) username_attribute: null - authz: + authz: roles_from_myldap: http_enabled: false transport_enabled: false @@ -190,8 +190,8 @@ opendistro_security: rolebase: 'ou=groups,dc=example,dc=com' # Filter to search for roles (currently in the whole subtree beneath rolebase) # {0} is substituted with the DN of the user - # {1} is substituted with the username - # {2} is substituted with an attribute value from user's directory entry, of the authenticated user. Use userroleattribute to specify the name of the attribute + # {1} is substituted with the username + # {2} is substituted with an attribute value from user's directory entry, of the authenticated user. Use userroleattribute to specify the name of the attribute rolesearch: '(member={0})' # Specify the name of the attribute which value should be substituted with {2} above userroleattribute: null @@ -205,12 +205,12 @@ opendistro_security: resolve_nested_roles: true userbase: 'ou=people,dc=example,dc=com' # Filter to search for users (currently in the whole subtree beneath userbase) - # {0} is substituted with the username + # {0} is substituted with the username usersearch: '(uid={0})' # Skip users matching a user name, a wildcard or a regex pattern - #skip_users: + #skip_users: # - 'cn=Michael Jackson,ou*people,o=TEST' - # - '/\S*/' + # - '/\S*/' roles_from_another_ldap: enabled: false authorization_backend: diff --git a/src/test/resources/legacy/securityconfig_v6/internal_users.yml b/src/test/resources/legacy/securityconfig_v6/internal_users.yml index d8d5b0d3a4..64b6295bbe 100644 --- a/src/test/resources/legacy/securityconfig_v6/internal_users.yml +++ b/src/test/resources/legacy/securityconfig_v6/internal_users.yml @@ -19,13 +19,13 @@ opendistro_security_logstash: roles: - logstash -#password is: kibanaserver +#password is: kibanaserver kibanaserver: readonly: true hash: $2a$12$4AcgAt3xwOWadA5s5blL6ev39OXDNhmOesEoo33eZtrq2N0YrU3H. #password is: kibanaro -kibanaro: +kibanaro: hash: $2a$12$JJSXNfTowz7Uu5ttXfeYpeYE0arACvcwlPBStB1F.MI7f0U9Z4DGC roles: - kibanauser diff --git a/src/test/resources/legacy/securityconfig_v6/migration/roles.yml b/src/test/resources/legacy/securityconfig_v6/migration/roles.yml index 0163e4a7bb..52f9dd60a4 100644 --- a/src/test/resources/legacy/securityconfig_v6/migration/roles.yml +++ b/src/test/resources/legacy/securityconfig_v6/migration/roles.yml @@ -3,7 +3,7 @@ # - '' # indices: # '': -# '': +# '': # - '' # _dls_: '' # _fls_: @@ -15,9 +15,9 @@ # and a type. If a request is executed against all indices (or all types) then the asterix ('*') is needed. # Every role a user has will be examined if it allows the action against an index (or type). At least one role must match # for the request to be successful. If no role match then the request will be denied. Currently a match must happen within -# one single role - that means that permissions can not span multiple roles. +# one single role - that means that permissions can not span multiple roles. -# For , and simple wildcards and regular expressions are possible. +# For , and simple wildcards and regular expressions are possible. # A asterix (*) will match any character sequence (or an empty sequence) # A question mark (?) will match any single character (but NOT empty character) # Example: '*my*index' will match 'my_first_index' as well as 'myindex' but not 'myindex1' @@ -27,7 +27,7 @@ # '//' # Example: '/\S*/' will match any non whitespace characters -# Important: +# Important: # Index, alias or type names can not contain dots (.) in the or expression. # Reason is that we currently parse the config file into a opensearch settings object which cannot cope with dots in keys. # Workaround: Just configure something like '?kibana' instead of '.kibana' or 'my?index' instead of 'my.index' @@ -54,7 +54,7 @@ opendistro_security_readall: '*': - READ -# Read all and monitor, but no write permissions +# Read all and monitor, but no write permissions opendistro_security_readall_and_monitor: cluster: - CLUSTER_MONITOR diff --git a/src/test/resources/legacy/securityconfig_v6/roles.yml b/src/test/resources/legacy/securityconfig_v6/roles.yml index d755d67dbe..65f02a7106 100644 --- a/src/test/resources/legacy/securityconfig_v6/roles.yml +++ b/src/test/resources/legacy/securityconfig_v6/roles.yml @@ -3,7 +3,7 @@ # - '' # indices: # '': -# '': +# '': # - '' # _dls_: '' # _fls_: @@ -15,9 +15,9 @@ # and a type. If a request is executed against all indices (or all types) then the asterix ('*') is needed. # Every role a user has will be examined if it allows the action against an index (or type). At least one role must match # for the request to be successful. If no role match then the request will be denied. Currently a match must happen within -# one single role - that means that permissions can not span multiple roles. +# one single role - that means that permissions can not span multiple roles. -# For , and simple wildcards and regular expressions are possible. +# For , and simple wildcards and regular expressions are possible. # A asterix (*) will match any character sequence (or an empty sequence) # A question mark (?) will match any single character (but NOT empty character) # Example: '*my*index' will match 'my_first_index' as well as 'myindex' but not 'myindex1' @@ -27,7 +27,7 @@ # '//' # Example: '/\S*/' will match any non whitespace characters -# Important: +# Important: # Index, alias or type names can not contain dots (.) in the or expression. # Reason is that we currently parse the config file into a opensearch settings object which cannot cope with dots in keys. # Workaround: Just configure something like '?kibana' instead of '.kibana' or 'my?index' instead of 'my.index' @@ -57,7 +57,7 @@ opendistro_security_readall: '*': - READ -# Read all and monitor, but no write permissions +# Read all and monitor, but no write permissions opendistro_security_readall_and_monitor: cluster: - CLUSTER_MONITOR @@ -97,7 +97,7 @@ opendistro_security_kibana_user: - INDICES_ALL '?management-beats': '*': - - INDICES_ALL + - INDICES_ALL '*': '*': - indices:data/read/field_caps* @@ -133,7 +133,7 @@ opendistro_security_kibana_server: - "indices:admin/aliases*" # For logstash and beats -opendistro_security_logstash: +opendistro_security_logstash: cluster: - CLUSTER_MONITOR - CLUSTER_COMPOSITE_OPS diff --git a/src/test/resources/legacy/securityconfig_v6/roles_mapping.yml b/src/test/resources/legacy/securityconfig_v6/roles_mapping.yml index b3263eb234..588ba13f6e 100644 --- a/src/test/resources/legacy/securityconfig_v6/roles_mapping.yml +++ b/src/test/resources/legacy/securityconfig_v6/roles_mapping.yml @@ -9,12 +9,12 @@ opendistro_security_all_access: opendistro_security_logstash: backendroles: - logstash - + opendistro_security_kibana_server: readonly: true users: - kibanaserver - + opendistro_security_kibana_user: backendroles: - kibanauser diff --git a/src/test/resources/multitenancy/config_basic_auth.yml b/src/test/resources/multitenancy/config_basic_auth.yml index f60caab0b7..72f73f8305 100644 --- a/src/test/resources/multitenancy/config_basic_auth.yml +++ b/src/test/resources/multitenancy/config_basic_auth.yml @@ -22,7 +22,7 @@ config: internalProxies: ".*" remoteIpHeader: "x-forwarded-for" authc: - basic_internal_auth_domain: + basic_internal_auth_domain: http_enabled: true transport_enabled: true order: 0 diff --git a/src/test/resources/restapi/audit.yml b/src/test/resources/restapi/audit.yml index 06eb47a56d..796c92f828 100644 --- a/src/test/resources/restapi/audit.yml +++ b/src/test/resources/restapi/audit.yml @@ -33,7 +33,7 @@ config: # configs internal_config: true external_config: false - + # compliance read read_metadata_only: false read_watched_fields: {} diff --git a/src/test/resources/restapi/security_config.json b/src/test/resources/restapi/security_config.json index e8acc0a22a..e5c09050cc 100644 --- a/src/test/resources/restapi/security_config.json +++ b/src/test/resources/restapi/security_config.json @@ -1,5 +1,5 @@ { - + "dynamic":{ "filtered_alias_mode":"warn", "disable_rest_auth": false, @@ -29,13 +29,13 @@ "challenge":true, "type":"kerberos", "config":{ - + } }, "authentication_backend":{ "type":"noop", "config":{ - + } }, "description":"Migrated from v6" @@ -48,13 +48,13 @@ "challenge":true, "type":"clientcert", "config":{ - + } }, "authentication_backend":{ "type":"noop", "config":{ - + } }, "description":"Migrated from v6" @@ -74,7 +74,7 @@ "authentication_backend":{ "type":"noop", "config":{ - + } }, "description":"Migrated from v6" @@ -87,13 +87,13 @@ "challenge":true, "type":"basic", "config":{ - + } }, "authentication_backend":{ "type":"intern", "config":{ - + } }, "description":"Migrated from v6" @@ -106,7 +106,7 @@ "authorization_backend":{ "type":"xxx", "config":{ - + } }, "description":"Migrated from v6" @@ -127,12 +127,12 @@ } }, "auth_failure_listeners":{ - + }, "do_not_fail_on_forbidden":false, "multi_rolespan_enabled":false, "hosts_resolver_mode":"ip-only", "do_not_fail_on_forbidden_empty":false } - + } diff --git a/src/test/resources/restapi/users_key_not_quoted.json b/src/test/resources/restapi/users_key_not_quoted.json index e69de29bb2..8b13789179 100644 --- a/src/test/resources/restapi/users_key_not_quoted.json +++ b/src/test/resources/restapi/users_key_not_quoted.json @@ -0,0 +1 @@ + diff --git a/src/test/resources/roles_invalidxcontent.yml b/src/test/resources/roles_invalidxcontent.yml index 8d805273cf..f67c09a823 100644 --- a/src/test/resources/roles_invalidxcontent.yml +++ b/src/test/resources/roles_invalidxcontent.yml @@ -5,6 +5,6 @@ opendistro_security_public: indices: indices: '.notexistingindexcvnjl9809991' - '*': + '*': - ALL invalid yml diff --git a/tools/install_demo_configuration.sh b/tools/install_demo_configuration.sh index 6d6203124a..21174e6f63 100755 --- a/tools/install_demo_configuration.sh +++ b/tools/install_demo_configuration.sh @@ -383,7 +383,7 @@ echo "plugins.security.enable_snapshot_restore_privilege: true" | $SUDO_CMD tee echo "plugins.security.check_snapshot_restore_write_privileges: true" | $SUDO_CMD tee -a "$OPENSEARCH_CONF_FILE" > /dev/null echo 'plugins.security.restapi.roles_enabled: ["all_access", "security_rest_api_access"]' | $SUDO_CMD tee -a "$OPENSEARCH_CONF_FILE" > /dev/null echo 'plugins.security.system_indices.enabled: true' | $SUDO_CMD tee -a "$OPENSEARCH_CONF_FILE" > /dev/null -echo 'plugins.security.system_indices.indices: [".plugins-ml-model", ".plugins-ml-task", ".opendistro-alerting-config", ".opendistro-alerting-alert*", ".opendistro-anomaly-results*", ".opendistro-anomaly-detector*", ".opendistro-anomaly-checkpoints", ".opendistro-anomaly-detection-state", ".opendistro-reports-*", ".opensearch-notifications-*", ".opensearch-notebooks", ".opensearch-observability", ".ql-datasources", ".opendistro-asynchronous-search-response*", ".replication-metadata-store", ".opensearch-knn-models"]' | $SUDO_CMD tee -a "$OPENSEARCH_CONF_FILE" > /dev/null +echo 'plugins.security.system_indices.indices: [".plugins-ml-model-group", ".plugins-ml-model", ".plugins-ml-task", ".opendistro-alerting-config", ".opendistro-alerting-alert*", ".opendistro-anomaly-results*", ".opendistro-anomaly-detector*", ".opendistro-anomaly-checkpoints", ".opendistro-anomaly-detection-state", ".opendistro-reports-*", ".opensearch-notifications-*", ".opensearch-notebooks", ".opensearch-observability", ".ql-datasources", ".opendistro-asynchronous-search-response*", ".replication-metadata-store", ".opensearch-knn-models"]' | $SUDO_CMD tee -a "$OPENSEARCH_CONF_FILE" > /dev/null #network.host if $SUDO_CMD grep --quiet -i "^network.host" "$OPENSEARCH_CONF_FILE"; then