├── .editorconfig ├── .gitignore ├── .travis.yml ├── README.md ├── checkstyle.xml ├── header.txt ├── images ├── eclipse_port_fwd.png ├── eclipse_run_args.png ├── eclipse_run_env.png └── eclipse_run_main.png ├── license.txt ├── pom.xml ├── samples ├── applications_mapping.json ├── elasticsearch.yml ├── sg_actiongroups.yml ├── sg_config.yml ├── sg_roles.yml └── sg_rolesmapping.yml ├── src ├── it │ ├── java │ │ └── io │ │ │ └── fabric8 │ │ │ └── elasticsearch │ │ │ ├── AccessControlIntegrationTest.java │ │ │ ├── ElasticsearchIntegrationTest.java │ │ │ ├── GeneralUserWorkflowIntegrationTest.java │ │ │ ├── KibanaIndexModeIntegrationBase.java │ │ │ ├── KibanaIndexModeSharedOpsIntegrationTest.java │ │ │ ├── KibanaIndexModeUniqueIntegrationTest.java │ │ │ ├── KibanaIndexUpgradeIntegrationTest.java │ │ │ ├── ProxyUsernameIntegrationTest.java │ │ │ └── RequestRunner.java │ └── resources │ │ ├── keystore.jks │ │ ├── sgconfig │ │ ├── actiongroups.yml │ │ ├── config.yml │ │ ├── internalusers.yml │ │ ├── roles.yml │ │ └── rolesmapping.yml │ │ └── truststore.jks ├── main │ ├── assemblies │ │ └── plugin.xml │ ├── java │ │ └── io │ │ │ └── fabric8 │ │ │ └── elasticsearch │ │ │ ├── plugin │ │ │ ├── ConfigurationSettings.java │ │ │ ├── KibanaIndexMode.java │ │ │ ├── OpenShiftElasticSearchConfigurationException.java │ │ │ ├── OpenShiftElasticSearchPlugin.java │ │ │ ├── OpenshiftAPIService.java │ │ │ ├── OpenshiftRequestContextFactory.java │ │ │ ├── PluginClient.java │ │ │ ├── PluginServiceFactory.java │ │ │ ├── PluginSettings.java │ │ │ ├── acl │ │ │ │ ├── ACLDocumentManager.java │ │ │ │ ├── BaseRolesMappingSyncStrategy.java │ │ │ │ ├── BaseRolesSyncStrategy.java │ │ │ │ ├── ConfigCallback.java │ │ │ │ ├── ConfigurationLoader.java │ │ │ │ ├── DynamicACLFilter.java │ │ │ │ ├── ProjectRolesMappingSyncStrategy.java │ │ │ │ ├── ProjectRolesSyncStrategy.java │ │ │ │ ├── RoleBuilder.java │ │ │ │ ├── RolesBuilder.java │ │ │ │ ├── RolesMappingBuilder.java │ │ │ │ ├── RolesMappingSyncStrategy.java │ │ │ │ ├── RolesSyncStrategy.java │ │ │ │ ├── SearchGuardACLDocument.java │ │ │ │ ├── SearchGuardRoles.java │ │ │ │ ├── SearchGuardRolesMapping.java │ │ │ │ ├── SearchGuardSyncStrategyFactory.java │ │ │ │ ├── UserRolesMappingSyncStrategy.java │ │ │ │ └── UserRolesSyncStrategy.java │ │ │ ├── auth │ │ │ │ ├── BackendRoleRetriever.java │ │ │ │ ├── FileAuthenticationBackend.java │ │ │ │ └── OpenShiftTokenAuthentication.java │ │ │ ├── filter │ │ │ │ └── FieldStatsResponseFilter.java │ │ │ ├── kibana │ │ │ │ ├── DocumentBuilder.java │ │ │ │ ├── IndexMappingLoader.java │ │ │ │ ├── KibanaSeed.java │ │ │ │ └── KibanaUtils.java │ │ │ ├── model │ │ │ │ └── Project.java │ │ │ └── rest │ │ │ │ ├── OpenShiftRestResponse.java │ │ │ │ └── RestChannelInterceptor.java │ │ │ └── util │ │ │ ├── IndexUtil.java │ │ │ └── RequestUtils.java │ └── plugin-metadata │ │ ├── plugin-descriptor.properties │ │ └── plugin-security.policy └── test │ ├── java │ └── io │ │ └── fabric8 │ │ └── elasticsearch │ │ ├── plugin │ │ ├── OpenshiftAPIServiceTest.java │ │ ├── OpenshiftRequestContextFactoryTest.java │ │ ├── PluginSettingsTest.java │ │ ├── Samples.java │ │ ├── TestUtils.java │ │ ├── acl │ │ │ ├── BaseRolesSyncStrategyTest.java │ │ │ ├── SearchGuardRoleACLTest.java │ │ │ └── SearchGuardRolesMappingACLTest.java │ │ ├── auth │ │ │ ├── FileAuthenticationBackendTest.java │ │ │ └── OpenShiftTokenAuthenticationTest.java │ │ ├── filter │ │ │ └── FieldStatsResponseFilterTest.java │ │ ├── kibana │ │ │ ├── IndexMappingLoaderTest.java │ │ │ ├── KibanaSeedTest.java │ │ │ └── KibanaUtilsTest.java │ │ └── rest │ │ │ └── OpenShiftRestResponseTest.java │ │ └── util │ │ ├── IndexUtilTest.java │ │ ├── RequestUtilsTest.java │ │ └── TestRestRequest.java │ └── resources │ ├── index-pattern.json │ ├── io │ └── fabric8 │ │ └── elasticsearch │ │ └── plugin │ │ ├── elasticsearch_test_config.yaml │ │ ├── elasticsearch_test_expected.json │ │ ├── passwords.yml │ │ ├── project_strategy_roles_shared_non_ops_kibana_mode.yml │ │ ├── project_strategy_roles_shared_ops_kibana_mode.yml │ │ ├── project_strategy_roles_unique_kibana_mode.yml │ │ ├── project_strategy_rolesmapping_shared_non_ops_kibana_mode.yml │ │ ├── project_strategy_rolesmapping_shared_ops_kibana_mode.yml │ │ ├── project_strategy_rolesmapping_unique_kibana_mode.yml │ │ ├── roles_shared_non_ops_kibana_index.yml │ │ ├── searchguard_acl.json │ │ ├── searchguard_acl_with_openshift_projects.json │ │ ├── searchguard_roles_acl.yml │ │ ├── searchguard_rolesmapping_acl.yml │ │ ├── user_strategy_roles_shared_non_ops_kibana_mode.yml │ │ ├── user_strategy_roles_shared_ops_kibana_mode.yml │ │ ├── user_strategy_roles_unique_kibana_mode.yml │ │ ├── user_strategy_rolesmapping_shared_non_ops_kibana_mode.yml │ │ ├── user_strategy_rolesmapping_shared_ops_kibana_mode.yml │ │ └── user_strategy_rolesmapping_unique_kibana_mode.yml │ ├── java.policy │ ├── log4j.properties │ └── sgconfig │ ├── actiongroups.yml │ ├── config.yml │ ├── internalusers.yml │ ├── logging-es.truststore.jks │ ├── roles.yml │ └── rolesmapping.yml └── tools └── sgadmin.sh /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | indent_style = space 7 | indent_size = 2 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | velocity.log 3 | ### Maven template 4 | target/ 5 | pom.xml.tag 6 | pom.xml.releaseBackup 7 | pom.xml.versionsBackup 8 | pom.xml.next 9 | release.properties 10 | dependency-reduced-pom.xml 11 | buildNumber.properties 12 | .mvn/timing.properties 13 | 14 | # Eclipse 15 | .project 16 | .classpath 17 | .checkstyle 18 | .settings/ 19 | .metadata/ 20 | 21 | ### JetBrains template 22 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion 23 | 24 | *.iml 25 | 26 | ## Directory-based project format: 27 | .idea/ 28 | # if you remove the above rule, at least ignore the following: 29 | 30 | # User-specific stuff: 31 | # .idea/workspace.xml 32 | # .idea/tasks.xml 33 | # .idea/dictionaries 34 | 35 | # Sensitive or high-churn files: 36 | # .idea/dataSources.ids 37 | # .idea/dataSources.xml 38 | # .idea/sqlDataSources.xml 39 | # .idea/dynamic.xml 40 | # .idea/uiDesigner.xml 41 | 42 | # Gradle: 43 | # .idea/gradle.xml 44 | # .idea/libraries 45 | 46 | # Mongo Explorer plugin: 47 | # .idea/mongoSettings.xml 48 | 49 | ## File-based project format: 50 | *.ipr 51 | *.iws 52 | 53 | ## Plugin-specific files: 54 | 55 | # IntelliJ 56 | /out/ 57 | 58 | # mpeltonen/sbt-idea plugin 59 | .idea_modules/ 60 | 61 | # JIRA plugin 62 | atlassian-ide-plugin.xml 63 | 64 | # Crashlytics plugin (for Android Studio and IntelliJ) 65 | com_crashlytics_export_strings.xml 66 | crashlytics.properties 67 | crashlytics-build.properties 68 | 69 | 70 | /test/ 71 | /bin/ 72 | /bin/ 73 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | sudo: false 4 | 5 | jdk: 6 | - oraclejdk8 7 | 8 | script: 9 | # run both the unit tests and integration tests 10 | - mvn verify 11 | -------------------------------------------------------------------------------- /header.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) ${project.inceptionYear} ${owner} 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /images/eclipse_port_fwd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabric8io/openshift-elasticsearch-plugin/2d17bafd8a79fc4d4611d12801b88e7d7146a1fd/images/eclipse_port_fwd.png -------------------------------------------------------------------------------- /images/eclipse_run_args.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabric8io/openshift-elasticsearch-plugin/2d17bafd8a79fc4d4611d12801b88e7d7146a1fd/images/eclipse_run_args.png -------------------------------------------------------------------------------- /images/eclipse_run_env.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabric8io/openshift-elasticsearch-plugin/2d17bafd8a79fc4d4611d12801b88e7d7146a1fd/images/eclipse_run_env.png -------------------------------------------------------------------------------- /images/eclipse_run_main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabric8io/openshift-elasticsearch-plugin/2d17bafd8a79fc4d4611d12801b88e7d7146a1fd/images/eclipse_run_main.png -------------------------------------------------------------------------------- /samples/applications_mapping.json: -------------------------------------------------------------------------------- 1 | { 2 | "title":"$TITLE$", 3 | "timeFieldName":"time", 4 | "description":"This is the Kibana index file for operations logs", 5 | "fields": "[{\"name\":\"_index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false},{\"name\":\"kubernetes_labels_name\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false}, {\"name\":\"docker_container_id\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false}, {\"name\":\"hostname\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false}, {\"name\":\"kubernetes_labels_openshift_io/build_name\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false}, {\"name\":\"_type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":false}, {\"name\":\"kubernetes_labels_deploymentconfig\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false}, {\"name\":\"message\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false}, {\"name\":\"version\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false}, {\"name\":\"kubernetes_pod_name\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false}, {\"name\":\"kubernetes_namespace_name\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false}, {\"name\":\"kubernetes_labels_deployment\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false}, {\"name\":\"kubernetes_container_name\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false}, {\"name\":\"kubernetes_pod_id\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false}, {\"name\":\"kubernetes_labels_openshift_io/deployer-pod-for_name\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false}, {\"name\":\"_source\",\"type\":\"_source\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false}, {\"name\":\"_id\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false}, {\"name\":\"time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":false},{\"name\":\"kubernetes_host\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false}]" 6 | } -------------------------------------------------------------------------------- /samples/sg_actiongroups.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | ALL: 18 | - "indices:*" 19 | MANAGE: 20 | - "indices:monitor/*" 21 | - "indices:admin/*" 22 | CREATE_INDEX: 23 | - "indices:admin/create" 24 | MANAGE_ALIASES: 25 | - "indices:admin/aliases*" 26 | MONITOR: 27 | - "indices:monitor/*" 28 | DATA_ACCESS: 29 | - "indices:data/*" 30 | WRITE: 31 | - "indices:data/write*" 32 | READ: 33 | - "indices:data/read*" 34 | DELETE: 35 | - "indices:data/write/delete*" 36 | CRUD: 37 | - READ 38 | - WRITE 39 | SEARCH: 40 | - "indices:data/read/search*" 41 | - "indices:data/read/msearch*" 42 | - SUGGEST 43 | SUGGEST: 44 | - "indices:data/read/suggest*" 45 | INDEX: 46 | - "indices:data/write/index*" 47 | - "indices:data/write/update*" 48 | GET: 49 | - "indices:data/read/get*" 50 | - "indices:data/read/mget*" 51 | 52 | # CLUSTER 53 | CLUSTER_ALL: 54 | - cluster:* 55 | CLUSTER_MONITOR: 56 | - cluster:monitor/* 57 | -------------------------------------------------------------------------------- /samples/sg_config.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | searchguard: 18 | dynamic: 19 | http: 20 | xff: 21 | enabled: true 22 | remoteIpHeader: 'remoteAddress' 23 | proxiesHeader: 'remoteAddress' 24 | trustedProxies: '.*' 25 | internalProxies: '.*' 26 | authc: 27 | authentication_domain_proxy: 28 | enabled: true 29 | order: 0 30 | http_authenticator: 31 | challenge: false 32 | type: proxy 33 | config: 34 | user_header: 'x-proxy-remote-user' 35 | authentication_backend: 36 | type: noop 37 | authentication_domain_basic_internal: 38 | enabled: true 39 | order: 1 40 | http_authenticator: 41 | type: clientcert 42 | challenge: false 43 | authentication_backend: 44 | type: noop 45 | -------------------------------------------------------------------------------- /samples/sg_roles.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | sg_role_kibana: 18 | cluster: 19 | - cluster:monitor/nodes/info 20 | - cluster:monitor/health 21 | indices: 22 | '*': 23 | '*': 24 | - indices:admin/mappings/fields/get* 25 | - indices:admin/validate/query* 26 | - indices:admin/get* 27 | - READ 28 | '?kibana': 29 | '*': 30 | - ALL 31 | 32 | sg_role_fluentd: 33 | indices: 34 | '*': 35 | '*': 36 | - CRUD 37 | - CREATE_INDEX 38 | 39 | sg_role_curator: 40 | indices: 41 | '*': 42 | '*': 43 | - CRUD 44 | 45 | sg_role_admin: 46 | indices: 47 | '*': 48 | '*': 49 | - ALL 50 | cluster: 51 | - CLUSTER_ALL 52 | 53 | sg_project_operations: 54 | indices: 55 | '?operations?*': 56 | '*': 57 | - READ 58 | - indices:admin/mappings/fields/get* 59 | - indices:admin/validate/query* 60 | - indices:admin/get* 61 | '*?*?*': 62 | '*': 63 | - READ 64 | - indices:admin/mappings/fields/get* 65 | - indices:admin/validate/query* 66 | - indices:admin/get* 67 | -------------------------------------------------------------------------------- /samples/sg_rolesmapping.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | sg_role_kibana: 18 | users: 19 | - 'CN=system.logging.kibana,OU=OpenShift,O=Logging,L=Test,C=DE' 20 | 21 | sg_role_fluentd: 22 | users: 23 | - 'CN=system.logging.fluentd,OU=OpenShift,O=Logging,L=Test,C=DE' 24 | 25 | sg_role_curator: 26 | users: 27 | - 'CN=system.logging.curator,OU=OpenShift,O=Logging,L=Test,C=DE' 28 | 29 | sg_role_admin: 30 | users: 31 | - 'CN=system.admin,OU=OpenShift,O=Logging,L=Test,C=DE' 32 | -------------------------------------------------------------------------------- /src/it/java/io/fabric8/elasticsearch/AccessControlIntegrationTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch; 18 | 19 | import org.junit.Before; 20 | import org.junit.Test; 21 | 22 | import io.fabric8.elasticsearch.plugin.KibanaIndexMode; 23 | import okhttp3.Headers; 24 | 25 | /* 26 | * This integration test verifies the ability (or not) to access Elasticsearch 27 | * depending upon what credentials are provided 28 | */ 29 | public class AccessControlIntegrationTest extends ElasticsearchIntegrationTest { 30 | 31 | 32 | @Before 33 | public void setup() throws Exception { 34 | givenDocumentIsIndexed("project.multi-tenancy-1.uuid.1970.01.01", "test", "0", "multi-tenancy-1-doc0"); 35 | givenDocumentIsIndexed("project.multi-tenancy-2.uuid.1970.01.01", "test", "0", "multi-tenancy-2-doc0"); 36 | givenDocumentIsIndexed("project.multi-tenancy-3.uuid.1970.01.01", "test", "0", "multi-tenancy-3-doc0"); 37 | } 38 | 39 | @Test 40 | public void testUserAccessDeletedAndRecreatedNamespace() throws Exception { 41 | final String userName = "nonadminuser"; 42 | //artificially seed user's kibanaIndex 43 | String kibanaIndex = getKibanaIndex(KibanaIndexMode.UNIQUE, userName, false); 44 | givenDocumentIsIndexed(kibanaIndex, "config", KibanaIndexModeIntegrationBase.OLD_KIBANA_VERSION, "myKibanaIndex"); 45 | givenDocumentIsIndexed("project.test.uuid1.1970.01.01", "test", "0", "test.uuid1-doc0"); 46 | givenDocumentIsIndexed("project.test.uuid2.1970.01.01", "test", "0", "test.uuid2-doc0"); 47 | 48 | givenUserIsNotClusterAdmin(userName); 49 | givenUserIsAdminForProject("test","uuid2"); 50 | 51 | whenGettingDocument(String.format("%s/_count", formatProjectIndexPattern("test", "*"))); 52 | assertThatResponseIsForbidden(); 53 | 54 | whenGettingDocument(String.format("%s/_count", formatProjectIndexPattern("test", "uuid2"))); 55 | assertThatResponseIsSuccessful(); 56 | 57 | } 58 | 59 | @Test 60 | public void testUsersAccessWithTokenFollowedByWithout() throws Exception { 61 | final String [] projects = {"multi-tenancy-1", "multi-tenancy-2"}; 62 | final String userName = "nonadminuser"; 63 | //artificially seed user's kibanaIndex 64 | String kibanaIndex = getKibanaIndex(KibanaIndexMode.UNIQUE, userName, false); 65 | givenDocumentIsIndexed(kibanaIndex, "config", KibanaIndexModeIntegrationBase.OLD_KIBANA_VERSION, "myKibanaIndex"); 66 | givenUserIsNotClusterAdmin(userName); 67 | givenUserIsAdminForProjects(projects); 68 | 69 | final String uri = String.format("%s/_count", formatProjectIndexPattern("multi-tenancy-1","uuid")); 70 | 71 | //no username or token 72 | whenGettingDocument(uri); 73 | assertThatResponseIsSuccessful(); 74 | 75 | Headers.Builder builder = new Headers.Builder() 76 | .add("connection","close") 77 | .add("x-proxy-remote-user", userName) 78 | .add("x-forwarded-for", "127.0.0.1"); 79 | 80 | //username with no token 81 | whenGettingDocument(uri, builder.build()); 82 | assertThatResponseIsUnauthorized(); 83 | 84 | } 85 | 86 | @Test 87 | public void testUsersAccessWithNoToken() throws Exception { 88 | final String [] projects = {"multi-tenancy-1", "multi-tenancy-2"}; 89 | final String userName = "nonadminuser"; 90 | //artificially seed user's kibanaIndex 91 | String kibanaIndex = getKibanaIndex(KibanaIndexMode.UNIQUE, userName, false); 92 | givenDocumentIsIndexed(kibanaIndex, "config", KibanaIndexModeIntegrationBase.OLD_KIBANA_VERSION, "myKibanaIndex"); 93 | givenUserIsNotClusterAdmin(userName); 94 | givenUserIsAdminForProjects(projects); 95 | 96 | final String uri = String.format("%s/_count", formatProjectIndexPattern("multi-tenancy-1","uuid")); 97 | 98 | Headers.Builder builder = new Headers.Builder() 99 | .add("connection","close") 100 | .add("x-forwarded-for", "127.0.0.1"); 101 | 102 | //no username or token 103 | whenGettingDocument(uri, builder.build()); 104 | assertThatResponseIsUnauthorized(); 105 | 106 | //username with no token 107 | builder.add("x-proxy-remote-user", userName); 108 | whenGettingDocument(uri, builder.build()); 109 | assertThatResponseIsUnauthorized(); 110 | 111 | } 112 | 113 | @Test 114 | public void testUsersAccessWithInvalidToken() throws Exception { 115 | final String uri = String.format("%s/_count", formatProjectIndexPattern("multi-tenancy-1","uuid")); 116 | final String userName = "nonadminuser"; 117 | 118 | Headers.Builder builder = new Headers.Builder() 119 | .add("connection","close") 120 | .add("X-Forwarded-For", "127.0.0.1"); 121 | 122 | givenUserHasBadToken(); 123 | 124 | //no username with empty token 125 | builder.add("Authorization", ""); 126 | whenGettingDocument(uri, builder.build()); 127 | assertThatResponseIsUnauthorized(); 128 | 129 | //username with empty token 130 | builder.add("X-Proxy-Remote-User", userName); 131 | whenGettingDocument(uri, builder.build()); 132 | assertThatResponseIsUnauthorized(); 133 | 134 | //username with invalid token 135 | builder.add("Authorization", "Bearer bogusToken"); 136 | whenGettingDocument(uri, builder.build()); 137 | assertThatResponseIsUnauthorized(); 138 | 139 | } 140 | 141 | } 142 | -------------------------------------------------------------------------------- /src/it/java/io/fabric8/elasticsearch/GeneralUserWorkflowIntegrationTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch; 18 | 19 | import org.elasticsearch.common.xcontent.XContentBuilder; 20 | import org.elasticsearch.common.xcontent.XContentFactory; 21 | import org.junit.Before; 22 | import org.junit.Test; 23 | 24 | import io.fabric8.elasticsearch.plugin.ConfigurationSettings; 25 | import io.fabric8.elasticsearch.plugin.KibanaIndexMode; 26 | import io.fabric8.elasticsearch.plugin.kibana.KibanaUtils; 27 | 28 | /* 29 | * This integration test verifies the ability (or not) to access Elasticsearch 30 | * depending upon what credentials are provided 31 | */ 32 | public class GeneralUserWorkflowIntegrationTest extends ElasticsearchIntegrationTest { 33 | 34 | 35 | @Before 36 | public void setup() throws Exception { 37 | } 38 | 39 | /* 40 | * This test verifies a basic nonadmin workflow, specifically to address 41 | * https://bugzilla.redhat.com/show_bug.cgi?id=1679613. 42 | * org.elasticsearch.ElasticsearchException: org.elasticsearch.action.ActionRequestValidationException: Validation Failed: 1: id is missing; 43 | * at io.fabric8.elasticsearch.plugin.PluginClient.execute(PluginClient.java:322) ~[openshift-elasticsearch-plugin-5.6.13.2-redhat-1.jar:?] 44 | * at io.fabric8.elasticsearch.plugin.PluginClient.documentExists(PluginClient.java:238) ~[openshift-elasticsearch-plugin-5.6.13.2-redhat-1.jar:?] 45 | * at io.fabric8.elasticsearch.plugin.kibana.KibanaSeed.setDashboards(KibanaSeed.java:80) ~[openshift-elasticsearch-plugin-5.6.13.2-redhat-1.jar:?] 46 | * 47 | * where its possible to have a defaultIndex but the value is null 48 | */ 49 | @Test 50 | public void testNonadminUserRequestWorkflow() throws Exception { 51 | final String userName = "CN=Foo Bar,OU=People,OU=org-cs-0,DC=org-cs-0,DC=iuk,DC=local"; 52 | //artificially seed user's kibanaIndex 53 | String kibanaIndex = getKibanaIndex(KibanaIndexMode.UNIQUE, userName, false); 54 | XContentBuilder contentBuilder = XContentFactory.jsonBuilder() 55 | .startObject() 56 | .field("defaultIndex",(String)null) 57 | .endObject(); 58 | givenDocumentIsIndexed(kibanaIndex, "config", ConfigurationSettings.DEFAULT_KIBANA_VERSION, contentBuilder); 59 | givenDocumentIsIndexed(kibanaIndex, KibanaUtils.INDICIES_TYPE, "project.foo.uid.*", "bogus pattern"); 60 | 61 | givenUserIsNotClusterAdmin(userName); 62 | givenUserIsAdminForProject("foo","uid"); 63 | 64 | whenGettingDocument(String.format("%s/_count", formatProjectIndexPattern("foo", "uid"))); 65 | assertThatResponseIsSuccessful(); 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/it/java/io/fabric8/elasticsearch/KibanaIndexModeIntegrationBase.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | 21 | import java.util.Map; 22 | 23 | import org.elasticsearch.common.xcontent.XContentHelper; 24 | import org.elasticsearch.common.xcontent.json.JsonXContent; 25 | import org.junit.Before; 26 | 27 | import okhttp3.Response; 28 | 29 | 30 | public abstract class KibanaIndexModeIntegrationBase extends ElasticsearchIntegrationTest { 31 | 32 | protected static final String OLD_KIBANA_VERSION = "4.6.4"; 33 | 34 | @SuppressWarnings("unchecked") 35 | protected void assertThatMessageEquals(String message) throws Exception { 36 | Response response = (Response) testContext.get(RESPONSE); 37 | Map source = XContentHelper.convertToMap(JsonXContent.jsonXContent, response.body().byteStream(),false); 38 | Map doc = (Map) source.get("_source"); 39 | assertEquals("Exp. Message content to be equal", message, doc.get("msg")); 40 | } 41 | 42 | @Before 43 | public void setup() throws Exception { 44 | //https://bugzilla.redhat.com/show_bug.cgi?id=1746377 45 | for (int i = 0; i < 1100; ++ i) { 46 | givenDocumentIsIndexed("project.multi-tenancy-1.uuid.1970.01.01", "test", String.valueOf(i), "multi-tenancy-1-doc0"); 47 | } 48 | givenDocumentIsIndexed("project.multi-tenancy-2.uuid.1970.01.01", "test", "0", "multi-tenancy-2-doc0"); 49 | givenDocumentIsIndexed("project.multi-tenancy-3.uuid.1970.01.01", "test", "0", "multi-tenancy-3-doc0"); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/it/java/io/fabric8/elasticsearch/KibanaIndexModeSharedOpsIntegrationTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch; 18 | 19 | import org.elasticsearch.common.settings.Settings; 20 | import org.junit.Test; 21 | 22 | import io.fabric8.elasticsearch.plugin.ConfigurationSettings; 23 | import io.fabric8.elasticsearch.plugin.KibanaIndexMode; 24 | 25 | 26 | public class KibanaIndexModeSharedOpsIntegrationTest extends KibanaIndexModeIntegrationBase { 27 | 28 | @Override 29 | protected Settings additionalNodeSettings() { 30 | return Settings.builder() 31 | .put(KibanaIndexMode.OPENSHIFT_KIBANA_INDEX_MODE, KibanaIndexMode.SHARED_OPS) 32 | .build(); 33 | } 34 | 35 | @Test 36 | public void testNonAdminUserRetrievingDocuments() throws Exception { 37 | final String [] projects = {"multi-tenancy-1", "multi-tenancy-2"}; 38 | final String userName = "nonadminuser"; 39 | //artificially seed user's kibanaIndex 40 | String kibanaIndex = getKibanaIndex(KibanaIndexMode.SHARED_OPS, userName, false); 41 | givenDocumentIsIndexed(kibanaIndex, "config", OLD_KIBANA_VERSION, "myKibanaIndex"); 42 | givenUserIsNotClusterAdmin(userName); 43 | givenUserIsAdminForProjects(projects); 44 | 45 | //verify access to unique kibana index 46 | whenGettingDocument(String.format("%s/config/%s", kibanaIndex, OLD_KIBANA_VERSION)); 47 | assertThatResponseIsSuccessful(); 48 | 49 | 50 | //verify seeded index patterns 51 | for (String project : projects) { 52 | whenGettingDocument(String.format("%s/index-pattern/%s", kibanaIndex, formatProjectIndexPattern(project, "uuid"))); 53 | assertThatResponseIsSuccessful(); 54 | } 55 | 56 | //verify access to index pattern for project we dont administer 57 | whenGettingDocument(String.format("%s/index-pattern/%s", kibanaIndex, formatProjectIndexPattern("multi-tenancy-3", "uuid"))); 58 | assertThatResponseIsNotFound(); 59 | 60 | //verify search to individual projects 61 | for (String project : projects) { 62 | whenGettingDocument(String.format("%s/_count", formatProjectIndexPattern(project, "uuid"))); 63 | assertThatResponseIsSuccessful(); 64 | } 65 | 66 | //verify search across multiple projects 67 | whenSearchingProjects(projects); 68 | assertThatResponseIsSuccessful(); 69 | 70 | //verify search to operations projects 71 | whenGettingDocument(".operations.*/_count"); 72 | assertThatResponseIsForbidden(); 73 | 74 | //verify access to unique kibana index 75 | //this is a false positive on '.kibana' because we transform to a unique index 76 | whenGettingDocument(".kibana/config/" + OLD_KIBANA_VERSION); 77 | assertThatResponseIsSuccessful(); 78 | assertThatMessageEquals("myKibanaIndex"); 79 | } 80 | 81 | @Test 82 | public void testOperationsUserRetrievingDocuments() throws Exception { 83 | final String [] projects = {"multi-tenancy-1", "multi-tenancy-2", "multi-tenancy-2"}; 84 | final String userName = "anAdminUser"; 85 | 86 | givenUserIsClusterAdmin(userName); 87 | givenUserIsAdminForProjects(projects); 88 | 89 | //verify search to individual projects 90 | for (String project : projects) { 91 | whenGettingDocument(String.format("%s/_count", formatProjectIndexPattern(project, "uuid"))); 92 | assertThatResponseIsSuccessful(); 93 | } 94 | 95 | //verify search across multiple projects 96 | whenSearchingProjects(projects); 97 | assertThatResponseIsSuccessful(); 98 | 99 | //verify search to operations projects 100 | whenGettingDocument(".operations.*/_count"); 101 | assertThatResponseIsSuccessful(); 102 | 103 | //verify access to unique kibana index 104 | whenGettingDocument(String.format(".kibana/config/%s", ConfigurationSettings.DEFAULT_KIBANA_VERSION)); 105 | assertThatResponseIsSuccessful(); 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/it/java/io/fabric8/elasticsearch/KibanaIndexModeUniqueIntegrationTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch; 18 | 19 | import org.elasticsearch.common.settings.Settings; 20 | import org.junit.Test; 21 | 22 | import io.fabric8.elasticsearch.plugin.KibanaIndexMode; 23 | 24 | public class KibanaIndexModeUniqueIntegrationTest extends KibanaIndexModeIntegrationBase { 25 | 26 | @Override 27 | protected Settings additionalNodeSettings() { 28 | return Settings.builder() 29 | .put(KibanaIndexMode.OPENSHIFT_KIBANA_INDEX_MODE, KibanaIndexMode.UNIQUE) 30 | .build(); 31 | } 32 | 33 | @Test 34 | public void testNonAdminUserRetrievingDocuments() throws Exception { 35 | final String [] projects = {"multi-tenancy-1", "multi-tenancy-2"}; 36 | final String userName = "nonadminuser"; 37 | //artificially seed user's kibanaIndex 38 | String kibanaIndex = getKibanaIndex(KibanaIndexMode.UNIQUE, userName, false); 39 | givenDocumentIsIndexed(kibanaIndex, "config", OLD_KIBANA_VERSION, "myKibanaIndex"); 40 | givenUserIsNotClusterAdmin(userName); 41 | givenUserIsAdminForProjects(projects); 42 | 43 | //verify access to unique kibana index 44 | whenGettingDocument(String.format("%s/config/%s", kibanaIndex, OLD_KIBANA_VERSION)); 45 | assertThatResponseIsSuccessful(); 46 | 47 | //verify search to individual projects 48 | for (String project : projects) { 49 | whenGettingDocument(String.format("%s/_count", formatProjectIndexPattern(project, "uuid"))); 50 | assertThatResponseIsSuccessful(); 51 | } 52 | 53 | //verify search across multiple projects 54 | whenSearchingProjects(projects); 55 | assertThatResponseIsSuccessful(); 56 | 57 | //verify search to operations projects 58 | whenGettingDocument(".operations.*/_count"); 59 | assertThatResponseIsForbidden(); 60 | 61 | //verify access to unique kibana index 62 | //this is a false positive on '.kibana' because we transform to a unique index 63 | whenGettingDocument(".kibana/config/" + OLD_KIBANA_VERSION); 64 | assertThatResponseIsSuccessful(); 65 | assertThatMessageEquals("myKibanaIndex"); 66 | } 67 | 68 | @Test 69 | public void testOperationsUserRetrievingDocuments() throws Exception { 70 | final String [] projects = {"multi-tenancy-1", "multi-tenancy-2", "multi-tenancy-3"}; 71 | final String userName = "anAdminUser"; 72 | //artificially seed user's kibanaIndex 73 | String kibanaIndex = getKibanaIndex(KibanaIndexMode.UNIQUE, userName, true); 74 | 75 | givenDocumentIsIndexed(kibanaIndex, "config", OLD_KIBANA_VERSION, "myKibanaIndex"); 76 | givenUserIsClusterAdmin(userName); 77 | givenUserIsAdminForProjects(projects); 78 | 79 | //verify access to unique kibana index 80 | whenGettingDocument(String.format("%s/config/%s", kibanaIndex, OLD_KIBANA_VERSION)); 81 | assertThatResponseIsSuccessful(); 82 | 83 | //verify search to individual projects 84 | for (String project : projects) { 85 | whenGettingDocument(String.format("%s/_count", formatProjectIndexPattern(project, "uuid"))); 86 | assertThatResponseIsSuccessful(); 87 | } 88 | 89 | //verify search across multiple projects 90 | whenSearchingProjects(projects); 91 | assertThatResponseIsSuccessful(); 92 | 93 | //verify search to operations projects 94 | whenGettingDocument(".operations.*/_count"); 95 | assertThatResponseIsSuccessful(); 96 | 97 | //verify access to unique kibana index 98 | //this is a false positive on '.kibana' because we transform to a unique index 99 | whenGettingDocument(".kibana/config/" + OLD_KIBANA_VERSION); 100 | assertThatResponseIsSuccessful(); 101 | assertThatMessageEquals("myKibanaIndex"); 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/it/java/io/fabric8/elasticsearch/KibanaIndexUpgradeIntegrationTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | 21 | import java.util.Arrays; 22 | import java.util.Map; 23 | 24 | import org.elasticsearch.common.settings.Settings; 25 | import org.elasticsearch.common.xcontent.XContentBuilder; 26 | import org.elasticsearch.common.xcontent.XContentFactory; 27 | import org.elasticsearch.common.xcontent.XContentHelper; 28 | import org.elasticsearch.common.xcontent.json.JsonXContent; 29 | import org.junit.Test; 30 | 31 | import io.fabric8.elasticsearch.plugin.ConfigurationSettings; 32 | import io.fabric8.elasticsearch.plugin.KibanaIndexMode; 33 | import io.fabric8.elasticsearch.plugin.kibana.KibanaUtils; 34 | import okhttp3.Response; 35 | 36 | public class KibanaIndexUpgradeIntegrationTest extends KibanaIndexModeIntegrationBase { 37 | 38 | @Override 39 | protected Settings additionalNodeSettings() { 40 | return Settings.builder() 41 | .put(KibanaIndexMode.OPENSHIFT_KIBANA_INDEX_MODE, KibanaIndexMode.UNIQUE) 42 | .putArray(ConfigurationSettings.OPENSHIFT_KIBANA_OPS_INDEX_PATTERNS, Arrays.asList(".all")) 43 | .build(); 44 | } 45 | 46 | @Test 47 | public void testUpgradeOfKibanaIndexForNonOps() throws Exception { 48 | final String userName = "nonadminuser"; 49 | //artificially seed user's kibanaIndex 50 | String kibanaIndex = getKibanaIndex(KibanaIndexMode.UNIQUE, userName, false); 51 | XContentBuilder contentBuilder = XContentFactory.jsonBuilder() 52 | .startObject() 53 | .field("defaultIndex","project.foo.uid.*") 54 | .endObject(); 55 | givenDocumentIsIndexed(kibanaIndex, "config", OLD_KIBANA_VERSION, contentBuilder); 56 | givenDocumentIsIndexed(kibanaIndex, KibanaUtils.INDICIES_TYPE, "project.foo.uid.*", "bogus pattern"); 57 | givenDocumentIsIndexed("project.foo.uid.1970.01.01", "test","0","testMsg"); 58 | givenDocumentIsRemoved(".kibana", "config", ConfigurationSettings.DEFAULT_KIBANA_VERSION); 59 | givenUserIsNotClusterAdmin(userName); 60 | givenUserIsAdminForProjects("foo"); 61 | 62 | 63 | //verify access to unique kibana index 64 | String docUri = String.format("%s/config/%s", kibanaIndex, ConfigurationSettings.DEFAULT_KIBANA_VERSION); 65 | whenGettingDocument(docUri); 66 | assertThatResponseIsSuccessful(); 67 | assertThatDefaultIndexPatternIs("project.foo.uid.*"); 68 | } 69 | 70 | @Test 71 | public void testUpgradeOfKibanaIndexForOps() throws Exception { 72 | final String userName = "adminuser"; 73 | //artificially seed user's kibanaIndex 74 | String kibanaIndex = getKibanaIndex(KibanaIndexMode.UNIQUE, userName, false); 75 | XContentBuilder contentBuilder = XContentFactory.jsonBuilder() 76 | .startObject() 77 | .field("defaultIndex",".all") 78 | .endObject(); 79 | givenDocumentIsIndexed(kibanaIndex, "config", OLD_KIBANA_VERSION, contentBuilder); 80 | givenDocumentIsIndexed(kibanaIndex, KibanaUtils.INDICIES_TYPE, ".all", "bogus pattern"); 81 | givenDocumentIsRemoved(".kibana", "config", ConfigurationSettings.DEFAULT_KIBANA_VERSION); 82 | givenUserIsClusterAdmin(userName); 83 | givenUserIsAdminForProjects("foo"); 84 | 85 | 86 | //verify access to unique kibana index 87 | String docUri = String.format("%s/config/%s", kibanaIndex, ConfigurationSettings.DEFAULT_KIBANA_VERSION); 88 | whenGettingDocument(docUri); 89 | assertThatResponseIsSuccessful(); 90 | assertThatDefaultIndexPatternIs(".all"); 91 | } 92 | 93 | @SuppressWarnings("unchecked") 94 | private void assertThatDefaultIndexPatternIs(String indexPattern) throws Exception { 95 | Response response = (Response) testContext.get(RESPONSE); 96 | Map source = XContentHelper.convertToMap(JsonXContent.jsonXContent, response.body().byteStream(),false); 97 | Map doc = (Map) source.get("_source"); 98 | assertEquals("Exp. default index to be equal", indexPattern, doc.get("defaultIndex")); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/it/java/io/fabric8/elasticsearch/ProxyUsernameIntegrationTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch; 18 | 19 | import org.junit.Test; 20 | 21 | import io.fabric8.elasticsearch.plugin.OpenshiftRequestContextFactory; 22 | 23 | 24 | public class ProxyUsernameIntegrationTest extends ElasticsearchIntegrationTest { 25 | 26 | @Test 27 | public void testClusterAdminUserWithSimpleNameCreateProfileIndex() throws Exception { 28 | givenUserIsClusterAdmin("admin"); 29 | givenUserIsAdminForProjects("logging", "openshift"); 30 | 31 | whenGettingDocument("_cat/indices"); 32 | 33 | assertThatResponseIsSuccessful(); 34 | } 35 | 36 | @Test 37 | public void testNormalUserWithSimpleNameCreateProfileIndex() throws Exception { 38 | givenUserIsNotClusterAdmin("somerandomuser"); 39 | givenUserIsAdminForProjects("myproject"); 40 | 41 | whenGettingDocument("_cat/indices"); 42 | assertThatResponseIsForbidden(); 43 | } 44 | 45 | @Test 46 | public void testUsersWithSimpleNameCreatesProfileIndex() throws Exception { 47 | String [] users = {"foo@email.com", 48 | "CN=jdoe,OU=DL IT,OU=User Accounts,DC=example,DC=com", 49 | "test\\username", 50 | "CN=Lastname\\\\, Firstname,OU=Users,OU=TDBFG,DC=d2-tdbfg,DC=com" 51 | }; 52 | 53 | for (String username : users) { 54 | givenUserIsNotClusterAdmin(username); 55 | givenUserIsAdminForProjects("myproject"); 56 | 57 | whenCheckingIndexExists(".kibana." + OpenshiftRequestContextFactory.getUsernameHash(formatUserName(username))); 58 | assertThatResponseIsSuccessful(); 59 | } 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/it/resources/keystore.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabric8io/openshift-elasticsearch-plugin/2d17bafd8a79fc4d4611d12801b88e7d7146a1fd/src/it/resources/keystore.jks -------------------------------------------------------------------------------- /src/it/resources/sgconfig/actiongroups.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | ALL: 18 | - "indices:*" 19 | MANAGE: 20 | - "indices:monitor/*" 21 | - "indices:admin/*" 22 | CREATE_INDEX: 23 | - "indices:admin/create" 24 | MANAGE_ALIASES: 25 | - "indices:admin/aliases*" 26 | MONITOR: 27 | - "indices:monitor/*" 28 | DATA_ACCESS: 29 | - "indices:data/*" 30 | WRITE: 31 | - "indices:data/write*" 32 | READ: 33 | - "indices:data/read*" 34 | DELETE: 35 | - "indices:data/write/delete*" 36 | CRUD: 37 | - READ 38 | - WRITE 39 | SEARCH: 40 | - "indices:data/read/search*" 41 | - "indices:data/read/msearch*" 42 | - SUGGEST 43 | SUGGEST: 44 | - "indices:data/read/suggest*" 45 | INDEX: 46 | - "indices:data/write/index*" 47 | - "indices:data/write/update*" 48 | GET: 49 | - "indices:data/read/get*" 50 | - "indices:data/read/mget*" 51 | 52 | INDEX_ANY_ADMIN: 53 | - indices:admin/mappings/fields/get* 54 | - indices:admin/validate/query* 55 | - indices:admin/get* 56 | - READ 57 | 58 | INDEX_KIBANA: 59 | - ALL 60 | INDEX_ANY_KIBANA: 61 | - INDEX_ANY_ADMIN 62 | - MANAGE 63 | - WRITE 64 | INDEX_OPERATIONS: 65 | - INDEX_ANY_ADMIN 66 | INDEX_ANY_OPERATIONS: 67 | - INDEX_ANY_ADMIN 68 | INDEX_PROJECT: 69 | - INDEX_ANY_ADMIN 70 | METRICS: 71 | - cluster:monitor/nodes/stats 72 | - cluster:monitor/health 73 | USER_CLUSTER_OPERATIONS: 74 | - "indices:data/read/msearch" 75 | - "indices:data/read/scroll*" 76 | 77 | # CLUSTER 78 | CLUSTER_ALL: 79 | - cluster:* 80 | CLUSTER_MONITOR: 81 | - cluster:monitor/* 82 | CLUSTER_MONITOR_KIBANA: 83 | - cluster:monitor/nodes/info 84 | - cluster:monitor/health 85 | CLUSTER_OPERATIONS: 86 | - ALL 87 | -------------------------------------------------------------------------------- /src/it/resources/sgconfig/config.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | searchguard: 18 | dynamic: 19 | http: 20 | xff: 21 | enabled: true 22 | remoteIpHeader: 'x-forwarded-for' 23 | trustedProxies: '.*' 24 | internalProxies: '.*' 25 | authc: 26 | authentication_domain_proxy: 27 | enabled: true 28 | order: 0 29 | http_authenticator: 30 | challenge: false 31 | type: proxy 32 | config: 33 | user_header: 'x-proxy-remote-user' 34 | authentication_backend: 35 | type: noop 36 | authentication_domain_basic_internal: 37 | enabled: true 38 | order: 1 39 | http_authenticator: 40 | type: clientcert 41 | challenge: false 42 | authentication_backend: 43 | type: noop 44 | 45 | -------------------------------------------------------------------------------- /src/it/resources/sgconfig/internalusers.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | # This is the internal user database 18 | # The hash value is a bcrypt hash and can be generated with plugin/tools/hash.sh 19 | admin: 20 | hash: $2a$12$VcCDgh2NDk07JGN0rjGbM.Ad41qVR/YFJcgHp0UGns5JDymv..TOG 21 | #password is: admin 22 | #keys cannot contain dots 23 | #if you have a username with dots then specify it with username: XXX 24 | mister_picard: 25 | username: mister.picard 26 | hash: $2a$12$wkY2BsRneCU5za1OPYlzsehQit6gu2vprVv/4jHiSEEBv2ThunaTS 27 | #password is: picard 28 | spock: 29 | hash: $2a$12$GI9JXffO3WUjTsU7Yy3E4.LBxC2ILo66Zg/rr79BpikSL2IIRezQa 30 | #password is: spock 31 | roles: 32 | - vulcan 33 | - starfleet 34 | kirk: 35 | hash: $2a$12$xZOcnwYPYQ3zIadnlQIJ0eNhX1ngwMkTN.oMwkKxoGvDVPn4/6XtO 36 | #password is: kirk 37 | roles: 38 | - captains 39 | - starfleet 40 | worf: 41 | hash: $2a$12$A41IxPXV1/Dx46C6i1ufGubv.p3qYX7xVcY46q33sylYbIqQVwTMu 42 | #password is: worf 43 | logstash: 44 | hash: $2a$12$u1ShR4l4uBS3Uv59Pa2y5.1uQuZBrZtmNfqB3iM/.jL0XoV9sghS2 45 | #password is: logstash 46 | kibanaserver: 47 | hash: $2a$12$4AcgAt3xwOWadA5s5blL6ev39OXDNhmOesEoo33eZtrq2N0YrU3H. 48 | #password is: kibanaserver 49 | kibanaro: 50 | hash: $2a$12$JJSXNfTowz7Uu5ttXfeYpeYE0arACvcwlPBStB1F.MI7f0U9Z4DGC 51 | #password is: kibanaro 52 | readall: 53 | hash: $2a$12$ae4ycwzwvLtZxwZ82RmiEunBbIPiAmGZduBAjKN0TXdwQFtCwARz2 54 | #password is: readall 55 | dlsflsuser: 56 | hash: $2a$12$30rb6oabnodiSdysdWJnhO.4sVRkyNudPC1woYCJFhXja3rkyXbam 57 | #password is: dlsflsuser 58 | test: 59 | hash: $2a$12$1HqHxm3QTfzwkse7vwzhFOV4gDv787cZ8BwmCwNEyJhn0CZoo8VVu 60 | #password is: test 61 | -------------------------------------------------------------------------------- /src/it/resources/sgconfig/roles.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | sg_role_kibana: 18 | cluster: 19 | - cluster:monitor/nodes/info 20 | - cluster:monitor/health 21 | indices: 22 | '?kibana': 23 | '*': 24 | - ALL 25 | 26 | sg_role_prometheus: 27 | cluster: 28 | - METRICS 29 | indices: {} 30 | 31 | sg_role_fluentd: 32 | indices: 33 | '*': 34 | '*': 35 | - WRITE 36 | - CREATE_INDEX 37 | 38 | sg_role_curator: 39 | cluster: 40 | - CLUSTER_MONITOR 41 | indices: 42 | '*': 43 | '*': 44 | - READ 45 | - MANAGE 46 | 47 | sg_role_admin: 48 | indices: 49 | '*': 50 | '*': 51 | - ALL 52 | cluster: 53 | - CLUSTER_ALL 54 | 55 | sg_project_operations: 56 | indices: 57 | '?operations?*': 58 | '*': 59 | - READ 60 | - indices:admin/mappings/fields/get* 61 | - indices:admin/validate/query* 62 | - indices:admin/get* 63 | '*?*?*': 64 | '*': 65 | - READ 66 | - indices:admin/mappings/fields/get* 67 | - indices:admin/validate/query* 68 | - indices:admin/get* 69 | -------------------------------------------------------------------------------- /src/it/resources/sgconfig/rolesmapping.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | sg_role_kibana: 18 | users: 19 | - 'kibana' 20 | 21 | sg_role_fluentd: 22 | users: 23 | - 'fluentd' 24 | 25 | sg_role_curator: 26 | users: 27 | - 'curator' 28 | 29 | sg_role_admin: 30 | users: 31 | - 'admin' 32 | - '_sg_internal' -------------------------------------------------------------------------------- /src/it/resources/truststore.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabric8io/openshift-elasticsearch-plugin/2d17bafd8a79fc4d4611d12801b88e7d7146a1fd/src/it/resources/truststore.jks -------------------------------------------------------------------------------- /src/main/assemblies/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | plugin 21 | 22 | zip 23 | 24 | false 25 | 26 | 27 | ${basedir}/src/main/plugin-metadata/plugin-security.policy 28 | elasticsearch 29 | false 30 | 31 | 32 | ${basedir}/src/main/plugin-metadata/plugin-descriptor.properties 33 | elasticsearch 34 | true 35 | 36 | 37 | ${basedir}/tools/sgadmin.sh 38 | elasticsearch 39 | true 40 | 0755 41 | 42 | 43 | 44 | 45 | elasticsearch 46 | true 47 | true 48 | 49 | log4j:log4j 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/ConfigurationSettings.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin; 18 | 19 | public interface ConfigurationSettings extends KibanaIndexMode{ 20 | 21 | /** Searchguard settings here **/ 22 | static final String SEARCHGUARD_AUTHENTICATION_PROXY_HEADER = "searchguard.authentication.proxy.header"; 23 | static final String SEARCHGUARD_CONFIG_INDEX_NAME = "searchguard.config_index_name"; 24 | static final String SEARCHGUARD_ROLE_TYPE = "roles"; 25 | static final String SEARCHGUARD_MAPPING_TYPE = "rolesmapping"; 26 | static final String SEARCHGUARD_CONFIG_ID = "0"; 27 | static final String[] SEARCHGUARD_INITIAL_CONFIGS = new String[] { "config", "roles", "rolesmapping", 28 | "actiongroups", "internalusers" }; 29 | static final String SEARCHGUARD_ADMIN_DN = "searchguard.authcz.admin_dn"; 30 | 31 | static final String SG_CONFIG_SETTING_PATH = "searchguard.config.path"; 32 | static final String SG_CLIENT_KS_PATH = "openshift.searchguard.keystore.path"; 33 | static final String SG_CLIENT_TS_PATH = "openshift.searchguard.truststore.path"; 34 | static final String SG_CLIENT_KS_PASS = "openshift.searchguard.keystore.password"; 35 | static final String SG_CLIENT_TS_PASS = "openshift.searchguard.truststore.password"; 36 | static final String SG_CLIENT_KS_TYPE = "openshift.searchguard.keystore.type"; 37 | static final String SG_CLIENT_TS_TYPE = "openshift.searchguard.truststore.type"; 38 | 39 | static final String DEFAULT_SEARCHGUARD_ADMIN_DN = "CN=system.admin,OU=client,O=client,L=Test,C=DE"; 40 | 41 | static final String DEFAULT_SG_CONFIG_SETTING_PATH = "/opt/app-root/src/sgconfig/"; 42 | static final String DEFAULT_SG_CLIENT_KS_PATH = "/usr/share/elasticsearch/config/admin.jks"; 43 | static final String DEFAULT_SG_CLIENT_TS_PATH = "/usr/share/elasticsearch/config/logging-es.truststore.jks"; 44 | static final String DEFAULT_SG_CLIENT_KS_PASS = "kspass"; 45 | static final String DEFAULT_SG_CLIENT_TS_PASS = "tspass"; 46 | static final String DEFAULT_SG_CLIENT_KS_TYPE = "JKS"; 47 | static final String DEFAULT_SG_CLIENT_TS_TYPE = "JKS"; 48 | /** Searchguard settings here **/ 49 | 50 | /** Kibana settings here **/ 51 | static final String KIBANA_CONFIG_INDEX_NAME = "kibana.config_index_name"; 52 | static final String KIBANA_CONFIG_VERSION = "kibana.version"; 53 | static final String KIBANA_VERSION_HEADER = "kibana.version.header"; 54 | 55 | static final String DEFAULT_KIBANA_VERSION = "5.6.16"; 56 | static final String DEFAULT_KIBANA_VERSION_HEADER = "kbn-version"; 57 | /** Kibana settings here **/ 58 | 59 | /** 60 | * The maximum time time in milliseconds to wait for SearchGuard to sync the 61 | * ACL from a write from this plugin until load by searchguard 62 | */ 63 | 64 | /** OpenShift settings here **/ 65 | static final String OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_APP = "io.fabric8.elasticsearch.kibana.mapping.app"; 66 | static final String OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_OPERATIONS = "io.fabric8.elasticsearch.kibana.mapping.ops"; 67 | static final String OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_EMPTY = "io.fabric8.elasticsearch.kibana.mapping.empty"; 68 | static final String OPENSHIFT_ES_USER_PROFILE_PREFIX = "io.fabric8.elasticsearch.acl.user_profile_prefix"; 69 | 70 | static final String OPENSHIFT_CONFIG_OPS_ALLOW_CLUSTER_READER = "openshift.operations.allow_cluster_reader"; 71 | static final String OPENSHIFT_CONFIG_OPS_PROJECTS = "openshift.operations.project.names"; 72 | static final String[] DEFAULT_OPENSHIFT_OPS_PROJECTS = new String[] { "default", "openshift", "openshift-infra", 73 | "kube-system" }; 74 | static final String OPENSHIFT_REQUEST_CONTEXT = "x-openshift-request-context"; 75 | static final String SYNC_AND_SEED = "x-openshift-sync-and-seed-acls"; 76 | 77 | static final String DEFAULT_AUTH_PROXY_HEADER = "X-Proxy-Remote-User"; 78 | static final String DEFAULT_SECURITY_CONFIG_INDEX = "searchguard"; 79 | static final String DEFAULT_USER_PROFILE_PREFIX = ".kibana"; 80 | static final String[] DEFAULT_WHITELISTED_USERS = new String[] { "$logging.$infra.$fluentd", 81 | "$logging.$infra.$kibana", "$logging.$infra.$curator" }; 82 | 83 | static final String [] DEFAULT_KIBANA_OPS_INDEX_PATTERNS = new String[] { 84 | ".operations.*", ".orphaned.*", "project.*", ".all" 85 | }; 86 | 87 | static final String OPENSHIFT_ACL_EXPIRE_IN_MILLIS = "openshift.acl.expire_in_millis"; 88 | 89 | static final String OPENSHIFT_CONTEXT_CACHE_MAXSIZE = "openshift.context.cache.maxsize"; 90 | static final String OPENSHIFT_CONTEXT_CACHE_EXPIRE_SECONDS = "openshift.context.cache.expireseconds"; 91 | static final int DEFAULT_OPENSHIFT_CONTEXT_CACHE_MAXSIZE = 500; 92 | static final long DEFAULT_OPENSHIFT_CONTEXT_CACHE_EXPIRE_SECONDS = 120; 93 | 94 | /** 95 | * The strategy to use for generating roles and role mappings 96 | */ 97 | static final String OPENSHIFT_ACL_ROLE_STRATEGY = "openshift.acl.role_strategy"; 98 | static final String DEFAULT_ACL_ROLE_STRATEGY = "user"; 99 | 100 | /** 101 | * List of index patterns to create for operations users 102 | */ 103 | static final String OPENSHIFT_KIBANA_OPS_INDEX_PATTERNS = "openshift.kibana.ops_index_patterns"; 104 | 105 | static final String OPENSHIFT_CONFIG_TIME_FIELD_NAME = "openshift.config.time_field_name"; 106 | static final String OPENSHIFT_CONFIG_COMMON_DATA_MODEL = "openshift.config.use_common_data_model"; 107 | static final String OPENSHIFT_CONFIG_PROJECT_INDEX_PREFIX = "openshift.config.project_index_prefix"; 108 | static final String OPENSHIFT_DEFAULT_PROJECT_INDEX_PREFIX = "project"; 109 | 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/KibanaIndexMode.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin; 18 | 19 | public interface KibanaIndexMode { 20 | /** 21 | * The setting that determines the kibana index is used by users. Valid values are one of the following: 22 | * 23 | * * unique (Default) - Each user gets a unique index for kibana visualizations (e.g. .kibana.USER_UUID) 24 | * * shared_ops - Users who are in an ops role will share an index (e.g. kibana_ops) while non ops users will 25 | * have a unique index (e.g. .kibana.USER_UUID) 26 | * * shared_non_ops - Users who are in an ops role will share an index (e.g. kibana) while non-ops users will 27 | * share an index (e.g. .kibana_non_ops) 28 | */ 29 | static final String OPENSHIFT_KIBANA_INDEX_MODE = "openshift.kibana.index.mode"; 30 | 31 | static final String UNIQUE = "unique"; 32 | static final String SHARED_OPS = "shared_ops"; 33 | static final String SHARED_NON_OPS = "shared_non_ops"; 34 | static final String DEFAULT_MODE = UNIQUE; 35 | } -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/OpenShiftElasticSearchConfigurationException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin; 18 | 19 | @SuppressWarnings("serial") 20 | public class OpenShiftElasticSearchConfigurationException extends RuntimeException { 21 | 22 | public OpenShiftElasticSearchConfigurationException(String message) { 23 | super(message); 24 | } 25 | 26 | public OpenShiftElasticSearchConfigurationException(String message, Throwable e) { 27 | super(message, e); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/PluginServiceFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin; 18 | 19 | import org.elasticsearch.common.util.concurrent.ThreadContext; 20 | 21 | import io.fabric8.elasticsearch.plugin.auth.BackendRoleRetriever; 22 | 23 | /** 24 | * Static factory class to provide late binding between 25 | * SG Authentication implementations and this plugin's 26 | * utility classes 27 | */ 28 | public class PluginServiceFactory { 29 | 30 | private static OpenshiftRequestContextFactory contextFactory; 31 | private static OpenshiftAPIService apiService; 32 | private static boolean isReady; 33 | private static ThreadContext threadContext; 34 | private static BackendRoleRetriever backendRoleRetriever; 35 | 36 | private PluginServiceFactory() { 37 | } 38 | 39 | public static OpenshiftRequestContextFactory getContextFactory() { 40 | return contextFactory; 41 | } 42 | 43 | public static void setContextFactory(OpenshiftRequestContextFactory contextFactory) { 44 | PluginServiceFactory.contextFactory = contextFactory; 45 | } 46 | 47 | public static OpenshiftAPIService getApiService() { 48 | return apiService; 49 | } 50 | 51 | public static void setApiService(OpenshiftAPIService apiService) { 52 | PluginServiceFactory.apiService = apiService; 53 | } 54 | 55 | public static boolean isReady() { 56 | return isReady; 57 | } 58 | 59 | public static void markReady() { 60 | isReady = true; 61 | } 62 | 63 | public static void markNotReady() { 64 | isReady = false; 65 | } 66 | 67 | public static ThreadContext getThreadContext() { 68 | return threadContext; 69 | } 70 | 71 | public static void setThreadContext(ThreadContext threadContext) { 72 | PluginServiceFactory.threadContext = threadContext; 73 | } 74 | 75 | public static BackendRoleRetriever getBackendRoleRetriever() { 76 | return backendRoleRetriever; 77 | } 78 | 79 | public static void setBackendRoleRetriever(BackendRoleRetriever backendRoleRetriever) { 80 | PluginServiceFactory.backendRoleRetriever = backendRoleRetriever; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/PluginSettings.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin; 18 | 19 | import static io.fabric8.elasticsearch.plugin.acl.SearchGuardSyncStrategyFactory.PROJECT; 20 | import static io.fabric8.elasticsearch.plugin.acl.SearchGuardSyncStrategyFactory.USER; 21 | 22 | import java.util.Arrays; 23 | import java.util.HashSet; 24 | import java.util.Set; 25 | 26 | import org.apache.commons.lang.ArrayUtils; 27 | import org.apache.logging.log4j.Logger; 28 | import org.elasticsearch.common.logging.Loggers; 29 | import org.elasticsearch.common.settings.Settings; 30 | 31 | public class PluginSettings implements ConfigurationSettings { 32 | 33 | private static final Logger LOGGER = Loggers.getLogger(PluginSettings.class); 34 | 35 | private String kibanaIndexMode; 36 | private String roleStrategy; 37 | private final String cdmProjectPrefix; 38 | private final String defaultKibanaIndex; 39 | private final String searchGuardIndex; 40 | private final String kibanaVersion; 41 | private final String kbnVersionHeader; 42 | private final Set opsIndexPatterns; 43 | private final long expireInMillis; 44 | private final Settings settings; 45 | 46 | public PluginSettings(final Settings settings) { 47 | this.settings = settings; 48 | this.kibanaIndexMode = settings.get(OPENSHIFT_KIBANA_INDEX_MODE, KibanaIndexMode.DEFAULT_MODE); 49 | if (!ArrayUtils.contains(new String[] { UNIQUE, SHARED_OPS, SHARED_NON_OPS }, kibanaIndexMode.toLowerCase())) { 50 | this.kibanaIndexMode = UNIQUE; 51 | } 52 | 53 | this.roleStrategy = settings.get(OPENSHIFT_ACL_ROLE_STRATEGY, DEFAULT_ACL_ROLE_STRATEGY); 54 | if (!ArrayUtils.contains(new String[] { PROJECT, USER }, roleStrategy.toLowerCase())) { 55 | this.kibanaIndexMode = USER; 56 | } 57 | 58 | this.cdmProjectPrefix = settings.get(OPENSHIFT_CONFIG_PROJECT_INDEX_PREFIX, 59 | OPENSHIFT_DEFAULT_PROJECT_INDEX_PREFIX); 60 | this.defaultKibanaIndex = settings.get(KIBANA_CONFIG_INDEX_NAME, DEFAULT_USER_PROFILE_PREFIX); 61 | this.searchGuardIndex = settings.get(SEARCHGUARD_CONFIG_INDEX_NAME, DEFAULT_SECURITY_CONFIG_INDEX); 62 | this.kibanaVersion = settings.get(KIBANA_CONFIG_VERSION, DEFAULT_KIBANA_VERSION); 63 | this.kbnVersionHeader = settings.get(KIBANA_VERSION_HEADER, DEFAULT_KIBANA_VERSION_HEADER); 64 | this.opsIndexPatterns = new HashSet(Arrays.asList(settings.getAsArray(OPENSHIFT_KIBANA_OPS_INDEX_PATTERNS, DEFAULT_KIBANA_OPS_INDEX_PATTERNS))); 65 | this.expireInMillis = settings.getAsLong(OPENSHIFT_CONTEXT_CACHE_EXPIRE_SECONDS, 66 | DEFAULT_OPENSHIFT_CONTEXT_CACHE_EXPIRE_SECONDS) * 1000; 67 | 68 | LOGGER.info("Using kibanaIndexMode: '{}'", this.kibanaIndexMode); 69 | LOGGER.debug("searchGuardIndex: {}", this.searchGuardIndex); 70 | LOGGER.debug("roleStrategy: {}", this.roleStrategy); 71 | 72 | } 73 | 74 | public Settings getSettings() { 75 | return this.settings; 76 | } 77 | 78 | public long getACLExpiresInMillis() { 79 | return expireInMillis; 80 | } 81 | 82 | public String getRoleStrategy() { 83 | return this.roleStrategy; 84 | } 85 | 86 | public String getKibanaIndexMode() { 87 | return kibanaIndexMode; 88 | } 89 | 90 | public String getCdmProjectPrefix() { 91 | return cdmProjectPrefix; 92 | } 93 | 94 | public String getDefaultKibanaIndex() { 95 | return defaultKibanaIndex; 96 | } 97 | 98 | public String getSearchGuardIndex() { 99 | return searchGuardIndex; 100 | } 101 | 102 | public String getKibanaVersion() { 103 | return kibanaVersion; 104 | } 105 | 106 | public String getKbnVersionHeader() { 107 | return kbnVersionHeader; 108 | } 109 | 110 | public void setKibanaIndexMode(String kibanaIndexMode) { 111 | this.kibanaIndexMode = kibanaIndexMode; 112 | } 113 | 114 | public Set getKibanaOpsIndexPatterns() { 115 | return opsIndexPatterns; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/acl/BaseRolesMappingSyncStrategy.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.acl; 18 | 19 | import io.fabric8.elasticsearch.plugin.OpenshiftRequestContextFactory.OpenshiftRequestContext; 20 | 21 | public abstract class BaseRolesMappingSyncStrategy implements RolesMappingSyncStrategy { 22 | 23 | protected final SearchGuardRolesMapping mappings; 24 | private String expire; 25 | 26 | protected BaseRolesMappingSyncStrategy(final SearchGuardRolesMapping mappings, long expiresInMillis) { 27 | this.mappings = mappings; 28 | this.expire = String.valueOf(expiresInMillis); 29 | } 30 | 31 | protected abstract void syncFromImpl(OpenshiftRequestContext context, RolesMappingBuilder builder); 32 | 33 | protected String getExpires() { 34 | return expire; 35 | } 36 | 37 | @Override 38 | public void syncFrom(OpenshiftRequestContext context) { 39 | RolesMappingBuilder builder = new RolesMappingBuilder(); 40 | syncFromImpl(context, builder); 41 | mappings.addAll(builder.build()); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/acl/BaseRolesSyncStrategy.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.acl; 18 | 19 | import static io.fabric8.elasticsearch.plugin.acl.SearchGuardRoles.USER_KIBANA_PREFIX; 20 | import static io.fabric8.elasticsearch.plugin.acl.SearchGuardRoles.USER_PREFIX; 21 | 22 | import io.fabric8.elasticsearch.plugin.KibanaIndexMode; 23 | import io.fabric8.elasticsearch.plugin.OpenshiftRequestContextFactory; 24 | import io.fabric8.elasticsearch.plugin.OpenshiftRequestContextFactory.OpenshiftRequestContext; 25 | 26 | public abstract class BaseRolesSyncStrategy implements RolesSyncStrategy { 27 | 28 | protected SearchGuardRoles roles; 29 | private final String userProfilePrefix; 30 | 31 | protected BaseRolesSyncStrategy(SearchGuardRoles roles, String userProfilePrefix) { 32 | this.roles = roles; 33 | this.userProfilePrefix = userProfilePrefix; 34 | 35 | } 36 | 37 | protected abstract void syncFromImpl(OpenshiftRequestContext context, RolesBuilder builder); 38 | 39 | @Override 40 | public void syncFrom(OpenshiftRequestContext context) { 41 | RolesBuilder builder = new RolesBuilder(); 42 | syncFromImpl(context, builder); 43 | roles.addAll(builder.build()); 44 | } 45 | 46 | protected String formatKibanaIndexName(OpenshiftRequestContext context, String kibanaIndexMode) { 47 | String kibanaIndex = OpenshiftRequestContextFactory.getKibanaIndex(userProfilePrefix, 48 | kibanaIndexMode, context.getUser(), context.isOperationsUser()); 49 | return kibanaIndex.replace('.','?'); 50 | } 51 | 52 | public static String formatKibanaRoleName(OpenshiftRequestContext context) { 53 | final String kibanaIndexMode = context.getKibanaIndexMode(); 54 | if (context.isOperationsUser() ) { 55 | switch (kibanaIndexMode) { 56 | case KibanaIndexMode.UNIQUE: 57 | return SearchGuardRoles.formatUniqueKibanaRoleName(context.getUser()); 58 | default: 59 | return SearchGuardRolesMapping.KIBANA_SHARED_ROLE; 60 | } 61 | } 62 | switch (kibanaIndexMode) { 63 | case KibanaIndexMode.SHARED_NON_OPS: 64 | return SearchGuardRolesMapping.KIBANA_SHARED_NON_OPS_ROLE; 65 | default: 66 | return SearchGuardRoles.formatUniqueKibanaRoleName(context.getUser()); 67 | } 68 | } 69 | 70 | public static String formatUserRoleName(String username) { 71 | return String.format("%s_%s", USER_PREFIX, OpenshiftRequestContextFactory.getUsernameHash(username)); 72 | } 73 | 74 | public static String formatUserKibanaRoleName(String username) { 75 | return String.format("%s_%s", USER_KIBANA_PREFIX, OpenshiftRequestContextFactory.getUsernameHash(username)); 76 | } 77 | 78 | } -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/acl/ConfigCallback.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * Copyright 2015 floragunn UG (haftungsbeschränkt) 19 | * 20 | * Licensed under the Apache License, Version 2.0 (the "License"); 21 | * you may not use this file except in compliance with the License. 22 | * You may obtain a copy of the License at 23 | * 24 | * http://www.apache.org/licenses/LICENSE-2.0 25 | * 26 | * Unless required by applicable law or agreed to in writing, software 27 | * distributed under the License is distributed on an "AS IS" BASIS, 28 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 | * See the License for the specific language governing permissions and 30 | * limitations under the License. 31 | * 32 | */ 33 | 34 | package io.fabric8.elasticsearch.plugin.acl; 35 | 36 | import org.elasticsearch.action.get.MultiGetResponse.Failure; 37 | import org.elasticsearch.common.settings.Settings; 38 | 39 | /* 40 | * HACK: Copy of SG ConfigCallback to make use of ConfigurationLoader 41 | */ 42 | public interface ConfigCallback { 43 | 44 | void success(String type, Settings settings, Long version); 45 | 46 | void noData(String type); 47 | 48 | void singleFailure(Failure failure); 49 | 50 | void failure(Throwable t); 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/acl/DynamicACLFilter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.acl; 18 | 19 | import java.util.function.UnaryOperator; 20 | 21 | import org.apache.commons.lang.StringUtils; 22 | import org.apache.logging.log4j.Logger; 23 | import org.elasticsearch.client.Client; 24 | import org.elasticsearch.client.node.NodeClient; 25 | import org.elasticsearch.common.logging.Loggers; 26 | import org.elasticsearch.common.util.concurrent.ThreadContext; 27 | import org.elasticsearch.rest.RestChannel; 28 | import org.elasticsearch.rest.RestHandler; 29 | import org.elasticsearch.rest.RestRequest; 30 | import org.elasticsearch.threadpool.ThreadPool; 31 | 32 | import io.fabric8.elasticsearch.plugin.ConfigurationSettings; 33 | import io.fabric8.elasticsearch.plugin.OpenshiftRequestContextFactory.OpenshiftRequestContext; 34 | import io.fabric8.elasticsearch.plugin.PluginSettings; 35 | import io.fabric8.elasticsearch.plugin.kibana.KibanaSeed; 36 | import io.fabric8.elasticsearch.plugin.rest.RestChannelInterceptor; 37 | import io.fabric8.elasticsearch.util.RequestUtils; 38 | 39 | /** 40 | * REST filter to update the ACL when a user first makes a request 41 | */ 42 | public class DynamicACLFilter implements ConfigurationSettings { 43 | 44 | private static final Logger LOGGER = Loggers.getLogger(DynamicACLFilter.class); 45 | private final String kibanaVersion; 46 | private final String kbnVersionHeader; 47 | private final String cdmProjectPrefix; 48 | private KibanaSeed kibanaSeed; 49 | private final ACLDocumentManager aclManager; 50 | private final RequestUtils utils; 51 | private final ThreadContext threadContext; 52 | private final String defaultKibanaIndex; 53 | 54 | public DynamicACLFilter(final PluginSettings settings, 55 | final KibanaSeed seed, 56 | final Client client, 57 | final ThreadPool threadPool, 58 | final RequestUtils utils, 59 | final ACLDocumentManager aclManager) { 60 | this.threadContext = threadPool.getThreadContext(); 61 | this.kibanaSeed = seed; 62 | this.kibanaVersion = settings.getKibanaVersion(); 63 | this.kbnVersionHeader = settings.getKbnVersionHeader(); 64 | this.cdmProjectPrefix = settings.getCdmProjectPrefix(); 65 | this.defaultKibanaIndex = settings.getDefaultKibanaIndex(); 66 | this.utils = utils; 67 | this.aclManager = aclManager; 68 | } 69 | 70 | /* 71 | * The hacky logic here is we assume authentication occurs using the authenticator 72 | * we provide. This works first by allowing SG to use the authenticator to establish 73 | * a user and their roles. We then dynamically update the ACL document, seed dashboards, 74 | * and modify the kibana uri if needed. 75 | */ 76 | public RestHandler wrap(final RestHandler original, final UnaryOperator unaryOperator) { 77 | return new RestHandler() { 78 | 79 | private final RestHandler localHandler = new RestHandler() { 80 | 81 | @Override 82 | public void handleRequest(RestRequest request, RestChannel channel, NodeClient client) throws Exception { 83 | if ((request = continueProcessing(request, channel)) != null) { 84 | RestChannelInterceptor interceptor = new RestChannelInterceptor(channel, threadContext, defaultKibanaIndex); 85 | original.handleRequest(request, interceptor, client); 86 | } 87 | } 88 | }; 89 | 90 | @Override 91 | public void handleRequest(RestRequest request, RestChannel channel, NodeClient client) throws Exception { 92 | 93 | RestHandler handler = unaryOperator.apply(localHandler); 94 | handler.handleRequest(request, channel, client); 95 | } 96 | }; 97 | } 98 | 99 | public RestRequest continueProcessing(RestRequest request, RestChannel channel) throws Exception { 100 | try { 101 | if (threadContext.getTransient(OPENSHIFT_REQUEST_CONTEXT) != null) { 102 | OpenshiftRequestContext requestContext = threadContext.getTransient(OPENSHIFT_REQUEST_CONTEXT); 103 | request = utils.modifyRequest(request, requestContext, channel); 104 | Boolean syncAndSeed = threadContext.getTransient(SYNC_AND_SEED); 105 | if (requestContext != OpenshiftRequestContext.EMPTY){ 106 | if(Boolean.TRUE.equals(syncAndSeed)) { 107 | LOGGER.debug("Seeding dashboards and syncing ACLs for user {}", requestContext.getUser()); 108 | utils.logRequest(request); 109 | final String kbnVersion = getKibanaVersion(request); 110 | kibanaSeed.setDashboards(requestContext, kbnVersion, cdmProjectPrefix); 111 | aclManager.syncAcl(requestContext); 112 | } else { 113 | LOGGER.debug("Cache hit. Skipping dashboards and syncing ACLs for user {}", requestContext.getUser()); 114 | } 115 | } 116 | } 117 | } catch (Exception e) { 118 | LOGGER.error("Error handling request", e); 119 | } 120 | return request; 121 | } 122 | 123 | 124 | private String getKibanaVersion(final RestRequest request) { 125 | String kbnVersion = StringUtils.defaultIfEmpty(request.header(kbnVersionHeader), ""); 126 | if (StringUtils.isEmpty(kbnVersion)) { 127 | return this.kibanaVersion; 128 | } 129 | return kbnVersion; 130 | } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/acl/ProjectRolesMappingSyncStrategy.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.acl; 18 | 19 | import static io.fabric8.elasticsearch.plugin.acl.SearchGuardRoles.PROJECT_PREFIX; 20 | 21 | import io.fabric8.elasticsearch.plugin.OpenshiftRequestContextFactory.OpenshiftRequestContext; 22 | import io.fabric8.elasticsearch.plugin.model.Project; 23 | 24 | public class ProjectRolesMappingSyncStrategy extends BaseRolesMappingSyncStrategy { 25 | 26 | public ProjectRolesMappingSyncStrategy(SearchGuardRolesMapping rolesMapping, long expiresInMillis) { 27 | super(rolesMapping, expiresInMillis); 28 | } 29 | 30 | @Override 31 | protected void syncFromImpl(OpenshiftRequestContext context, RolesMappingBuilder builder) { 32 | 33 | final String username = context.getUser(); 34 | for (Project project : context.getProjects()) { 35 | String projectRoleName = String.format("%s_%s", PROJECT_PREFIX, project.getName().replace('.', '_')); 36 | 37 | builder.addUser(projectRoleName, username); 38 | } 39 | 40 | if (context.isOperationsUser()) { 41 | builder.addUser(SearchGuardRolesMapping.ADMIN_ROLE, username) 42 | .expire(getExpires()); 43 | } 44 | String kibanaRoleName = BaseRolesSyncStrategy.formatKibanaRoleName(context); 45 | builder.addUser(kibanaRoleName, username) 46 | .expire(getExpires()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/acl/ProjectRolesSyncStrategy.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.acl; 18 | 19 | import org.apache.commons.lang.StringUtils; 20 | 21 | import io.fabric8.elasticsearch.plugin.OpenshiftRequestContextFactory.OpenshiftRequestContext; 22 | import io.fabric8.elasticsearch.plugin.model.Project; 23 | 24 | /** 25 | * SearchGuard Roles Document sync strategy based on roles 26 | * derived from projects. This should generate role mappings like: 27 | * 28 | gen_project_foo_bar: 29 | indices: 30 | ?foo?bar?*: 31 | '*': [INDEX_PROJECT] 32 | project?foo?bar?*: 33 | '*': [INDEX_PROJECT] 34 | * 35 | */ 36 | public class ProjectRolesSyncStrategy extends BaseRolesSyncStrategy { 37 | 38 | 39 | private final String cdmProjectPrefix; 40 | private final String kibanaIndexMode; 41 | private final String expires; 42 | 43 | public ProjectRolesSyncStrategy(SearchGuardRoles roles, 44 | final String userProfilePrefix, final String cdmProjectPrefix, final String kibanaIndexMode, final long expiresInMillies) { 45 | super(roles, userProfilePrefix); 46 | this.roles = roles; 47 | this.cdmProjectPrefix = cdmProjectPrefix; 48 | this.kibanaIndexMode = kibanaIndexMode; 49 | this.expires = String.valueOf(expiresInMillies); 50 | } 51 | 52 | @Override 53 | public void syncFromImpl(OpenshiftRequestContext context, RolesBuilder builder) { 54 | for (Project project : context.getProjects()) { 55 | String projectName = String.format("%s_%s", SearchGuardRoles.PROJECT_PREFIX, project.getName().replace('.', '_')); 56 | String indexName = String.format("%s?%s?*", project.getName().replace('.', '?'), project.getUID()); 57 | RoleBuilder role = new RoleBuilder(projectName) 58 | .setActions(indexName, ALL,PROJECT_ROLE_ACTIONS) 59 | .expires(expires); 60 | 61 | // If using common data model, allow access to both the 62 | // $projname.$uuid.* indices and 63 | // the project.$projname.$uuid.* indices for backwards compatibility 64 | if (StringUtils.isNotEmpty(cdmProjectPrefix)) { 65 | indexName = String.format("%s?%s?%s?*", cdmProjectPrefix.replace('.', '?'), project.getName().replace('.', '?'), project.getUID()); 66 | role.setActions(indexName, ALL, PROJECT_ROLE_ACTIONS); 67 | } 68 | 69 | builder.addRole(role.build()); 70 | } 71 | 72 | //create role to user's Kibana index 73 | String kibanaRoleName = formatKibanaRoleName(context); 74 | String kibanaIndexName = formatKibanaIndexName(context, kibanaIndexMode); 75 | RoleBuilder kibanaRole = new RoleBuilder(kibanaRoleName) 76 | .setActions(kibanaIndexName, ALL, KIBANA_ROLE_INDEX_ACTIONS); 77 | if (context.isOperationsUser()) { 78 | kibanaRole.setClusters(KIBANA_ROLE_CLUSTER_ACTIONS) 79 | .setActions(ALL, ALL, KIBANA_ROLE_ALL_INDEX_ACTIONS); 80 | }else { 81 | kibanaRole.expires(expires); 82 | } 83 | builder.addRole(kibanaRole.build()); 84 | 85 | //statically add to roles? 86 | if (context.isOperationsUser()) { 87 | RoleBuilder opsKibanaRole = new RoleBuilder(kibanaRoleName) 88 | .setClusters(KIBANA_ROLE_CLUSTER_ACTIONS) 89 | .setActions(kibanaIndexName, ALL, KIBANA_ROLE_INDEX_ACTIONS); 90 | 91 | builder.addRole(opsKibanaRole.build()); 92 | RoleBuilder opsRole = new RoleBuilder(SearchGuardRolesMapping.ADMIN_ROLE) 93 | .setClusters(OPERATIONS_ROLE_CLUSTER_ACTIONS) 94 | .setActions("?operations?", ALL, OPERATIONS_ROLE_OPERATIONS_ACTIONS) 95 | .setActions("*?*?*", ALL, OPERATIONS_ROLE_ANY_ACTIONS); 96 | builder.addRole(opsRole.build()); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/acl/RoleBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.acl; 18 | 19 | import java.util.ArrayList; 20 | import java.util.Arrays; 21 | import java.util.HashMap; 22 | import java.util.HashSet; 23 | import java.util.List; 24 | import java.util.Map; 25 | import java.util.Set; 26 | 27 | import io.fabric8.elasticsearch.plugin.acl.SearchGuardRoles.Roles; 28 | import io.fabric8.elasticsearch.plugin.acl.SearchGuardRoles.Roles.Indices; 29 | import io.fabric8.elasticsearch.plugin.acl.SearchGuardRoles.Roles.Indices.Type; 30 | 31 | public class RoleBuilder { 32 | 33 | private Roles role = new Roles(); 34 | private String name; 35 | private Set clusters = new HashSet(); 36 | private Map>> indices = new HashMap>>(); 37 | private String expires; 38 | 39 | public RoleBuilder(String name) { 40 | this.name = name; 41 | } 42 | 43 | public RoleBuilder expires(String expiresInMillis) { 44 | this.expires = expiresInMillis; 45 | return this; 46 | } 47 | 48 | public RoleBuilder setClusters(List clusters) { 49 | if (clusters != null) { 50 | this.clusters = new HashSet(clusters); 51 | } 52 | return this; 53 | } 54 | 55 | public RoleBuilder setClusters(String[] clusters) { 56 | return setClusters(Arrays.asList(clusters)); 57 | } 58 | 59 | public RoleBuilder setClusterActions(String [] clusterActions) { 60 | return setClusters(clusterActions); 61 | } 62 | 63 | public RoleBuilder addIndex(String index) { 64 | indices.put(index, new HashMap>()); 65 | return this; 66 | } 67 | 68 | public RoleBuilder setActions(String index, String type, List actions) { 69 | if (!indices.containsKey(index)) { 70 | addIndex(index); 71 | } 72 | 73 | indices.get(index).put(type, new HashSet(actions)); 74 | return this; 75 | } 76 | 77 | public RoleBuilder setActions(String index, String type, String[] actions) { 78 | return setActions(index, type, Arrays.asList(actions)); 79 | } 80 | 81 | public Roles build() { 82 | role.setName(name); 83 | role.setCluster(new ArrayList(clusters)); 84 | role.setExpires(expires); 85 | 86 | List roleIndices = new ArrayList(); 87 | for (String indexKey : indices.keySet()) { 88 | 89 | Indices index = new Indices(); 90 | index.setIndex(indexKey); 91 | 92 | List types = new ArrayList(); 93 | for (String typeKey : indices.get(indexKey).keySet()) { 94 | Type type = new Type(); 95 | type.setType(typeKey); 96 | type.setActions(new ArrayList(indices.get(indexKey).get(typeKey))); 97 | types.add(type); 98 | } 99 | 100 | index.setTypes(types); 101 | roleIndices.add(index); 102 | } 103 | 104 | role.setIndices(roleIndices); 105 | return role; 106 | } 107 | } -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/acl/RolesBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.acl; 18 | 19 | import java.util.Collection; 20 | import java.util.HashMap; 21 | import java.util.List; 22 | import java.util.Map; 23 | 24 | import io.fabric8.elasticsearch.plugin.acl.SearchGuardRoles.Roles; 25 | import io.fabric8.elasticsearch.plugin.acl.SearchGuardRoles.Roles.Indices; 26 | 27 | public class RolesBuilder { 28 | 29 | private Map roles = new HashMap<>(); 30 | 31 | public Collection build() { 32 | return roles.values(); 33 | } 34 | 35 | public RolesBuilder addRole(Roles role) { 36 | roles.put(role.getName(), role); 37 | return this; 38 | } 39 | 40 | public RoleBuilder newRoleBuilder(String name) { 41 | return new RoleBuilder(name); 42 | } 43 | 44 | public static class RoleBuilder { 45 | private Roles role = new Roles(); 46 | 47 | RoleBuilder(String name){ 48 | role.setName(name); 49 | } 50 | 51 | public RoleBuilder name(String name) { 52 | role.setName(name); 53 | return this; 54 | } 55 | 56 | public RoleBuilder expires(String expiresInMillies) { 57 | role.setExpires(expiresInMillies); 58 | return this; 59 | } 60 | 61 | public RoleBuilder addClusterAction(String action) { 62 | role.addClusterAction(action); 63 | return this; 64 | } 65 | 66 | public RoleBuilder setClusterActions(List actions) { 67 | role.setCluster(actions); 68 | return this; 69 | } 70 | 71 | public RoleBuilder addIndexAction(Indices action) { 72 | role.addIndexAction(action); 73 | return this; 74 | } 75 | 76 | public RoleBuilder addIndexAction(String index, String type, String action) { 77 | role.addIndexAction(index, type, action); 78 | return this; 79 | } 80 | 81 | public RoleBuilder setIndicesActions(List actions) { 82 | role.setIndices(actions); 83 | return this; 84 | } 85 | 86 | public Roles build() { 87 | return role; 88 | } 89 | 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/acl/RolesMappingBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.acl; 18 | 19 | import java.util.ArrayList; 20 | import java.util.HashMap; 21 | import java.util.HashSet; 22 | import java.util.List; 23 | import java.util.Map; 24 | 25 | import io.fabric8.elasticsearch.plugin.acl.SearchGuardRolesMapping.RolesMapping; 26 | 27 | public class RolesMappingBuilder { 28 | 29 | private Map> roles = new HashMap<>(); 30 | private List rolesMappings = new ArrayList(); 31 | private String expire; 32 | 33 | public List build() { 34 | 35 | for (String role : roles.keySet()) { 36 | RolesMapping mapping = new RolesMapping(); 37 | mapping.setExpire(expire); 38 | mapping.setName(role); 39 | mapping.setUsers(new ArrayList(roles.get(role))); 40 | 41 | rolesMappings.add(mapping); 42 | } 43 | 44 | return rolesMappings; 45 | } 46 | 47 | public RolesMappingBuilder addRole(String role) { 48 | roles.put(role, new HashSet()); 49 | return this; 50 | } 51 | 52 | public RolesMappingBuilder setUsers(String role, List users) { 53 | roles.put(role, new HashSet(users)); 54 | return this; 55 | } 56 | 57 | public RolesMappingBuilder addUser(String role, String user) { 58 | if (!roles.containsKey(role)) { 59 | addRole(role); 60 | } 61 | 62 | roles.get(role).add(user); 63 | return this; 64 | } 65 | 66 | public RolesMappingBuilder expire(String expire) { 67 | this.expire = expire; 68 | return this; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/acl/RolesMappingSyncStrategy.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.acl; 18 | 19 | import io.fabric8.elasticsearch.plugin.OpenshiftRequestContextFactory.OpenshiftRequestContext; 20 | 21 | /** 22 | * Strategy to sync between SearchGuard Documents and request context 23 | * 24 | */ 25 | public interface RolesMappingSyncStrategy { 26 | 27 | /** 28 | * Sync the document to the request context 29 | * @param context The request context 30 | */ 31 | void syncFrom(final OpenshiftRequestContext context); 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/acl/RolesSyncStrategy.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.acl; 18 | 19 | import io.fabric8.elasticsearch.plugin.OpenshiftRequestContextFactory.OpenshiftRequestContext; 20 | 21 | /** 22 | * Strategy to sync between SearchGuard Documents and request context 23 | * 24 | */ 25 | public interface RolesSyncStrategy { 26 | 27 | static final String[] USER_ALL_INDEX_ACTIONS = { "USER_ALL_INDEX_OPS" }; 28 | static final String[] USER_KIBANA_ROLE_CLUSTER_ACTIONS = { "USER_KIBANA_CLUSTER_OPERATIONS" }; 29 | static final String[] USER_ROLE_CLUSTER_ACTIONS = { "USER_CLUSTER_OPERATIONS" }; 30 | static final String[] PROJECT_ROLE_ACTIONS = { "INDEX_PROJECT" }; 31 | static final String[] KIBANA_ROLE_ALL_INDEX_ACTIONS = { "INDEX_ANY_KIBANA" }; 32 | static final String[] KIBANA_ROLE_INDEX_ACTIONS = { "INDEX_KIBANA" }; 33 | static final String[] KIBANA_ROLE_CLUSTER_ACTIONS = { "CLUSTER_MONITOR_KIBANA" }; 34 | static final String[] OPERATIONS_ROLE_CLUSTER_ACTIONS = { "CLUSTER_OPERATIONS" }; 35 | static final String[] OPERATIONS_ROLE_OPERATIONS_ACTIONS = { "INDEX_OPERATIONS" }; 36 | static final String[] OPERATIONS_ROLE_ANY_ACTIONS = { "INDEX_ANY_OPERATIONS" }; 37 | static final String ALL = "*"; 38 | 39 | /** 40 | * Sync the context 41 | * 42 | * @param context The context to use to add to the roles 43 | */ 44 | void syncFrom(final OpenshiftRequestContext context); 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/acl/SearchGuardACLDocument.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.acl; 18 | 19 | import java.util.Map; 20 | 21 | import org.elasticsearch.common.xcontent.ToXContentObject; 22 | 23 | public interface SearchGuardACLDocument extends ToXContentObject { 24 | 25 | static final String EXPIRES = "expires"; 26 | 27 | String getType(); 28 | 29 | T load(Map sourceAsMap); 30 | 31 | Long getVersion(); 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/acl/SearchGuardRolesMapping.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.acl; 18 | 19 | import java.io.IOException; 20 | 21 | import java.util.ArrayList; 22 | import java.util.Collection; 23 | import java.util.HashMap; 24 | import java.util.HashSet; 25 | import java.util.Iterator; 26 | import java.util.List; 27 | import java.util.Map; 28 | import java.util.Set; 29 | 30 | import org.apache.commons.lang.builder.ToStringBuilder; 31 | import org.apache.commons.lang.builder.ToStringStyle; 32 | import org.elasticsearch.common.xcontent.XContentBuilder; 33 | 34 | import io.fabric8.elasticsearch.plugin.ConfigurationSettings; 35 | 36 | public class SearchGuardRolesMapping implements Iterable, SearchGuardACLDocument { 37 | 38 | public static final String ADMIN_ROLE = "gen_project_operations"; 39 | public static final String KIBANA_SHARED_ROLE = SearchGuardRoles.ROLE_PREFIX + "_ocp_kibana_shared"; 40 | public static final String KIBANA_SHARED_NON_OPS_ROLE = SearchGuardRoles.ROLE_PREFIX + "_ocp_kibana_shared_non_ops"; 41 | private static final String USER_HEADER = "users"; 42 | private static final String BACKEND_ROLES = "backendroles"; 43 | private Map mappings = new HashMap<>(); 44 | private Long version; 45 | 46 | public static class RolesMapping { 47 | 48 | private Boolean protect; 49 | private String name; 50 | private Set users = new HashSet(); 51 | private Set backendroles = new HashSet(); 52 | private String expire; 53 | 54 | public Boolean getProtected() { 55 | return this.protect; 56 | } 57 | 58 | public void setProtected(boolean protect) { 59 | this.protect = protect; 60 | } 61 | 62 | public String getName() { 63 | return name; 64 | } 65 | 66 | public void setName(String name) { 67 | this.name = name; 68 | } 69 | 70 | public Collection getUsers() { 71 | return users; 72 | } 73 | 74 | public void setUsers(Collection users) { 75 | if(users == null ) { 76 | users = new HashSet<>(); 77 | } 78 | this.users = new HashSet<>(users); 79 | } 80 | 81 | public void setBackendRoles(Collection roles) { 82 | if(roles == null ) { 83 | roles = new HashSet<>(); 84 | } 85 | this.backendroles = new HashSet<>(roles); 86 | } 87 | 88 | public Set getBackendRoles() { 89 | return this.backendroles; 90 | } 91 | 92 | 93 | @Override 94 | public String toString() { 95 | return new StringBuilder() 96 | .append("name=").append(getName()).append("\n") 97 | .append("expire=").append(getExpire()).append("\n") 98 | .append("users=").append(getUsers().toArray()).append("\n") 99 | .append("backendroles=").append(getBackendRoles().toArray()).append("\n") 100 | .toString(); 101 | } 102 | 103 | public void addAll(Collection users) { 104 | this.users.addAll(users); 105 | } 106 | 107 | public void setExpire(String expire) { 108 | this.expire = expire; 109 | } 110 | 111 | public String getExpire() { 112 | return this.expire; 113 | } 114 | } 115 | 116 | public SearchGuardRolesMapping() { 117 | } 118 | 119 | public SearchGuardRolesMapping(Long version) { 120 | if(version != null && version.longValue() >= 0) { 121 | this.version = version; 122 | } 123 | } 124 | 125 | public Long getVersion() { 126 | return version; 127 | } 128 | 129 | @Override 130 | public Iterator iterator() { 131 | return new ArrayList<>(mappings.values()).iterator(); 132 | } 133 | 134 | @Override 135 | public String toString() { 136 | return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); 137 | } 138 | 139 | public void removeRolesMapping(RolesMapping mapping) { 140 | mappings.remove(mapping.getName()); 141 | } 142 | 143 | @SuppressWarnings("unchecked") 144 | public SearchGuardRolesMapping load(Map source) { 145 | if(source == null) { 146 | return this; 147 | } 148 | for (String key : source.keySet()) { 149 | Map rawMappings = (Map) source.get(key); 150 | 151 | RolesMapping mapping = new RolesMapping(); 152 | mapping.setName(key); 153 | mapping.setUsers((List)(rawMappings.get(USER_HEADER))); 154 | mapping.setBackendRoles((List)(rawMappings.get(BACKEND_ROLES))); 155 | if(rawMappings.containsKey(EXPIRES)) { 156 | mapping.setExpire((String)rawMappings.get(EXPIRES)); 157 | } 158 | mappings.put(mapping.getName(), mapping); 159 | } 160 | 161 | return this; 162 | } 163 | 164 | @Override 165 | public String getType() { 166 | return ConfigurationSettings.SEARCHGUARD_MAPPING_TYPE; 167 | } 168 | 169 | public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException{ 170 | try { 171 | // output keys are names of mapping 172 | for (RolesMapping mapping : mappings.values()) { 173 | builder.startObject(mapping.getName()); 174 | if(mapping.getExpire() != null) { 175 | builder.field(EXPIRES, mapping.getExpire()); 176 | } 177 | builder.array(USER_HEADER, mapping.getUsers().toArray()); 178 | if(!mapping.getBackendRoles().isEmpty()) { 179 | builder.array(BACKEND_ROLES, mapping.getBackendRoles().toArray()); 180 | } 181 | builder.endObject(); 182 | } 183 | return builder; 184 | } catch (IOException e) { 185 | throw new RuntimeException("Unable to convert the SearchGuardRolesMapping to JSON", e); 186 | } 187 | } 188 | 189 | public void addAll(Collection mappings) { 190 | for (RolesMapping rolesMapping : mappings) { 191 | if(this.mappings.containsKey(rolesMapping.getName())){ 192 | this.mappings.get(rolesMapping.getName()).addAll(rolesMapping.getUsers()); 193 | } else { 194 | this.mappings.put(rolesMapping.getName(), rolesMapping); 195 | } 196 | } 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/acl/SearchGuardSyncStrategyFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.acl; 18 | 19 | import io.fabric8.elasticsearch.plugin.PluginSettings; 20 | 21 | /** 22 | * Factory class for creating SearchGuard sync strategies 23 | * 24 | */ 25 | public class SearchGuardSyncStrategyFactory { 26 | 27 | public static final String PROJECT = "project"; 28 | public static final String USER = "user"; 29 | 30 | private final PluginSettings settings; 31 | 32 | public SearchGuardSyncStrategyFactory(final PluginSettings settings) { 33 | this.settings = settings; 34 | } 35 | 36 | public RolesMappingSyncStrategy createRolesMappingSyncStrategy(SearchGuardRolesMapping mapping, long currentTime) { 37 | final long expires = currentTime + settings.getACLExpiresInMillis(); 38 | if(PROJECT.equals(settings.getRoleStrategy())) { 39 | return new ProjectRolesMappingSyncStrategy(mapping, expires); 40 | } 41 | return new UserRolesMappingSyncStrategy(mapping, expires); 42 | } 43 | 44 | public RolesSyncStrategy createRolesSyncStrategy(SearchGuardRoles roles, long currentTime) { 45 | final long expires = currentTime + settings.getACLExpiresInMillis(); 46 | if(PROJECT.equals(settings.getRoleStrategy())) { 47 | return new ProjectRolesSyncStrategy(roles, 48 | settings.getDefaultKibanaIndex(), settings.getCdmProjectPrefix(), settings.getKibanaIndexMode(), expires); 49 | } 50 | return new UserRolesSyncStrategy(roles, 51 | settings.getDefaultKibanaIndex(), settings.getCdmProjectPrefix(), settings.getKibanaIndexMode(), expires); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/acl/UserRolesMappingSyncStrategy.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.acl; 18 | 19 | import io.fabric8.elasticsearch.plugin.OpenshiftRequestContextFactory.OpenshiftRequestContext; 20 | 21 | /** 22 | * SearchGuard Roles Document sync strategy based on roles 23 | * derived from users. This should generate role mappings like: 24 | * 25 | * gen_project_operations: 26 | * users: [user1, user3] 27 | * gen_ocp_kibana_shared: 28 | * users: [user1, user3] 29 | * gen_user_user2: 30 | * users: [user2] 31 | * gen_kibana_user2: 32 | * users: [user2] 33 | */ 34 | public class UserRolesMappingSyncStrategy extends BaseRolesMappingSyncStrategy { 35 | 36 | public UserRolesMappingSyncStrategy(SearchGuardRolesMapping mapping, long expiresInMillis) { 37 | super(mapping, expiresInMillis); 38 | } 39 | 40 | @Override 41 | protected void syncFromImpl(OpenshiftRequestContext context, RolesMappingBuilder builder) { 42 | 43 | final String user = context.getUser(); 44 | String kibanaRoleName = BaseRolesSyncStrategy.formatKibanaRoleName(context); 45 | builder.addUser(kibanaRoleName, user) 46 | .expire(getExpires()); 47 | if (context.isOperationsUser()) { 48 | builder.addUser(SearchGuardRolesMapping.ADMIN_ROLE, user) 49 | .expire(getExpires()); 50 | } else { 51 | String roleName = BaseRolesSyncStrategy.formatUserRoleName(user); 52 | builder.addUser(roleName, user).expire(getExpires()); 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/acl/UserRolesSyncStrategy.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.acl; 18 | 19 | import org.apache.commons.lang.StringUtils; 20 | 21 | import io.fabric8.elasticsearch.plugin.OpenshiftRequestContextFactory.OpenshiftRequestContext; 22 | import io.fabric8.elasticsearch.plugin.model.Project; 23 | 24 | public class UserRolesSyncStrategy extends BaseRolesSyncStrategy implements RolesSyncStrategy { 25 | 26 | private final String cdmProjectPrefix; 27 | private final String kibanaIndexMode; 28 | private String expire; 29 | 30 | public UserRolesSyncStrategy(SearchGuardRoles roles, String userProfilePrefix, String cdmProjectPrefix, String kibanaIndexMode, long expiresInMillis) { 31 | super(roles, userProfilePrefix); 32 | this.cdmProjectPrefix = cdmProjectPrefix; 33 | this.kibanaIndexMode = kibanaIndexMode; 34 | this.expire = String.valueOf(expiresInMillis); 35 | } 36 | 37 | protected void syncFromImpl(OpenshiftRequestContext context, RolesBuilder builder) { 38 | String kibIndexName = formatKibanaIndexName(context, kibanaIndexMode); 39 | String kibRoleName = formatKibanaRoleName(context); 40 | RoleBuilder kibRole = new RoleBuilder(kibRoleName) 41 | .setClusterActions(KIBANA_ROLE_CLUSTER_ACTIONS) 42 | .setActions(kibIndexName, ALL, KIBANA_ROLE_INDEX_ACTIONS) 43 | .expires(expire); 44 | builder.addRole(kibRole.build()); 45 | 46 | //think this can be statically added to roles doc 47 | if (context.isOperationsUser()) { 48 | RoleBuilder opsRole = new RoleBuilder(SearchGuardRolesMapping.ADMIN_ROLE) 49 | .setClusters(OPERATIONS_ROLE_CLUSTER_ACTIONS) 50 | .setActions(ALL, ALL, OPERATIONS_ROLE_ANY_ACTIONS) 51 | .expires(expire); 52 | builder.addRole(opsRole.build()); 53 | return; 54 | } 55 | 56 | String roleName = formatUserRoleName(context.getUser()); 57 | RoleBuilder role = new RoleBuilder(roleName) 58 | .setClusters(USER_ROLE_CLUSTER_ACTIONS) 59 | .expires(expire); 60 | 61 | //permissions for projects 62 | for (Project project : context.getProjects()) { 63 | String indexName = String.format("%s?%s?*", project.getName().replace('.', '?'), project.getUID()); 64 | role.setActions(indexName, ALL, PROJECT_ROLE_ACTIONS); 65 | // If using common data model, allow access to both the 66 | // $projname.$uuid.* indices and 67 | // the project.$projname.$uuid.* indices for backwards compatibility 68 | if (StringUtils.isNotEmpty(cdmProjectPrefix)) { 69 | indexName = String.format("%s?%s?%s?*", cdmProjectPrefix.replace('.', '?'), project.getName().replace('.', '?'), project.getUID()); 70 | role.setActions(indexName, ALL, PROJECT_ROLE_ACTIONS); 71 | } 72 | } 73 | builder.addRole(role.build()); 74 | 75 | } 76 | } -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/auth/BackendRoleRetriever.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.auth; 18 | 19 | import java.util.Collection; 20 | 21 | public interface BackendRoleRetriever { 22 | Collection retrieveBackendRoles(String token); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/filter/FieldStatsResponseFilter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.filter; 18 | 19 | import org.apache.logging.log4j.Logger; 20 | import org.elasticsearch.ElasticsearchException; 21 | import org.elasticsearch.action.ActionListener; 22 | import org.elasticsearch.action.ActionRequest; 23 | import org.elasticsearch.action.ActionResponse; 24 | import org.elasticsearch.action.fieldstats.FieldStatsRequest; 25 | import org.elasticsearch.action.fieldstats.FieldStatsResponse; 26 | import org.elasticsearch.action.support.ActionFilter; 27 | import org.elasticsearch.action.support.ActionFilterChain; 28 | import org.elasticsearch.common.logging.Loggers; 29 | import org.elasticsearch.rest.RestStatus; 30 | import org.elasticsearch.tasks.Task; 31 | 32 | import io.fabric8.elasticsearch.plugin.PluginClient; 33 | 34 | /** 35 | * Filter to modify the response code when an 36 | * index does not exist. 37 | * 38 | * This is for the case 39 | * where we have created an alias but it matches 40 | * no indexes and the request of '_field_stats?level=indices' 41 | * causes SG to generate a 403. 42 | * 43 | */ 44 | public class FieldStatsResponseFilter implements ActionFilter { 45 | 46 | public static final String INDICES_FIELD_STATS_READ_ACTION = "indices:data/read/field_stats"; 47 | private static final Logger LOGGER = Loggers.getLogger(FieldStatsResponseFilter.class); 48 | private final PluginClient client; 49 | 50 | public FieldStatsResponseFilter(PluginClient client) { 51 | this.client = client; 52 | } 53 | 54 | @Override 55 | public int order() { 56 | return Integer.MAX_VALUE; 57 | } 58 | 59 | @SuppressWarnings({ "rawtypes", "unchecked" }) 60 | @Override 61 | public void apply(final Task task, final String action, final ActionRequest request, final ActionListener listener, 62 | final ActionFilterChain chain) { 63 | if(INDICES_FIELD_STATS_READ_ACTION.equals(action)) { 64 | chain.proceed(task, action, request, new ActionListener() { 65 | 66 | @Override 67 | public void onResponse(ActionResponse response) { 68 | if(response instanceof FieldStatsResponse) { 69 | if(((FieldStatsResponse)response).getIndicesMergedFieldStats().isEmpty()) { 70 | LOGGER.trace("Modifying the response to be {}", RestStatus.NO_CONTENT); 71 | ElasticsearchException err = new ElasticsearchException("The index returned an empty result. " 72 | + "You can use the Time Picker to change the time filter or select a higher time interval", 73 | RestStatus.NO_CONTENT); 74 | listener.onFailure(err); 75 | return; 76 | } 77 | } 78 | listener.onResponse(response); 79 | } 80 | 81 | @Override 82 | public void onFailure(Exception e) { 83 | LOGGER.trace("Evaluating failure for action '{}' to see if we need to change from a 403", action); 84 | Exception err = e; 85 | if( INDICES_FIELD_STATS_READ_ACTION.equals(action) && request instanceof FieldStatsRequest) { 86 | for (String index : ((FieldStatsRequest)request).indices()) { 87 | if(!client.indexExists(index)) { 88 | LOGGER.trace("Modifying the response to be {}", RestStatus.NOT_FOUND); 89 | err = new ElasticsearchException("The index '" + index + "' was not found. This could mean data has not yet been collected.", 90 | RestStatus.NOT_FOUND); 91 | break; 92 | } 93 | } 94 | } 95 | listener.onFailure(err); 96 | } 97 | }); 98 | 99 | } else { 100 | chain.proceed(task, action, request, listener); 101 | } 102 | 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/kibana/DocumentBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.kibana; 18 | 19 | import org.apache.commons.lang.StringEscapeUtils; 20 | 21 | public class DocumentBuilder { 22 | 23 | private static final String SEARCH_FIELDS = "{\"properties\":{\"title\":{\"type\":\"string\"},\"description\":" 24 | + "{\"type\":\"string\"},\"hits\":{\"type\":\"integer\"},\"columns\":{\"type\":\"string\"},\"sort\":" 25 | + "{\"type\":\"string\"},\"version\":{\"type\":\"integer\"},\"kibanaSavedObjectMeta\":{\"properties\":" 26 | + "{\"searchSourceJSON\":{\"type\":\"string\"}}}}}"; 27 | 28 | private StringBuffer contents; 29 | private boolean containsFields; 30 | 31 | public DocumentBuilder() { 32 | contents = new StringBuffer(); 33 | containsFields = false; 34 | contents.append('{'); 35 | } 36 | 37 | public DocumentBuilder title(String title) { 38 | return addField("title", title); 39 | } 40 | 41 | public DocumentBuilder description(String description) { 42 | return addField("description", description); 43 | } 44 | 45 | public DocumentBuilder version(int value) { 46 | return addField("version", value); 47 | } 48 | 49 | public DocumentBuilder timeFieldName(String name) { 50 | return addField("timeFieldName", name); 51 | } 52 | 53 | public DocumentBuilder intervalName(String name) { 54 | return addField("intervalName", name); 55 | } 56 | 57 | public DocumentBuilder searchProperty() { 58 | 59 | addComma(); 60 | 61 | contents.append("\"properties\":"); 62 | contents.append(StringEscapeUtils.escapeJava(SEARCH_FIELDS)); 63 | 64 | if (!containsFields) { 65 | containsFields = true; 66 | } 67 | 68 | return this; 69 | } 70 | 71 | public DocumentBuilder defaultIndex(String index) { 72 | return addField(KibanaSeed.DEFAULT_INDEX_FIELD, index); 73 | } 74 | 75 | private DocumentBuilder addField(String key, int value) { 76 | 77 | addComma(); 78 | 79 | contents.append('"'); 80 | contents.append(key); 81 | contents.append("\":"); 82 | contents.append(value); 83 | 84 | if (!containsFields) { 85 | containsFields = true; 86 | } 87 | 88 | return this; 89 | } 90 | 91 | private DocumentBuilder addField(String key, String value) { 92 | 93 | addComma(); 94 | contents.append('"'); 95 | contents.append(key); 96 | contents.append("\":\""); 97 | contents.append(value); 98 | contents.append('"'); 99 | 100 | if (!containsFields) { 101 | containsFields = true; 102 | } 103 | 104 | return this; 105 | } 106 | 107 | private void addComma() { 108 | if (containsFields) { 109 | contents.append(','); 110 | } 111 | } 112 | 113 | public String build() { 114 | contents.append('}'); 115 | return contents.toString(); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/kibana/IndexMappingLoader.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.kibana; 18 | 19 | import java.io.File; 20 | import java.io.FileInputStream; 21 | import java.io.InputStream; 22 | import java.security.AccessController; 23 | import java.security.PrivilegedAction; 24 | import java.util.HashMap; 25 | import java.util.Map; 26 | 27 | import org.apache.commons.io.IOUtils; 28 | import org.apache.logging.log4j.Logger; 29 | import org.elasticsearch.SpecialPermission; 30 | import org.elasticsearch.common.logging.Loggers; 31 | import org.elasticsearch.common.settings.Settings; 32 | 33 | import io.fabric8.elasticsearch.plugin.ConfigurationSettings; 34 | 35 | public class IndexMappingLoader implements ConfigurationSettings { 36 | 37 | private static Logger logger = Loggers.getLogger(IndexMappingLoader.class); 38 | private final String appMappingsTemplate; 39 | private final String opsMappingsTemplate; 40 | private final String emptyProjectMappingsTemplate; 41 | 42 | public IndexMappingLoader(final Settings settings) { 43 | final SecurityManager sm = System.getSecurityManager(); 44 | if (sm != null) { 45 | sm.checkPermission(new SpecialPermission()); 46 | } 47 | Map result = AccessController.doPrivileged(new PrivilegedAction>() { 48 | 49 | @Override 50 | public Map run() { 51 | Map mappings = new HashMap<>(); 52 | mappings.put("app", loadMapping(settings, OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_APP)); 53 | mappings.put("opp", loadMapping(settings, OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_OPERATIONS)); 54 | mappings.put("empty", loadMapping(settings, OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_EMPTY)); 55 | return mappings; 56 | } 57 | 58 | }); 59 | appMappingsTemplate = result.get("app"); 60 | opsMappingsTemplate = result.get("opp"); 61 | emptyProjectMappingsTemplate = result.get("empty"); 62 | } 63 | 64 | private String loadMapping(final Settings settings, final String key) { 65 | String mapping = settings.get(key); 66 | if (mapping != null && new File(mapping).exists()) { 67 | logger.info("Trying to load Kibana mapping for {} from plugin: {}", key, mapping); 68 | try { 69 | InputStream stream = new FileInputStream(mapping.toString()); 70 | return IOUtils.toString(stream); 71 | } catch (Exception e) { 72 | logger.error("Unable to load the Kibana mapping specified by {}: {}", key, e, mapping); 73 | } 74 | } 75 | throw new RuntimeException("Unable to load index mapping for " + key 76 | + ". The key was not in the settings or it specified a file that does not exists."); 77 | } 78 | 79 | public String getApplicationMappingsTemplate() { 80 | return appMappingsTemplate; 81 | } 82 | 83 | public String getOperationsMappingsTemplate() { 84 | return opsMappingsTemplate; 85 | } 86 | 87 | public String getEmptyProjectMappingsTemplate() { 88 | return emptyProjectMappingsTemplate; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/model/Project.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.model; 18 | 19 | import org.apache.commons.lang.ObjectUtils; 20 | 21 | /** 22 | * Simple model to represent an OpenShift project 23 | * 24 | */ 25 | public class Project implements Comparable { 26 | 27 | public static final Project EMPTY = new Project("",""); 28 | private final String name; 29 | private final String uid; 30 | 31 | public Project(String name, String uid) { 32 | this.name = name; 33 | this.uid = uid; 34 | } 35 | 36 | public String getUID(){ 37 | return uid; 38 | } 39 | 40 | public String getName() { 41 | return name; 42 | } 43 | 44 | @Override 45 | public int hashCode() { 46 | final int prime = 31; 47 | int result = 1; 48 | result = prime * result + ((name == null) ? 0 : name.hashCode()); 49 | result = prime * result + ((uid == null) ? 0 : uid.hashCode()); 50 | return result; 51 | } 52 | 53 | @Override 54 | public boolean equals(Object obj) { 55 | if (this == obj) { 56 | return true; 57 | } 58 | if (obj == null) { 59 | return false; 60 | } 61 | if (getClass() != obj.getClass()) { 62 | return false; 63 | } 64 | Project other = (Project) obj; 65 | if (name == null) { 66 | if (other.name != null) { 67 | return false; 68 | } 69 | } else if (!name.equals(other.name)) { 70 | return false; 71 | } 72 | if (uid == null) { 73 | if (other.uid != null) { 74 | return false; 75 | } 76 | } else if (!uid.equals(other.uid)) { 77 | return false; 78 | } 79 | return true; 80 | } 81 | 82 | @Override 83 | public String toString() { 84 | return "Project [name=" + ObjectUtils.defaultIfNull(name,"") + ", uid=" + ObjectUtils.defaultIfNull(uid,"") + "]"; 85 | } 86 | 87 | @Override 88 | public int compareTo(Project o) { 89 | if (o.getName() == null) { 90 | return 1; 91 | } 92 | if (this.getName() == null) { 93 | return -1; 94 | } 95 | return this.getName().compareTo(o.getName()); 96 | } 97 | 98 | } -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/rest/OpenShiftRestResponse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.rest; 18 | 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | import org.apache.logging.log4j.Logger; 23 | import org.elasticsearch.ElasticsearchException; 24 | import org.elasticsearch.common.bytes.BytesArray; 25 | import org.elasticsearch.common.bytes.BytesReference; 26 | import org.elasticsearch.common.logging.Loggers; 27 | import org.elasticsearch.rest.RestResponse; 28 | import org.elasticsearch.rest.RestStatus; 29 | 30 | import io.fabric8.elasticsearch.plugin.OpenshiftRequestContextFactory.OpenshiftRequestContext; 31 | 32 | class OpenShiftRestResponse extends RestResponse { 33 | 34 | private final RestResponse response; 35 | private final BytesReference content; 36 | private static final Logger LOGGER = Loggers.getLogger(OpenShiftRestResponse.class); 37 | 38 | OpenShiftRestResponse(final RestResponse response, final OpenshiftRequestContext context, final String defaultKibanaIndex){ 39 | this.response = response; 40 | this.content = evaluateContentForKibanaIndex(response.content(), context, defaultKibanaIndex); 41 | } 42 | 43 | @Override 44 | public String contentType() { 45 | return response.contentType(); 46 | } 47 | 48 | @Override 49 | public BytesReference content() { 50 | return content; 51 | } 52 | 53 | @Override 54 | public RestStatus status() { 55 | return response.status(); 56 | } 57 | 58 | @Override 59 | public void copyHeaders(ElasticsearchException ex) { 60 | response.copyHeaders(ex); 61 | } 62 | 63 | @Override 64 | public void addHeader(String name, String value) { 65 | response.addHeader(name, value); 66 | } 67 | 68 | @Override 69 | public Map> getHeaders() { 70 | return response.getHeaders(); 71 | } 72 | 73 | private BytesReference evaluateContentForKibanaIndex(BytesReference contentRef, OpenshiftRequestContext context, String defaultKibanaIndex) { 74 | if (context == null || context == OpenshiftRequestContext.EMPTY) { 75 | return contentRef; 76 | } 77 | String content = contentRef.utf8ToString(); 78 | if(content.contains("_index\":\"" + context.getKibanaIndex())) { 79 | LOGGER.debug("Replacing the content that references the kibana index"); 80 | String replaced = content.replaceAll("_index\":\"" + context.getKibanaIndex() + "\"", "_index\":\"" + defaultKibanaIndex + "\""); 81 | return new BytesArray(replaced); 82 | } 83 | return contentRef; 84 | } 85 | } -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/plugin/rest/RestChannelInterceptor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.rest; 18 | 19 | import java.io.IOException; 20 | 21 | import org.elasticsearch.common.io.stream.BytesStreamOutput; 22 | import org.elasticsearch.common.util.concurrent.ThreadContext; 23 | import org.elasticsearch.common.xcontent.XContentBuilder; 24 | import org.elasticsearch.common.xcontent.XContentType; 25 | import org.elasticsearch.rest.RestChannel; 26 | import org.elasticsearch.rest.RestRequest; 27 | import org.elasticsearch.rest.RestResponse; 28 | 29 | import io.fabric8.elasticsearch.plugin.ConfigurationSettings; 30 | import io.fabric8.elasticsearch.plugin.OpenshiftRequestContextFactory.OpenshiftRequestContext; 31 | 32 | /** 33 | * Intercepts the response and modifies it if necessary 34 | */ 35 | public class RestChannelInterceptor implements RestChannel { 36 | 37 | private final RestChannel channel; 38 | private final ThreadContext threadContext; 39 | private final String defaultKibanaIndex; 40 | 41 | public RestChannelInterceptor(final RestChannel channel, ThreadContext threadContext, String defaultKibanaIndex) { 42 | this.channel = channel; 43 | this.threadContext = threadContext; 44 | this.defaultKibanaIndex = defaultKibanaIndex; 45 | } 46 | 47 | @Override 48 | public XContentBuilder newErrorBuilder() throws IOException { 49 | return channel.newErrorBuilder(); 50 | } 51 | 52 | @Override 53 | public XContentBuilder newBuilder() throws IOException { 54 | return channel.newBuilder(); 55 | } 56 | 57 | @Override 58 | public XContentBuilder newBuilder(XContentType contentType, boolean useFiltering) throws IOException { 59 | return channel.newBuilder(contentType, useFiltering); 60 | } 61 | 62 | @Override 63 | public BytesStreamOutput bytesOutput() { 64 | return channel.bytesOutput(); 65 | } 66 | 67 | @Override 68 | public RestRequest request() { 69 | return channel.request(); 70 | } 71 | 72 | @Override 73 | public boolean detailedErrorsEnabled() { 74 | return channel.detailedErrorsEnabled(); 75 | } 76 | 77 | @Override 78 | public void sendResponse(RestResponse response) { 79 | OpenshiftRequestContext context = threadContext.getTransient(ConfigurationSettings.OPENSHIFT_REQUEST_CONTEXT); 80 | channel.sendResponse(new OpenShiftRestResponse(response, context, defaultKibanaIndex)); 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/io/fabric8/elasticsearch/util/IndexUtil.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.util; 18 | 19 | import java.util.HashSet; 20 | import java.util.Set; 21 | 22 | /** 23 | * A utility for manipulating index strings 24 | * 25 | */ 26 | public class IndexUtil { 27 | 28 | /** 29 | * Take a set of indices and remove the date suffix 30 | * project.logging.ae5ca3cb-890e-11e7-b9c2-52540050d5ea.2017.09.06 becomes: 31 | * project.logging.ae5ca3cb-890e-11e7-b9c2-52540050d5ea.* 32 | * 33 | * @param value the value to use in place of the date 34 | * @param indices the set of indices to process 35 | * @return A set of the indices with modified values 36 | */ 37 | public Set replaceDateSuffix(final String value, final Set indices){ 38 | Set modified = new HashSet<>(); 39 | final String sub = "." + value; 40 | for (String index : indices) { 41 | modified.add(index.replaceFirst("\\.\\d\\d\\d\\d\\.\\d\\d.\\d\\d$", sub)); 42 | } 43 | return modified; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/plugin-metadata/plugin-descriptor.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | name=${elasticsearch.plugin.name} 18 | version=${project.version} 19 | jvm=true 20 | classname=io.fabric8.elasticsearch.plugin.OpenShiftElasticSearchPlugin 21 | description=${project.name} 22 | elasticsearch.version=${elasticsearch.version} 23 | java.version=1.8 -------------------------------------------------------------------------------- /src/main/plugin-metadata/plugin-security.policy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | grant { 18 | // search-guard-ssl 19 | //below permissions are needed for netty native open ssl support 20 | permission java.lang.RuntimePermission "loadLibrary.*"; 21 | permission java.lang.RuntimePermission "getClassLoader"; 22 | permission java.lang.RuntimePermission "accessClassInPackage.sun.misc"; 23 | permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; 24 | permission java.security.SecurityPermission "getProperty.ssl.KeyManagerFactory.algorithm"; 25 | permission java.lang.RuntimePermission "accessDeclaredMembers"; 26 | permission java.lang.RuntimePermission "accessClassInPackage.sun.security.x509"; 27 | permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch"; 28 | permission java.io.FilePermission "/proc/sys/net/core/somaxconn","read"; 29 | permission java.util.PropertyPermission "sun.nio.ch.bugLevel", "write"; 30 | permission java.util.PropertyPermission "jdk.tls.rejectClientInitiatedRenegotiation", "write"; 31 | 32 | permission java.security.SecurityPermission "setProperty.ocsp.enable"; 33 | permission java.util.PropertyPermission "com.sun.security.enableCRLDP", "write"; 34 | permission java.util.PropertyPermission "es.set.netty.runtime.available.processors", "write"; 35 | 36 | permission java.net.NetPermission "getNetworkInformation"; 37 | permission java.net.SocketPermission "*", "connect,accept,resolve"; 38 | 39 | // search-guard 40 | permission java.lang.RuntimePermission "shutdownHooks"; 41 | permission java.lang.RuntimePermission "getClassLoader"; 42 | permission java.lang.RuntimePermission "setContextClassLoader"; 43 | permission javax.security.auth.AuthPermission "modifyPrivateCredentials"; 44 | permission javax.security.auth.AuthPermission "doAs"; 45 | permission javax.security.auth.kerberos.ServicePermission "*","accept"; 46 | permission java.util.PropertyPermission "javax.security.auth.useSubjectCredsOnly","write"; 47 | permission java.util.PropertyPermission "java.security.krb5.conf","write"; 48 | permission java.util.PropertyPermission "sun.security.krb5.debug","write"; 49 | permission java.util.PropertyPermission "java.security.debug","write"; 50 | permission java.util.PropertyPermission "sun.security.spnego.debug","write"; 51 | 52 | //Enable when we switch to UnboundID LDAP SDK 53 | //permission java.util.PropertyPermission "*", "read,write"; 54 | //permission java.lang.RuntimePermission "setFactory"; 55 | //permission javax.net.ssl.SSLPermission "setHostnameVerifier"; 56 | 57 | //below permissions are needed for netty native open ssl support 58 | permission java.lang.RuntimePermission "loadLibrary.*"; 59 | permission java.lang.RuntimePermission "accessClassInPackage.sun.misc"; 60 | permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; 61 | permission java.security.SecurityPermission "getProperty.ssl.KeyManagerFactory.algorithm"; 62 | permission java.lang.RuntimePermission "accessDeclaredMembers"; 63 | permission java.lang.RuntimePermission "accessClassInPackage.sun.security.x509"; 64 | permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch"; 65 | permission java.io.FilePermission "/proc/sys/net/core/somaxconn","read"; 66 | permission java.util.PropertyPermission "sun.nio.ch.bugLevel", "write"; 67 | 68 | permission java.security.SecurityPermission "setProperty.ocsp.enable"; 69 | permission java.util.PropertyPermission "com.sun.security.enableCRLDP", "write"; 70 | 71 | // openshift-elasticsearch-plugin 72 | permission java.lang.RuntimePermission "accessDeclaredMembers"; 73 | permission java.lang.RuntimePermission "setFactory"; 74 | permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; 75 | permission java.io.FilePermission "<>", "read,execute,readlink"; 76 | permission java.net.NetPermission "getProxySelector"; 77 | permission java.net.NetPermission "getCookieHandler"; 78 | permission java.lang.RuntimePermission "accessClassInPackage.sun.security.ssl"; 79 | }; -------------------------------------------------------------------------------- /src/test/java/io/fabric8/elasticsearch/plugin/PluginSettingsTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | 21 | import org.elasticsearch.common.settings.Settings; 22 | import org.junit.Test; 23 | 24 | public class PluginSettingsTest { 25 | 26 | private Settings settings = Settings.EMPTY; 27 | 28 | @Test 29 | public void testRoleStrategyDefault() { 30 | PluginSettings plugin = new PluginSettings(settings); 31 | assertEquals("Exp. the plugin default to make roles based on users", "user", plugin.getRoleStrategy()); 32 | } 33 | 34 | @Test 35 | public void testKibanaIndexModeDefault() { 36 | PluginSettings plugin = new PluginSettings(settings); 37 | assertEquals("Exp. the plugin default to make kibana index mode unique", "unique", plugin.getKibanaIndexMode()); 38 | } 39 | 40 | @Test 41 | public void testGetACLExpiresInMillis() { 42 | PluginSettings plugin = new PluginSettings(settings); 43 | assertEquals("Exp. the plugin default to make kibana index mode unique", 44 | ConfigurationSettings.DEFAULT_OPENSHIFT_CONTEXT_CACHE_EXPIRE_SECONDS * 1000, plugin.getACLExpiresInMillis()); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/io/fabric8/elasticsearch/plugin/Samples.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin; 18 | 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | 22 | import org.apache.commons.io.IOUtils; 23 | 24 | public enum Samples { 25 | 26 | ROLES_ACL("searchguard_roles_acl.yml"), 27 | ROLESMAPPING_ACL("searchguard_rolesmapping_acl.yml"), 28 | OPENSHIFT_ROLES_ACL("searchguard_roles_acl_with_openshift_projects.yml"), 29 | OPENSHIFT_ROLESMAPPING_ACL("searchguard_rolesmapping_acl_with_openshift_projects.yml"), 30 | PASSWORDS("passwords.yml"), 31 | PROJECT_STRATEGY_ROLES_SHARED_OPS_KIBANA_MODE("project_strategy_roles_shared_ops_kibana_mode.yml"), 32 | PROJECT_STRATEGY_ROLES_SHARED_NON_OPS_KIBANA_MODE("project_strategy_roles_shared_non_ops_kibana_mode.yml"), 33 | PROJECT_STRATEGY_ROLES_UNIQUE_KIBANA_MODE("project_strategy_roles_unique_kibana_mode.yml"), 34 | 35 | PROJECT_STRATEGY_ROLESMAPPING_UNIQUE_KIBANA_MODE("project_strategy_rolesmapping_unique_kibana_mode.yml"), 36 | PROJECT_STRATEGY_ROLESMAPPING_SHARED_OPS_KIBANA_MODE("project_strategy_rolesmapping_shared_ops_kibana_mode.yml"), 37 | PROJECT_STRATEGY_ROLESMAPPING_SHARED_NON_OPS_KIBANA_MODE("project_strategy_rolesmapping_shared_non_ops_kibana_mode.yml"), 38 | 39 | USER_STRATEGY_ROLESMAPPING_SHARED_OPS_KIBANA_MODE("user_strategy_rolesmapping_shared_ops_kibana_mode.yml"), 40 | USER_STRATEGY_ROLESMAPPING_SHARED_NON_OPS_KIBANA_MODE("user_strategy_rolesmapping_shared_non_ops_kibana_mode.yml"), 41 | USER_STRATEGY_ROLESMAPPING_UNIQUE_KIBANA_MODE("user_strategy_rolesmapping_unique_kibana_mode.yml"), 42 | 43 | USER_STRATEGY_ROLES_SHARED_OPS_KIBANA_MODE("user_strategy_roles_shared_ops_kibana_mode.yml"), 44 | USER_STRATEGY_ROLES_SHARED_NON_OPS_KIBANA_MODE("user_strategy_roles_shared_non_ops_kibana_mode.yml"), 45 | USER_STRATEGY_ROLES_UNIQUE_KIBANA_MODE("user_strategy_roles_unique_kibana_mode.yml"); 46 | 47 | private String path; 48 | 49 | Samples(String path) { 50 | this.path = path; 51 | } 52 | 53 | public String getContent() { 54 | InputStream is = Samples.class.getResourceAsStream(path); 55 | try { 56 | return IOUtils.toString(is, "UTF-8"); 57 | } catch (IOException e) { 58 | throw new RuntimeException(String.format("Unable to read file {}", path), e); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/io/fabric8/elasticsearch/plugin/TestUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | 21 | import java.io.StringReader; 22 | import java.util.Map; 23 | import java.util.TreeMap; 24 | 25 | import org.elasticsearch.common.xcontent.ToXContent; 26 | import org.elasticsearch.common.xcontent.XContentBuilder; 27 | import org.elasticsearch.common.xcontent.XContentFactory; 28 | import org.elasticsearch.common.xcontent.XContentHelper; 29 | import org.elasticsearch.common.xcontent.XContentType; 30 | import org.yaml.snakeyaml.Yaml; 31 | 32 | public class TestUtils { 33 | 34 | 35 | @SuppressWarnings("unchecked") 36 | public static Map buildMap(StringReader reader) { 37 | return (Map) new Yaml().load(reader); 38 | } 39 | 40 | public static void assertYaml(String message, String exp, ToXContent content) throws Exception { 41 | XContentBuilder builder = XContentFactory.yamlBuilder(); 42 | builder.startObject(); 43 | content.toXContent(builder, ToXContent.EMPTY_PARAMS); 44 | builder.endObject(); 45 | Map act = XContentHelper.convertToMap(builder.bytes(), true, XContentType.YAML).v2(); 46 | assertEquals(message, exp, new Yaml().dump(new TreeMap<>(act))); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/io/fabric8/elasticsearch/plugin/acl/BaseRolesSyncStrategyTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.acl; 18 | 19 | import static io.fabric8.elasticsearch.plugin.acl.BaseRolesSyncStrategy.formatUserRoleName; 20 | import static org.junit.Assert.assertEquals; 21 | 22 | import org.apache.commons.codec.digest.DigestUtils; 23 | import org.junit.Test; 24 | 25 | public class BaseRolesSyncStrategyTest { 26 | 27 | @Test 28 | public void testFormatUserNameRoleFromEmail() { 29 | assertEquals("gen_user_" + DigestUtils.sha1Hex("user@email.com"), formatUserRoleName("user@email.com")); 30 | } 31 | 32 | @Test 33 | public void testFormatUserNameRoleThatHasSlash() { 34 | assertEquals("gen_user_" + DigestUtils.sha1Hex("test\\\\user"), formatUserRoleName("test\\\\user")); 35 | } 36 | 37 | @Test 38 | public void testFormatUserNameRoleThatHasForwardSlash() { 39 | assertEquals("gen_user_" + DigestUtils.sha1Hex("test/user"), formatUserRoleName("test/user")); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/io/fabric8/elasticsearch/plugin/auth/FileAuthenticationBackendTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.auth; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | import static org.junit.Assert.assertFalse; 21 | import static org.junit.Assert.assertNull; 22 | import static org.junit.Assert.assertTrue; 23 | import static org.mockito.Mockito.mock; 24 | 25 | import java.io.File; 26 | import java.io.IOException; 27 | import java.util.Arrays; 28 | import java.util.HashMap; 29 | import java.util.List; 30 | import java.util.Map; 31 | import java.util.Random; 32 | 33 | import org.apache.commons.io.FileUtils; 34 | import org.elasticsearch.ElasticsearchSecurityException; 35 | import org.elasticsearch.common.settings.Settings; 36 | import org.elasticsearch.common.util.concurrent.ThreadContext; 37 | import org.elasticsearch.rest.RestRequest; 38 | import org.junit.Before; 39 | import org.junit.Test; 40 | 41 | import com.floragunn.searchguard.action.configupdate.TransportConfigUpdateAction; 42 | import com.floragunn.searchguard.user.AuthCredentials; 43 | import com.floragunn.searchguard.user.User; 44 | 45 | import io.fabric8.elasticsearch.plugin.OpenShiftElasticSearchConfigurationException; 46 | import io.fabric8.elasticsearch.plugin.Samples; 47 | import io.fabric8.elasticsearch.util.TestRestRequest; 48 | 49 | public class FileAuthenticationBackendTest { 50 | 51 | private static final String AUTHORIZATION = "Authorization"; 52 | private FileAuthenticationBackend auth; 53 | private User user; 54 | private Settings settings; 55 | private File tmp; 56 | private TransportConfigUpdateAction tcua = mock(TransportConfigUpdateAction.class); 57 | private ThreadContext context = new ThreadContext(Settings.EMPTY); 58 | 59 | @Before 60 | public void setup() throws IOException { 61 | tmp = File.createTempFile("passwd", Integer.toString(new Random().nextInt()), new File(System.getProperty("java.io.tmpdir"))); 62 | FileUtils.writeStringToFile(tmp, Samples.PASSWORDS.getContent()); 63 | givenFilePath(tmp.getAbsolutePath()); 64 | givenAuthenticationBackend(); 65 | } 66 | 67 | private void givenFilePath(String path) { 68 | settings = Settings.builder().put(FileAuthenticationBackend.FILE, path).build(); 69 | } 70 | 71 | private void givenAuthenticationBackend() { 72 | auth = new FileAuthenticationBackend(settings, tcua); 73 | } 74 | 75 | private RestRequest givenRequestWithAuth(String value) { 76 | Map> headers = new HashMap<>(); 77 | headers.put(AUTHORIZATION, Arrays.asList(value)); 78 | return new TestRestRequest(headers); 79 | } 80 | 81 | private User whenAuthenticating(String username, String passwd) { 82 | AuthCredentials credentials = new AuthCredentials(username, passwd.getBytes()); 83 | return auth.authenticate(credentials ); 84 | } 85 | 86 | @Test(expected = OpenShiftElasticSearchConfigurationException.class) 87 | public void testInitializationWithEmptyFilePath() { 88 | givenFilePath(""); 89 | givenAuthenticationBackend(); 90 | } 91 | 92 | public void testReRequestAuthenticationAlwaysReturnsFalse() { 93 | assertFalse(auth.reRequestAuthentication(null, null)); 94 | } 95 | 96 | @Test 97 | public void testExtractCredentialsWithNoAuthHeader() { 98 | RestRequest request = givenRequestWithAuth(null); 99 | assertNull(auth.extractCredentials(request, context)); 100 | } 101 | 102 | @Test 103 | public void testExtractCredentialsWithAuthHeaderNotBasic() { 104 | RestRequest request = givenRequestWithAuth("foo bar"); 105 | assertNull(auth.extractCredentials(request, context)); 106 | } 107 | 108 | @Test 109 | public void testExtractCredentialsWithAuthHeaderNoPassword() { 110 | RestRequest request = givenRequestWithAuth("basic Zm9vOgo="); //basic foo: 111 | assertNull("Exp a password to be required to auth", auth.extractCredentials(request, context)); 112 | } 113 | 114 | @Test 115 | public void testExtractCredentialsWithAuthHeaderAndPassword() { 116 | RestRequest request = givenRequestWithAuth("Basic Zm9vOmJhcgo="); //Basic foo:bar 117 | AuthCredentials exp = new AuthCredentials("foo","bar".getBytes()); 118 | AuthCredentials act = auth.extractCredentials(request, context); 119 | assertEquals("Exp. the AuthCredentials to match", exp, act); 120 | } 121 | 122 | @Test(expected = OpenShiftElasticSearchConfigurationException.class) 123 | public void testInitializationWithNonExistentFilePath() { 124 | givenFilePath("/foo/bar"); 125 | givenAuthenticationBackend(); 126 | } 127 | 128 | @Test(expected = OpenShiftElasticSearchConfigurationException.class) 129 | public void testInitializationWithUnParsableContent() throws Exception { 130 | FileUtils.writeStringToFile(tmp, "random content"); 131 | //givenFilePath 132 | givenAuthenticationBackend(); 133 | } 134 | 135 | @Test(expected = ElasticsearchSecurityException.class) 136 | public void testAuthenticateWhenUsernameNotFound() { 137 | //givenFilePath 138 | //givenAuthenticationBackend 139 | whenAuthenticating("somerandomuser", "somepasswd"); 140 | } 141 | 142 | @Test(expected = ElasticsearchSecurityException.class) 143 | public void testAuthenticateWhenUsernameIsFoundAndPasswordMatchFails() { 144 | //givenFilePath 145 | //givenAuthenticationBackend 146 | whenAuthenticating("foo", "somepasswd"); 147 | } 148 | 149 | @Test 150 | public void testAuthenticateWhenUsernameIsFoundAndPasswordMatchSucceeds() { 151 | //givenFilePath 152 | //givenAuthenticationBackend 153 | user = whenAuthenticating("foo", "bar"); 154 | assertEquals("foo", user.getName()); 155 | } 156 | 157 | @Test 158 | public void testExistsWhenUserExists() { 159 | //givenFilePath 160 | //givenAuthenticationBackend 161 | user = new User("foo"); 162 | assertTrue("Exp. true when user does exist in the file", auth.exists(user)); 163 | } 164 | 165 | @Test 166 | public void testExistsWhenUserDoesNotExists() { 167 | user = new User("someuser"); 168 | assertFalse("Exp. false when user does not exist in the file", auth.exists(user)); 169 | } 170 | 171 | } 172 | -------------------------------------------------------------------------------- /src/test/java/io/fabric8/elasticsearch/plugin/filter/FieldStatsResponseFilterTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.filter; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | import static org.mockito.Mockito.any; 21 | import static org.mockito.Mockito.anyString; 22 | import static org.mockito.Mockito.doAnswer; 23 | import static org.mockito.Mockito.mock; 24 | import static org.mockito.Mockito.verify; 25 | import static org.mockito.Mockito.when; 26 | 27 | import org.elasticsearch.ElasticsearchException; 28 | import org.elasticsearch.action.ActionListener; 29 | import org.elasticsearch.action.ActionRequest; 30 | import org.elasticsearch.action.ActionResponse; 31 | import org.elasticsearch.action.fieldstats.FieldStatsRequest; 32 | import org.elasticsearch.action.support.ActionFilterChain; 33 | import org.elasticsearch.tasks.Task; 34 | import org.junit.Before; 35 | import org.junit.Test; 36 | import org.mockito.invocation.InvocationOnMock; 37 | import org.mockito.stubbing.Answer; 38 | 39 | import io.fabric8.elasticsearch.plugin.PluginClient; 40 | 41 | @SuppressWarnings("rawtypes") 42 | public class FieldStatsResponseFilterTest { 43 | 44 | private FieldStatsResponseFilter filter; 45 | private ActionFilterChain chain = mock(ActionFilterChain.class); 46 | private String action = FieldStatsResponseFilter.INDICES_FIELD_STATS_READ_ACTION; 47 | private ActionResponse response = mock(ActionResponse.class); 48 | private ActionRequest request = mock(ActionRequest.class); 49 | private ActionListener listener = mock(ActionListener.class); 50 | private Task task = mock(Task.class); 51 | private RuntimeException exception = mock(RuntimeException.class); 52 | private PluginClient client = mock(PluginClient.class); 53 | 54 | @Before 55 | public void setUp() throws Exception { 56 | filter = new FieldStatsResponseFilter(client); 57 | } 58 | 59 | @Test 60 | public void testFilterIsOrderedToBeLast() { 61 | assertEquals(Integer.MAX_VALUE, filter.order()); 62 | } 63 | 64 | @SuppressWarnings("unchecked") 65 | private void givenAnExeptionOccurs() { 66 | doAnswer(new Answer() { 67 | @Override 68 | public Object answer(InvocationOnMock invocation) throws Throwable { 69 | Object[] args = invocation.getArguments(); 70 | ActionListener listener = (ActionListener) args[3]; 71 | listener.onFailure(exception); 72 | return null; 73 | } 74 | }).when(chain).proceed(any(Task.class), anyString(), any(ActionRequest.class), any(ActionListener.class)); 75 | } 76 | 77 | private FieldStatsRequest givenAFieldStatsRequest() { 78 | FieldStatsRequest request = mock(FieldStatsRequest.class); 79 | when(request.indices()).thenReturn(new String [] {"project.foo.uuid.*"}); 80 | return request; 81 | } 82 | 83 | @Test 84 | public void testApplyActionRequestMakesPassThroughCallToOnFailureWithModifiedReturnValueWhenIndexIsMissing() { 85 | //given the chain will be called and wrappers the listener 86 | givenAnExeptionOccurs(); 87 | FieldStatsRequest request = givenAFieldStatsRequest(); 88 | when(client.indexExists(anyString())).thenReturn(false); 89 | 90 | //when 91 | filter.apply(task, action, request, listener, chain ); 92 | 93 | //then the original listener should be notified with the modified exception 94 | verify(listener).onFailure(any(ElasticsearchException.class)); 95 | } 96 | 97 | @Test 98 | public void testApplyActionRequestMakesPassThroughCallToOnFailureWithModifiedReturnValueWhenIndexExists() { 99 | //given the chain will be called and wrappers the listener 100 | givenAnExeptionOccurs(); 101 | FieldStatsRequest request = givenAFieldStatsRequest(); 102 | when(client.indexExists(anyString())).thenReturn(true); 103 | 104 | //when 105 | filter.apply(task, action, request, listener, chain ); 106 | 107 | //then the original listener should be notified with the modified exception 108 | verify(listener).onFailure(any(ElasticsearchException.class)); 109 | } 110 | 111 | @Test 112 | public void testApplyActionRequestMakesPassThroughCallToOnFailureWhenRequestIsNotReadFieldsRequest() { 113 | //given the chain will be called and wrappers the listener 114 | givenAnExeptionOccurs(); 115 | 116 | //when 117 | filter.apply(task, action, request, listener, chain ); 118 | 119 | //then the original listener should be notified 120 | verify(listener).onFailure(exception); 121 | } 122 | 123 | @Test 124 | public void testApplyActionRequestMakesPassThroughCallToOnFailureWhenActionIsNotOfInterest() { 125 | //given the chain will be called and wrappers the listener 126 | givenAnExeptionOccurs(); 127 | request = mock(FieldStatsRequest.class); 128 | //when 129 | filter.apply(task, "someaction", request, listener, chain ); 130 | 131 | //then the original listener should be notified 132 | verify(listener).onFailure(exception); 133 | } 134 | 135 | @SuppressWarnings("unchecked") 136 | @Test 137 | public void testApplyActionRequestMakesPassThroughCallToOnResponse() { 138 | //given the chain will be called and wrappers the listener 139 | doAnswer(new Answer() { 140 | @Override 141 | public Object answer(InvocationOnMock invocation) throws Throwable { 142 | Object[] args = invocation.getArguments(); 143 | ActionListener listener = (ActionListener) args[3]; 144 | listener.onResponse(response); 145 | return null; 146 | } 147 | }).when(chain).proceed(any(Task.class), anyString(), any(ActionRequest.class), any(ActionListener.class)); 148 | 149 | //when 150 | filter.apply(task, action, request, listener, chain ); 151 | 152 | //then the original listener should be notified 153 | verify(listener).onResponse(response); 154 | } 155 | 156 | } 157 | -------------------------------------------------------------------------------- /src/test/java/io/fabric8/elasticsearch/plugin/kibana/IndexMappingLoaderTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.plugin.kibana; 18 | 19 | import static org.junit.Assert.assertNotNull; 20 | 21 | import java.nio.file.Files; 22 | import java.nio.file.Path; 23 | 24 | import org.elasticsearch.common.settings.Settings; 25 | import org.junit.Test; 26 | 27 | import io.fabric8.elasticsearch.plugin.ConfigurationSettings; 28 | 29 | public class IndexMappingLoaderTest { 30 | 31 | @Test(expected = RuntimeException.class) 32 | public void testInitializationWithDefaultsWhenFilesNotFound() { 33 | Settings settings = Settings.builder() 34 | .put(ConfigurationSettings.OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_APP, "/tmp/foo") 35 | .put(ConfigurationSettings.OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_EMPTY, "/tmp/foo") 36 | .put(ConfigurationSettings.OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_OPERATIONS, "/tmp/foo").build(); 37 | new IndexMappingLoader(settings); 38 | } 39 | 40 | @Test 41 | public void testInitializationFromFiles() throws Exception { 42 | Path tmp = Files.createTempDirectory(null); 43 | Path appFile = Files.createTempFile(tmp, "app",".json"); 44 | Path oppFile = Files.createTempFile(tmp, "opp",".json"); 45 | Path empty = Files.createTempFile(tmp, "empty",".json"); 46 | 47 | Settings settings = Settings.builder() 48 | .put(ConfigurationSettings.OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_APP,appFile.toString()) 49 | .put(ConfigurationSettings.OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_OPERATIONS,oppFile.toString()) 50 | .put(ConfigurationSettings.OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_EMPTY,empty.toString()) 51 | .build(); 52 | IndexMappingLoader loader = new IndexMappingLoader(settings); 53 | assertNotNull(loader.getApplicationMappingsTemplate()); 54 | assertNotNull(loader.getOperationsMappingsTemplate()); 55 | assertNotNull(loader.getEmptyProjectMappingsTemplate()); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/io/fabric8/elasticsearch/util/IndexUtilTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.util; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | 21 | import java.util.HashSet; 22 | import java.util.Set; 23 | 24 | import org.junit.Test; 25 | 26 | public class IndexUtilTest { 27 | 28 | @Test 29 | public void testReplaceDateSuffix() { 30 | IndexUtil util = new IndexUtil(); 31 | Set indices = new HashSet<>(); 32 | indices.add("project.logging.ae5ca3cb-890e-11e7-b9c2-52540050d5ea.2017.09.06"); 33 | indices.add("project.logging.ae5ca3cb-890e-11e7-b9c2-52540050d5ea.2017.09.09"); 34 | Set replaced = util.replaceDateSuffix("*", indices); 35 | assertEquals(1, replaced.size()); 36 | assertEquals("project.logging.ae5ca3cb-890e-11e7-b9c2-52540050d5ea.*", (String)replaced.toArray()[0]); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/io/fabric8/elasticsearch/util/RequestUtilsTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.util; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | 21 | import java.util.Arrays; 22 | import java.util.Collections; 23 | import java.util.HashSet; 24 | import java.util.List; 25 | import java.util.Map; 26 | import java.util.TreeMap; 27 | 28 | import org.elasticsearch.common.settings.Settings; 29 | import org.elasticsearch.rest.RestRequest; 30 | import org.junit.Before; 31 | import org.junit.Test; 32 | 33 | import io.fabric8.elasticsearch.plugin.ConfigurationSettings; 34 | import io.fabric8.elasticsearch.plugin.OpenshiftRequestContextFactory; 35 | import io.fabric8.elasticsearch.plugin.OpenshiftRequestContextFactory.OpenshiftRequestContext; 36 | import io.fabric8.elasticsearch.plugin.PluginSettings; 37 | 38 | public class RequestUtilsTest { 39 | 40 | private static final String CONTENT_TYPE = "Content-Type"; 41 | private static final String PROXY_HEADER = "aValue"; 42 | private static final String USER = "auser"; 43 | private RequestUtils util; 44 | 45 | @Before 46 | public void setUp() throws Exception { 47 | Settings settings = Settings.builder().put(ConfigurationSettings.SEARCHGUARD_AUTHENTICATION_PROXY_HEADER, PROXY_HEADER).build(); 48 | PluginSettings pluginSettings = new PluginSettings(settings); 49 | util = new RequestUtils(pluginSettings, null); 50 | } 51 | 52 | @Test 53 | public void testGetUserFromHeader() { 54 | Map> headers = new TreeMap>(String.CASE_INSENSITIVE_ORDER); 55 | headers.put(PROXY_HEADER, Arrays.asList(USER)); 56 | RestRequest request = new TestRestRequest(headers); 57 | 58 | assertEquals(USER, util.getUser(request)); 59 | } 60 | 61 | @Test 62 | public void testModifyContentType() { 63 | Map> headers = new TreeMap>(String.CASE_INSENSITIVE_ORDER); 64 | headers.put(CONTENT_TYPE, Arrays.asList("application/x-ndjson")); 65 | RestRequest request = new TestRestRequest(headers); 66 | 67 | OpenshiftRequestContext context = new OpenshiftRequestContextFactory.OpenshiftRequestContext("foo", null, false, new HashSet<>(), null, null, Collections.emptyList()); 68 | RestRequest modifyRequest = util.modifyRequest(request, context , null); 69 | assertEquals("application/json", modifyRequest.header(CONTENT_TYPE)); 70 | } 71 | 72 | @Test 73 | public void testModifyContentTypeWhenContextIsEmpty() { 74 | Map> headers = new TreeMap>(String.CASE_INSENSITIVE_ORDER); 75 | headers.put(CONTENT_TYPE, Arrays.asList("application/x-ndjson")); 76 | RestRequest request = new TestRestRequest(headers); 77 | 78 | RestRequest modifyRequest = util.modifyRequest(request, OpenshiftRequestContext.EMPTY , null); 79 | assertEquals("", request, modifyRequest); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/test/java/io/fabric8/elasticsearch/util/TestRestRequest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.fabric8.elasticsearch.util; 18 | 19 | import java.util.Collections; 20 | import java.util.List; 21 | import java.util.Map; 22 | 23 | import org.elasticsearch.common.bytes.BytesArray; 24 | import org.elasticsearch.common.bytes.BytesReference; 25 | import org.elasticsearch.common.xcontent.NamedXContentRegistry; 26 | import org.elasticsearch.rest.RestRequest; 27 | 28 | public class TestRestRequest extends RestRequest { 29 | 30 | private static final String URI = "test/restrequest"; 31 | private BytesArray content = new BytesArray(""); 32 | 33 | @SuppressWarnings("unchecked") 34 | public TestRestRequest(Map> headers) { 35 | super(NamedXContentRegistry.EMPTY, Collections.EMPTY_MAP, URI, headers); 36 | } 37 | 38 | @Override 39 | public Method method() { 40 | return Method.GET; 41 | } 42 | 43 | @Override 44 | public String uri() { 45 | return URI; 46 | } 47 | 48 | @Override 49 | public boolean hasContent() { 50 | return false; 51 | } 52 | 53 | @Override 54 | public BytesReference content() { 55 | return content; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/elasticsearch_test_config.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | openshift: 18 | acl: 19 | users: 20 | names: ["system.test.user", "system.logging.test"] 21 | system.test.user: 22 | execute: ["actionrequestfilter.test"] 23 | actionrequestfilter.test.comment: "user can only write" 24 | system.logging.test: 25 | bypass: ["*"] 26 | execute: ["actionrequestfilter.logging"] 27 | actionrequestfilter.logging.comment: "logging can only read from every other index" 28 | system.logging.test.*.comment: "test can do anything in the test index" 29 | system.logging.test.*.indices: [".test.*"] 30 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/elasticsearch_test_expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "acl": [ 3 | { 4 | "__Comment__": "Default is to deny all", 5 | "filters_bypass": [], 6 | "filters_execute": [] 7 | }, 8 | { 9 | "__Comment__": "user can only write", 10 | "users": [ 11 | "system.test.user" 12 | ], 13 | "filters_bypass": [], 14 | "filters_execute": ["actionrequestfilter.test"] 15 | }, 16 | { 17 | "__Comment__": "logging can only read from every other index", 18 | "users": [ 19 | "system.logging.test" 20 | ], 21 | "filters_bypass": [], 22 | "filters_execute": ["actionrequestfilter.logging"] 23 | }, 24 | { 25 | "__Comment__": "test can do anything in the test index", 26 | "users": [ 27 | "system.logging.test" 28 | ], 29 | "indices": [ 30 | ".test.*" 31 | ], 32 | "filters_bypass": ["*"], 33 | "filters_execute": [] 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/passwords.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | # username with a b64 encoded password of 'bar' 18 | foo: 19 | passwd: YmFyCg== 20 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/project_strategy_roles_shared_non_ops_kibana_mode.yml: -------------------------------------------------------------------------------- 1 | gen_ocp_kibana_shared: 2 | cluster: [CLUSTER_MONITOR_KIBANA] 3 | indices: 4 | ?kibana: 5 | '*': [INDEX_KIBANA] 6 | gen_ocp_kibana_shared_non_ops: 7 | expires: '10' 8 | indices: 9 | ?kibana_non_ops: 10 | '*': [INDEX_KIBANA] 11 | gen_project_foo_bar: 12 | expires: '10' 13 | indices: 14 | ?project?foo?bar?123abc?*: 15 | '*': [INDEX_PROJECT] 16 | foo?bar?123abc?*: 17 | '*': [INDEX_PROJECT] 18 | gen_project_operations: 19 | cluster: [CLUSTER_OPERATIONS] 20 | indices: 21 | '*?*?*': 22 | '*': [INDEX_ANY_OPERATIONS] 23 | ?operations?: 24 | '*': [INDEX_OPERATIONS] 25 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/project_strategy_roles_shared_ops_kibana_mode.yml: -------------------------------------------------------------------------------- 1 | gen_kibana_a1881c06eec96db9901c7bbfe41c42a3f08e9cb4: 2 | expires: '10' 3 | indices: 4 | ?kibana?a1881c06eec96db9901c7bbfe41c42a3f08e9cb4: 5 | '*': [INDEX_KIBANA] 6 | gen_ocp_kibana_shared: 7 | cluster: [CLUSTER_MONITOR_KIBANA] 8 | indices: 9 | ?kibana: 10 | '*': [INDEX_KIBANA] 11 | gen_project_foo_bar: 12 | expires: '10' 13 | indices: 14 | ?project?foo?bar?123abc?*: 15 | '*': [INDEX_PROJECT] 16 | foo?bar?123abc?*: 17 | '*': [INDEX_PROJECT] 18 | gen_project_operations: 19 | cluster: [CLUSTER_OPERATIONS] 20 | indices: 21 | '*?*?*': 22 | '*': [INDEX_ANY_OPERATIONS] 23 | ?operations?: 24 | '*': [INDEX_OPERATIONS] 25 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/project_strategy_roles_unique_kibana_mode.yml: -------------------------------------------------------------------------------- 1 | gen_kibana_a1881c06eec96db9901c7bbfe41c42a3f08e9cb4: 2 | expires: '10' 3 | indices: 4 | ?kibana?a1881c06eec96db9901c7bbfe41c42a3f08e9cb4: 5 | '*': [INDEX_KIBANA] 6 | gen_kibana_b3daa77b4c04a9551b8781d03191fe098f325e67: 7 | cluster: [CLUSTER_MONITOR_KIBANA] 8 | indices: 9 | ?kibana?b3daa77b4c04a9551b8781d03191fe098f325e67: 10 | '*': [INDEX_KIBANA] 11 | gen_project_foo_bar: 12 | expires: '10' 13 | indices: 14 | ?project?foo?bar?123abc?*: 15 | '*': [INDEX_PROJECT] 16 | foo?bar?123abc?*: 17 | '*': [INDEX_PROJECT] 18 | gen_project_operations: 19 | cluster: [CLUSTER_OPERATIONS] 20 | indices: 21 | '*?*?*': 22 | '*': [INDEX_ANY_OPERATIONS] 23 | ?operations?: 24 | '*': [INDEX_OPERATIONS] 25 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/project_strategy_rolesmapping_shared_non_ops_kibana_mode.yml: -------------------------------------------------------------------------------- 1 | gen_ocp_kibana_shared: 2 | expires: '10' 3 | users: [user1, user3] 4 | gen_ocp_kibana_shared_non_ops: 5 | expires: '10' 6 | users: [user2] 7 | gen_project_foo_bar: 8 | expires: '10' 9 | users: [user2] 10 | gen_project_operations: 11 | expires: '10' 12 | users: [user1, user3] 13 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/project_strategy_rolesmapping_shared_ops_kibana_mode.yml: -------------------------------------------------------------------------------- 1 | gen_kibana_a1881c06eec96db9901c7bbfe41c42a3f08e9cb4: 2 | expires: '10' 3 | users: [user2] 4 | gen_ocp_kibana_shared: 5 | expires: '10' 6 | users: [user1, user3] 7 | gen_project_foo_bar: 8 | expires: '10' 9 | users: [user2] 10 | gen_project_operations: 11 | expires: '10' 12 | users: [user1, user3] 13 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/project_strategy_rolesmapping_unique_kibana_mode.yml: -------------------------------------------------------------------------------- 1 | gen_kibana_0b7f849446d3383546d15a480966084442cd2193: 2 | expires: '10' 3 | users: [user3] 4 | gen_kibana_a1881c06eec96db9901c7bbfe41c42a3f08e9cb4: 5 | expires: '10' 6 | users: [user2] 7 | gen_kibana_b3daa77b4c04a9551b8781d03191fe098f325e67: 8 | expires: '10' 9 | users: [user1] 10 | gen_project_foo_bar: 11 | expires: '10' 12 | users: [user2] 13 | gen_project_operations: 14 | expires: '10' 15 | users: [user1, user3] 16 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/roles_shared_non_ops_kibana_index.yml: -------------------------------------------------------------------------------- 1 | gen_kibana_a1881c06eec96db9901c7bbfe41c42a3f08e9cb4: 2 | expires: '10' 3 | indices: 4 | ?kibana_non_ops: 5 | '*': [INDEX_KIBANA] 6 | gen_kibana_b3daa77b4c04a9551b8781d03191fe098f325e67: 7 | expires: '10' 8 | indices: 9 | ?kibana_non_ops: 10 | '*': [INDEX_KIBANA] 11 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/searchguard_acl.json: -------------------------------------------------------------------------------- 1 | { 2 | "acl": [ 3 | { 4 | "__Comment__": "By default no filters are executed and no filters a by-passed. In such a case a exception is throws an access will be denied.", 5 | "filters_bypass": [], 6 | "filters_execute": [] 7 | }, 8 | { 9 | "__Comment__": "For admin role all filters are bypassed (so none will be executed) for all indices. This means unrestricted access at all for this role.", 10 | "roles": [ 11 | "admin" 12 | ], 13 | "filters_bypass": ["*"], 14 | "filters_execute": [] 15 | }, 16 | { 17 | "__Comment__": "For every authenticated user who access the index 'public' for this access all non dls and all non fls filters are executed.", 18 | "indices": [ 19 | "public" 20 | ], 21 | "filters_bypass": ["dlsfilter.*","dlsfilter.*"], 22 | "filters_execute": ["*"] 23 | }, 24 | { 25 | "__Comment__": "For marketing role all filters are bypassed (so none will be executed) for index 'marketing'. This means unrestricted access to this index for this role.", 26 | "roles": ["marketing"], 27 | "indices": [ 28 | "marketing" 29 | ], 30 | "filters_bypass": ["*"], 31 | "filters_execute": [] 32 | }, 33 | { 34 | "__Comment__": "For finance role all filters are bypassed (so none will be executed) for index 'finance'. This means unrestricted access to this index for this role.", 35 | "roles": ["finance"], 36 | "indices": [ 37 | "financ*" 38 | ], 39 | "filters_bypass": ["*"], 40 | "filters_execute": [] 41 | }, 42 | { 43 | "__Comment__": "For marketing role the filters 'flsfilter.filter_sensitive_finance' and 'actionrequestfilter.readonly' are executed (but no other filters) for index 'finance'", 44 | "roles": ["marketing"], 45 | "indices": [ 46 | "financ*" 47 | ], 48 | "filters_bypass": [], 49 | "filters_execute": ["flsfilter.filter_sensitive_fina*","actionrequestfilter.readonly"] 50 | }, 51 | { 52 | "__Comment__": "For roles 'ceo' 'marketing' 'finance' all filters are bypassed (so none will be executed) for alias 'planning'. This means unrestricted access to this alias for this roles.", 53 | "roles": [ 54 | "ce*o","marke*ing","*nanc*" 55 | ], 56 | "aliases": [ 57 | "planning" 58 | ], 59 | "filters_bypass": ["*"], 60 | "filters_execute": [] 61 | }, 62 | { 63 | "__Comment__": "For finance role the filters 'dlsfilter.filter_sensite_from_ceodata' and 'actionrequestfilter.readonly' are executed (but no other filters) for index 'ceodata'", 64 | "roles": [ 65 | "finance" 66 | ], 67 | "indices": [ 68 | "ceodat*" 69 | ], 70 | "filters_bypass": [], 71 | "filters_execute": ["dlsfilter.filter_sensitive_from_ceodata", "actionrequestfilter.readonly"] 72 | }, 73 | { 74 | "__Comment__": "For role 'ceo' all filters are bypassed (so none will be executed) for index 'ceodata'. This means unrestricted access to this index for this role.", 75 | "roles": [ 76 | "ce*o" 77 | ], 78 | "indices": [ 79 | "ceodata" 80 | ], 81 | "filters_bypass": ["*"], 82 | "filters_execute": [] 83 | } 84 | ] 85 | } -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/searchguard_acl_with_openshift_projects.json: -------------------------------------------------------------------------------- 1 | { 2 | "acl": [ 3 | { 4 | "__Comment__" : "[openshift-elasticsearch-plugin]", 5 | "users": [ 6 | "mytestuser" 7 | ], 8 | "indices": [ 9 | "projectA", "projectB" 10 | ], 11 | "filters_bypass": ["*"], 12 | "filters_execute": [] 13 | }, 14 | { 15 | "__Comment__" : "[openshift-elasticsearch-plugin]", 16 | "users": [ 17 | "myotheruser" 18 | ], 19 | "indices": [ 20 | "projectB", "projectC" 21 | ], 22 | "filters_bypass": ["*"], 23 | "filters_execute": [] 24 | }, 25 | { 26 | "__Comment__": "By default no filters are executed and no filters a by-passed. In such a case a exception is throws an access will be denied.", 27 | "filters_bypass": [], 28 | "filters_execute": [] 29 | }, 30 | { 31 | "__Comment__": "For admin role all filters are bypassed (so none will be executed) for all indices. This means unrestricted access at all for this role.", 32 | "roles": [ 33 | "admin" 34 | ], 35 | "filters_bypass": ["*"], 36 | "filters_execute": [] 37 | }, 38 | { 39 | "__Comment__": "For every authenticated user who access the index 'public' for this access all non dls and all non fls filters are executed.", 40 | "indices": [ 41 | "public" 42 | ], 43 | "filters_bypass": ["dlsfilter.*","dlsfilter.*"], 44 | "filters_execute": ["*"] 45 | }, 46 | { 47 | "__Comment__": "For marketing role all filters are bypassed (so none will be executed) for index 'marketing'. This means unrestricted access to this index for this role.", 48 | "roles": ["marketing"], 49 | "indices": [ 50 | "marketing" 51 | ], 52 | "filters_bypass": ["*"], 53 | "filters_execute": [] 54 | }, 55 | { 56 | "__Comment__": "For finance role all filters are bypassed (so none will be executed) for index 'finance'. This means unrestricted access to this index for this role.", 57 | "roles": ["finance"], 58 | "indices": [ 59 | "financ*" 60 | ], 61 | "filters_bypass": ["*"], 62 | "filters_execute": [] 63 | }, 64 | { 65 | "__Comment__": "For marketing role the filters 'flsfilter.filter_sensitive_finance' and 'actionrequestfilter.readonly' are executed (but no other filters) for index 'finance'", 66 | "roles": ["marketing"], 67 | "indices": [ 68 | "financ*" 69 | ], 70 | "filters_bypass": [], 71 | "filters_execute": ["flsfilter.filter_sensitive_fina*","actionrequestfilter.readonly"] 72 | }, 73 | { 74 | "__Comment__": "For roles 'ceo' 'marketing' 'finance' all filters are bypassed (so none will be executed) for alias 'planning'. This means unrestricted access to this alias for this roles.", 75 | "roles": [ 76 | "ce*o","marke*ing","*nanc*" 77 | ], 78 | "aliases": [ 79 | "planning" 80 | ], 81 | "filters_bypass": ["*"], 82 | "filters_execute": [] 83 | }, 84 | { 85 | "__Comment__": "For finance role the filters 'dlsfilter.filter_sensite_from_ceodata' and 'actionrequestfilter.readonly' are executed (but no other filters) for index 'ceodata'", 86 | "roles": [ 87 | "finance" 88 | ], 89 | "indices": [ 90 | "ceodat*" 91 | ], 92 | "filters_bypass": [], 93 | "filters_execute": ["dlsfilter.filter_sensitive_from_ceodata", "actionrequestfilter.readonly"] 94 | }, 95 | { 96 | "__Comment__": "For role 'ceo' all filters are bypassed (so none will be executed) for index 'ceodata'. This means unrestricted access to this index for this role.", 97 | "roles": [ 98 | "ce*o" 99 | ], 100 | "indices": [ 101 | "ceodata" 102 | ], 103 | "filters_bypass": ["*"], 104 | "filters_execute": [] 105 | } 106 | ] 107 | } -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/searchguard_roles_acl.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | sg_role_kibana: 18 | cluster: 19 | - cluster:monitor/nodes/info 20 | - cluster:monitor/health 21 | indices: 22 | '*': 23 | '*': 24 | - indices:admin/mappings/fields/get* 25 | - indices:admin/validate/query* 26 | - indices:admin/get* 27 | - READ 28 | '?kibana': 29 | '*': 30 | - ALL 31 | 32 | sg_role_fluentd: 33 | indices: 34 | '*': 35 | '*': 36 | - CRUD 37 | - CREATE_INDEX 38 | 39 | sg_role_curator: 40 | indices: 41 | '*': 42 | '*': 43 | - CRUD 44 | 45 | sg_role_admin: 46 | indices: 47 | '*': 48 | '*': 49 | - ALL 50 | cluster: 51 | - CLUSTER_ALL 52 | 53 | sg_role_prometheus: 54 | cluster: [METRICS] 55 | 56 | sg_project_operations: 57 | indices: 58 | '?operations?*': 59 | '*': 60 | - READ 61 | - indices:admin/mappings/fields/get* 62 | - indices:admin/validate/query* 63 | - indices:admin/get* 64 | '*?*?*': 65 | '*': 66 | - READ 67 | - indices:admin/mappings/fields/get* 68 | - indices:admin/validate/query* 69 | - indices:admin/get* 70 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/searchguard_rolesmapping_acl.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | sg_role_kibana: 18 | users: 19 | - 'CN=system.logging.kibana,OU=OpenShift,O=Logging,L=Test,C=DE' 20 | 21 | sg_role_fluentd: 22 | users: 23 | - 'CN=system.logging.fluentd,OU=OpenShift,O=Logging,L=Test,C=DE' 24 | 25 | sg_role_curator: 26 | users: 27 | - 'CN=system.logging.curator,OU=OpenShift,O=Logging,L=Test,C=DE' 28 | 29 | sg_role_admin: 30 | users: 31 | - 'CN=system.admin,OU=OpenShift,O=Logging,L=Test,C=DE' 32 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/user_strategy_roles_shared_non_ops_kibana_mode.yml: -------------------------------------------------------------------------------- 1 | gen_ocp_kibana_shared: 2 | cluster: [CLUSTER_MONITOR_KIBANA] 3 | expires: '15' 4 | indices: 5 | ?kibana: 6 | '*': [INDEX_KIBANA] 7 | gen_ocp_kibana_shared_non_ops: 8 | cluster: [CLUSTER_MONITOR_KIBANA] 9 | expires: '15' 10 | indices: 11 | ?kibana_non_ops: 12 | '*': [INDEX_KIBANA] 13 | gen_project_operations: 14 | cluster: [CLUSTER_OPERATIONS] 15 | expires: '15' 16 | indices: 17 | '*': 18 | '*': [INDEX_ANY_OPERATIONS] 19 | gen_user_4c54bf89fe913f39fc22d76309f80cdc6192928f: 20 | cluster: [USER_CLUSTER_OPERATIONS] 21 | expires: '15' 22 | indices: 23 | ?project?distinguishedproj?123abc?*: 24 | '*': [INDEX_PROJECT] 25 | distinguishedproj?123abc?*: 26 | '*': [INDEX_PROJECT] 27 | gen_user_994a33f6a157ba4a286395f81a4333db1e6cefb6: 28 | cluster: [USER_CLUSTER_OPERATIONS] 29 | expires: '15' 30 | indices: 31 | ?project?foo?bar?123abc?*: 32 | '*': [INDEX_PROJECT] 33 | ?project?xyz?123abc?*: 34 | '*': [INDEX_PROJECT] 35 | foo?bar?123abc?*: 36 | '*': [INDEX_PROJECT] 37 | xyz?123abc?*: 38 | '*': [INDEX_PROJECT] 39 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/user_strategy_roles_shared_ops_kibana_mode.yml: -------------------------------------------------------------------------------- 1 | gen_kibana_4c54bf89fe913f39fc22d76309f80cdc6192928f: 2 | cluster: [CLUSTER_MONITOR_KIBANA] 3 | expires: '15' 4 | indices: 5 | ?kibana?4c54bf89fe913f39fc22d76309f80cdc6192928f: 6 | '*': [INDEX_KIBANA] 7 | gen_kibana_994a33f6a157ba4a286395f81a4333db1e6cefb6: 8 | cluster: [CLUSTER_MONITOR_KIBANA] 9 | expires: '15' 10 | indices: 11 | ?kibana?994a33f6a157ba4a286395f81a4333db1e6cefb6: 12 | '*': [INDEX_KIBANA] 13 | gen_ocp_kibana_shared: 14 | cluster: [CLUSTER_MONITOR_KIBANA] 15 | expires: '15' 16 | indices: 17 | ?kibana: 18 | '*': [INDEX_KIBANA] 19 | gen_project_operations: 20 | cluster: [CLUSTER_OPERATIONS] 21 | expires: '15' 22 | indices: 23 | '*': 24 | '*': [INDEX_ANY_OPERATIONS] 25 | gen_user_4c54bf89fe913f39fc22d76309f80cdc6192928f: 26 | cluster: [USER_CLUSTER_OPERATIONS] 27 | expires: '15' 28 | indices: 29 | ?project?distinguishedproj?123abc?*: 30 | '*': [INDEX_PROJECT] 31 | distinguishedproj?123abc?*: 32 | '*': [INDEX_PROJECT] 33 | gen_user_994a33f6a157ba4a286395f81a4333db1e6cefb6: 34 | cluster: [USER_CLUSTER_OPERATIONS] 35 | expires: '15' 36 | indices: 37 | ?project?foo?bar?123abc?*: 38 | '*': [INDEX_PROJECT] 39 | ?project?xyz?123abc?*: 40 | '*': [INDEX_PROJECT] 41 | foo?bar?123abc?*: 42 | '*': [INDEX_PROJECT] 43 | xyz?123abc?*: 44 | '*': [INDEX_PROJECT] 45 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/user_strategy_roles_unique_kibana_mode.yml: -------------------------------------------------------------------------------- 1 | gen_kibana_0b7f849446d3383546d15a480966084442cd2193: 2 | cluster: [CLUSTER_MONITOR_KIBANA] 3 | expires: '15' 4 | indices: 5 | ?kibana?0b7f849446d3383546d15a480966084442cd2193: 6 | '*': [INDEX_KIBANA] 7 | gen_kibana_4c54bf89fe913f39fc22d76309f80cdc6192928f: 8 | cluster: [CLUSTER_MONITOR_KIBANA] 9 | expires: '15' 10 | indices: 11 | ?kibana?4c54bf89fe913f39fc22d76309f80cdc6192928f: 12 | '*': [INDEX_KIBANA] 13 | gen_kibana_994a33f6a157ba4a286395f81a4333db1e6cefb6: 14 | cluster: [CLUSTER_MONITOR_KIBANA] 15 | expires: '15' 16 | indices: 17 | ?kibana?994a33f6a157ba4a286395f81a4333db1e6cefb6: 18 | '*': [INDEX_KIBANA] 19 | gen_kibana_b3daa77b4c04a9551b8781d03191fe098f325e67: 20 | cluster: [CLUSTER_MONITOR_KIBANA] 21 | expires: '15' 22 | indices: 23 | ?kibana?b3daa77b4c04a9551b8781d03191fe098f325e67: 24 | '*': [INDEX_KIBANA] 25 | gen_project_operations: 26 | cluster: [CLUSTER_OPERATIONS] 27 | expires: '15' 28 | indices: 29 | '*': 30 | '*': [INDEX_ANY_OPERATIONS] 31 | gen_user_4c54bf89fe913f39fc22d76309f80cdc6192928f: 32 | cluster: [USER_CLUSTER_OPERATIONS] 33 | expires: '15' 34 | indices: 35 | ?project?distinguishedproj?123abc?*: 36 | '*': [INDEX_PROJECT] 37 | distinguishedproj?123abc?*: 38 | '*': [INDEX_PROJECT] 39 | gen_user_994a33f6a157ba4a286395f81a4333db1e6cefb6: 40 | cluster: [USER_CLUSTER_OPERATIONS] 41 | expires: '15' 42 | indices: 43 | ?project?foo?bar?123abc?*: 44 | '*': [INDEX_PROJECT] 45 | ?project?xyz?123abc?*: 46 | '*': [INDEX_PROJECT] 47 | foo?bar?123abc?*: 48 | '*': [INDEX_PROJECT] 49 | xyz?123abc?*: 50 | '*': [INDEX_PROJECT] 51 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/user_strategy_rolesmapping_shared_non_ops_kibana_mode.yml: -------------------------------------------------------------------------------- 1 | gen_ocp_kibana_shared: 2 | expires: '15' 3 | users: [user1, user3] 4 | gen_ocp_kibana_shared_non_ops: 5 | expires: '15' 6 | users: [user2.bar@email.com, 'CN=jdoe,OU=DL IT,OU=User Accounts,DC=example,DC=com'] 7 | gen_project_operations: 8 | expires: '15' 9 | users: [user1, user3] 10 | gen_user_4c54bf89fe913f39fc22d76309f80cdc6192928f: 11 | expires: '15' 12 | users: ['CN=jdoe,OU=DL IT,OU=User Accounts,DC=example,DC=com'] 13 | gen_user_994a33f6a157ba4a286395f81a4333db1e6cefb6: 14 | expires: '15' 15 | users: [user2.bar@email.com] 16 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/user_strategy_rolesmapping_shared_ops_kibana_mode.yml: -------------------------------------------------------------------------------- 1 | gen_kibana_4c54bf89fe913f39fc22d76309f80cdc6192928f: 2 | expires: '15' 3 | users: ['CN=jdoe,OU=DL IT,OU=User Accounts,DC=example,DC=com'] 4 | gen_kibana_994a33f6a157ba4a286395f81a4333db1e6cefb6: 5 | expires: '15' 6 | users: [user2.bar@email.com] 7 | gen_ocp_kibana_shared: 8 | expires: '15' 9 | users: [user1, user3] 10 | gen_project_operations: 11 | expires: '15' 12 | users: [user1, user3] 13 | gen_user_4c54bf89fe913f39fc22d76309f80cdc6192928f: 14 | expires: '15' 15 | users: ['CN=jdoe,OU=DL IT,OU=User Accounts,DC=example,DC=com'] 16 | gen_user_994a33f6a157ba4a286395f81a4333db1e6cefb6: 17 | expires: '15' 18 | users: [user2.bar@email.com] 19 | -------------------------------------------------------------------------------- /src/test/resources/io/fabric8/elasticsearch/plugin/user_strategy_rolesmapping_unique_kibana_mode.yml: -------------------------------------------------------------------------------- 1 | gen_kibana_0b7f849446d3383546d15a480966084442cd2193: 2 | expires: '15' 3 | users: [user3] 4 | gen_kibana_4c54bf89fe913f39fc22d76309f80cdc6192928f: 5 | expires: '15' 6 | users: ['CN=jdoe,OU=DL IT,OU=User Accounts,DC=example,DC=com'] 7 | gen_kibana_994a33f6a157ba4a286395f81a4333db1e6cefb6: 8 | expires: '15' 9 | users: [user2.bar@email.com] 10 | gen_kibana_b3daa77b4c04a9551b8781d03191fe098f325e67: 11 | expires: '15' 12 | users: [user1] 13 | gen_project_operations: 14 | expires: '15' 15 | users: [user1, user3] 16 | gen_user_4c54bf89fe913f39fc22d76309f80cdc6192928f: 17 | expires: '15' 18 | users: ['CN=jdoe,OU=DL IT,OU=User Accounts,DC=example,DC=com'] 19 | gen_user_994a33f6a157ba4a286395f81a4333db1e6cefb6: 20 | expires: '15' 21 | users: [user2.bar@email.com] 22 | -------------------------------------------------------------------------------- /src/test/resources/java.policy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Red Hat, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | grant { 18 | permission java.security.AllPermission; 19 | }; -------------------------------------------------------------------------------- /src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | status = error 18 | 19 | # log action execution errors for easier debugging 20 | logger.action.name = org.elasticsearch 21 | logger.action.level = debug 22 | logger.action.appenderRef.console.ref = console 23 | 24 | appender.console.type = Console 25 | appender.console.name = console 26 | appender.console.layout.type = PatternLayout 27 | appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] %marker%m%n 28 | 29 | appender.rolling.type = RollingFile 30 | appender.rolling.name = rolling 31 | appender.rolling.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}.log 32 | appender.rolling.layout.type = PatternLayout 33 | appender.rolling.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] %marker%.-10000m%n 34 | appender.rolling.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}-%d{yyyy-MM-dd}.log 35 | appender.rolling.policies.type = Policies 36 | appender.rolling.policies.time.type = TimeBasedTriggeringPolicy 37 | appender.rolling.policies.time.interval = 1 38 | appender.rolling.policies.time.modulate = true 39 | 40 | rootLogger.level = trace 41 | rootLogger.appenderRef.console.ref = console 42 | 43 | appender.deprecation_rolling.type = RollingFile 44 | appender.deprecation_rolling.name = deprecation_rolling 45 | appender.deprecation_rolling.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}_deprecation.log 46 | appender.deprecation_rolling.layout.type = PatternLayout 47 | appender.deprecation_rolling.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] %marker%.-10000m%n 48 | appender.deprecation_rolling.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}_deprecation-%i.log.gz 49 | appender.deprecation_rolling.policies.type = Policies 50 | appender.deprecation_rolling.policies.size.type = SizeBasedTriggeringPolicy 51 | appender.deprecation_rolling.policies.size.size = 1GB 52 | appender.deprecation_rolling.strategy.type = DefaultRolloverStrategy 53 | appender.deprecation_rolling.strategy.max = 4 54 | 55 | logger.deprecation.name = org.elasticsearch.deprecation 56 | logger.deprecation.level = warn 57 | logger.deprecation.appenderRef.deprecation_rolling.ref = deprecation_rolling 58 | logger.deprecation.additivity = false 59 | 60 | appender.index_search_slowlog_rolling.type = RollingFile 61 | appender.index_search_slowlog_rolling.name = index_search_slowlog_rolling 62 | appender.index_search_slowlog_rolling.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}_index_search_slowlog.log 63 | appender.index_search_slowlog_rolling.layout.type = PatternLayout 64 | appender.index_search_slowlog_rolling.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %marker%.-10000m%n 65 | appender.index_search_slowlog_rolling.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}_index_search_slowlog-%d{yyyy-MM-dd}.log 66 | appender.index_search_slowlog_rolling.policies.type = Policies 67 | appender.index_search_slowlog_rolling.policies.time.type = TimeBasedTriggeringPolicy 68 | appender.index_search_slowlog_rolling.policies.time.interval = 1 69 | appender.index_search_slowlog_rolling.policies.time.modulate = true 70 | 71 | logger.index_search_slowlog_rolling.name = index.search.slowlog 72 | logger.index_search_slowlog_rolling.level = trace 73 | logger.index_search_slowlog_rolling.appenderRef.index_search_slowlog_rolling.ref = index_search_slowlog_rolling 74 | logger.index_search_slowlog_rolling.additivity = false 75 | 76 | appender.index_indexing_slowlog_rolling.type = RollingFile 77 | appender.index_indexing_slowlog_rolling.name = index_indexing_slowlog_rolling 78 | appender.index_indexing_slowlog_rolling.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}_index_indexing_slowlog.log 79 | appender.index_indexing_slowlog_rolling.layout.type = PatternLayout 80 | appender.index_indexing_slowlog_rolling.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %marker%.-10000m%n 81 | appender.index_indexing_slowlog_rolling.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}_index_indexing_slowlog-%d{yyyy-MM-dd}.log 82 | appender.index_indexing_slowlog_rolling.policies.type = Policies 83 | appender.index_indexing_slowlog_rolling.policies.time.type = TimeBasedTriggeringPolicy 84 | appender.index_indexing_slowlog_rolling.policies.time.interval = 1 85 | appender.index_indexing_slowlog_rolling.policies.time.modulate = true 86 | 87 | logger.index_indexing_slowlog.name = index.indexing.slowlog.index 88 | logger.index_indexing_slowlog.level = trace 89 | logger.index_indexing_slowlog.appenderRef.index_indexing_slowlog_rolling.ref = index_indexing_slowlog_rolling 90 | logger.index_indexing_slowlog.additivity = false 91 | -------------------------------------------------------------------------------- /src/test/resources/sgconfig/actiongroups.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | ALL: 18 | - "indices:*" 19 | MANAGE: 20 | - "indices:monitor/*" 21 | - "indices:admin/*" 22 | CREATE_INDEX: 23 | - "indices:admin/create" 24 | MANAGE_ALIASES: 25 | - "indices:admin/aliases*" 26 | MONITOR: 27 | - "indices:monitor/*" 28 | DATA_ACCESS: 29 | - "indices:data/*" 30 | WRITE: 31 | - "indices:data/write*" 32 | READ: 33 | - "indices:data/read*" 34 | DELETE: 35 | - "indices:data/write/delete*" 36 | CRUD: 37 | - READ 38 | - WRITE 39 | SEARCH: 40 | - "indices:data/read/search*" 41 | - "indices:data/read/msearch*" 42 | - SUGGEST 43 | SUGGEST: 44 | - "indices:data/read/suggest*" 45 | INDEX: 46 | - "indices:data/write/index*" 47 | - "indices:data/write/update*" 48 | GET: 49 | - "indices:data/read/get*" 50 | - "indices:data/read/mget*" 51 | 52 | INDEX_ANY_ADMIN: 53 | - indices:admin/mappings/fields/get* 54 | - indices:admin/validate/query* 55 | - indices:admin/get* 56 | - READ 57 | 58 | INDEX_KIBANA: 59 | - ALL 60 | INDEX_ANY_KIBANA: 61 | - INDEX_ANY_ADMIN 62 | - MANAGE 63 | - WRITE 64 | INDEX_OPERATIONS: 65 | - INDEX_ANY_ADMIN 66 | INDEX_ANY_OPERATIONS: 67 | - INDEX_ANY_ADMIN 68 | INDEX_PROJECT: 69 | - INDEX_ANY_ADMIN 70 | METRICS: 71 | - cluster:monitor/nodes/stats 72 | - cluster:monitor/health 73 | USER_CLUSTER_OPERATIONS: 74 | - "indices:data/read/msearch" 75 | - "indices:data/read/scroll*" 76 | 77 | # CLUSTER 78 | CLUSTER_ALL: 79 | - cluster:* 80 | CLUSTER_MONITOR: 81 | - cluster:monitor/* 82 | CLUSTER_MONITOR_KIBANA: 83 | - cluster:monitor/nodes/info 84 | - cluster:monitor/health 85 | CLUSTER_OPERATIONS: 86 | - ALL 87 | -------------------------------------------------------------------------------- /src/test/resources/sgconfig/config.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | searchguard: 18 | dynamic: 19 | http: 20 | xff: 21 | enabled: true 22 | remoteIpHeader: 'x-forwarded-for' 23 | trustedProxies: '.*' 24 | internalProxies: '.*' 25 | authc: 26 | openshift_domain: 27 | enabled: true 28 | order: 0 29 | http_authenticator: 30 | challenge: false 31 | type: io.fabric8.elasticsearch.plugin.auth.OpenShiftTokenAuthentication 32 | authentication_backend: 33 | type: io.fabric8.elasticsearch.plugin.auth.OpenShiftTokenAuthentication -------------------------------------------------------------------------------- /src/test/resources/sgconfig/internalusers.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | # This is the internal user database 18 | # The hash value is a bcrypt hash and can be generated with plugin/tools/hash.sh 19 | admin: 20 | hash: $2a$12$VcCDgh2NDk07JGN0rjGbM.Ad41qVR/YFJcgHp0UGns5JDymv..TOG 21 | #password is: admin 22 | #keys cannot contain dots 23 | #if you have a username with dots then specify it with username: XXX 24 | mister_picard: 25 | username: mister.picard 26 | hash: $2a$12$wkY2BsRneCU5za1OPYlzsehQit6gu2vprVv/4jHiSEEBv2ThunaTS 27 | #password is: picard 28 | spock: 29 | hash: $2a$12$GI9JXffO3WUjTsU7Yy3E4.LBxC2ILo66Zg/rr79BpikSL2IIRezQa 30 | #password is: spock 31 | roles: 32 | - vulcan 33 | - starfleet 34 | kirk: 35 | hash: $2a$12$xZOcnwYPYQ3zIadnlQIJ0eNhX1ngwMkTN.oMwkKxoGvDVPn4/6XtO 36 | #password is: kirk 37 | roles: 38 | - captains 39 | - starfleet 40 | worf: 41 | hash: $2a$12$A41IxPXV1/Dx46C6i1ufGubv.p3qYX7xVcY46q33sylYbIqQVwTMu 42 | #password is: worf 43 | logstash: 44 | hash: $2a$12$u1ShR4l4uBS3Uv59Pa2y5.1uQuZBrZtmNfqB3iM/.jL0XoV9sghS2 45 | #password is: logstash 46 | kibanaserver: 47 | hash: $2a$12$4AcgAt3xwOWadA5s5blL6ev39OXDNhmOesEoo33eZtrq2N0YrU3H. 48 | #password is: kibanaserver 49 | kibanaro: 50 | hash: $2a$12$JJSXNfTowz7Uu5ttXfeYpeYE0arACvcwlPBStB1F.MI7f0U9Z4DGC 51 | #password is: kibanaro 52 | readall: 53 | hash: $2a$12$ae4ycwzwvLtZxwZ82RmiEunBbIPiAmGZduBAjKN0TXdwQFtCwARz2 54 | #password is: readall 55 | dlsflsuser: 56 | hash: $2a$12$30rb6oabnodiSdysdWJnhO.4sVRkyNudPC1woYCJFhXja3rkyXbam 57 | #password is: dlsflsuser 58 | test: 59 | hash: $2a$12$1HqHxm3QTfzwkse7vwzhFOV4gDv787cZ8BwmCwNEyJhn0CZoo8VVu 60 | #password is: test 61 | -------------------------------------------------------------------------------- /src/test/resources/sgconfig/logging-es.truststore.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabric8io/openshift-elasticsearch-plugin/2d17bafd8a79fc4d4611d12801b88e7d7146a1fd/src/test/resources/sgconfig/logging-es.truststore.jks -------------------------------------------------------------------------------- /src/test/resources/sgconfig/roles.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | sg_role_kibana: 18 | cluster: 19 | - cluster:monitor/nodes/info 20 | - cluster:monitor/health 21 | indices: 22 | '?kibana': 23 | '*': 24 | - ALL 25 | 26 | sg_role_prometheus: 27 | cluster: 28 | - METRICS 29 | indices: {} 30 | 31 | sg_role_fluentd: 32 | indices: 33 | '*': 34 | '*': 35 | - WRITE 36 | - CREATE_INDEX 37 | 38 | sg_role_curator: 39 | cluster: 40 | - CLUSTER_MONITOR 41 | indices: 42 | '*': 43 | '*': 44 | - READ 45 | - MANAGE 46 | 47 | sg_role_admin: 48 | indices: 49 | '*': 50 | '*': 51 | - ALL 52 | cluster: 53 | - CLUSTER_ALL 54 | 55 | sg_project_operations: 56 | indices: 57 | '?operations?*': 58 | '*': 59 | - READ 60 | - indices:admin/mappings/fields/get* 61 | - indices:admin/validate/query* 62 | - indices:admin/get* 63 | '*?*?*': 64 | '*': 65 | - READ 66 | - indices:admin/mappings/fields/get* 67 | - indices:admin/validate/query* 68 | - indices:admin/get* 69 | -------------------------------------------------------------------------------- /src/test/resources/sgconfig/rolesmapping.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Red Hat, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | sg_role_kibana: 18 | users: 19 | - 'kibana' 20 | 21 | sg_role_fluentd: 22 | users: 23 | - 'fluentd' 24 | 25 | sg_role_curator: 26 | users: 27 | - 'curator' 28 | 29 | sg_role_admin: 30 | users: 31 | - 'admin' 32 | - '_sg_internal' -------------------------------------------------------------------------------- /tools/sgadmin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (C) 2015 Red Hat, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | if [ -n "${DEBUG:-}" ]; then 19 | set -x 20 | fi 21 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 22 | 23 | BIN_PATH="java" 24 | ES_CONF="${ES_CONF:-$DIR/../../config}" 25 | SCRIPT_CP="${SCRIPT_CP:-$DIR/*:$DIR/../../lib/*}" 26 | 27 | pushd "${ES_CONF}" 28 | "$BIN_PATH" $JAVA_OPTS -Dsg.display_lic_none=true -cp "${SCRIPT_CP}" com.floragunn.searchguard.tools.SearchGuardAdmin "$@" 29 | popd 30 | --------------------------------------------------------------------------------