This is an automated email from the ASF dual-hosted git repository. jensdeppe pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push: new 31d73ed GEODE-6350: Use MockMvc for testing RegionManagement integration tests (#3149) 31d73ed is described below commit 31d73ed1f0450c37c829d26f67ef68e7cd65f1f5 Author: Jens Deppe <jde...@pivotal.io> AuthorDate: Tue Feb 5 11:52:36 2019 -0800 GEODE-6350: Use MockMvc for testing RegionManagement integration tests (#3149) * Moves the tests out of geode-assembly and into geode-web-management * Introduce commonTest sourceSet which will be used for both integrationTest and distributedTest sources * Drop .security from some test packages * Fix the lifecycle integration between Spring and JUnit rules --- .../internal/RegionManagementIntegrationTest.java | 72 ------------- .../RegionManagementSecurityIntegrationTest.java | 104 ------------------ geode-web-management/build.gradle | 52 +++++++-- .../internal/rest/LocatorCleanupEventListener.java | 40 +++++++ .../LocatorWithSecurityManagerContextLoader.java | 47 +++++++++ .../internal/rest/PlainLocatorContextLoader.java | 51 +++++++++ .../rest/StandardRequestPostProcessor.java | 30 ++++++ .../rest/RegionManagementIntegrationTest.java | 87 ++++++++++++++++ .../RegionManagementSecurityIntegrationTest.java | 116 +++++++++++++++++++++ 9 files changed, 416 insertions(+), 183 deletions(-) diff --git a/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/RegionManagementIntegrationTest.java b/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/RegionManagementIntegrationTest.java deleted file mode 100644 index 8d0b7f0..0000000 --- a/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/RegionManagementIntegrationTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more contributor license - * agreements. See the NOTICE file distributed with this work for additional information regarding - * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. You may obtain a - * copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package org.apache.geode.management.internal; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; - -import org.apache.geode.cache.configuration.RegionConfig; -import org.apache.geode.management.internal.api.ClusterManagementResult; -import org.apache.geode.test.junit.rules.GeodeDevRestClient; -import org.apache.geode.test.junit.rules.LocatorStarterRule; -import org.apache.geode.test.junit.rules.RequiresGeodeHome; - -public class RegionManagementIntegrationTest { - - @ClassRule - public static LocatorStarterRule locator = - new LocatorStarterRule().withHttpService().withAutoStart(); - - @ClassRule - public static RequiresGeodeHome requiresGeodeHome = new RequiresGeodeHome(); - - public static GeodeDevRestClient restClient; - - @BeforeClass - public static void setUpClass() throws Exception { - restClient = - new GeodeDevRestClient("/geode-management/v2", "localhost", locator.getHttpPort(), false); - } - - @Test - public void sanityCheck() throws Exception { - RegionConfig regionConfig = new RegionConfig(); - regionConfig.setName("customers"); - regionConfig.setType("REPLICATE"); - - ObjectMapper mapper = new ObjectMapper(); - String json = mapper.writeValueAsString(regionConfig); - - ClusterManagementResult result = - restClient.doPostAndAssert("/regions", json, null, null) - .hasStatusCode(500) - .getClusterManagementResult(); - assertThat(result.isSuccessful()).isFalse(); - assertThat(result.isSuccessfullyPersisted()).isFalse(); - assertThat(result.isSuccessfullyAppliedOnMembers()).isFalse(); - assertThat(result.getPersistenceStatus().getMessage()) - .isEqualTo("no members found to create cache element"); - } - - @Test - public void ping() throws Exception { - restClient.doGetAndAssert("/ping").hasStatusCode(200).hasResponseBody().isEqualTo("pong"); - } -} diff --git a/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/RegionManagementSecurityIntegrationTest.java b/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/RegionManagementSecurityIntegrationTest.java deleted file mode 100644 index 61fc91f..0000000 --- a/geode-assembly/src/integrationTest/java/org/apache/geode/management/internal/RegionManagementSecurityIntegrationTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more contributor license - * agreements. See the NOTICE file distributed with this work for additional information regarding - * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. You may obtain a - * copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package org.apache.geode.management.internal; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; - -import org.apache.geode.cache.configuration.RegionConfig; -import org.apache.geode.management.internal.api.ClusterManagementResult; -import org.apache.geode.security.SimpleTestSecurityManager; -import org.apache.geode.test.junit.rules.GeodeDevRestClient; -import org.apache.geode.test.junit.rules.LocatorStarterRule; -import org.apache.geode.test.junit.rules.RequiresGeodeHome; - -public class RegionManagementSecurityIntegrationTest { - - @ClassRule - public static LocatorStarterRule locator = new LocatorStarterRule().withHttpService() - .withSecurityManager(SimpleTestSecurityManager.class).withAutoStart(); - - @ClassRule - public static RequiresGeodeHome requiresGeodeHome = new RequiresGeodeHome(); - - public static GeodeDevRestClient restClient; - - @BeforeClass - public static void setUpClass() { - restClient = - new GeodeDevRestClient("/geode-management/v2", "localhost", locator.getHttpPort(), false); - } - - private RegionConfig regionConfig; - private String json; - - @Before - public void before() throws JsonProcessingException { - regionConfig = new RegionConfig(); - regionConfig.setName("customers"); - regionConfig.setType("REPLICATE"); - ObjectMapper mapper = new ObjectMapper(); - json = mapper.writeValueAsString(regionConfig); - } - - @Test - public void sanityCheck_not_authorized() throws Exception { - ClusterManagementResult result = - restClient.doPostAndAssert("/regions", json, "user", "user") - .hasStatusCode(403) - .getClusterManagementResult(); - assertThat(result.isSuccessful()).isFalse(); - assertThat(result.getPersistenceStatus().getMessage()) - .isEqualTo("user not authorized for DATA:MANAGE"); - } - - @Test - public void sanityCheckWithNoCredentials() throws Exception { - ClusterManagementResult result = - restClient.doPostAndAssert("/regions", json, null, null) - .hasStatusCode(401).getClusterManagementResult(); - assertThat(result.getPersistenceStatus().getMessage()) - .isEqualTo("Full authentication is required to access this resource"); - assertThat(result.isSuccessful()).isFalse(); - } - - @Test - public void sanityCheckWithWrongCredentials() throws Exception { - ClusterManagementResult result = - restClient.doPostAndAssert("/regions", json, "test", "invalid_pswd") - .hasStatusCode(401).getClusterManagementResult(); - assertThat(result.getPersistenceStatus().getMessage()) - .isEqualTo("Authentication error. Please check your credentials."); - assertThat(result.isSuccessful()).isFalse(); - } - - @Test - public void sanityCheck_success() throws Exception { - ClusterManagementResult result = - restClient.doPostAndAssert("/regions", json, "dataManage", "dataManage") - .hasStatusCode(500) - .getClusterManagementResult(); - assertThat(result.isSuccessful()).isFalse(); - assertThat(result.getPersistenceStatus().getMessage()) - .isEqualTo("no members found to create cache element"); - } -} diff --git a/geode-web-management/build.gradle b/geode-web-management/build.gradle index 3b55c61..f3868c8 100644 --- a/geode-web-management/build.gradle +++ b/geode-web-management/build.gradle @@ -18,9 +18,26 @@ apply plugin: 'war' apply from: "${project.projectDir}/../gradle/geode-dependency-management.gradle" apply from: "${project.projectDir}/../gradle/publish.gradle" +configurations { + commonTestCompile +} -dependencies { +sourceSets { + integrationTest { + resources { + srcDir "${projectDir}/src/main/webapp" + } + } + commonTest { + java { + srcDir "${projectDir}/src/commonTest/java" + } + compileClasspath = configurations.commonTestCompile + } +} + +dependencies { compileOnly(project(':geode-core')) compileOnly('javax.servlet:javax.servlet-api') @@ -62,6 +79,15 @@ dependencies { exclude module: 'spring-beans' } + commonTestCompile(project(':geode-core')) + commonTestCompile(project(':geode-junit')) { + exclude module: 'geode-core' + } + commonTestCompile(project(':geode-dunit')) { + exclude module: 'geode-core' + } + commonTestCompile('org.springframework:spring-test') + commonTestCompile('org.springframework:spring-webmvc') testCompile(project(':geode-junit')) { exclude module: 'geode-core' @@ -69,7 +95,11 @@ dependencies { testCompile(project(':geode-core')) testCompile('javax.servlet:javax.servlet-api') + integrationTestCompile(sourceSets.commonTest.output) + + integrationTestCompile(project(':geode-core')) integrationTestCompile('org.springframework:spring-test') + integrationTestCompile('org.springframework:spring-webmvc') integrationTestCompile('org.springframework.security:spring-security-test') integrationTestCompile(project(':geode-junit')) { @@ -78,13 +108,21 @@ dependencies { integrationTestCompile(project(':geode-dunit')) { exclude module: 'geode-core' } -} + integrationTestRuntimeOnly('org.apache.logging.log4j:log4j-slf4j-impl') { + exclude module: 'slf4j-api' + } + + distributedTestCompile(sourceSets.commonTest.output) + + distributedTestCompile('org.springframework:spring-test') + distributedTestCompile('org.springframework:spring-webmvc') + distributedTestCompile('org.springframework.security:spring-security-test') -sourceSets { - integrationTest { - resources { - srcDir "${projectDir}/src/main/webapp" - } + distributedTestCompile(project(':geode-junit')) { + exclude module: 'geode-core' + } + distributedTestCompile(project(':geode-dunit')) { + exclude module: 'geode-core' } } diff --git a/geode-web-management/src/commonTest/java/org/apache/geode/management/internal/rest/LocatorCleanupEventListener.java b/geode-web-management/src/commonTest/java/org/apache/geode/management/internal/rest/LocatorCleanupEventListener.java new file mode 100644 index 0000000..d7af991 --- /dev/null +++ b/geode-web-management/src/commonTest/java/org/apache/geode/management/internal/rest/LocatorCleanupEventListener.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package org.apache.geode.management.internal.rest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.event.ContextClosedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; +import org.springframework.web.context.WebApplicationContext; + +import org.apache.geode.test.junit.rules.LocatorStarterRule; + +@Component +public class LocatorCleanupEventListener { + + @Autowired + private WebApplicationContext webApplicationContext; + + @EventListener + public void handleContextCloseEvent(ContextClosedEvent closedEvent) { + LocatorStarterRule locator = + (LocatorStarterRule) webApplicationContext.getServletContext().getAttribute("locator"); + if (locator != null) { + locator.after(); + } + } +} diff --git a/geode-web-management/src/commonTest/java/org/apache/geode/management/internal/rest/LocatorWithSecurityManagerContextLoader.java b/geode-web-management/src/commonTest/java/org/apache/geode/management/internal/rest/LocatorWithSecurityManagerContextLoader.java new file mode 100644 index 0000000..4f03a2a --- /dev/null +++ b/geode-web-management/src/commonTest/java/org/apache/geode/management/internal/rest/LocatorWithSecurityManagerContextLoader.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package org.apache.geode.management.internal.rest; + +import org.springframework.test.context.web.GenericXmlWebContextLoader; +import org.springframework.test.context.web.WebMergedContextConfiguration; +import org.springframework.web.context.support.GenericWebApplicationContext; + +import org.apache.geode.internal.cache.HttpService; +import org.apache.geode.security.SimpleTestSecurityManager; +import org.apache.geode.test.junit.rules.LocatorStarterRule; + +class LocatorWithSecurityManagerContextLoader extends GenericXmlWebContextLoader { + + private LocatorStarterRule locator = new LocatorStarterRule() + .withSecurityManager(SimpleTestSecurityManager.class) + .withAutoStart(); + + @Override + protected void loadBeanDefinitions(GenericWebApplicationContext context, + WebMergedContextConfiguration webMergedConfig) { + + locator.before(); + + super.loadBeanDefinitions(context, webMergedConfig); + context.getServletContext().setAttribute(HttpService.SECURITY_SERVICE_SERVLET_CONTEXT_PARAM, + locator.getCache().getSecurityService()); + context.getServletContext().setAttribute(HttpService.CLUSTER_MANAGEMENT_SERVICE_CONTEXT_PARAM, + locator.getLocator().getClusterManagementService()); + + context.getServletContext().setAttribute("locator", locator); + } + +} diff --git a/geode-web-management/src/commonTest/java/org/apache/geode/management/internal/rest/PlainLocatorContextLoader.java b/geode-web-management/src/commonTest/java/org/apache/geode/management/internal/rest/PlainLocatorContextLoader.java new file mode 100644 index 0000000..e2a28b7 --- /dev/null +++ b/geode-web-management/src/commonTest/java/org/apache/geode/management/internal/rest/PlainLocatorContextLoader.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package org.apache.geode.management.internal.rest; + +import org.springframework.test.context.web.GenericXmlWebContextLoader; +import org.springframework.test.context.web.WebMergedContextConfiguration; +import org.springframework.web.context.support.GenericWebApplicationContext; + +import org.apache.geode.internal.cache.HttpService; +import org.apache.geode.test.junit.rules.LocatorStarterRule; + +/** + * This is quite horrible. In particular we're trying to link the lifecycle of the + * LocatorStarterRule and Spring's application context. The locator is injected into the + * ServletContext so that it can be retrieved and cleaned up in the LocatorCleanupEventListener. + * There has to be a better way... + */ +class PlainLocatorContextLoader extends GenericXmlWebContextLoader { + + private LocatorStarterRule locator = new LocatorStarterRule() + .withAutoStart(); + + @Override + protected void loadBeanDefinitions(GenericWebApplicationContext context, + WebMergedContextConfiguration webMergedConfig) { + + locator.before(); + + super.loadBeanDefinitions(context, webMergedConfig); + context.getServletContext().setAttribute(HttpService.SECURITY_SERVICE_SERVLET_CONTEXT_PARAM, + locator.getCache().getSecurityService()); + context.getServletContext().setAttribute(HttpService.CLUSTER_MANAGEMENT_SERVICE_CONTEXT_PARAM, + locator.getLocator().getClusterManagementService()); + + context.getServletContext().setAttribute("locator", locator); + } + +} diff --git a/geode-web-management/src/commonTest/java/org/apache/geode/management/internal/rest/StandardRequestPostProcessor.java b/geode-web-management/src/commonTest/java/org/apache/geode/management/internal/rest/StandardRequestPostProcessor.java new file mode 100644 index 0000000..92a3d5f --- /dev/null +++ b/geode-web-management/src/commonTest/java/org/apache/geode/management/internal/rest/StandardRequestPostProcessor.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package org.apache.geode.management.internal.rest; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.test.web.servlet.request.RequestPostProcessor; + +class StandardRequestPostProcessor implements RequestPostProcessor { + @Override + public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) { + request.addHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON); + request.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); + return request; + } +} diff --git a/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/RegionManagementIntegrationTest.java b/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/RegionManagementIntegrationTest.java new file mode 100644 index 0000000..afca659 --- /dev/null +++ b/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/RegionManagementIntegrationTest.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package org.apache.geode.management.internal.rest; + +import static org.hamcrest.Matchers.is; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.RequestPostProcessor; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import org.apache.geode.cache.configuration.RegionConfig; + +@RunWith(SpringRunner.class) +@ContextConfiguration(locations = {"classpath*:WEB-INF/geode-management-servlet.xml"}, + loader = PlainLocatorContextLoader.class) +@WebAppConfiguration +public class RegionManagementIntegrationTest { + + static RequestPostProcessor POST_PROCESSOR = + new StandardRequestPostProcessor(); + + @Autowired + private WebApplicationContext webApplicationContext; + + private MockMvc mockMvc; + + @Before + public void before() { + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) + .build(); + } + + @Test + @WithMockUser + public void sanityCheck() throws Exception { + RegionConfig regionConfig = new RegionConfig(); + regionConfig.setName("customers"); + regionConfig.setType("REPLICATE"); + + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(regionConfig); + + mockMvc.perform(post("/v2/regions") + .with(POST_PROCESSOR) + .content(json)) + .andExpect(status().isInternalServerError()) + .andExpect(jsonPath("$.persistenceStatus.status", is("FAILURE"))) + .andExpect(jsonPath("$.persistenceStatus.message", + is("no members found to create cache element"))); + } + + @Test + @WithMockUser + public void ping() throws Exception { + mockMvc.perform(get("/v2/ping") + .with(POST_PROCESSOR)) + .andExpect(content().string("pong")); + } +} diff --git a/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/RegionManagementSecurityIntegrationTest.java b/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/RegionManagementSecurityIntegrationTest.java new file mode 100644 index 0000000..5516254 --- /dev/null +++ b/geode-web-management/src/integrationTest/java/org/apache/geode/management/internal/rest/RegionManagementSecurityIntegrationTest.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package org.apache.geode.management.internal.rest; + +import static org.hamcrest.Matchers.is; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; +import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.RequestPostProcessor; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import org.apache.geode.cache.configuration.RegionConfig; + +@RunWith(SpringRunner.class) +@ContextConfiguration(locations = {"classpath*:WEB-INF/geode-management-servlet.xml"}, + loader = LocatorWithSecurityManagerContextLoader.class) +@WebAppConfiguration +public class RegionManagementSecurityIntegrationTest { + + static RequestPostProcessor POST_PROCESSOR = + new StandardRequestPostProcessor(); + + @Autowired + private WebApplicationContext webApplicationContext; + + private RegionConfig regionConfig; + private String json; + private MockMvc mockMvc; + + @Before + public void before() throws JsonProcessingException { + regionConfig = new RegionConfig(); + regionConfig.setName("customers"); + regionConfig.setType("REPLICATE"); + ObjectMapper mapper = new ObjectMapper(); + json = mapper.writeValueAsString(regionConfig); + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) + .apply(springSecurity()) + .build(); + } + + @Test + public void sanityCheck_not_authorized() throws Exception { + mockMvc.perform(post("/v2/regions") + .with(httpBasic("user", "user")) + .with(POST_PROCESSOR) + .content(json)) + .andExpect(status().isForbidden()) + .andExpect(jsonPath("$.persistenceStatus.status", is("FAILURE"))) + .andExpect(jsonPath("$.persistenceStatus.message", + is("user not authorized for DATA:MANAGE"))); + } + + @Test + public void sanityCheckWithNoCredentials() throws Exception { + mockMvc.perform(post("/v2/regions") + .with(POST_PROCESSOR) + .content(json)) + .andExpect(status().isUnauthorized()) + .andExpect(jsonPath("$.persistenceStatus.status", is("FAILURE"))) + .andExpect(jsonPath("$.persistenceStatus.message", + is("Full authentication is required to access this resource"))); + } + + @Test + public void sanityCheckWithWrongCredentials() throws Exception { + mockMvc.perform(post("/v2/regions") + .with(httpBasic("user", "wrong_password")) + .with(POST_PROCESSOR) + .content(json)) + .andExpect(status().isUnauthorized()) + .andExpect(jsonPath("$.persistenceStatus.status", is("FAILURE"))) + .andExpect(jsonPath("$.persistenceStatus.message", + is("Authentication error. Please check your credentials."))); + } + + @Test + public void sanityCheck_success() throws Exception { + mockMvc.perform(post("/v2/regions") + .with(httpBasic("dataManage", "dataManage")) + .with(POST_PROCESSOR) + .content(json)) + .andExpect(status().isInternalServerError()) + .andExpect(jsonPath("$.persistenceStatus.status", is("FAILURE"))) + .andExpect(jsonPath("$.persistenceStatus.message", + is("no members found to create cache element"))); + } + +}