http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9d7a6960/geode-core/src/test/java/org/apache/geode/security/ClientMultiUserAuthzDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/ClientMultiUserAuthzDUnitTest.java b/geode-core/src/test/java/org/apache/geode/security/ClientMultiUserAuthzDUnitTest.java new file mode 100644 index 0000000..38f9988 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/ClientMultiUserAuthzDUnitTest.java @@ -0,0 +1,345 @@ +/* + * 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 com.gemstone.gemfire.security; + +import static com.gemstone.gemfire.security.SecurityTestUtils.*; +import static com.gemstone.gemfire.test.dunit.LogWriterUtils.*; + +import java.util.Iterator; +import java.util.Properties; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.execute.Function; +import com.gemstone.gemfire.cache.operations.OperationContext.OperationCode; +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; +import com.gemstone.gemfire.internal.cache.execute.PRClientServerTestBase; +import com.gemstone.gemfire.internal.cache.functions.TestFunction; +import com.gemstone.gemfire.security.generator.AuthzCredentialGenerator; +import com.gemstone.gemfire.security.generator.CredentialGenerator; +import com.gemstone.gemfire.test.dunit.VM; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +@Category({ DistributedTest.class, SecurityTest.class }) +public class ClientMultiUserAuthzDUnitTest extends ClientAuthorizationTestCase { + + @Override + public final void preTearDownClientAuthorizationTestBase() throws Exception { + closeCache(); + } + + /** + * Tests with one user authorized to do puts/gets/containsKey/destroys and + * another not authorized for the same. + */ + @Test + public void testOps1() throws Exception { + for (Iterator<AuthzCredentialGenerator> iter = getDummyGeneratorCombos().iterator(); iter.hasNext();) { + AuthzCredentialGenerator gen = iter.next(); + CredentialGenerator cGen = gen.getCredentialGenerator(); + Properties extraAuthProps = cGen.getSystemProperties(); + Properties javaProps = cGen.getJavaProperties(); + Properties extraAuthzProps = gen.getSystemProperties(); + String authenticator = cGen.getAuthenticator(); + String authInit = cGen.getAuthInit(); + String accessor = gen.getAuthorizationCallback(); + + getLogWriter().info("testOps1: Using authinit: " + authInit); + getLogWriter().info("testOps1: Using authenticator: " + authenticator); + getLogWriter().info("testOps1: Using accessor: " + accessor); + + // Start servers with all required properties + Properties serverProps = buildProperties(authenticator, accessor, false, extraAuthProps, extraAuthzProps); + + int port1 = createCacheServerOnVM(server1, javaProps, serverProps); + int port2 = createCacheServerOnVM(server2, javaProps, serverProps); + + if (!prepareClientsForOps(gen, cGen, new OperationCode[] { OperationCode.PUT, OperationCode.PUT}, new OperationCode[] { OperationCode.GET, OperationCode.GET}, javaProps, authInit, port1, port2)) { + continue; + } + + verifyPutsGets(); + + if (!prepareClientsForOps(gen, cGen, new OperationCode[] { OperationCode.PUT, OperationCode.CONTAINS_KEY}, new OperationCode[] { OperationCode.DESTROY, OperationCode.DESTROY}, javaProps, authInit, port1, port2)) { + continue; + } + + verifyContainsKeyDestroys(); + + if (!prepareClientsForOps(gen, cGen, new OperationCode[] { OperationCode.PUT, OperationCode.CONTAINS_KEY}, new OperationCode[] { OperationCode.INVALIDATE, OperationCode.INVALIDATE}, javaProps, authInit, port1, port2)) { + continue; + } + + verifyContainsKeyInvalidates(); + + if (!prepareClientsForOps(gen, cGen, new OperationCode[] { OperationCode.GET, OperationCode.GET}, new OperationCode[] { OperationCode.REGION_DESTROY, OperationCode.REGION_DESTROY}, javaProps, authInit, port1, port2)) { + continue; + } + + verifyGetAllInTX(); + verifyGetAllRegionDestroys(); + } + } + + /** + * Test query/function execute + */ + @Test + public void testOps2() throws Exception { + AuthzCredentialGenerator gen = getXmlAuthzGenerator(); + CredentialGenerator cGen = gen.getCredentialGenerator(); + Properties extraAuthProps = cGen.getSystemProperties(); + Properties javaProps = cGen.getJavaProperties(); + Properties extraAuthzProps = gen.getSystemProperties(); + String authenticator = cGen.getAuthenticator(); + String authInit = cGen.getAuthInit(); + String accessor = gen.getAuthorizationCallback(); + + getLogWriter().info("testOps2: Using authinit: " + authInit); + getLogWriter().info("testOps2: Using authenticator: " + authenticator); + getLogWriter().info("testOps2: Using accessor: " + accessor); + + // Start servers with all required properties + Properties serverProps = buildProperties(authenticator, accessor, false, extraAuthProps, extraAuthzProps); + + int port1 = createCacheServerOnVM(server1, javaProps, serverProps); + int port2 = createCacheServerOnVM(server2, javaProps, serverProps); + + // Start client1 with valid/invalid QUERY credentials + Properties[] client1Credentials = new Properties[] { + gen.getAllowedCredentials(new OperationCode[] {OperationCode.PUT, OperationCode.QUERY}, new String[] {regionName}, 1), + gen.getDisallowedCredentials(new OperationCode[] {OperationCode.PUT, OperationCode.QUERY}, new String[] {regionName}, 1) + }; + + javaProps = cGen.getJavaProperties(); + getLogWriter().info("testOps2: For first client credentials: " + client1Credentials[0] + "\n" + client1Credentials[1]); + + final Properties finalJavaProps = javaProps; + client1.invoke(() -> createCacheClientForMultiUserMode(2, authInit, client1Credentials, finalJavaProps, new int[] {port1, port2}, -1, false, NO_EXCEPTION)); + + // Start client2 with valid/invalid EXECUTE_FUNCTION credentials + Properties[] client2Credentials = new Properties[] { + gen.getAllowedCredentials(new OperationCode[] {OperationCode.EXECUTE_FUNCTION}, new String[] {regionName}, 2), + gen.getDisallowedCredentials(new OperationCode[] {OperationCode.EXECUTE_FUNCTION}, new String[] {regionName}, 9) + }; + + javaProps = cGen.getJavaProperties(); + getLogWriter().info("testOps2: For second client credentials: " + client2Credentials[0] + "\n" + client2Credentials[1]); + + final Properties finalJavaProps2 = javaProps; + client2.invoke(() -> createCacheClientForMultiUserMode(2, authInit, client2Credentials, finalJavaProps2, new int[] {port1, port2}, -1, false, NO_EXCEPTION)); + + Function function = new TestFunction(true,TestFunction.TEST_FUNCTION1); + + server1.invoke(() -> PRClientServerTestBase.registerFunction(function)); + + server2.invoke(() -> PRClientServerTestBase.registerFunction(function)); + + // Perform some put operations before verifying queries + client1.invoke(() -> doMultiUserPuts(4, 2, new int[] {NO_EXCEPTION, NOTAUTHZ_EXCEPTION})); + client1.invoke(() -> doMultiUserQueries(2, new int[] {NO_EXCEPTION, NOTAUTHZ_EXCEPTION}, 4)); + client1.invoke(() -> doMultiUserQueryExecute(2, new int[] {NO_EXCEPTION, NOTAUTHZ_EXCEPTION}, 4)); + + // Verify that the FE succeeds/fails + client2.invoke(() ->doMultiUserFE(2, function, new int[] {NO_EXCEPTION, NOTAUTHZ_EXCEPTION}, false)); + + // Failover + server1.invoke(() -> closeCache()); + Thread.sleep(2000); + + client1.invoke(() -> doMultiUserPuts(4, 2, new int[] {NO_EXCEPTION, NOTAUTHZ_EXCEPTION})); + + client1.invoke(() -> doMultiUserQueries(2, new int[] {NO_EXCEPTION, NOTAUTHZ_EXCEPTION}, 4)); + client1.invoke(() -> doMultiUserQueryExecute(2, new int[] {NO_EXCEPTION, NOTAUTHZ_EXCEPTION}, 4)); + + // Verify that the FE succeeds/fails + client2.invoke(() -> doMultiUserFE(2, function, new int[] {NO_EXCEPTION, NOTAUTHZ_EXCEPTION}, true)); + } + + @Test + public void testOpsWithClientsInDifferentModes() throws Exception { + for (Iterator<AuthzCredentialGenerator> iter = getDummyGeneratorCombos().iterator(); iter.hasNext();) { + AuthzCredentialGenerator gen = iter.next(); + CredentialGenerator cGen = gen.getCredentialGenerator(); + Properties extraAuthProps = cGen.getSystemProperties(); + Properties javaProps = cGen.getJavaProperties(); + Properties extraAuthzProps = gen.getSystemProperties(); + String authenticator = cGen.getAuthenticator(); + String authInit = cGen.getAuthInit(); + String accessor = gen.getAuthorizationCallback(); + + getLogWriter().info("testOpsWithClientsInDifferentModes: Using authinit: " + authInit); + getLogWriter().info("testOpsWithClientsInDifferentModes: Using authenticator: " + authenticator); + getLogWriter().info("testOpsWithClientsInDifferentModes: Using accessor: " + accessor); + + // Start servers with all required properties + Properties serverProps = buildProperties(authenticator, accessor, false, extraAuthProps, extraAuthzProps); + + int port1 = createCacheServerOnVM(server1, javaProps, serverProps); + int port2 = createCacheServerOnVM(server2, javaProps, serverProps); + + if (!prepareClientsForOps(gen, cGen, new OperationCode[] { OperationCode.PUT, OperationCode.PUT}, new OperationCode[] { OperationCode.GET, OperationCode.GET}, javaProps, authInit, port1, port2, false, true)) { + continue; + } + + verifyPutsGets(false, true); + + if (!prepareClientsForOps(gen, cGen, new OperationCode[] { OperationCode.PUT, OperationCode.CONTAINS_KEY}, new OperationCode[] { OperationCode.DESTROY, OperationCode.DESTROY}, javaProps, authInit, port1, port2, false, false)) { + continue; + } + + verifyContainsKeyDestroys(false, false); + } + } + + private boolean prepareClientsForOps(final AuthzCredentialGenerator gen, final CredentialGenerator cGen, final OperationCode[] client1OpCodes, final OperationCode[] client2OpCodes, final Properties javaProps, final String authInit, final int port1, final int port2) { + return prepareClientsForOps(gen, cGen, client1OpCodes, client2OpCodes, javaProps, authInit, port1, port2, true /* both clients in multiuser mode */, false /* unused */); + } + + private boolean prepareClientsForOps(final AuthzCredentialGenerator gen, final CredentialGenerator cGen, final OperationCode[] client1OpCodes, final OperationCode[] client2OpCodes, Properties javaProps, final String authInit, final int port1, final int port2, final boolean bothClientsInMultiuserMode, final boolean allowOp) { + // Start client1 with valid/invalid client1OpCodes credentials + Properties[] client1Credentials = new Properties[] { gen.getAllowedCredentials(client1OpCodes, new String[] {regionName}, 1), gen.getDisallowedCredentials(new OperationCode[] {client1OpCodes[1]}, new String[] {regionName}, 1)}; + + if (client1Credentials[0] == null || client1Credentials[0].size() == 0) { + getLogWriter().info("testOps1: Unable to obtain valid credentials with " + client1OpCodes[0].toString() + " permission; skipping this combination."); + return false; + } + + if (client1Credentials[1] == null || client1Credentials[1].size() == 0) { + getLogWriter().info("testOps1: Unable to obtain valid credentials with no " + client1OpCodes[0].toString() + " permission; skipping this combination."); + return false; + } + + javaProps = cGen.getJavaProperties(); + getLogWriter().info("testOps1: For first client credentials: " + client1Credentials[0] + "\n" + client1Credentials[1]); + final Properties finalJavaProps = javaProps; + + client1.invoke(() -> createCacheClientForMultiUserMode(2, authInit, client1Credentials, finalJavaProps, new int[] {port1, port2}, -1, false, NO_EXCEPTION)); + + // Start client2 with valid/invalid client2OpCodes credentials + Properties[] client2Credentials = new Properties[] { gen.getAllowedCredentials(client2OpCodes, new String[] {regionName}, 2), gen.getDisallowedCredentials(client2OpCodes, new String[] {regionName}, 9)}; + + if (client2Credentials[0] == null || client2Credentials[0].size() == 0) { + getLogWriter().info("testOps1: Unable to obtain valid credentials with " + client2OpCodes[0].toString() + " permission; skipping this combination."); + return false; + } + + if (client2Credentials[1] == null || client2Credentials[1].size() == 0) { + getLogWriter().info("testOps1: Unable to obtain valid credentials with no " + client2OpCodes[0].toString() + " permission; skipping this combination."); + return false; + } + + javaProps = cGen.getJavaProperties(); + getLogWriter().info("testOps1: For second client credentials: " + client2Credentials[0] + "\n" + client2Credentials[1]); + + if (bothClientsInMultiuserMode) { + final Properties finalJavaProps2 = javaProps; + client2.invoke(() -> createCacheClientForMultiUserMode(2, authInit, client2Credentials, finalJavaProps2, new int[] {port1, port2}, -1, false, NO_EXCEPTION)); + + } else { + int credentialsIndex = allowOp ? 0 : 1; + final Properties finalJavaProps2 = javaProps; + client2.invoke(() -> createCacheClient(authInit, client2Credentials[credentialsIndex], finalJavaProps2, new int[] {port1, port2}, -1, false, false, NO_EXCEPTION)); + } + + return true; + } + + private void verifyPutsGets() throws Exception { + verifyPutsGets(true, false /*unused */); + } + + private void verifyPutsGets(final boolean isMultiuser, final boolean opAllowed) throws Exception { + // Perform some put operations from client1 + client1.invoke(() -> doMultiUserPuts(2, 2, new int[] { NO_EXCEPTION, NOTAUTHZ_EXCEPTION})); + + // Verify that the gets succeed/fail + if (isMultiuser) { + client2.invoke(() -> doMultiUserGets(2, 2, new int[] {NO_EXCEPTION, NOTAUTHZ_EXCEPTION})); + + } else { + int expectedResult = (opAllowed) ? NO_EXCEPTION : NOTAUTHZ_EXCEPTION; + client2.invoke(() -> doMultiUserGets(1, 1, new int[] {expectedResult})); + } + } + + private void verifyContainsKeyDestroys() throws Exception { + verifyContainsKeyDestroys(true, false /* unused */); + } + + private void verifyContainsKeyDestroys(final boolean isMultiUser, final boolean opAllowed) throws Exception { + // Do puts before verifying containsKey + client1.invoke(() -> doMultiUserPuts(2, 2, new int[] {NO_EXCEPTION, NO_EXCEPTION})); + client1.invoke(() -> doMultiUserContainsKeys(1, 2, new int[] {NO_EXCEPTION, NOTAUTHZ_EXCEPTION}, new boolean[] {true, false})); + + // Verify that the destroys succeed/fail + if (isMultiUser) { + client2.invoke(() -> doMultiUserDestroys(2, 2, new int[] {NO_EXCEPTION, NOTAUTHZ_EXCEPTION})); + + } else { + int expectedResult = (opAllowed) ? NO_EXCEPTION : NOTAUTHZ_EXCEPTION; + client2.invoke(() -> doMultiUserDestroys(1, 1, new int[] {expectedResult})); + } + } + + private void verifyContainsKeyInvalidates() throws Exception { + verifyContainsKeyInvalidates(true, false /* unused */); + } + + private void verifyContainsKeyInvalidates(final boolean isMultiUser, final boolean opAllowed) throws Exception { + // Do puts before verifying containsKey + client1.invoke(() -> doMultiUserPuts(2, 2, new int[] {NO_EXCEPTION, NO_EXCEPTION})); + client1.invoke(() -> doMultiUserContainsKeys(1, 2, new int[] {NO_EXCEPTION, NOTAUTHZ_EXCEPTION}, new boolean[] {true, false})); + + // Verify that the invalidates succeed/fail + if (isMultiUser) { + client2.invoke(() -> doMultiUserInvalidates(2, 2, new int[] {NO_EXCEPTION, NOTAUTHZ_EXCEPTION})); + + } else { + int expectedResult = (opAllowed) ? NO_EXCEPTION : NOTAUTHZ_EXCEPTION; + client2.invoke(() -> doMultiUserInvalidates(1, 1, new int[] {expectedResult})); + } + } + + private void verifyGetAllInTX() { + server1.invoke(() -> doPuts()); + client1.invoke(() -> doMultiUserGetAll(2, new int[] {NO_EXCEPTION, NOTAUTHZ_EXCEPTION}, true/*use TX*/)); + } + + private void verifyGetAllRegionDestroys() { + server1.invoke(() -> doPuts()); + client1.invoke(() -> doMultiUserGetAll(2, new int[] {NO_EXCEPTION, NOTAUTHZ_EXCEPTION})); + + // Verify that the region destroys succeed/fail + client2.invoke(() -> doMultiUserRegionDestroys(2, new int[] {NO_EXCEPTION, NOTAUTHZ_EXCEPTION})); + } + + private void doPuts() { + Region region = GemFireCacheImpl.getInstance().getRegion(REGION_NAME); + region.put("key1", "value1"); + region.put("key2", "value2"); + } + + private int createCacheServerOnVM(final VM server, final Properties javaProps, final Properties serverProps) { + return server.invoke(() -> ClientAuthorizationTestCase.createCacheServer(getLocatorPort(), serverProps, javaProps)); + } +}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9d7a6960/geode-core/src/test/java/org/apache/geode/security/DeltaClientAuthorizationDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/DeltaClientAuthorizationDUnitTest.java b/geode-core/src/test/java/org/apache/geode/security/DeltaClientAuthorizationDUnitTest.java new file mode 100644 index 0000000..0efd3d6 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/DeltaClientAuthorizationDUnitTest.java @@ -0,0 +1,201 @@ +/* + * 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 com.gemstone.gemfire.security; + +import static com.gemstone.gemfire.security.ClientAuthenticationTestUtils.createCacheClient; +import static com.gemstone.gemfire.security.SecurityTestUtils.*; +import static com.gemstone.gemfire.test.dunit.Assert.*; +import static com.gemstone.gemfire.test.dunit.LogWriterUtils.*; + +import java.util.Properties; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.DeltaTestImpl; +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.operations.OperationContext.OperationCode; +import com.gemstone.gemfire.internal.cache.PartitionedRegionLocalMaxMemoryDUnitTest.TestObject1; +import com.gemstone.gemfire.security.generator.AuthzCredentialGenerator; +import com.gemstone.gemfire.security.generator.CredentialGenerator; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +/** + * @since GemFire 6.1 + */ +@Category({ DistributedTest.class, SecurityTest.class }) +public final class DeltaClientAuthorizationDUnitTest extends ClientAuthorizationTestCase { + + private DeltaTestImpl[] deltas = new DeltaTestImpl[8]; + + @Override + protected final void preSetUpClientAuthorizationTestBase() throws Exception { + setUpDeltas(); + } + + @Override + public final void preTearDownClientAuthorizationTestBase() throws Exception { + closeCache(); + } + + @Test + public void testAllowPutsGets() throws Exception { + AuthzCredentialGenerator gen = this.getXmlAuthzGenerator(); + CredentialGenerator cGen = gen.getCredentialGenerator(); + + Properties extraAuthProps = cGen.getSystemProperties(); + Properties javaProps = cGen.getJavaProperties(); + Properties extraAuthzProps = gen.getSystemProperties(); + + String authenticator = cGen.getAuthenticator(); + String authInit = cGen.getAuthInit(); + String accessor = gen.getAuthorizationCallback(); + + getLogWriter().info("testAllowPutsGets: Using authinit: " + authInit); + getLogWriter().info("testAllowPutsGets: Using authenticator: " + authenticator); + getLogWriter().info("testAllowPutsGets: Using accessor: " + accessor); + + // Start servers with all required properties + Properties serverProps = buildProperties(authenticator, accessor, false, extraAuthProps, extraAuthzProps); + + int port1 = createServer1(javaProps, serverProps); + int port2 = createServer2(javaProps, serverProps); + + // Start client1 with valid CREATE credentials + Properties createCredentials = gen.getAllowedCredentials(new OperationCode[] { OperationCode.PUT }, new String[] { REGION_NAME }, 1); + javaProps = cGen.getJavaProperties(); + + getLogWriter().info("testAllowPutsGets: For first client credentials: " + createCredentials); + + createClient1(javaProps, authInit, port1, port2, createCredentials); + + // Start client2 with valid GET credentials + Properties getCredentials = gen.getAllowedCredentials(new OperationCode[] { OperationCode.GET }, new String[] { REGION_NAME }, 2); + javaProps = cGen.getJavaProperties(); + + getLogWriter().info("testAllowPutsGets: For second client credentials: " + getCredentials); + + createClient2(javaProps, authInit, port1, port2, getCredentials); + + // Perform some put operations from client1 + client1.invoke(() -> doPuts(2, NO_EXCEPTION)); + + Thread.sleep(5000); + assertTrue("Delta feature NOT used", client1.invoke(() -> DeltaTestImpl.toDeltaFeatureUsed())); + + // Verify that the gets succeed + client2.invoke(() -> doGets(2, NO_EXCEPTION)); + } + + private void createClient2(final Properties javaProps, final String authInit, final int port1, final int port2, final Properties getCredentials) { + client2.invoke(() -> createCacheClient(authInit, getCredentials, javaProps, port1, port2, 0, NO_EXCEPTION)); + } + + private void createClient1(final Properties javaProps, final String authInit, final int port1, final int port2, final Properties createCredentials) { + client1.invoke(() -> createCacheClient(authInit, createCredentials, javaProps, port1, port2, 0, NO_EXCEPTION)); + } + + private int createServer2(final Properties javaProps, final Properties serverProps) { + return server2.invoke(() -> createCacheServer(getLocatorPort(), serverProps, javaProps)); + } + + private int createServer1(final Properties javaProps, final Properties serverProps) { + return server1.invoke(() -> createCacheServer(getLocatorPort(), serverProps, javaProps)); + } + + private void doPuts(final int num, final int expectedResult) { + assertTrue(num <= KEYS.length); + Region region = getCache().getRegion(REGION_NAME); + assertNotNull(region); + for (int index = 0; index < num; ++index) { + region.put(KEYS[index], deltas[0]); + } + for (int index = 0; index < num; ++index) { + region.put(KEYS[index], deltas[index]); + if (expectedResult != NO_EXCEPTION) { + fail("Expected a NotAuthorizedException while doing puts"); + } + } + } + + private void doGets(final int num, final int expectedResult) { + assertTrue(num <= KEYS.length); + + Region region = getCache().getRegion(REGION_NAME); + assertNotNull(region); + + for (int index = 0; index < num; ++index) { + region.localInvalidate(KEYS[index]); + Object value = region.get(KEYS[index]); + if (expectedResult != NO_EXCEPTION) { + fail("Expected a NotAuthorizedException while doing gets"); + } + assertNotNull(value); + assertEquals(deltas[index], value); + } + } + + private final void setUpDeltas() { + for (int i = 0; i < 8; i++) { + deltas[i] = new DeltaTestImpl(0, "0", new Double(0), new byte[0], new TestObject1("0", 0)); + } + deltas[1].setIntVar(5); + deltas[2].setIntVar(5); + deltas[3].setIntVar(5); + deltas[4].setIntVar(5); + deltas[5].setIntVar(5); + deltas[6].setIntVar(5); + deltas[7].setIntVar(5); + + deltas[2].resetDeltaStatus(); + deltas[2].setByteArr(new byte[] { 1, 2, 3, 4, 5 }); + deltas[3].setByteArr(new byte[] { 1, 2, 3, 4, 5 }); + deltas[4].setByteArr(new byte[] { 1, 2, 3, 4, 5 }); + deltas[5].setByteArr(new byte[] { 1, 2, 3, 4, 5 }); + //deltas[6].setByteArr(new byte[] { 1, 2, 3, 4, 5 }); + //deltas[7].setByteArr(new byte[] { 1, 2, 3, 4, 5 }); + + deltas[3].resetDeltaStatus(); + deltas[3].setDoubleVar(new Double(5)); + deltas[4].setDoubleVar(new Double(5)); + deltas[5].setDoubleVar(new Double(5)); + deltas[6].setDoubleVar(new Double(5)); + deltas[7].setDoubleVar(new Double(5)); + + deltas[4].resetDeltaStatus(); + deltas[4].setStr("str changed"); + deltas[5].setStr("str changed"); + deltas[6].setStr("str changed"); + //deltas[7].setStr("str changed"); + + deltas[5].resetDeltaStatus(); + deltas[5].setIntVar(100); + deltas[5].setTestObj(new TestObject1("CHANGED", 100)); + deltas[6].setTestObj(new TestObject1("CHANGED", 100)); + deltas[7].setTestObj(new TestObject1("CHANGED", 100)); + + deltas[6].resetDeltaStatus(); + deltas[6].setByteArr(new byte[] { 1, 2, 3 }); + deltas[7].setByteArr(new byte[] { 1, 2, 3 }); + + deltas[7].resetDeltaStatus(); + deltas[7].setStr("delta string"); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9d7a6960/geode-core/src/test/java/org/apache/geode/security/DeltaClientPostAuthorizationDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/DeltaClientPostAuthorizationDUnitTest.java b/geode-core/src/test/java/org/apache/geode/security/DeltaClientPostAuthorizationDUnitTest.java new file mode 100644 index 0000000..ff8d23d --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/DeltaClientPostAuthorizationDUnitTest.java @@ -0,0 +1,284 @@ +/* + * 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 com.gemstone.gemfire.security; + +import static com.gemstone.gemfire.security.SecurityTestUtils.*; +import static com.gemstone.gemfire.test.dunit.Assert.*; +import static com.gemstone.gemfire.test.dunit.IgnoredException.*; +import static com.gemstone.gemfire.test.dunit.LogWriterUtils.*; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.Random; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.DeltaTestImpl; +import com.gemstone.gemfire.cache.operations.OperationContext.OperationCode; +import com.gemstone.gemfire.internal.AvailablePortHelper; +import com.gemstone.gemfire.internal.cache.PartitionedRegionLocalMaxMemoryDUnitTest; +import com.gemstone.gemfire.security.generator.AuthzCredentialGenerator; +import com.gemstone.gemfire.security.generator.CredentialGenerator; +import com.gemstone.gemfire.test.dunit.VM; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +/** + * @since GemFire 6.1 + */ +@Category({ DistributedTest.class, SecurityTest.class }) +public class DeltaClientPostAuthorizationDUnitTest extends ClientAuthorizationTestCase { + + private static final int PAUSE = 5 * 1000; // TODO: replace with Awaitility + + private DeltaTestImpl[] deltas = new DeltaTestImpl[8]; + + @Override + public final void preSetUpClientAuthorizationTestBase() throws Exception { + setUpDeltas(); + addIgnoredException("Unexpected IOException"); + addIgnoredException("SocketException"); + } + + @Override + public final void preTearDownClientAuthorizationTestBase() throws Exception { + closeCache(); + } + + @Test + public void testPutPostOpNotifications() throws Exception { + OperationWithAction[] allOps = allOps(); + + AuthzCredentialGenerator gen = this.getXmlAuthzGenerator(); + CredentialGenerator cGen = gen.getCredentialGenerator(); + Properties extraAuthProps = cGen.getSystemProperties(); + Properties javaProps = cGen.getJavaProperties(); + Properties extraAuthzProps = gen.getSystemProperties(); + String authenticator = cGen.getAuthenticator(); + String authInit = cGen.getAuthInit(); + String accessor = gen.getAuthorizationCallback(); + TestAuthzCredentialGenerator tgen = new TestAuthzCredentialGenerator(gen); + + getLogWriter().info("testAllOpsNotifications: Using authinit: " + authInit); + getLogWriter().info("testAllOpsNotifications: Using authenticator: " + authenticator); + getLogWriter().info("testAllOpsNotifications: Using accessor: " + accessor); + + // Start servers with all required properties + Properties serverProps = buildProperties(authenticator, accessor, true, extraAuthProps, extraAuthzProps); + + // Get ports for the servers + int[] randomAvailableTCPPorts = AvailablePortHelper.getRandomAvailableTCPPorts(2); + int port1 = randomAvailableTCPPorts[0]; + int port2 = randomAvailableTCPPorts[1]; + + // Perform all the ops on the clients + List opBlock = new ArrayList(); + Random rnd = new Random(); + + for (int opNum = 0; opNum < allOps.length; ++opNum) { + // Start client with valid credentials as specified in OperationWithAction + OperationWithAction currentOp = allOps[opNum]; + if (currentOp.equals(OperationWithAction.OPBLOCK_END) || currentOp.equals(OperationWithAction.OPBLOCK_NO_FAILOVER)) { + + // End of current operation block; execute all the operations on the servers with failover + if (opBlock.size() > 0) { + // Start the first server and execute the operation block + server1.invoke(() -> ClientAuthorizationTestCase.createCacheServer(getLocatorPort(), port1, serverProps, javaProps )); + server2.invoke(() -> closeCache()); + + executeOpBlock(opBlock, port1, port2, authInit, extraAuthProps, extraAuthzProps, tgen, rnd); + + if (!currentOp.equals(OperationWithAction.OPBLOCK_NO_FAILOVER)) { + // Failover to the second server and run the block again + server2.invoke(() -> ClientAuthorizationTestCase.createCacheServer(getLocatorPort(), port2, serverProps, javaProps )); + server1.invoke(() -> closeCache()); + + executeOpBlock(opBlock, port1, port2, authInit, extraAuthProps, extraAuthzProps, tgen, rnd); + } + + opBlock.clear(); + } + + } else { + currentOp.setOpNum(opNum); + opBlock.add(currentOp); + } + } + } + + @Override + protected final void executeOpBlock(final List<OperationWithAction> opBlock, final int port1, final int port2, final String authInit, final Properties extraAuthProps, final Properties extraAuthzProps, final TestCredentialGenerator credentialGenerator, final Random random) throws InterruptedException { + for (Iterator<OperationWithAction> opIter = opBlock.iterator(); opIter.hasNext();) { + // Start client with valid credentials as specified in OperationWithAction + OperationWithAction currentOp = opIter.next(); + OperationCode opCode = currentOp.getOperationCode(); + int opFlags = currentOp.getFlags(); + int clientNum = currentOp.getClientNum(); + VM clientVM = null; + boolean useThisVM = false; + + switch (clientNum) { + case 1: + clientVM = client1; + break; + case 2: + clientVM = client2; + break; + case 3: + useThisVM = true; + break; + default: + fail("executeOpBlock: Unknown client number " + clientNum); + break; + } + + getLogWriter().info("executeOpBlock: performing operation number [" + currentOp.getOpNum() + "]: " + currentOp); + + if ((opFlags & OpFlags.USE_OLDCONN) == 0) { + Properties opCredentials; + int newRnd = random.nextInt(100) + 1; + String currentRegionName = '/' + regionName; + if ((opFlags & OpFlags.USE_SUBREGION) > 0) { + currentRegionName += ('/' + SUBREGION_NAME); + } + + String credentialsTypeStr; + OperationCode authOpCode = currentOp.getAuthzOperationCode(); + int[] indices = currentOp.getIndices(); + CredentialGenerator cGen = credentialGenerator.getCredentialGenerator(); + final Properties javaProps = cGen == null ? null : cGen.getJavaProperties(); + + if ((opFlags & OpFlags.CHECK_NOTAUTHZ) > 0 || (opFlags & OpFlags.USE_NOTAUTHZ) > 0) { + opCredentials = credentialGenerator.getDisallowedCredentials(new OperationCode[] { authOpCode }, new String[] { currentRegionName }, indices, newRnd); + credentialsTypeStr = " unauthorized " + authOpCode; + + } else { + opCredentials = credentialGenerator.getAllowedCredentials(new OperationCode[] {opCode, authOpCode }, new String[] { currentRegionName }, indices, newRnd); + credentialsTypeStr = " authorized " + authOpCode; + } + + Properties clientProps = concatProperties(new Properties[] { opCredentials, extraAuthProps, extraAuthzProps }); + + // Start the client with valid credentials but allowed or disallowed to perform an operation + getLogWriter().info("executeOpBlock: For client" + clientNum + credentialsTypeStr + " credentials: " + opCredentials); + boolean setupDynamicRegionFactory = (opFlags & OpFlags.ENABLE_DRF) > 0; + if (useThisVM) { + createCacheClient(authInit, clientProps, javaProps, new int[] { port1, port2 }, 0, setupDynamicRegionFactory, NO_EXCEPTION); + + } else { + clientVM.invoke(() -> createCacheClient(authInit, clientProps, javaProps, new int[] { port1, port2 }, 0, setupDynamicRegionFactory, NO_EXCEPTION)); + } + } + + int expectedResult; + if ((opFlags & OpFlags.CHECK_NOTAUTHZ) > 0) { + expectedResult = NOTAUTHZ_EXCEPTION; + } else if ((opFlags & OpFlags.CHECK_EXCEPTION) > 0) { + expectedResult = OTHER_EXCEPTION; + } else { + expectedResult = NO_EXCEPTION; + } + + // Perform the operation from selected client + if (useThisVM) { + doOp(opCode, currentOp.getIndices(), new Integer( + opFlags), new Integer(expectedResult)); + } + else { + int[] indices = currentOp.getIndices(); + clientVM.invoke(() -> DeltaClientPostAuthorizationDUnitTest.doOp(opCode, + indices, new Integer(opFlags), + new Integer(expectedResult) )); + } + } + } + + private void setUpDeltas() { + for (int i = 0; i < 8; i++) { + deltas[i] = new DeltaTestImpl(0, "0", new Double(0), new byte[0], new PartitionedRegionLocalMaxMemoryDUnitTest.TestObject1("0", 0)); + } + deltas[1].setIntVar(5); + deltas[2].setIntVar(5); + deltas[3].setIntVar(5); + deltas[4].setIntVar(5); + deltas[5].setIntVar(5); + deltas[6].setIntVar(5); + deltas[7].setIntVar(5); + + deltas[2].resetDeltaStatus(); + deltas[2].setByteArr(new byte[] { 1, 2, 3, 4, 5 }); + deltas[3].setByteArr(new byte[] { 1, 2, 3, 4, 5 }); + deltas[4].setByteArr(new byte[] { 1, 2, 3, 4, 5 }); + deltas[5].setByteArr(new byte[] { 1, 2, 3, 4, 5 }); + //deltas[6].setByteArr(new byte[] { 1, 2, 3, 4, 5 }); + //deltas[7].setByteArr(new byte[] { 1, 2, 3, 4, 5 }); + + deltas[3].resetDeltaStatus(); + deltas[3].setDoubleVar(new Double(5)); + deltas[4].setDoubleVar(new Double(5)); + deltas[5].setDoubleVar(new Double(5)); + deltas[6].setDoubleVar(new Double(5)); + deltas[7].setDoubleVar(new Double(5)); + + deltas[4].resetDeltaStatus(); + deltas[4].setStr("str changed"); + deltas[5].setStr("str changed"); + deltas[6].setStr("str changed"); + //deltas[7].setStr("str changed"); + + deltas[5].resetDeltaStatus(); + deltas[5].setIntVar(100); + deltas[5].setTestObj(new PartitionedRegionLocalMaxMemoryDUnitTest.TestObject1("CHANGED", 100)); + deltas[6].setTestObj(new PartitionedRegionLocalMaxMemoryDUnitTest.TestObject1("CHANGED", 100)); + deltas[7].setTestObj(new PartitionedRegionLocalMaxMemoryDUnitTest.TestObject1("CHANGED", 100)); + + deltas[6].resetDeltaStatus(); + deltas[6].setByteArr(new byte[] { 1, 2, 3 }); + deltas[7].setByteArr(new byte[] { 1, 2, 3 }); + + deltas[7].resetDeltaStatus(); + deltas[7].setStr("delta string"); + } + + private OperationWithAction[] allOps() { + return new OperationWithAction[] { + // Test CREATE and verify with a GET + new OperationWithAction(OperationCode.REGISTER_INTEREST, OperationCode.GET, 2, OpFlags.USE_REGEX | OpFlags.REGISTER_POLICY_NONE, 8), + new OperationWithAction(OperationCode.REGISTER_INTEREST, OperationCode.GET, 3, OpFlags.USE_REGEX | OpFlags.REGISTER_POLICY_NONE | OpFlags.USE_NOTAUTHZ, 8), + new OperationWithAction(OperationCode.PUT), + new OperationWithAction(OperationCode.GET, 2, OpFlags.USE_OLDCONN | OpFlags.LOCAL_OP, 4), + new OperationWithAction(OperationCode.GET, 3, OpFlags.USE_OLDCONN | OpFlags.LOCAL_OP | OpFlags.CHECK_FAIL, 4), + + // OPBLOCK_END indicates end of an operation block that needs to be executed on each server when doing failover + OperationWithAction.OPBLOCK_END, + + // Test UPDATE and verify with a GET + new OperationWithAction(OperationCode.REGISTER_INTEREST, OperationCode.GET, 2, OpFlags.USE_REGEX | OpFlags.REGISTER_POLICY_NONE, 8), + new OperationWithAction(OperationCode.REGISTER_INTEREST, OperationCode.GET, 3, OpFlags.USE_REGEX | OpFlags.REGISTER_POLICY_NONE | OpFlags.USE_NOTAUTHZ, 8), + new OperationWithAction(OperationCode.PUT, 1, OpFlags.USE_OLDCONN | OpFlags.USE_NEWVAL, 4), + new OperationWithAction(OperationCode.GET, 2, OpFlags.USE_OLDCONN | OpFlags.LOCAL_OP | OpFlags.USE_NEWVAL, 4), + new OperationWithAction(OperationCode.GET, 3, OpFlags.USE_OLDCONN | OpFlags.LOCAL_OP | OpFlags.USE_NEWVAL | OpFlags.CHECK_FAIL, 4), + + OperationWithAction.OPBLOCK_END + }; + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9d7a6960/geode-core/src/test/java/org/apache/geode/security/GemFireSecurityExceptionTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/GemFireSecurityExceptionTest.java b/geode-core/src/test/java/org/apache/geode/security/GemFireSecurityExceptionTest.java new file mode 100644 index 0000000..5aa01ff --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/GemFireSecurityExceptionTest.java @@ -0,0 +1,169 @@ +/* + * 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 com.gemstone.gemfire.security; + +import static com.googlecode.catchexception.CatchException.*; +import static org.assertj.core.api.Assertions.*; + +import java.io.NotSerializableException; +import java.io.Serializable; +import javax.naming.NamingException; + +import org.apache.commons.lang.SerializationUtils; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.TestName; + +import com.gemstone.gemfire.test.junit.categories.SecurityTest; +import com.gemstone.gemfire.test.junit.categories.UnitTest; + +/** + * Unit tests for {@link GemFireSecurityException}. + */ +@Category({ UnitTest.class, SecurityTest.class }) +public class GemFireSecurityExceptionTest { + + private String message; + private String causeMessage; + private Object nonSerializableResolvedObj; + private NamingException nonSerializableNamingException; + private SerializableObject serializableResolvedObj; + private NamingException serializableNamingException; + + @Rule + public TestName testName = new TestName(); + + @Before + public void setUp() throws Exception { + this.message = testName.getMethodName() + " message"; + this.causeMessage = testName.getMethodName() + " cause message"; + + this.nonSerializableResolvedObj = new Object(); + this.nonSerializableNamingException = new NamingException(this.causeMessage); + this.nonSerializableNamingException.setResolvedObj(this.nonSerializableResolvedObj); + + this.serializableResolvedObj = new SerializableObject(this.testName.getMethodName()); + this.serializableNamingException = new NamingException(this.causeMessage); + this.serializableNamingException.setResolvedObj(this.serializableResolvedObj); + + assertPreConditions(); + } + + private void assertPreConditions() { + catchException(this).clone(this.nonSerializableNamingException); + assertThat((Throwable)caughtException()).isNotNull(); + assertThat((Throwable)caughtException().getCause()).isInstanceOf(NotSerializableException.class); + + catchException(this).clone(this.serializableNamingException); + assertThat((Throwable)caughtException()).isNull(); + + assertThat(this.nonSerializableResolvedObj).isNotInstanceOf(Serializable.class); + + catchException(this).clone(this.serializableResolvedObj); + assertThat((Throwable)caughtException()).isNull(); + } + + @Test + public void isSerializable() throws Exception { + assertThat(GemFireSecurityException.class).isInstanceOf(Serializable.class); + } + + @Test + public void serializes() throws Exception { + GemFireSecurityException instance = new GemFireSecurityException(this.message); + + GemFireSecurityException cloned = (GemFireSecurityException) SerializationUtils.clone(instance); + + assertThat(cloned).hasMessage(this.message); + } + + @Test + public void serializesWithThrowable() throws Exception { + Throwable cause = new Exception(this.causeMessage); + GemFireSecurityException instance = new GemFireSecurityException(this.message, cause); + + GemFireSecurityException cloned = (GemFireSecurityException) SerializationUtils.clone(instance); + + assertThat(cloned).hasMessage(this.message).hasCause(cause); + assertThat(cloned.getCause()).hasMessage(this.causeMessage); + } + + @Test + public void serializesWithNonSerializableNamingException() throws Exception { + GemFireSecurityException instance = new GemFireSecurityException(this.message, this.nonSerializableNamingException); + + GemFireSecurityException cloned = (GemFireSecurityException) SerializationUtils.clone(instance); + + assertThat(cloned).hasMessage(this.message).hasCause(this.nonSerializableNamingException); + NamingException cause = (NamingException) cloned.getCause(); + assertThat(cause).hasMessage(this.causeMessage); + assertThat(cause.getResolvedObj()).isNull(); + } + + @Test + public void serializesWithSerializableNamingException() throws Exception { + GemFireSecurityException instance = new GemFireSecurityException(this.message, this.serializableNamingException); + + GemFireSecurityException cloned = (GemFireSecurityException) SerializationUtils.clone(instance); + + assertThat(cloned).hasMessage(this.message).hasCause(this.serializableNamingException); + NamingException cause = (NamingException) cloned.getCause(); + assertThat(cause).hasMessage(this.causeMessage); + assertThat(cause.getResolvedObj()).isNotNull().isEqualTo(this.serializableResolvedObj); + } + + @Test + public void isSerializableReturnsTrueForSerializableClass() throws Exception { + assertThat(new GemFireSecurityException("").isSerializable(this.serializableResolvedObj)).isTrue(); + } + + @Test + public void isSerializableReturnsFalseForNonSerializableClass() throws Exception { + assertThat(new GemFireSecurityException("").isSerializable(this.nonSerializableResolvedObj)).isFalse(); + } + + public Object clone(final Serializable object) { + return SerializationUtils.clone(object); + } + + public static class SerializableObject implements Serializable { + + private String name; + + SerializableObject(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + SerializableObject that = (SerializableObject) o; + + return name != null ? name.equals(that.name) : that.name == null; + + } + + @Override + public int hashCode() { + return name != null ? name.hashCode() : 0; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9d7a6960/geode-core/src/test/java/org/apache/geode/security/IntegratedClientAuthDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/IntegratedClientAuthDUnitTest.java b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientAuthDUnitTest.java new file mode 100644 index 0000000..73bfcb4 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientAuthDUnitTest.java @@ -0,0 +1,64 @@ +/* + * 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 com.gemstone.gemfire.security; + +import static com.googlecode.catchexception.CatchException.*; +import static org.assertj.core.api.Assertions.*; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.cache.client.ClientCacheFactory; +import com.gemstone.gemfire.cache.client.ClientRegionFactory; +import com.gemstone.gemfire.cache.client.ClientRegionShortcut; +import com.gemstone.gemfire.test.dunit.IgnoredException; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +@Category({ DistributedTest.class, SecurityTest.class }) +public class IntegratedClientAuthDUnitTest extends AbstractSecureServerDUnitTest { + + @Test + public void authWithCorrectPasswordShouldPass() { + client1.invoke("logging in super-user with correct password", () -> { + ClientCache cache = new ClientCacheFactory(createClientProperties("super-user", "1234567")).setPoolSubscriptionEnabled(true) + .addPoolServer("localhost", serverPort) + .create(); + + ClientRegionFactory<String, String> crf = cache.createClientRegionFactory(ClientRegionShortcut.PROXY); + + crf.create(REGION_NAME); + }); + } + + @Test + public void authWithIncorrectPasswordShouldFail() { + IgnoredException.addIgnoredException(AuthenticationFailedException.class.getName()); + + client2.invoke("logging in super-user with wrong password", () -> { + AuthenticationFailedException expected = new AuthenticationFailedException("Authentication error. Please check your credentials."); + + catchException(new ClientCacheFactory(createClientProperties("super-user", "wrong")).setPoolSubscriptionEnabled(true) + .addPoolServer("localhost", serverPort)) + .create(); + assertThat((Throwable) caughtException()).hasCause(expected); + }); + } +} + + http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9d7a6960/geode-core/src/test/java/org/apache/geode/security/IntegratedClientContainsKeyAuthDistributedTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/IntegratedClientContainsKeyAuthDistributedTest.java b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientContainsKeyAuthDistributedTest.java new file mode 100644 index 0000000..336cf87 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientContainsKeyAuthDistributedTest.java @@ -0,0 +1,55 @@ +/* + * 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 com.gemstone.gemfire.security; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.test.dunit.AsyncInvocation; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +@Category({ DistributedTest.class, SecurityTest.class }) +public class IntegratedClientContainsKeyAuthDistributedTest extends AbstractSecureServerDUnitTest { + + @Test + public void testContainsKey() throws InterruptedException { + AsyncInvocation ai1 = client1.invokeAsync(() -> { + ClientCache cache = createClientCache("key1User", "1234567", serverPort); + final Region region = cache.getRegion(REGION_NAME); + assertTrue(region.containsKeyOnServer("key1")); + assertNotAuthorized(() -> region.containsKeyOnServer("key3"), "DATA:READ:AuthRegion:key3"); + }); + + AsyncInvocation ai2 = client2.invokeAsync(() -> { + ClientCache cache = createClientCache("authRegionReader", "1234567", serverPort); + final Region region = cache.getRegion(REGION_NAME); + region.containsKeyOnServer("key3"); + assertTrue(region.containsKeyOnServer("key1")); + }); + + ai1.join(); + ai2.join(); + ai1.checkException(); + ai2.checkException(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9d7a6960/geode-core/src/test/java/org/apache/geode/security/IntegratedClientDestroyInvalidateAuthDistributedTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/IntegratedClientDestroyInvalidateAuthDistributedTest.java b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientDestroyInvalidateAuthDistributedTest.java new file mode 100644 index 0000000..e811d86 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientDestroyInvalidateAuthDistributedTest.java @@ -0,0 +1,84 @@ +/* + * 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 com.gemstone.gemfire.security; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.cache.client.ClientCacheFactory; +import com.gemstone.gemfire.cache.client.ClientRegionShortcut; +import com.gemstone.gemfire.test.dunit.AsyncInvocation; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +@Category({ DistributedTest.class, SecurityTest.class }) +public class IntegratedClientDestroyInvalidateAuthDistributedTest extends AbstractSecureServerDUnitTest { + + @Test + public void testDestroyInvalidate() throws InterruptedException { + + // Delete one key and invalidate another key with an authorized user. + AsyncInvocation ai1 = client1.invokeAsync(() -> { + ClientCache cache = new ClientCacheFactory(createClientProperties("dataUser", "1234567")).setPoolSubscriptionEnabled(true) + .addPoolServer("localhost", serverPort) + .create(); + + Region region = cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(REGION_NAME); + assertTrue(region.containsKeyOnServer("key1")); + + // Destroy key1 + region.destroy("key1"); + assertFalse(region.containsKeyOnServer("key1")); + + // Invalidate key2 + assertNotNull("Value of key2 should not be null", region.get("key2")); + region.invalidate("key2"); + assertNull("Value of key2 should have been null", region.get("key2")); + + }); + + // Delete one key and invalidate another key with an unauthorized user. + AsyncInvocation ai2 = client2.invokeAsync(() -> { + ClientCache cache = new ClientCacheFactory(createClientProperties("authRegionReader", "1234567")).setPoolSubscriptionEnabled(true) + .addPoolServer("localhost", serverPort) + .create(); + + Region region = cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(REGION_NAME); + + assertTrue(region.containsKeyOnServer("key3")); + + // Destroy key1 + assertNotAuthorized(() -> region.destroy("key3"), "DATA:WRITE:AuthRegion"); + assertTrue(region.containsKeyOnServer("key3")); + + // Invalidate key2 + assertNotNull("Value of key4 should not be null", region.get("key4")); + assertNotAuthorized(() -> region.invalidate("key4"), "DATA:WRITE:AuthRegion"); + assertNotNull("Value of key4 should not be null", region.get("key4")); + }); + + ai1.join(); + ai2.join(); + ai1.checkException(); + ai2.checkException(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9d7a6960/geode-core/src/test/java/org/apache/geode/security/IntegratedClientDestroyRegionAuthDistributedTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/IntegratedClientDestroyRegionAuthDistributedTest.java b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientDestroyRegionAuthDistributedTest.java new file mode 100644 index 0000000..adb7c0b --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientDestroyRegionAuthDistributedTest.java @@ -0,0 +1,65 @@ +/* + * 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 com.gemstone.gemfire.security; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.cache.client.ClientCacheFactory; +import com.gemstone.gemfire.cache.client.ClientRegionShortcut; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +@Category({ DistributedTest.class, SecurityTest.class }) +public class IntegratedClientDestroyRegionAuthDistributedTest extends AbstractSecureServerDUnitTest { + + @Test + public void testDestroyRegion() throws InterruptedException { + client1.invoke(() -> { + ClientCache cache = new ClientCacheFactory(createClientProperties("dataWriter", "1234567")).setPoolSubscriptionEnabled(true) + .addPoolServer("localhost", serverPort) + .create(); + + Region region = cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(REGION_NAME); + assertNotAuthorized(() -> region.destroyRegion(), "DATA:MANAGE"); + }); + + client2.invoke(() -> { + ClientCache cache = new ClientCacheFactory(createClientProperties("authRegionManager", "1234567")).setPoolSubscriptionEnabled(true) + .addPoolServer("localhost", serverPort) + .create(); + + Region region = cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(REGION_NAME); + assertNotAuthorized(() -> region.destroyRegion(), "DATA:MANAGE"); + }); + + client3.invoke(() -> { + ClientCache cache = new ClientCacheFactory(createClientProperties("super-user", "1234567")).setPoolSubscriptionEnabled(true) + .addPoolServer("localhost", serverPort) + .create(); + + Region region = cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(REGION_NAME); + region.destroyRegion(); + assertThat(region.isDestroyed()).isTrue(); + }); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9d7a6960/geode-core/src/test/java/org/apache/geode/security/IntegratedClientExecuteFunctionAuthDistributedTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/IntegratedClientExecuteFunctionAuthDistributedTest.java b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientExecuteFunctionAuthDistributedTest.java new file mode 100644 index 0000000..bf4b027 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientExecuteFunctionAuthDistributedTest.java @@ -0,0 +1,61 @@ +/* + * 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 com.gemstone.gemfire.security; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.cache.execute.Function; +import com.gemstone.gemfire.cache.execute.FunctionService; +import com.gemstone.gemfire.cache.execute.ResultCollector; +import com.gemstone.gemfire.internal.cache.functions.TestFunction; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +@Category({ DistributedTest.class, SecurityTest.class }) +public class IntegratedClientExecuteFunctionAuthDistributedTest extends AbstractSecureServerDUnitTest { + + private final static Function function = new TestFunction(true, TestFunction.TEST_FUNCTION1); + + @Test + public void testExecuteRegionFunction() { + + FunctionService.registerFunction(function); + + client1.invoke("logging in with dataReader", () -> { + ClientCache cache = createClientCache("dataReader", "1234567", serverPort); + + FunctionService.registerFunction(function); + assertNotAuthorized(() -> FunctionService.onServer(cache.getDefaultPool()) + .withArgs(Boolean.TRUE) + .execute(function.getId()), "DATA:WRITE"); + }); + + client2.invoke("logging in with super-user", () -> { + ClientCache cache = createClientCache("super-user", "1234567", serverPort); + + FunctionService.registerFunction(function); + ResultCollector rc = FunctionService.onServer(cache.getDefaultPool()) + .withArgs(Boolean.TRUE) + .execute(function.getId()); + rc.getResult(); + }); + } +} + + http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9d7a6960/geode-core/src/test/java/org/apache/geode/security/IntegratedClientExecuteRegionFunctionAuthDistributedTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/IntegratedClientExecuteRegionFunctionAuthDistributedTest.java b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientExecuteRegionFunctionAuthDistributedTest.java new file mode 100644 index 0000000..08425a0 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientExecuteRegionFunctionAuthDistributedTest.java @@ -0,0 +1,62 @@ +/* + * 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 com.gemstone.gemfire.security; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.cache.execute.Function; +import com.gemstone.gemfire.cache.execute.FunctionService; +import com.gemstone.gemfire.cache.execute.ResultCollector; +import com.gemstone.gemfire.internal.cache.functions.TestFunction; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +@Category({ DistributedTest.class, SecurityTest.class }) +public class IntegratedClientExecuteRegionFunctionAuthDistributedTest + extends AbstractSecureServerDUnitTest { + + private final static Function function = new TestFunction(true, TestFunction.TEST_FUNCTION1); + + @Test + public void testExecuteRegionFunction() { + + FunctionService.registerFunction(function); + + client1.invoke("logging in with dataReader", () -> { + ClientCache cache = createClientCache("dataReader", "1234567", serverPort); + + FunctionService.registerFunction(function); + assertNotAuthorized(() -> FunctionService.onRegion(cache.getRegion(REGION_NAME)) + .withArgs(Boolean.TRUE) + .execute(function.getId()), "DATA:WRITE"); + }); + + client2.invoke("logging in with super-user", () -> { + ClientCache cache = createClientCache("super-user", "1234567", serverPort); + + FunctionService.registerFunction(function); + ResultCollector rc = FunctionService.onRegion(cache.getRegion(REGION_NAME)) + .withArgs(Boolean.TRUE) + .execute(function.getId()); + rc.getResult(); + }); + } +} + + http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9d7a6960/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetAllAuthDistributedTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetAllAuthDistributedTest.java b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetAllAuthDistributedTest.java new file mode 100644 index 0000000..1931633 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetAllAuthDistributedTest.java @@ -0,0 +1,57 @@ +/* + * 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 com.gemstone.gemfire.security; + +import static com.gemstone.gemfire.internal.Assert.assertTrue; +import static org.jgroups.util.Util.*; + +import java.util.Arrays; +import java.util.Map; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +@Category({ DistributedTest.class, SecurityTest.class }) +public class IntegratedClientGetAllAuthDistributedTest extends AbstractSecureServerDUnitTest { + + @Test + public void testGetAll() { + client1.invoke("logging in Stranger", () -> { + ClientCache cache = createClientCache("stranger", "1234567", serverPort); + + Region region = cache.getRegion(REGION_NAME); + Map emptyMap = region.getAll(Arrays.asList("key1", "key2", "key3", "key4")); + assertTrue(emptyMap.isEmpty()); + }); + + client2.invoke("logging in authRegionReader", () -> { + ClientCache cache = createClientCache("authRegionReader", "1234567", serverPort); + + Region region = cache.getRegion(REGION_NAME); + Map filledMap = region.getAll(Arrays.asList("key1", "key2", "key3", "key4")); + assertEquals("Map should contain 4 entries", 4, filledMap.size()); + assertTrue(filledMap.containsKey("key1")); + }); + } +} + + http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9d7a6960/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetClientPRMetaDataAuthDistributedTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetClientPRMetaDataAuthDistributedTest.java b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetClientPRMetaDataAuthDistributedTest.java new file mode 100644 index 0000000..2f2a013 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetClientPRMetaDataAuthDistributedTest.java @@ -0,0 +1,66 @@ +/* + * 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 com.gemstone.gemfire.security; + +import org.junit.Ignore; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.cache.client.ClientCacheFactory; +import com.gemstone.gemfire.cache.client.ClientRegionShortcut; +import com.gemstone.gemfire.cache.client.internal.ClientMetadataService; +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; +import com.gemstone.gemfire.internal.cache.LocalRegion; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +@Category({ DistributedTest.class, SecurityTest.class }) +public class IntegratedClientGetClientPRMetaDataAuthDistributedTest + extends AbstractSecureServerDUnitTest { + + @Test + @Ignore("This is not a supported client message") + // this would fail sporadically because ServerConnection.isInternalMessage would return true for this message, + // and it won't bind the correct subject on the executing thread. + public void testGetClientPartitionAttrCmd() { + client1.invoke("logging in stranger", () -> { + ClientCache cache = new ClientCacheFactory(createClientProperties("stranger", "1234567")).setPoolSubscriptionEnabled(true) + .addPoolServer("localhost", serverPort) + .create(); + + Region region = cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(REGION_NAME); + + ClientMetadataService service = ((GemFireCacheImpl) cache).getClientMetadataService(); + assertNotAuthorized(() -> service.getClientPRMetadata((LocalRegion) cache.getRegion(region.getName())), "CLUSTER:READ"); + }); + + client2.invoke("logging in super-user", () -> { + ClientCache cache = new ClientCacheFactory(createClientProperties("super-user", "1234567")).setPoolSubscriptionEnabled(true) + .addPoolServer("localhost", serverPort) + .create(); + + Region region = cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(REGION_NAME); + + ClientMetadataService service = ((GemFireCacheImpl) cache).getClientMetadataService(); + service.getClientPRMetadata((LocalRegion) cache.getRegion(region.getName())); + }); + } +} + + http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9d7a6960/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetClientPartitionAttrCmdAuthDistributedTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetClientPartitionAttrCmdAuthDistributedTest.java b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetClientPartitionAttrCmdAuthDistributedTest.java new file mode 100644 index 0000000..b18ca98 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetClientPartitionAttrCmdAuthDistributedTest.java @@ -0,0 +1,52 @@ +/* + * 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 com.gemstone.gemfire.security; + +import org.junit.Ignore; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.cache.client.internal.GetClientPartitionAttributesOp; +import com.gemstone.gemfire.cache.client.internal.PoolImpl; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +@Category({ DistributedTest.class, SecurityTest.class }) +public class IntegratedClientGetClientPartitionAttrCmdAuthDistributedTest + extends AbstractSecureServerDUnitTest { + + @Test + @Ignore("This is not a supported client message") + // this would fail sporatically because ServerConnection.isInternalMessage would return true for this message, + // and it won't bind the correct subject on the executing thread. + public void testGetClientPartitionAttrCmd() { + client1.invoke("logging in stranger", () -> { + ClientCache cache = createClientCache("stranger", "1234567", serverPort); + + assertNotAuthorized(() -> GetClientPartitionAttributesOp.execute((PoolImpl) cache.getDefaultPool(), REGION_NAME), "CLUSTER:READ"); + }); + + client2.invoke("logging in super-user with correct password", () -> { + ClientCache cache = createClientCache("super-user", "1234567", serverPort); + + GetClientPartitionAttributesOp.execute((PoolImpl) cache.getDefaultPool(), REGION_NAME); + }); + } +} + + http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9d7a6960/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetEntryAuthDistributedTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetEntryAuthDistributedTest.java b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetEntryAuthDistributedTest.java new file mode 100644 index 0000000..656659e --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetEntryAuthDistributedTest.java @@ -0,0 +1,76 @@ +/* + * 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 com.gemstone.gemfire.security; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.cache.CacheTransactionManager; +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.cache.client.ClientCacheFactory; +import com.gemstone.gemfire.cache.client.ClientRegionShortcut; +import com.gemstone.gemfire.test.dunit.AsyncInvocation; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +@Category({ DistributedTest.class, SecurityTest.class }) +public class IntegratedClientGetEntryAuthDistributedTest extends AbstractSecureServerDUnitTest { + + @Test + public void testGetEntry() throws InterruptedException { + // client1 connects to server as a user not authorized to do any operations + + AsyncInvocation ai1 = client1.invokeAsync(() -> { + ClientCache cache = new ClientCacheFactory(createClientProperties("stranger", "1234567")).setPoolSubscriptionEnabled(true) + .addPoolServer("localhost", serverPort) + .create(); + + CacheTransactionManager transactionManager = cache.getCacheTransactionManager(); + transactionManager.begin(); + try { + Region region = cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(REGION_NAME); + assertNotAuthorized(() -> region.getEntry("key3"), "DATA:READ:AuthRegion:key3"); + } finally { + transactionManager.commit(); + } + + }); + + AsyncInvocation ai2 = client2.invokeAsync(() -> { + ClientCache cache = new ClientCacheFactory(createClientProperties("authRegionReader", "1234567")).setPoolSubscriptionEnabled(true) + .addPoolServer("localhost", serverPort) + .create(); + + CacheTransactionManager transactionManager = cache.getCacheTransactionManager(); + transactionManager.begin(); + try { + Region region = cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(REGION_NAME); + region.getEntry("key3"); + } finally { + transactionManager.commit(); + } + + }); + + ai1.join(); + ai2.join(); + ai1.checkException(); + ai2.checkException(); + + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9d7a6960/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetPutAuthDistributedTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetPutAuthDistributedTest.java b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetPutAuthDistributedTest.java new file mode 100644 index 0000000..6d4374d --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/IntegratedClientGetPutAuthDistributedTest.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 com.gemstone.gemfire.security; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.test.dunit.AsyncInvocation; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.FlakyTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +@Category({ DistributedTest.class, SecurityTest.class, FlakyTest.class }) +public class IntegratedClientGetPutAuthDistributedTest extends AbstractSecureServerDUnitTest { + + @Test + public void testGetPutAuthorization() throws InterruptedException { + Map<String, String> allValues = new HashMap<String, String>(); + allValues.put("key1", "value1"); + allValues.put("key2", "value2"); + + List<String> keys = new ArrayList<>(); + keys.add("key1"); + keys.add("key2"); + + // client1 connects to server as a user not authorized to do any operations + AsyncInvocation ai1 = client1.invokeAsync(()->{ + ClientCache cache = createClientCache("stranger", "1234567", serverPort); + Region region = cache.getRegion(REGION_NAME); + + assertNotAuthorized(() -> region.put("key3", "value3"), "DATA:WRITE:AuthRegion:key3"); + assertNotAuthorized(() -> region.get("key3"), "DATA:READ:AuthRegion:key3"); + + //putall + assertNotAuthorized(() -> region.putAll(allValues), "DATA:WRITE:AuthRegion"); + + // not authorized for either keys, get no record back + Map keyValues = region.getAll(keys); + assertEquals(0, keyValues.size()); + + assertNotAuthorized(() -> region.keySetOnServer(), "DATA:READ:AuthRegion"); + }); + + + // client2 connects to user as a user authorized to use AuthRegion region + AsyncInvocation ai2 = client2.invokeAsync(()->{ + ClientCache cache = createClientCache("authRegionUser", "1234567", serverPort); + Region region = cache.getRegion(REGION_NAME); + + region.put("key3", "value3"); + assertEquals("value3", region.get("key3")); + + // put all + region.putAll(allValues); + + // get all + Map keyValues = region.getAll(keys); + assertEquals(2, keyValues.size()); + + // keyset + Set keySet = region.keySetOnServer(); + assertEquals(5, keySet.size()); + }); + + // client3 connects to user as a user authorized to use key1 in AuthRegion region + AsyncInvocation ai3 = client3.invokeAsync(()->{ + ClientCache cache = createClientCache("key1User", "1234567", serverPort); + Region region = cache.getRegion(REGION_NAME); + + assertNotAuthorized(() -> region.put("key2", "value1"), "DATA:WRITE:AuthRegion:key2"); + assertNotAuthorized(() -> region.get("key2"), "DATA:READ:AuthRegion:key2"); + + assertNotAuthorized(() -> region.putAll(allValues), "DATA:WRITE:AuthRegion"); + + // only authorized for one recrod + Map keyValues = region.getAll(keys); + assertEquals(1, keyValues.size()); + + // keyset + assertNotAuthorized(() -> region.keySetOnServer(), "DATA:READ:AuthRegion"); + }); + + ai1.join(); + ai2.join(); + ai3.join(); + + ai1.checkException(); + ai2.checkException(); + ai3.checkException(); + } + +}