You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by tu...@apache.org on 2015/11/03 12:26:39 UTC
[77/79] incubator-geode git commit: Integrated Security DUnitTest for
data/monitor commands
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3f931bab/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/MBeanSecurityJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/MBeanSecurityJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/MBeanSecurityJUnitTest.java
new file mode 100644
index 0000000..d8915a7
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/MBeanSecurityJUnitTest.java
@@ -0,0 +1,585 @@
+package com.gemstone.gemfire.management.internal.security;
+
+import hydra.Log;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceNotFoundException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.JMX;
+import javax.management.MBeanException;
+import javax.management.MBeanServerConnection;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+
+import org.junit.experimental.categories.Category;
+
+import junit.framework.TestCase;
+
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.asyncqueue.AsyncEvent;
+import com.gemstone.gemfire.cache.asyncqueue.AsyncEventListener;
+import com.gemstone.gemfire.cache.operations.OperationContext.OperationCode;
+import com.gemstone.gemfire.cache.server.CacheServer;
+import com.gemstone.gemfire.distributed.DistributedLockService;
+import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.internal.AvailablePortHelper;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.management.AsyncEventQueueMXBean;
+import com.gemstone.gemfire.management.CacheServerMXBean;
+import com.gemstone.gemfire.management.DiskStoreMXBean;
+import com.gemstone.gemfire.management.DistributedLockServiceMXBean;
+import com.gemstone.gemfire.management.DistributedRegionMXBean;
+import com.gemstone.gemfire.management.DistributedSystemMXBean;
+import com.gemstone.gemfire.management.LockServiceMXBean;
+import com.gemstone.gemfire.management.ManagerMXBean;
+import com.gemstone.gemfire.management.MemberMXBean;
+import com.gemstone.gemfire.management.RegionMXBean;
+import com.gemstone.gemfire.management.internal.MBeanJMXAdapter;
+import com.gemstone.gemfire.management.internal.security.ResourceOperationContext.ResourceOperationCode;
+import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+/**
+ * Test all mbean operations by granting and revoking the access levels required
+ * for performing that operation
+ *
+ * @author tushark
+ *
+ */
+@Category(UnitTest.class)
+public class MBeanSecurityJUnitTest extends TestCase {
+
+ private static final String USER = "custom";
+ private static final String PASSWORD = "password123";
+ private JMXConnector connector = null;
+
+
+ public static class MyAsyncEventListener implements AsyncEventListener {
+ @Override
+ public void close() {
+
+
+ }
+
+ @Override
+ public boolean processEvents(List<AsyncEvent> events) {
+ return false;
+ }
+
+ }
+
+ public void testGemfireMBeans() throws IOException, InstanceNotFoundException, MBeanException, ReflectionException,
+ AttributeNotFoundException, InvalidAttributeValueException, MalformedObjectNameException {
+ Log.createLogWriter("testGemfireMBeans", "info");
+ GemFireCacheImpl cache = null;
+ DistributedSystem ds = null;
+ Properties pr = new Properties();
+ pr.put("name", "testGemfireMBeans");
+ pr.put(DistributionConfig.JMX_MANAGER_NAME, "true");
+ pr.put(DistributionConfig.JMX_MANAGER_START_NAME, "true");
+ int port = AvailablePortHelper.getRandomAvailableTCPPort();
+ pr.put(DistributionConfig.JMX_MANAGER_PORT_NAME, String.valueOf(port));
+ pr.put(DistributionConfig.HTTP_SERVICE_PORT_NAME, "0");
+
+ pr.put(DistributionConfig.SECURITY_CLIENT_AUTHENTICATOR_NAME,
+ "com.gemstone.gemfire.management.internal.security.TestAuthenticator.create");
+ pr.put(DistributionConfig.SECURITY_CLIENT_ACCESSOR_NAME,
+ "com.gemstone.gemfire.management.internal.security.TestAccessControl.create");
+ pr.put(DistributionConfig.SECURITY_CLIENT_ACCESSOR_PP_NAME,
+ "com.gemstone.gemfire.management.internal.security.TestAccessControl.create");
+ ds = DistributedSystem.connect(pr);
+ cache = (GemFireCacheImpl) CacheFactory.create(ds);
+
+ DistributedLockService.create("mydsLock", ds);
+
+ TestAuthenticator.addUser(USER, PASSWORD);
+ TestAccessControl.grantResourceOp("custom", ResourceOperationCode.DATA_READ);
+ TestAccessControl.grantResourceOp("custom", ResourceOperationCode.CREATE_REGION);
+ TestAccessControl.grantCacheOp("custom", OperationCode.REGION_CREATE);
+ TestAccessControl.grantResourceOp("custom", ResourceOperationCode.CREATE_DISKSTORE);
+ TestAccessControl.grantResourceOp("custom", ResourceOperationCode.CREATE_AEQ);
+
+ int cacheServerPort = AvailablePortHelper.getRandomAvailableTCPPort();
+ CacheServer cacheServer = cache.addCacheServer();
+ cacheServer.setPort(cacheServerPort);
+ cacheServer.start();
+
+ connector = getGemfireMBeanServer(port, USER, PASSWORD);
+ MBeanServerConnection conn = connector.getMBeanServerConnection();
+ ObjectName memberON = (ObjectName) conn.invoke(MBeanJMXAdapter.getDistributedSystemName(), "fetchMemberObjectName",
+ new Object[] { "testGemfireMBeans" }, new String[] { String.class.getCanonicalName() });
+
+ MemberMXBean member = (MemberMXBean) JMX.newMBeanProxy(conn, memberON, MemberMXBean.class);
+
+ File diskDir = new File("mydiskstore");
+ diskDir.mkdir();
+ assertTrue(diskDir.exists());
+ String result = member.processCommand("create disk-store --name=mydiskstore --dir=" + diskDir.getAbsolutePath());
+ assertNotNull(result);
+ result = member.processCommand("create region --name=region1 --type=REPLICATE");
+ assertNotNull(result);
+ result = member.processCommand(
+ "create async-event-queue --id=aeq1 --listener=\"com.gemstone.gemfire.management.internal.security.MBeanSecurityJUnitTest$MyAsyncEventListener\"");
+ assertNotNull(result);
+
+ TestAccessControl.revokeResourceOp("custom", ResourceOperationCode.CREATE_REGION);
+ TestAccessControl.revokeCacheOp("custom", OperationCode.REGION_CREATE);
+ TestAccessControl.revokeResourceOp("custom", ResourceOperationCode.CREATE_DISKSTORE);
+ TestAccessControl.revokeResourceOp("custom", ResourceOperationCode.CREATE_AEQ);
+
+ doTestDistributedSystemMXBean(port);
+ doTestMemberMXBean(port);
+
+ doTestDiskStoreMXBean(port);
+ doTestCacheServerMXBean(port, cacheServerPort);
+ //TODO : needs WAN
+ // doTestGatewayReceiverMXBean(port);
+ // doTestGatewaySenderMXBean(port);
+ doTestLockServiceMXBean(port);
+ doTestManagerMXBean(port);
+ doTestRegionMXBean(port);
+ //TODO : Needs Locator in DS
+ doTestLocatorMXBean(port);
+ doTestDistributedLockServiceMXBean(port);
+ doTestDistributedRegionMXBean(port);
+ doTestAsyncEventQueueMXBean(port);
+ doTestAccessControlMXBean(port);
+
+ cache.close();
+ ds.disconnect();
+ }
+
+ private void doTestAccessControlMXBean(int port) throws MalformedObjectNameException, IOException {
+ ObjectName accessControlON = new ObjectName(ResourceConstants.OBJECT_NAME_ACCESSCONTROL);
+ checkMethod(port, AccessControlMXBean.class, accessControlON, "authorize",
+ new Object[] { ResourceOperationCode.DATA_READ.toString() },
+ ResourceOperationCode.LIST_DS);
+ }
+
+ private void doTestAsyncEventQueueMXBean(int port) throws InstanceNotFoundException, ReflectionException, IOException {
+ MBeanServerConnection conn = connector.getMBeanServerConnection();
+ ObjectName aeqON = MBeanJMXAdapter.getAsycnEventQueueMBeanName("testGemfireMBeans", "aeq1");
+
+ checkAttributes(port, AsyncEventQueueMXBean.class, aeqON, new String[] { "BatchSize", "BatchTimeInterval",
+ "BatchConflationEnabled", "Persistent", "Primary", "DispatcherThreads", "OrderPolicy", "DiskSynchronous",
+ "Parallel", "AsyncEventListener", "EventQueueSize" });
+
+ }
+
+ private void doTestDistributedRegionMXBean(int port) throws IOException, InstanceNotFoundException, MBeanException,
+ ReflectionException {
+ MBeanServerConnection conn = connector.getMBeanServerConnection();
+ ObjectName regionON = (ObjectName) conn.invoke(MBeanJMXAdapter.getDistributedSystemName(),
+ "fetchDistributedRegionObjectName", new Object[] { "/region1" },
+ new String[] { String.class.getCanonicalName() });
+
+ checkAttributes(port, DistributedRegionMXBean.class, regionON, new String[] { "Name", "RegionType", "FullPath",
+ "LastModifiedTime", "PutsRate", "GatewayEnabled", "PersistentEnabled" });
+
+ checkMethod(port, DistributedRegionMXBean.class, regionON, "listSubRegionPaths", new Object[] { true },
+ ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, DistributedRegionMXBean.class, regionON, "listRegionAttributes", null,
+ ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, DistributedRegionMXBean.class, regionON, "listMembershipAttributes", null,
+ ResourceOperationCode.LIST_DS);
+
+ }
+
+ private void doTestDistributedLockServiceMXBean(int port) throws IOException, InstanceNotFoundException,
+ MBeanException, ReflectionException {
+ MBeanServerConnection conn = connector.getMBeanServerConnection();
+ ObjectName mydsLockON = (ObjectName) conn.invoke(MBeanJMXAdapter.getDistributedSystemName(),
+ "fetchDistributedLockServiceObjectName", new Object[] { "mydsLock" },
+ new String[] { String.class.getCanonicalName() });
+
+ checkAttributes(port, DistributedLockServiceMXBean.class, mydsLockON, new String[] { "Name", "MemberCount",
+ "MemberNames" });
+
+ checkMethod(port, DistributedLockServiceMXBean.class, mydsLockON, "fetchGrantorMember", null,
+ ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, DistributedLockServiceMXBean.class, mydsLockON, "listHeldLocks", null,
+ ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, DistributedLockServiceMXBean.class, mydsLockON, "listThreadsHoldingLock", null,
+ ResourceOperationCode.LIST_DS);
+
+ }
+
+ private void doTestLocatorMXBean(int port) {
+
+ /*MBeanServerConnection conn = connector.getMBeanServerConnection();
+ ObjectName regionON = (ObjectName) conn.invoke(MBeanJMXAdapter.getDistributedSystemName(), "fetchRegionObjectName",
+ new Object[] { "testGemfireMBeans", "/region1" },
+ new String[] { String.class.getCanonicalName(), String.class.getCanonicalName() });
+
+ checkAttributes(port, LocatorMXBean.class, locatorON, new String[] { "Port",
+ "BindAddress",
+ "HostnameForClients",
+ "PeerLocator",
+ "ServerLocator"});
+
+ checkMethod(port, LocatorMXBean.class, locatorON, "viewLog", null,
+ ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, LocatorMXBean.class, locatorON, "listPotentialManagers", null,
+ ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, LocatorMXBean.class, locatorON, "listManagers", null,
+ ResourceOperationCode.LIST_DS);
+ */
+
+ }
+
+ private void doTestRegionMXBean(int port) throws IOException, InstanceNotFoundException, MBeanException,
+ ReflectionException {
+ MBeanServerConnection conn = connector.getMBeanServerConnection();
+ ObjectName regionON = (ObjectName) conn.invoke(MBeanJMXAdapter.getDistributedSystemName(), "fetchRegionObjectName",
+ new Object[] { "testGemfireMBeans", "/region1" },
+ new String[] { String.class.getCanonicalName(), String.class.getCanonicalName() });
+
+ checkAttributes(port, RegionMXBean.class, regionON, new String[] { "Name", "RegionType", "FullPath",
+ "LastModifiedTime", "PutsRate", "GatewayEnabled", "PersistentEnabled" });
+
+ checkMethod(port, RegionMXBean.class, regionON, "listSubregionPaths", new Object[] { true },
+ ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, RegionMXBean.class, regionON, "listRegionAttributes", null, ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, RegionMXBean.class, regionON, "listMembershipAttributes", null, ResourceOperationCode.LIST_DS);
+
+ }
+
+ private void doTestManagerMXBean(int port) throws IOException, InstanceNotFoundException, MBeanException,
+ ReflectionException, AttributeNotFoundException, InvalidAttributeValueException {
+
+ ObjectName managerON = MBeanJMXAdapter.getManagerName();
+
+ checkAttributes(port, ManagerMXBean.class, managerON, new String[] { "Running", "StatusMessage" });
+
+ checkSetAttribute(port, managerON, "StatusMessage", "StatusMessage", ResourceOperationCode.LIST_DS);
+
+ checkSetAttribute(port, managerON, "PulseURL", "PulseURL", ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, ManagerMXBean.class, managerON, "start", null, ResourceOperationCode.START_MANAGER);
+
+ /*-
+ * checkMethod(port, LockServiceMXBean.class, managerON, "stop", null,
+ * ResourceOperationCode.STOP_MANAGER);
+ */
+ }
+
+ private void doTestLockServiceMXBean(int port) throws IOException, InstanceNotFoundException, MBeanException,
+ ReflectionException {
+ MBeanServerConnection conn = connector.getMBeanServerConnection();
+ ObjectName mydsLockON = (ObjectName) conn.invoke(MBeanJMXAdapter.getDistributedSystemName(),
+ "fetchLockServiceObjectName", new Object[] { "testGemfireMBeans", "mydsLock" },
+ new String[] { String.class.getCanonicalName(), String.class.getCanonicalName() });
+ checkAttributes(port, LockServiceMXBean.class, mydsLockON, new String[]{"Name", "Distributed",
+ "MemberCount", "MemberNames", "LockGrantor"});
+
+ checkMethod(port, LockServiceMXBean.class, mydsLockON, "listThreadsHoldingLock", null,
+ ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, LockServiceMXBean.class, mydsLockON, "listHeldLocks", null,
+ ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, LockServiceMXBean.class, mydsLockON, "fetchGrantorMember", null,
+ ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, LockServiceMXBean.class, mydsLockON, "becomeLockGrantor", null,
+ ResourceOperationCode.BECOME_LOCK_GRANTOR);
+ }
+
+ private void doTestGatewaySenderMXBean(int port) {
+
+ }
+
+ private void doTestGatewayReceiverMXBean(int port) {
+
+ }
+
+ private void doTestCacheServerMXBean(int port, int cacheServerPort) throws IOException, InstanceNotFoundException,
+ MBeanException, ReflectionException {
+ MBeanServerConnection conn = connector.getMBeanServerConnection();
+ ObjectName cacheServerON = (ObjectName) conn.invoke(MBeanJMXAdapter.getDistributedSystemName(),
+ "fetchCacheServerObjectName", new Object[] { "testGemfireMBeans", cacheServerPort }, new String[] {
+ String.class.getCanonicalName(), int.class.getName() });
+
+ checkAttributes(port, CacheServerMXBean.class, cacheServerON, new String[] { "Port", "BindAddress",
+ "MaxConnections", "Running" });
+
+ checkMethod(port, CacheServerMXBean.class, cacheServerON, "showAllClientStats", null, ResourceOperationCode.LIST_DS);
+
+ /*checkMethod(port, CacheServerMXBean.class, cacheServerON, "showClientQueueDetails", null,
+ ResourceOperationCode.LIST_DS);*/
+
+ checkMethod(port, CacheServerMXBean.class, cacheServerON, "removeIndex", new Object[]{"indexName"},
+ ResourceOperationCode.DESTROY_INDEX);
+
+ checkMethod(port, CacheServerMXBean.class, cacheServerON, "executeContinuousQuery", new Object[]{"queryName"},
+ ResourceOperationCode.QUERY);
+
+ checkMethod(port, CacheServerMXBean.class, cacheServerON, "stopContinuousQuery", new Object[]{"queryName"},
+ ResourceOperationCode.STOP_CONTINUOUS_QUERY);
+ }
+
+ private void doTestDiskStoreMXBean(int port) throws IOException, InstanceNotFoundException, MBeanException,
+ ReflectionException, AttributeNotFoundException, InvalidAttributeValueException {
+ MBeanServerConnection conn = connector.getMBeanServerConnection();
+ ObjectName diskStoreON = (ObjectName) conn.invoke(MBeanJMXAdapter.getDistributedSystemName(),
+ "fetchDiskStoreObjectName", new Object[] { "testGemfireMBeans", "mydiskstore" },
+ new String[] { String.class.getCanonicalName(), String.class.getCanonicalName() });
+
+ checkMethod(port, DiskStoreMXBean.class, diskStoreON, "flush", null, ResourceOperationCode.FLUSH_DISKSTORE);
+
+ checkMethod(port, DiskStoreMXBean.class, diskStoreON, "forceRoll", null, ResourceOperationCode.FORCE_ROLL);
+
+ checkMethod(port, DiskStoreMXBean.class, diskStoreON, "forceCompaction", null,
+ ResourceOperationCode.FORCE_COMPACTION);
+
+ checkMethod(port, DiskStoreMXBean.class, diskStoreON, "isAutoCompact", null, ResourceOperationCode.LIST_DS);
+
+ checkSetAttribute(port, diskStoreON, "DiskUsageWarningPercentage", 0.78f,
+ ResourceOperationCode.SET_DISK_USAGE);
+
+ checkAttributes(port, DiskStoreMXBean.class, diskStoreON, new String[] { "MaxOpLogSize", "TimeInterval",
+ "WriteBufferSize", "DiskDirectories" , "AutoCompact", "CompactionThreshold" });
+ }
+
+ private void doTestMemberMXBean(int port) throws IOException, InstanceNotFoundException, MBeanException,
+ ReflectionException {
+ ObjectName distrSysON = MBeanJMXAdapter.getDistributedSystemName();
+ MBeanServerConnection conn = connector.getMBeanServerConnection();
+ ObjectName memberON = (ObjectName) conn.invoke(MBeanJMXAdapter.getDistributedSystemName(), "fetchMemberObjectName",
+ new Object[] { "testGemfireMBeans" }, new String[] { String.class.getCanonicalName() });
+
+ checkMethod(port, MemberMXBean.class, memberON, "showLog", new Object[] { 10 }, ResourceOperationCode.SHOW_LOG);
+
+ checkMethod(port, MemberMXBean.class, memberON, "viewLicense", null, ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, MemberMXBean.class, memberON, "compactAllDiskStores", null,
+ ResourceOperationCode.COMPACT_DISKSTORE);
+
+ checkMethod(port, MemberMXBean.class, memberON, "showJVMMetrics", null, ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, MemberMXBean.class, memberON, "showOSMetrics", null, ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, MemberMXBean.class, memberON, "listDiskStores", new Object[] { true },
+ ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, MemberMXBean.class, memberON, "listGemFireProperties", null, ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, MemberMXBean.class, memberON, "status", null, ResourceOperationCode.LIST_DS);
+ }
+
+ private void doTestDistributedSystemMXBean(int port) throws IOException {
+ ObjectName distrSysON = MBeanJMXAdapter.getDistributedSystemName();
+ checkMethod(port, DistributedSystemMXBean.class, distrSysON, "listMembers", null, ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, DistributedSystemMXBean.class, distrSysON, "changeAlertLevel", new Object[] { "error" },
+ ResourceOperationCode.CHANGE_ALERT_LEVEL);
+
+ checkMethod(port, DistributedSystemMXBean.class, distrSysON, "backupAllMembers", new Object[] { "error", "error" },
+ ResourceOperationCode.BACKUP_MEMBERS);
+
+ checkMethod(port, DistributedSystemMXBean.class, distrSysON, "showJVMMetrics", new Object[] { "memberName" },
+ ResourceOperationCode.LIST_DS);
+
+ checkMethod(port, DistributedSystemMXBean.class, distrSysON, "revokeMissingDiskStores",
+ new Object[] { "diskStoreId" }, ResourceOperationCode.REVOKE_MISSING_DISKSTORE);
+
+ checkMethod(port, DistributedSystemMXBean.class, distrSysON, "queryData", new Object[] { "queryString", "mmebers",
+ 10 }, ResourceOperationCode.QUERY);
+
+ checkMethod(port, DistributedSystemMXBean.class, distrSysON, "setQueryResultSetLimit", new Object[] { 10 },
+ ResourceOperationCode.QUERY);
+
+ checkMethod(port, DistributedSystemMXBean.class, distrSysON, "setQueryCollectionsDepth", new Object[] { 10 },
+ ResourceOperationCode.QUERY);
+ }
+
+ private void checkMethod(int port, Class<?> mxBean, ObjectName mbeanObjectName, String methodName, Object[] args,
+ ResourceOperationCode opCode) throws IOException {
+ if (connector == null)
+ connector = getGemfireMBeanServer(port, USER, PASSWORD);
+ MBeanServerConnection conn = connector.getMBeanServerConnection();
+ Object proxy = JMX.newMXBeanProxy(conn, mbeanObjectName, mxBean);
+ if (ResourceOperationCode.LIST_DS.equals(opCode)) {
+ testObject(proxy, methodName, args, false);
+ } else {
+ if (TestAccessControl.hasAccessToResourceOp(USER, opCode)) {
+ boolean removed = TestAccessControl.revokeResourceOp(USER, opCode);
+ if (!removed)
+ fail("Fail to removed opCode " + opCode);
+ }
+ testObject(proxy, methodName, args, true);
+ TestAccessControl.grantResourceOp(USER, opCode);
+ Log.getLogWriter().info("Grant opCode " + opCode);
+ testObject(proxy, methodName, args, false);
+ boolean removed = TestAccessControl.revokeResourceOp(USER, opCode);
+ if (!removed)
+ fail("Fail to removed opCode " + opCode);
+ else
+ Log.getLogWriter().info("Revoke opCode " + opCode);
+
+ }
+ }
+
+ private void checkAttributes(int port, Class<?> mxBean, ObjectName mbeanObjectName, String[] attrs)
+ throws IOException, InstanceNotFoundException, ReflectionException {
+ if (connector == null)
+ connector = getGemfireMBeanServer(port, USER, PASSWORD);
+ MBeanServerConnection conn = connector.getMBeanServerConnection();
+ try {
+ AttributeList list = conn.getAttributes(mbeanObjectName, attrs);
+ assertNotNull(list);
+ assertEquals(list.size(), attrs.length);
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("Unexpected exception " + e.getMessage());
+ } finally {
+
+ }
+
+ //Try individual attribute to test getAttribute hook
+ try {
+ for (String attr : attrs) {
+ conn.getAttribute(mbeanObjectName, attr);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("Unexpected exception " + e.getMessage());
+ } finally {
+
+ }
+
+ }
+
+ private void checkSetAttribute(int port, ObjectName mbeanObjectName, String attr, Object value,
+ ResourceOperationCode opcode) throws IOException, InstanceNotFoundException, AttributeNotFoundException,
+ InvalidAttributeValueException, MBeanException, ReflectionException {
+ if (connector == null)
+ connector = getGemfireMBeanServer(port, USER, PASSWORD);
+ MBeanServerConnection conn = connector.getMBeanServerConnection();
+ try {
+ Attribute attribute = new Attribute(attr, value);
+ conn.setAttribute(mbeanObjectName, attribute);
+ if (!opcode.equals(ResourceOperationCode.LIST_DS))
+ fail("SetAttribute suceeded without Access to " + opcode);
+ } catch (SecurityException e) {
+ // expected
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("Unexpected Exception " + e.getMessage());
+ }
+
+ if (!opcode.equals(ResourceOperationCode.LIST_DS)) {
+ try {
+ TestAccessControl.grantResourceOp(USER, opcode);
+ Attribute attribute = new Attribute(attr, value);
+ conn.setAttribute(mbeanObjectName, attribute);
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ fail("Unexpected SecurityException " + e.getMessage());
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("Unexpected Exception " + e.getMessage());
+ } finally {
+ TestAccessControl.revokeResourceOp(USER, opcode);
+ }
+ }
+
+ }
+
+ private void testObject(Object proxy, String methodName, Object[] args, boolean securityExceptionExpected) {
+ Method mt = null;
+ for (Method mts : proxy.getClass().getMethods()) {
+ if (mts.getName().equals(methodName)) {
+ mt = mts;
+ }
+ }
+ try {
+ Log.getLogWriter().info("Invoking method " + methodName);
+ mt.invoke(proxy, args);
+ if (securityExceptionExpected)
+ fail("Expected call to method " + methodName + " was expected to fail with security exception");
+ Log.getLogWriter().info("Successfully Invoked method " + methodName);
+ } catch (IllegalAccessException e) {
+ error("UnExpected error ", e);
+ fail(e.getMessage());
+ } catch (IllegalArgumentException e) {
+ error("UnExpected error ", e);
+ fail(e.getMessage());
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getCause();
+ if (t instanceof SecurityException) {
+ if (!securityExceptionExpected) {
+ fail("Did not expect call to method " + methodName + " to fail with security exception");
+ }
+ } else {
+ // other errors are expected as wrong parameters are passed
+ // error("UnExpected error ", e);
+ // fail(e.getMessage());
+ }
+ } catch (SecurityException e) {
+ if (!securityExceptionExpected) {
+ fail("Did not expect call to method " + methodName + " to fail with security exception");
+ }
+ }
+ }
+
+ private void error(String string, Exception e) {
+ System.out.println(string);
+ e.printStackTrace();
+ }
+
+ private JMXConnector getGemfireMBeanServer(int port, String user, String pwd) {
+ String[] creds = null;
+ if (user != null)
+ creds = new String[] { user, pwd };
+ return _getGemfireMBeanServer(port, creds);
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private JMXConnector _getGemfireMBeanServer(int port, Object creds) {
+ JMXServiceURL url;
+ try {
+ url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:" + port + "/jmxrmi");
+ if (creds != null) {
+ Map env = new HashMap();
+ env.put(JMXConnector.CREDENTIALS, creds);
+ JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
+ return jmxc;
+ } else {
+ JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
+ return jmxc;
+ }
+ } catch (MalformedURLException e) {
+ fail("Error connecting to port=" + port + " " + e.getMessage());
+ } catch (IOException e) {
+ fail("Error connecting to port=" + port + " " + e.getMessage());
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3f931bab/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/ResultHandler.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/ResultHandler.java b/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/ResultHandler.java
new file mode 100644
index 0000000..ab3c9ef
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/ResultHandler.java
@@ -0,0 +1,7 @@
+package com.gemstone.gemfire.management.internal.security;
+
+public interface ResultHandler {
+
+ void handleExecutionResult(Object result, String sysout);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3f931bab/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/TestAccessControl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/TestAccessControl.java b/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/TestAccessControl.java
new file mode 100644
index 0000000..e777b0c
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/TestAccessControl.java
@@ -0,0 +1,130 @@
+package com.gemstone.gemfire.management.internal.security;
+
+import hydra.Log;
+
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.operations.OperationContext;
+import com.gemstone.gemfire.cache.operations.OperationContext.OperationCode;
+import com.gemstone.gemfire.distributed.DistributedMember;
+import com.gemstone.gemfire.management.internal.security.ResourceOperationContext.ResourceOperationCode;
+import com.gemstone.gemfire.security.AccessControl;
+import com.gemstone.gemfire.security.NotAuthorizedException;
+
+public class TestAccessControl implements AccessControl {
+
+ private Principal principal=null;
+
+ public static Map<String,Set<ResourceOperationCode>> resourceOpCodeMap = new HashMap<String,Set<ResourceOperationCode>>();
+ public static Map<String,Set<OperationCode>> opCodeMap = new HashMap<String,Set<OperationCode>>();
+
+ public static void grantResourceOp(String user, ResourceOperationCode code) {
+ Set<ResourceOperationCode> list = resourceOpCodeMap.get(user);
+ if(list==null) {
+ list = new HashSet<ResourceOperationCode>();
+ resourceOpCodeMap.put(user,list);
+ }
+ list.add(code);
+ }
+
+ public static void grantCacheOp(String user, OperationCode code) {
+ Set<OperationCode> list = opCodeMap.get(user);
+ if(list==null) {
+ list = new HashSet<OperationCode>();
+ opCodeMap.put(user,list);
+ }
+ list.add(code);
+ }
+
+ public static boolean hasAccessToResourceOp(String user, ResourceOperationCode code) {
+ Set<ResourceOperationCode> list = resourceOpCodeMap.get(user);
+ return list.contains(code);
+ }
+
+ public static boolean revokeCacheOp(String user, OperationCode code) {
+ Set<OperationCode> list = opCodeMap.get(user);
+ boolean removed = list.remove(code);
+
+ if (!removed) {
+ Log.getLogWriter().warning("Code " + code + " was not found for REVOKE access");
+ }
+ return removed;
+ }
+
+ public static boolean revokeResourceOp(String user, ResourceOperationCode code) {
+ Set<ResourceOperationCode> list = resourceOpCodeMap.get(user);
+ boolean removed = list.remove(code);
+ if (!removed) {
+ Log.getLogWriter().warning("Code " + code + " was not found for REVOKE access");
+ }
+ return removed;
+ }
+
+ public static AccessControl create(){
+ return new TestAccessControl();
+ }
+
+ @Override
+ public void close() {
+
+ }
+
+ @Override
+ public void init(Principal principal, DistributedMember remoteMember, Cache cache) throws NotAuthorizedException {
+ this.principal = principal;
+ }
+
+ @Override
+ public boolean authorizeOperation(String regionName, OperationContext context) {
+ Log.getLogWriter().info("Context Received " + context);
+ Log.getLogWriter().info("Principal " + principal.getName());
+ boolean flag = false;
+ if (!context.getOperationCode().equals(OperationCode.RESOURCE)) {
+ if (opCodeMap.containsKey(principal.getName())) {
+ Set<OperationCode> codes = opCodeMap.get(principal.getName());
+ for (OperationCode code : codes) {
+ Log.getLogWriter().info("Checking OpCode=" + code);
+ flag = code.equals(context.getOperationCode());
+ if (flag) {
+ Log.getLogWriter().info("For Principal " + principal.getName() + " Found Granted CacheOp=" + code);
+ break;
+ }
+ }
+ }
+
+ if (flag) {
+ return true;
+ }
+ } else {
+ if (resourceOpCodeMap.containsKey(principal.getName())) {
+ Set<ResourceOperationCode> codes = resourceOpCodeMap.get(principal.getName());
+ ResourceOperationContext ctx = (ResourceOperationContext) context;
+ flag = false;
+ for (ResourceOperationCode code : codes) {
+ Log.getLogWriter().info("Checking ResourceOpCode=" + code);
+ flag = code.allowedOp(ctx.getResourceOperationCode());
+ if (flag) {
+ Log.getLogWriter().info("For Principal " + principal.getName() + " Found Granted ResourceOp=" + code);
+ return true;
+ }
+ }
+ Log.getLogWriter().info("For Principal " + principal.getName() + " authorizeOperation failed");
+ return false;
+ } else {
+ Log.getLogWriter().info("For Principal " + principal.getName() + " authorizeOperation failed");
+ return false;
+ }
+ }
+ Log.getLogWriter().info("For Principal " + principal.getName() + " authorizeOperation failed");
+ return false;
+ }
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3f931bab/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/TestAuthenticator.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/TestAuthenticator.java b/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/TestAuthenticator.java
new file mode 100644
index 0000000..0eae45f
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/management/internal/security/TestAuthenticator.java
@@ -0,0 +1,50 @@
+package com.gemstone.gemfire.management.internal.security;
+
+import hydra.Log;
+
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import com.gemstone.gemfire.LogWriter;
+import com.gemstone.gemfire.distributed.DistributedMember;
+import com.gemstone.gemfire.management.internal.security.ResourceOperationJUnit.TestUsernamePrincipal;
+import com.gemstone.gemfire.security.AuthenticationFailedException;
+import com.gemstone.gemfire.security.Authenticator;
+
+public class TestAuthenticator implements Authenticator {
+
+ public static Map<String,String> userRepo = new HashMap<String,String>();
+
+ public static void addUser(String user, String password) {
+ userRepo.put(user, password);
+ }
+
+ public static Authenticator create() {
+ return new TestAuthenticator();
+ }
+
+ @Override
+ public void close() {
+
+
+ }
+
+ @Override
+ public void init(Properties securityProps, LogWriter systemLogger, LogWriter securityLogger)
+ throws AuthenticationFailedException {
+ }
+
+ @Override
+ public Principal authenticate(Properties props, DistributedMember member) throws AuthenticationFailedException {
+ String user = props.getProperty(ResourceConstants.USER_NAME);
+ String pwd = props.getProperty(ResourceConstants.PASSWORD);
+ if (user != null && userRepo.containsKey(user) && pwd != null && pwd.equals(userRepo.get(user))) {
+ Log.getLogWriter().info("Authentication successful!! for " + user);
+ return new TestUsernamePrincipal(user);
+ } else
+ throw new AuthenticationFailedException("Wrong username/password");
+ }
+
+}