You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2016/05/03 23:51:53 UTC
[04/50] [abbrv] incubator-geode git commit: GEODE-17: Shiro
Integration
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/AbstractCommandsController.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/AbstractCommandsController.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/AbstractCommandsController.java
index 806e926..211d0b1 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/AbstractCommandsController.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/AbstractCommandsController.java
@@ -25,8 +25,8 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-import java.util.Properties;
import java.util.Set;
+import java.util.concurrent.Callable;
import javax.management.JMX;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
@@ -47,10 +47,10 @@ import com.gemstone.gemfire.management.internal.ManagementConstants;
import com.gemstone.gemfire.management.internal.SystemManagementService;
import com.gemstone.gemfire.management.internal.cli.shell.Gfsh;
import com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder;
-import com.gemstone.gemfire.management.internal.security.MBeanServerWrapper;
import com.gemstone.gemfire.management.internal.web.controllers.support.EnvironmentVariablesHandlerInterceptor;
import com.gemstone.gemfire.management.internal.web.controllers.support.MemberMXBeanAdapter;
import com.gemstone.gemfire.management.internal.web.util.UriUtils;
+import com.gemstone.gemfire.security.ShiroUtil;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.propertyeditors.StringArrayPropertyEditor;
import org.springframework.http.HttpStatus;
@@ -434,17 +434,11 @@ public abstract class AbstractCommandsController {
SystemManagementService service = (SystemManagementService) ManagementService
.getExistingManagementService(GemFireCacheImpl.getInstance());
MBeanServer mbs = getMBeanServer();
- MBeanServerWrapper wrapper = service.getManagementAgent().getMBeanServerWrapper();
- MBeanServer wrappedMbs = mbs;
- if(wrapper!=null) {
- wrapper.setMBeanServer(mbs);
- wrappedMbs = wrapper;
- }
- final DistributedSystemMXBean distributedSystemMXBean = JMX.newMXBeanProxy(wrappedMbs,
+ final DistributedSystemMXBean distributedSystemMXBean = JMX.newMXBeanProxy(mbs,
MBeanJMXAdapter.getDistributedSystemName(), DistributedSystemMXBean.class);
- managingMemberMXBeanProxy = createMemberMXBeanForManagerUsingProxy(wrappedMbs,
+ managingMemberMXBeanProxy = createMemberMXBeanForManagerUsingProxy(mbs,
distributedSystemMXBean.getMemberObjectName());
}
@@ -554,14 +548,20 @@ public abstract class AbstractCommandsController {
protected String processCommand(final String command) {
return processCommand(command, getEnvironment(), null);
}
+ protected Callable<ResponseEntity<String>> getProcessCommandCallable(final String command){
+ return getProcessCommandCallable(command, null);
+ }
- protected String processCommandWithCredentials(final String command, Properties credentials) {
- if (credentials != null) {
- EnvironmentVariablesHandlerInterceptor.CREDENTIALS.set(credentials);
- }
- return processCommand(command, getEnvironment(), null);
+ protected Callable<ResponseEntity<String>> getProcessCommandCallable(final String command, final byte[][] fileData){
+ Callable callable = new Callable<ResponseEntity<String>>() {
+ @Override public ResponseEntity<String> call() throws Exception {
+ return new ResponseEntity<String>(processCommand(command, fileData), HttpStatus.OK);
+ }
+ };
+ return ShiroUtil.associateWith(callable);
}
+
/**
* Executes the specified command as entered by the user using the GemFire Shell (Gfsh). Note, Gfsh performs
* validation of the command during parsing before sending the command to the Manager for processing.
@@ -579,13 +579,6 @@ public abstract class AbstractCommandsController {
return processCommand(command, getEnvironment(), fileData);
}
- protected String processCommandWithCredentials(final String command, final byte[][] fileData, Properties credentials) {
- if (credentials != null) {
- EnvironmentVariablesHandlerInterceptor.CREDENTIALS.set(credentials);
- }
- return processCommand(command, getEnvironment(), fileData);
- }
-
/**
* Executes the specified command as entered by the user using the GemFire Shell (Gfsh). Note, Gfsh performs
* validation of the command during parsing before sending the command to the Manager for processing.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/ConfigCommandsController.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/ConfigCommandsController.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/ConfigCommandsController.java
index 892833f..fa0f8e9 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/ConfigCommandsController.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/ConfigCommandsController.java
@@ -17,16 +17,12 @@
package com.gemstone.gemfire.management.internal.web.controllers;
import java.io.IOException;
-import java.util.Properties;
import java.util.concurrent.Callable;
import com.gemstone.gemfire.internal.lang.StringUtils;
import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings;
import com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder;
-import com.gemstone.gemfire.management.internal.web.controllers.support.EnvironmentVariablesHandlerInterceptor;
import com.gemstone.gemfire.management.internal.web.util.ConvertUtils;
-
-import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
@@ -170,13 +166,7 @@ public class ConfigCommandsController extends AbstractMultiPartCommandsControlle
command.addOption(CliStrings.EXPORT_CONFIG__DIR, decode(directory));
}
- final Properties credentials = EnvironmentVariablesHandlerInterceptor.CREDENTIALS.get();
-
- return new Callable<ResponseEntity<String>>() {
- @Override public ResponseEntity<String> call() throws Exception {
- return new ResponseEntity<String>(processCommandWithCredentials(command.toString(), credentials), HttpStatus.OK);
- }
- };
+ return getProcessCommandCallable(command.toString());
}
@RequestMapping(method = RequestMethod.GET, value = "/config/cluster")
@@ -191,13 +181,7 @@ public class ConfigCommandsController extends AbstractMultiPartCommandsControlle
command.addOption(CliStrings.EXPORT_SHARED_CONFIG__DIR, directory);
}
- final Properties credentials = EnvironmentVariablesHandlerInterceptor.CREDENTIALS.get();
-
- return new Callable<ResponseEntity<String>>() {
- @Override public ResponseEntity<String> call() throws Exception {
- return new ResponseEntity<String>(processCommandWithCredentials(command.toString(), credentials), HttpStatus.OK);
- }
- };
+ return getProcessCommandCallable(command.toString());
}
@RequestMapping(method = RequestMethod.POST, value = "/config/cluster")
@@ -209,13 +193,7 @@ public class ConfigCommandsController extends AbstractMultiPartCommandsControlle
command.addOption(CliStrings.IMPORT_SHARED_CONFIG__ZIP, zipFileName);
- final Properties credentials = EnvironmentVariablesHandlerInterceptor.CREDENTIALS.get();
-
- return new Callable<ResponseEntity<String>>() {
- @Override public ResponseEntity<String> call() throws Exception {
- return new ResponseEntity<String>(processCommandWithCredentials(command.toString(), ConvertUtils.convert(zipFileResources), credentials), HttpStatus.OK);
- }
- };
+ return getProcessCommandCallable(command.toString(), ConvertUtils.convert(zipFileResources));
}
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/DataCommandsController.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/DataCommandsController.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/DataCommandsController.java
index c04ce4a..91004b3 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/DataCommandsController.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/DataCommandsController.java
@@ -16,15 +16,11 @@
*/
package com.gemstone.gemfire.management.internal.web.controllers;
-import java.util.Properties;
import java.util.concurrent.Callable;
import com.gemstone.gemfire.internal.lang.StringUtils;
import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings;
import com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder;
-import com.gemstone.gemfire.management.internal.web.controllers.support.EnvironmentVariablesHandlerInterceptor;
-
-import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
@@ -139,13 +135,7 @@ public class DataCommandsController extends AbstractCommandsController {
command.addOption(CliStrings.EXPORT_DATA__REGION, decode(regionNamePath));
command.addOption(CliStrings.EXPORT_DATA__FILE, decode(file));
- final Properties credentials = EnvironmentVariablesHandlerInterceptor.CREDENTIALS.get();
-
- return new Callable<ResponseEntity<String>>() {
- @Override public ResponseEntity<String> call() throws Exception {
- return new ResponseEntity<String>(processCommandWithCredentials(command.toString(), credentials), HttpStatus.OK);
- }
- };
+ return getProcessCommandCallable(command.toString());
}
@RequestMapping(method = RequestMethod.POST, value = "/members/{member}/regions/{region}/data")
@@ -159,13 +149,7 @@ public class DataCommandsController extends AbstractCommandsController {
command.addOption(CliStrings.IMPORT_DATA__REGION, decode(regionNamePath));
command.addOption(CliStrings.IMPORT_DATA__FILE, decode(file));
- final Properties credentials = EnvironmentVariablesHandlerInterceptor.CREDENTIALS.get();
-
- return new Callable<ResponseEntity<String>>() {
- @Override public ResponseEntity<String> call() throws Exception {
- return new ResponseEntity<String>(processCommandWithCredentials(command.toString(), credentials), HttpStatus.OK);
- }
- };
+ return getProcessCommandCallable(command.toString());
}
@RequestMapping(method = RequestMethod.GET, value = "/regions/{region}/data/location")
@@ -208,13 +192,7 @@ public class DataCommandsController extends AbstractCommandsController {
command.addOption(CliStrings.QUERY__STEPNAME, stepName);
command.addOption(CliStrings.QUERY__INTERACTIVE, String.valueOf(Boolean.TRUE.equals(interactive)));
- final Properties credentials = EnvironmentVariablesHandlerInterceptor.CREDENTIALS.get();
-
- return new Callable<ResponseEntity<String>>() {
- @Override public ResponseEntity<String> call() throws Exception {
- return new ResponseEntity<String>(processCommandWithCredentials(command.toString(), credentials), HttpStatus.OK);
- }
- };
+ return getProcessCommandCallable(command.toString());
}
@RequestMapping(method = RequestMethod.POST, value = "/regions/data", params = "op=rebalance")
@@ -238,13 +216,7 @@ public class DataCommandsController extends AbstractCommandsController {
command.addOption(CliStrings.REBALANCE__SIMULATE, String.valueOf(simulate));
command.addOption(CliStrings.REBALANCE__TIMEOUT, String.valueOf(timeout));
- final Properties credentials = EnvironmentVariablesHandlerInterceptor.CREDENTIALS.get();
-
- return new Callable<ResponseEntity<String>>() {
- public ResponseEntity<String> call() throws Exception {
- return new ResponseEntity<String>(processCommandWithCredentials(command.toString(), credentials), HttpStatus.OK);
- }
- };
+ return getProcessCommandCallable(command.toString());
}
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/DiskStoreCommandsController.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/DiskStoreCommandsController.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/DiskStoreCommandsController.java
index d90cf88..d99909e 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/DiskStoreCommandsController.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/DiskStoreCommandsController.java
@@ -16,15 +16,11 @@
*/
package com.gemstone.gemfire.management.internal.web.controllers;
-import java.util.Properties;
import java.util.concurrent.Callable;
import com.gemstone.gemfire.internal.lang.StringUtils;
import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings;
import com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder;
-import com.gemstone.gemfire.management.internal.web.controllers.support.EnvironmentVariablesHandlerInterceptor;
-
-import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
@@ -70,13 +66,7 @@ public class DiskStoreCommandsController extends AbstractCommandsController {
command.addOption(CliStrings.BACKUP_DISK_STORE__BASELINEDIR, decode(baselineDir));
}
- final Properties credentials = EnvironmentVariablesHandlerInterceptor.CREDENTIALS.get();
-
- return new Callable<ResponseEntity<String>>() {
- @Override public ResponseEntity<String> call() throws Exception {
- return new ResponseEntity<String>(processCommandWithCredentials(command.toString(), credentials), HttpStatus.OK);
- }
- };
+ return getProcessCommandCallable(command.toString());
}
@RequestMapping(method = RequestMethod.POST, value = "/diskstores/{name}", params = "op=compact")
@@ -91,13 +81,7 @@ public class DiskStoreCommandsController extends AbstractCommandsController {
command.addOption(CliStrings.COMPACT_DISK_STORE__GROUP, StringUtils.concat(groups, StringUtils.COMMA_DELIMITER));
}
- final Properties credentials = EnvironmentVariablesHandlerInterceptor.CREDENTIALS.get();
-
- return new Callable<ResponseEntity<String>>() {
- @Override public ResponseEntity<String> call() throws Exception {
- return new ResponseEntity<String>(processCommandWithCredentials(command.toString(), credentials), HttpStatus.OK);
- }
- };
+ return getProcessCommandCallable(command.toString());
}
@RequestMapping(method = RequestMethod.POST, value = "/diskstores")
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/FunctionCommandsController.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/FunctionCommandsController.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/FunctionCommandsController.java
index da214a2..e8cee1d 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/FunctionCommandsController.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/FunctionCommandsController.java
@@ -16,15 +16,11 @@
*/
package com.gemstone.gemfire.management.internal.web.controllers;
-import java.util.Properties;
import java.util.concurrent.Callable;
import com.gemstone.gemfire.internal.lang.StringUtils;
import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings;
import com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder;
-import com.gemstone.gemfire.management.internal.web.controllers.support.EnvironmentVariablesHandlerInterceptor;
-
-import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
@@ -111,15 +107,7 @@ public class FunctionCommandsController extends AbstractCommandsController {
if (hasValue(resultCollector)) {
command.addOption(CliStrings.EXECUTE_FUNCTION__RESULTCOLLECTOR, resultCollector);
}
-
-
- final Properties credentials = EnvironmentVariablesHandlerInterceptor.CREDENTIALS.get();
-
- return new Callable<ResponseEntity<String>>() {
- @Override public ResponseEntity<String> call() throws Exception {
- return new ResponseEntity<String>(processCommandWithCredentials(command.toString(), credentials), HttpStatus.OK);
- }
- };
+ return getProcessCommandCallable(command.toString());
}
@RequestMapping(method = RequestMethod.DELETE, value = "/functions/{id}")
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/MiscellaneousCommandsController.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/MiscellaneousCommandsController.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/MiscellaneousCommandsController.java
index 68917a9..2326109 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/MiscellaneousCommandsController.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/MiscellaneousCommandsController.java
@@ -16,15 +16,11 @@
*/
package com.gemstone.gemfire.management.internal.web.controllers;
-import java.util.Properties;
import java.util.concurrent.Callable;
import com.gemstone.gemfire.internal.lang.StringUtils;
import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings;
import com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder;
-import com.gemstone.gemfire.management.internal.web.controllers.support.EnvironmentVariablesHandlerInterceptor;
-
-import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
@@ -89,13 +85,7 @@ public class MiscellaneousCommandsController extends AbstractCommandsController
command.addOption(CliStrings.EXPORT_LOGS__ENDTIME, endTime);
}
- final Properties credentials = EnvironmentVariablesHandlerInterceptor.CREDENTIALS.get();
-
- return new Callable<ResponseEntity<String>>() {
- @Override public ResponseEntity<String> call() throws Exception {
- return new ResponseEntity<String>(processCommandWithCredentials(command.toString(), credentials), HttpStatus.OK);
- }
- };
+ return getProcessCommandCallable(command.toString());
}
// TODO determine whether Async functionality is required
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/support/EnvironmentVariablesHandlerInterceptor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/support/EnvironmentVariablesHandlerInterceptor.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/support/EnvironmentVariablesHandlerInterceptor.java
index 569440d..34cf380 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/support/EnvironmentVariablesHandlerInterceptor.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/support/EnvironmentVariablesHandlerInterceptor.java
@@ -16,26 +16,21 @@
*/
package com.gemstone.gemfire.management.internal.web.controllers.support;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
import com.gemstone.gemfire.cache.Cache;
-import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
import com.gemstone.gemfire.internal.logging.LogService;
-import com.gemstone.gemfire.management.ManagementService;
-import com.gemstone.gemfire.management.internal.SystemManagementService;
-import com.gemstone.gemfire.management.internal.security.ManagementInterceptor;
+import com.gemstone.gemfire.management.internal.security.ResourceConstants;
import com.gemstone.gemfire.security.Authenticator;
+import com.gemstone.gemfire.security.ShiroUtil;
import org.apache.logging.log4j.Logger;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Properties;
-
/**
* The GetEnvironmentHandlerInterceptor class handles extracting Gfsh environment variables encoded in the HTTP request
* message as request parameters.
@@ -54,10 +49,6 @@ public class EnvironmentVariablesHandlerInterceptor extends HandlerInterceptorAd
private Authenticator auth = null;
-
- public static final ThreadLocal<Properties> CREDENTIALS = new ThreadLocal<Properties>();
-
-
private static final ThreadLocal<Map<String, String>> ENV = new ThreadLocal<Map<String, String>>() {
@Override
protected Map<String, String> initialValue() {
@@ -100,7 +91,9 @@ public class EnvironmentVariablesHandlerInterceptor extends HandlerInterceptorAd
}
- securityCheck(requestParameterValues);
+ String username = requestParameterValues.get(ResourceConstants.USER_NAME);
+ String password = requestParameterValues.get(ResourceConstants.PASSWORD);
+ ShiroUtil.login(username, password);
ENV.set(requestParameterValues);
@@ -108,37 +101,6 @@ public class EnvironmentVariablesHandlerInterceptor extends HandlerInterceptorAd
}
-
- protected void securityCheck(final Map<String, String> environment) {
-
- Properties credentials = new Properties();
-
- Iterator<Entry<String, String>> it = environment.entrySet().iterator();
- while (it.hasNext()) {
- Entry<String, String> entry = it.next();
- if (entry.getKey().startsWith(SECURITY_VARIABLE_REQUEST_HEADER_PREFIX)) {
- credentials.put(entry.getKey(), entry.getValue());
- }
-
- }
-
- GemFireCacheImpl instance = GemFireCacheImpl.getInstance();
- if(instance != null){
- SystemManagementService service = (SystemManagementService) ManagementService
- .getExistingManagementService(instance);
-
- ManagementInterceptor interceptor = service.getManagementAgent().getManagementInterceptor();
- if(interceptor!=null) {
- interceptor.authenticate(credentials);
- }
- CREDENTIALS.set(credentials);
- }
-
-
- }
-
-
-
@Override
public void afterCompletion(final HttpServletRequest request,
final HttpServletResponse response,
@@ -146,16 +108,6 @@ public class EnvironmentVariablesHandlerInterceptor extends HandlerInterceptorAd
final Exception ex)
throws Exception
{
- afterConcurrentHandlingStarted(request, response, handler);
+ ShiroUtil.logout();
}
-
- @Override
- public void afterConcurrentHandlingStarted(final HttpServletRequest request,
- final HttpServletResponse response,
- final Object handler)
- throws Exception
- {
- ENV.remove();
- }
-
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/main/java/com/gemstone/gemfire/security/CustomAuthRealm.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/security/CustomAuthRealm.java b/geode-core/src/main/java/com/gemstone/gemfire/security/CustomAuthRealm.java
new file mode 100644
index 0000000..3028f0b
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/security/CustomAuthRealm.java
@@ -0,0 +1,173 @@
+/*
+ * 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.management.internal.security.ResourceConstants.*;
+
+import java.lang.reflect.Method;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Principal;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.management.remote.JMXPrincipal;
+import javax.security.auth.Subject;
+
+import com.gemstone.gemfire.cache.operations.OperationContext;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.internal.ClassLoadUtil;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.lang.StringUtils;
+import com.gemstone.gemfire.management.internal.security.ResourceConstants;
+import com.gemstone.gemfire.management.internal.security.ResourceOperationContext;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.SimpleAuthenticationInfo;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.authz.AuthorizationInfo;
+import org.apache.shiro.authz.Permission;
+import org.apache.shiro.realm.AuthorizingRealm;
+import org.apache.shiro.subject.PrincipalCollection;
+
+public class CustomAuthRealm extends AuthorizingRealm{
+ public static final String REALM_NAME = "CUSTOMAUTHREALM";
+
+ private static final Logger logger = LogManager.getLogger(CustomAuthRealm.class);
+ private String authzFactoryName;
+ private String postAuthzFactoryName;
+ private String authenticatorFactoryName;
+ private Properties securityProps = null;
+ private ConcurrentMap<Principal, AccessControl> cachedAuthZCallback;
+ private ConcurrentMap<Principal, AccessControl> cachedPostAuthZCallback;
+
+ public CustomAuthRealm(Properties securityProps) {
+ this.securityProps = securityProps;
+ this.authzFactoryName = securityProps.getProperty(DistributionConfig.SECURITY_CLIENT_ACCESSOR_NAME);
+ this.postAuthzFactoryName = securityProps.getProperty(DistributionConfig.SECURITY_CLIENT_ACCESSOR_PP_NAME);
+ this.authenticatorFactoryName = securityProps.getProperty(DistributionConfig.SECURITY_CLIENT_AUTHENTICATOR_NAME);
+ this.cachedAuthZCallback = new ConcurrentHashMap<>();
+ this.cachedPostAuthZCallback = new ConcurrentHashMap<>();
+ logger.info("Started Management interceptor on JMX connector");
+ }
+
+ @Override
+ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
+ UsernamePasswordToken authToken = (UsernamePasswordToken) token;
+ String username = authToken.getUsername();
+ String password = new String(authToken.getPassword());
+
+ Properties credentialProps = new Properties();
+ credentialProps.put(ResourceConstants.USER_NAME, username);
+ credentialProps.put(ResourceConstants.PASSWORD, password);
+
+ Principal principal = getAuthenticator(securityProps).authenticate(credentialProps);
+
+ return new SimpleAuthenticationInfo(principal, authToken.getPassword(), REALM_NAME);
+ }
+
+
+ @Override
+ protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
+ // we intercepted the call to this method by overriding the isPermitted call
+ return null;
+ }
+
+ @Override
+ public boolean isPermitted(PrincipalCollection principals, Permission permission) {
+ ResourceOperationContext context =(ResourceOperationContext)permission;
+ Principal principal = (Principal)principals.getPrimaryPrincipal();
+
+ AccessControl accessControl = getAccessControl(principal, false);
+ return accessControl.authorizeOperation(null, context);
+ }
+
+ public AccessControl getAccessControl(Principal principal, boolean isPost) {
+ if (!isPost) {
+ if (cachedAuthZCallback.containsKey(principal)) {
+ return cachedAuthZCallback.get(principal);
+ } else if (!StringUtils.isBlank(authzFactoryName)) {
+ try {
+ Method authzMethod = ClassLoadUtil.methodFromName(authzFactoryName);
+ AccessControl authzCallback = (AccessControl) authzMethod.invoke(null, (Object[]) null);
+ authzCallback.init(principal, null);
+ cachedAuthZCallback.put(principal, authzCallback);
+ return authzCallback;
+ } catch (Exception ex) {
+ throw new AuthenticationFailedException(
+ LocalizedStrings.HandShake_FAILED_TO_ACQUIRE_AUTHENTICATOR_OBJECT.toLocalizedString(), ex);
+ }
+ }
+ } else {
+ if (cachedPostAuthZCallback.containsKey(principal)) {
+ return cachedPostAuthZCallback.get(principal);
+ } else if (!StringUtils.isBlank(postAuthzFactoryName)) {
+ try {
+ Method authzMethod = ClassLoadUtil.methodFromName(postAuthzFactoryName);
+ AccessControl postAuthzCallback = (AccessControl) authzMethod.invoke(null, (Object[]) null);
+ postAuthzCallback.init(principal, null);
+ cachedPostAuthZCallback.put(principal, postAuthzCallback);
+ return postAuthzCallback;
+ } catch (Exception ex) {
+ throw new AuthenticationFailedException(
+ LocalizedStrings.HandShake_FAILED_TO_ACQUIRE_AUTHENTICATOR_OBJECT.toLocalizedString(), ex);
+ }
+ }
+ }
+ return null;
+ }
+
+ private Authenticator getAuthenticator(Properties gfSecurityProperties) throws AuthenticationFailedException {
+ Authenticator auth;
+ try {
+ Method instanceGetter = ClassLoadUtil.methodFromName(this.authenticatorFactoryName);
+ auth = (Authenticator) instanceGetter.invoke(null, (Object[]) null);
+ } catch (Exception ex) {
+ throw new AuthenticationFailedException(
+ LocalizedStrings.HandShake_FAILED_TO_ACQUIRE_AUTHENTICATOR_OBJECT.toLocalizedString(), ex);
+ }
+ if (auth == null) {
+ throw new AuthenticationFailedException(
+ LocalizedStrings.HandShake_AUTHENTICATOR_INSTANCE_COULD_NOT_BE_OBTAINED.toLocalizedString());
+ }
+ auth.init(gfSecurityProperties);
+ return auth;
+ }
+
+ public void postAuthorize(OperationContext context) {
+ if (StringUtils.isBlank(postAuthzFactoryName)){
+ return ;
+ }
+
+ AccessControlContext acc = AccessController.getContext();
+ Subject subject = Subject.getSubject(acc);
+ Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
+ if (principals == null || principals.isEmpty()) {
+ throw new SecurityException(ACCESS_DENIED_MESSAGE);
+ }
+ Principal principal = principals.iterator().next();
+ AccessControl accessControl = getAccessControl(principal, true);
+ if (!accessControl.authorizeOperation(null, context)) {
+ throw new SecurityException(ACCESS_DENIED_MESSAGE);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/main/java/com/gemstone/gemfire/security/JMXShiroAuthenticator.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/security/JMXShiroAuthenticator.java b/geode-core/src/main/java/com/gemstone/gemfire/security/JMXShiroAuthenticator.java
new file mode 100644
index 0000000..7151dc5
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/security/JMXShiroAuthenticator.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 static com.gemstone.gemfire.management.internal.security.ResourceConstants.*;
+
+import java.util.Properties;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.remote.JMXAuthenticator;
+import javax.management.remote.JMXConnectionNotification;
+import javax.security.auth.Subject;
+
+import com.gemstone.gemfire.management.internal.security.ResourceConstants;
+
+/**
+ * this will make JMX authentication to use Shiro for Authentication
+ */
+
+public class JMXShiroAuthenticator implements JMXAuthenticator, NotificationListener {
+
+ @Override
+ public Subject authenticate(Object credentials) {
+ String username = null, password = null;
+ if (credentials instanceof String[]) {
+ final String[] aCredentials = (String[]) credentials;
+ username = aCredentials[0];
+ password = aCredentials[1];
+ } else if (credentials instanceof Properties) {
+ username = ((Properties) credentials).getProperty(ResourceConstants.USER_NAME);
+ password = ((Properties) credentials).getProperty(ResourceConstants.PASSWORD);
+ } else {
+ throw new SecurityException(WRONGE_CREDENTIALS_MESSAGE);
+ }
+
+ ShiroUtil.login(username, password);
+
+ // we are not using JMX mechanism to do authentication, therefore, this return value does not matter
+ return null;
+ }
+
+ @Override
+ public void handleNotification(Notification notification, Object handback) {
+ if (notification instanceof JMXConnectionNotification) {
+ JMXConnectionNotification cxNotification = (JMXConnectionNotification) notification;
+ String type = cxNotification.getType();
+ if (JMXConnectionNotification.CLOSED.equals(type)) {
+ ShiroUtil.logout();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/main/java/com/gemstone/gemfire/security/ShiroUtil.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/security/ShiroUtil.java b/geode-core/src/main/java/com/gemstone/gemfire/security/ShiroUtil.java
new file mode 100644
index 0000000..d19ff00
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/security/ShiroUtil.java
@@ -0,0 +1,94 @@
+package com.gemstone.gemfire.security;
+
+import java.util.concurrent.Callable;
+
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.management.internal.security.ResourceOperation;
+import com.gemstone.gemfire.management.internal.security.ResourceOperationContext;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.ShiroException;
+import org.apache.shiro.UnavailableSecurityManagerException;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.util.ThreadContext;
+
+public class ShiroUtil {
+
+ public static void login(String username, String password){
+ if(!isShiroConfigured())
+ return;
+
+ Subject currentUser = SecurityUtils.getSubject();
+
+ UsernamePasswordToken token =
+ new UsernamePasswordToken(username, password);
+ try {
+ LogService.getLogger().info("Logging in "+username+"/"+password);
+ currentUser.login(token);
+ } catch (ShiroException e) {
+ throw new AuthenticationFailedException(e.getMessage(), e);
+ }
+ }
+
+ public static void logout(){
+ if(!isShiroConfigured())
+ return;
+
+ Subject currentUser = SecurityUtils.getSubject();
+ try {
+ LogService.getLogger().info("Logging out "+currentUser.getPrincipal());
+ currentUser.logout();
+ }
+ catch(ShiroException e){
+ throw new AuthenticationFailedException(e.getMessage(), e);
+ }
+ // clean out Shiro's thread local content
+ ThreadContext.remove();
+ }
+
+ public static Callable associateWith(Callable callable){
+ if(!isShiroConfigured())
+ return callable;
+
+ Subject currentUser = SecurityUtils.getSubject();
+ return currentUser.associateWith(callable);
+ }
+
+ public static void authorize(ResourceOperationContext context) {
+ authorize(context.getResource().name(), context.getOperationCode().name(), context.getRegionName());
+ }
+
+ public static void authorize(ResourceOperation resourceOperation) {
+ authorize(resourceOperation.resource().name(), resourceOperation.operation().name());
+ }
+
+ public static void authorize(String resource, String operation){
+ authorize(resource, operation, null);
+ }
+
+ public static void authorize(String resource, String operation, String regionName){
+ if(!isShiroConfigured())
+ return;
+
+ ResourceOperationContext permission = new ResourceOperationContext(resource, operation, regionName);
+ Subject currentUser = SecurityUtils.getSubject();
+ try {
+ currentUser.checkPermission(permission);
+ }
+ catch(ShiroException e){
+ throw new GemFireSecurityException(e.getMessage(), e);
+ }
+ }
+
+ private static boolean isShiroConfigured(){
+ try{
+ SecurityUtils.getSecurityManager();
+ }
+ catch(UnavailableSecurityManagerException e){
+ return false;
+ }
+ return true;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/AccessControlMBeanJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/AccessControlMBeanJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/AccessControlMBeanJUnitTest.java
index a3d5d13..35bb3f2 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/AccessControlMBeanJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/AccessControlMBeanJUnitTest.java
@@ -20,11 +20,12 @@ import com.gemstone.gemfire.internal.AvailablePort;
import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
import org.junit.Before;
import org.junit.ClassRule;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import static org.assertj.core.api.Assertions.*;
+import static org.assertj.core.api.Assertions.assertThat;
@Category(IntegrationTest.class)
public class AccessControlMBeanJUnitTest {
@@ -49,6 +50,7 @@ public class AccessControlMBeanJUnitTest {
* @throws Exception
*/
@Test
+ @Ignore("No AccessControlMBean")
@JMXConnectionConfiguration(user = "stranger", password = "1234567")
public void testAnyAccess() throws Exception {
assertThat(bean.authorize("DATA", "READ")).isEqualTo(false);
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CacheServerMBeanAuthorizationJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CacheServerMBeanAuthorizationJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CacheServerMBeanAuthorizationJUnitTest.java
index 929032a..baa8393 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CacheServerMBeanAuthorizationJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CacheServerMBeanAuthorizationJUnitTest.java
@@ -16,6 +16,8 @@
*/
package com.gemstone.gemfire.management.internal.security;
+import static org.assertj.core.api.Assertions.*;
+
import com.gemstone.gemfire.internal.AvailablePort;
import com.gemstone.gemfire.management.CacheServerMXBean;
import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
@@ -25,8 +27,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
@Category(IntegrationTest.class)
public class CacheServerMBeanAuthorizationJUnitTest {
private static int jmxManagerPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
@@ -49,7 +49,7 @@ public class CacheServerMBeanAuthorizationJUnitTest {
@JMXConnectionConfiguration(user = "data-admin", password = "1234567")
public void testDataAdmin() throws Exception {
bean.removeIndex("foo");
- assertThatThrownBy(() -> bean.executeContinuousQuery("bar")).isInstanceOf(SecurityException.class).hasMessageContaining("DATA:READ");
+ assertThatThrownBy(() -> bean.executeContinuousQuery("bar")).hasMessageContaining("DATA:READ");
bean.fetchLoadProbe();
bean.getActiveCQCount();
bean.stopContinuousQuery("bar");
@@ -61,8 +61,8 @@ public class CacheServerMBeanAuthorizationJUnitTest {
@Test
@JMXConnectionConfiguration(user = "cluster-admin", password = "1234567")
public void testClusterAdmin() throws Exception {
- assertThatThrownBy(() -> bean.removeIndex("foo")).isInstanceOf(SecurityException.class).hasMessageContaining("DATA:MANAGE");
- assertThatThrownBy(() -> bean.executeContinuousQuery("bar")).isInstanceOf(SecurityException.class).hasMessageContaining("DATA:READ");
+ assertThatThrownBy(() -> bean.removeIndex("foo")).hasMessageContaining("DATA:MANAGE");
+ assertThatThrownBy(() -> bean.executeContinuousQuery("bar")).hasMessageContaining("DATA:READ");
bean.fetchLoadProbe();
}
@@ -70,21 +70,21 @@ public class CacheServerMBeanAuthorizationJUnitTest {
@Test
@JMXConnectionConfiguration(user = "data-user", password = "1234567")
public void testDataUser() throws Exception {
- assertThatThrownBy(() -> bean.removeIndex("foo")).isInstanceOf(SecurityException.class).hasMessageContaining("DATA:MANAGE");
+ assertThatThrownBy(() -> bean.removeIndex("foo")).hasMessageContaining("DATA:MANAGE");
bean.executeContinuousQuery("bar");
- assertThatThrownBy(() -> bean.fetchLoadProbe()).isInstanceOf(SecurityException.class).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> bean.fetchLoadProbe()).hasMessageContaining("CLUSTER:READ");
}
@Test
@JMXConnectionConfiguration(user = "stranger", password = "1234567")
public void testNoAccess() throws Exception {
- assertThatThrownBy(() -> bean.removeIndex("foo")).isInstanceOf(SecurityException.class).hasMessageContaining("DATA:MANAGE");
- assertThatThrownBy(() -> bean.executeContinuousQuery("bar")).isInstanceOf(SecurityException.class).hasMessageContaining("DATA:READ");
- assertThatThrownBy(() -> bean.fetchLoadProbe()).isInstanceOf(SecurityException.class).hasMessageContaining("CLUSTER:READ");
- assertThatThrownBy(() -> bean.getActiveCQCount()).isInstanceOf(SecurityException.class).hasMessageContaining("CLUSTER:READ");
- assertThatThrownBy(() -> bean.stopContinuousQuery("bar")).isInstanceOf(SecurityException.class).hasMessageContaining("DATA:MANAGE");
- assertThatThrownBy(() -> bean.closeAllContinuousQuery("bar")).isInstanceOf(SecurityException.class).hasMessageContaining("DATA:MANAGE");
- assertThatThrownBy(() -> bean.isRunning()).isInstanceOf(SecurityException.class).hasMessageContaining("CLUSTER:READ");
- assertThatThrownBy(() -> bean.showClientQueueDetails("bar")).isInstanceOf(SecurityException.class).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> bean.removeIndex("foo")).hasMessageContaining("DATA:MANAGE");
+ assertThatThrownBy(() -> bean.executeContinuousQuery("bar")).hasMessageContaining("DATA:READ");
+ assertThatThrownBy(() -> bean.fetchLoadProbe()).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> bean.getActiveCQCount()).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> bean.stopContinuousQuery("bar")).hasMessageContaining("DATA:MANAGE");
+ assertThatThrownBy(() -> bean.closeAllContinuousQuery("bar")).hasMessageContaining("DATA:MANAGE");
+ assertThatThrownBy(() -> bean.isRunning()).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> bean.showClientQueueDetails("bar")).hasMessageContaining("CLUSTER:READ");
}
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CacheServerMBeanShiroJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CacheServerMBeanShiroJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CacheServerMBeanShiroJUnitTest.java
new file mode 100644
index 0000000..e55623d
--- /dev/null
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CacheServerMBeanShiroJUnitTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.management.internal.security;
+
+import static org.assertj.core.api.Assertions.*;
+
+import com.gemstone.gemfire.internal.AvailablePort;
+import com.gemstone.gemfire.management.CacheServerMXBean;
+import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category(IntegrationTest.class)
+public class CacheServerMBeanShiroJUnitTest {
+ private static int jmxManagerPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+
+ private CacheServerMXBean bean;
+
+ @ClassRule
+ public static ShiroCacheStartRule serverRule = new ShiroCacheStartRule(jmxManagerPort, "shiro.ini");
+
+ @Rule
+ public MBeanServerConnectionRule connectionRule = new MBeanServerConnectionRule(jmxManagerPort);
+
+ @Before
+ public void setUp() throws Exception {
+ bean = connectionRule.getProxyMBean(CacheServerMXBean.class);
+ }
+
+ @Test
+ @JMXConnectionConfiguration(user = "root", password = "secret")
+ public void testAllAccess() throws Exception {
+ bean.removeIndex("foo");
+ bean.executeContinuousQuery("bar");
+ bean.fetchLoadProbe();
+ bean.getActiveCQCount();
+ bean.stopContinuousQuery("bar");
+ bean.closeAllContinuousQuery("bar");
+ bean.isRunning();
+ bean.showClientQueueDetails("foo");
+ }
+
+
+ @Test
+ @JMXConnectionConfiguration(user = "guest", password = "guest")
+ public void testNoAccess() throws Exception {
+ assertThatThrownBy(() -> bean.removeIndex("foo")).hasMessageContaining("DATA:MANAGE");
+ assertThatThrownBy(() -> bean.executeContinuousQuery("bar")).hasMessageContaining("DATA:READ");
+ assertThatThrownBy(() -> bean.fetchLoadProbe()).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> bean.getActiveCQCount()).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> bean.stopContinuousQuery("bar")).hasMessageContaining("DATA:MANAGE");
+ assertThatThrownBy(() -> bean.closeAllContinuousQuery("bar")).hasMessageContaining("DATA:MANAGE");
+ assertThatThrownBy(() -> bean.isRunning()).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> bean.showClientQueueDetails("bar")).hasMessageContaining("CLUSTER:READ");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CliCommandsSecurityTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CliCommandsSecurityTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CliCommandsSecurityTest.java
index 10bc7ae..5e49f92 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CliCommandsSecurityTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/CliCommandsSecurityTest.java
@@ -16,7 +16,7 @@
*/
package com.gemstone.gemfire.management.internal.security;
-import static org.assertj.core.api.Assertions.*;
+import static org.assertj.core.api.AssertionsForClassTypes.*;
import java.util.List;
@@ -62,6 +62,8 @@ public class CliCommandsSecurityTest {
@JMXConnectionConfiguration(user = "stranger", password = "1234567")
// the tests are run in alphabetical order, so the naming of the tests do matter
public void a_testNoAccess(){
+// List<TestCommand> clusterReads = new ArrayList<>();
+// clusterReads.add(new TestCommand("deploy --jar=group1_functions.jar --group=Group1", "CLUSTER:MANAGE"));
for (TestCommand command:commands) {
LogService.getLogger().info("processing: "+command.getCommand());
// for those commands that don't require any permission, any user can execute them
@@ -70,8 +72,7 @@ public class CliCommandsSecurityTest {
}
else {
assertThatThrownBy(() -> bean.processCommand(command.getCommand()))
- .hasMessageContaining(command.getPermission())
- .isInstanceOf(SecurityException.class);
+ .hasMessageContaining(command.getPermission());
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/DataCommandsSecurityTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/DataCommandsSecurityTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/DataCommandsSecurityTest.java
index 085723c..7517f49 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/DataCommandsSecurityTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/DataCommandsSecurityTest.java
@@ -16,8 +16,11 @@
*/
package com.gemstone.gemfire.management.internal.security;
+import static org.assertj.core.api.Assertions.*;
+
import com.gemstone.gemfire.internal.AvailablePort;
import com.gemstone.gemfire.management.MemberMXBean;
+import com.gemstone.gemfire.security.GemFireSecurityException;
import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
import org.junit.Before;
import org.junit.ClassRule;
@@ -25,8 +28,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
@Category(IntegrationTest.class)
public class DataCommandsSecurityTest {
private static int jmxManagerPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
@@ -49,11 +50,9 @@ public class DataCommandsSecurityTest {
@JMXConnectionConfiguration(user = "region1-user", password = "1234567")
public void testDataUser() throws Exception {
bean.processCommand("locate entry --key=k1 --region=region1");
- bean.processCommand("query --query='SELECT * FROM /region1'");
// can't operate on secureRegion
- assertThatThrownBy(() -> bean.processCommand("locate entry --key=k1 --region=secureRegion")).isInstanceOf(SecurityException.class);
- assertThatThrownBy(() -> bean.processCommand("query --query='SELECT * FROM /secureRegion")).isInstanceOf(SecurityException.class);
+ assertThatThrownBy(() -> bean.processCommand("locate entry --key=k1 --region=secureRegion")).isInstanceOf(GemFireSecurityException.class);
}
@JMXConnectionConfiguration(user = "secure-user", password = "1234567")
@@ -61,27 +60,23 @@ public class DataCommandsSecurityTest {
public void testSecureDataUser(){
// can do all these on both regions
bean.processCommand("locate entry --key=k1 --region=region1");
- bean.processCommand("query --query='SELECT * FROM /region1'");
-
bean.processCommand("locate entry --key=k1 --region=secureRegion");
- bean.processCommand("query --query='SELECT * FROM /secureRegion'");
}
// dataUser has all the permissions granted, but not to region2 (only to region1)
@JMXConnectionConfiguration(user = "region1-user", password = "1234567")
@Test
public void testRegionAcess(){
- assertThatThrownBy(() -> bean.processCommand("rebalance --include-region=region2")).isInstanceOf(SecurityException.class)
+ assertThatThrownBy(() -> bean.processCommand("rebalance --include-region=region2")).isInstanceOf(GemFireSecurityException.class)
.hasMessageContaining("DATA:MANAGE");
- assertThatThrownBy(() -> bean.processCommand("export data --region=region2 --file=foo.txt --member=value")).isInstanceOf(SecurityException.class);
- assertThatThrownBy(() -> bean.processCommand("import data --region=region2 --file=foo.txt --member=value")).isInstanceOf(SecurityException.class);
+ assertThatThrownBy(() -> bean.processCommand("export data --region=region2 --file=foo.txt --member=value")).isInstanceOf(GemFireSecurityException.class);
+ assertThatThrownBy(() -> bean.processCommand("import data --region=region2 --file=foo.txt --member=value")).isInstanceOf(GemFireSecurityException.class);
- assertThatThrownBy(() -> bean.processCommand("put --key=key1 --value=value1 --region=region2")).isInstanceOf(SecurityException.class)
+ assertThatThrownBy(() -> bean.processCommand("put --key=key1 --value=value1 --region=region2")).isInstanceOf(GemFireSecurityException.class)
.hasMessageContaining("DATA:WRITE");
- assertThatThrownBy(() -> bean.processCommand("get --key=key1 --region=region2")).isInstanceOf(SecurityException.class);
- assertThatThrownBy(() -> bean.processCommand("query --query='SELECT * FROM /region2'")).isInstanceOf(SecurityException.class);
- }
+ assertThatThrownBy(() -> bean.processCommand("get --key=key1 --region=region2")).isInstanceOf(GemFireSecurityException.class);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/DiskStoreMXBeanSecurityJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/DiskStoreMXBeanSecurityJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/DiskStoreMXBeanSecurityJUnitTest.java
index 2fddb39..f248736 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/DiskStoreMXBeanSecurityJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/DiskStoreMXBeanSecurityJUnitTest.java
@@ -16,6 +16,8 @@
*/
package com.gemstone.gemfire.management.internal.security;
+import static org.assertj.core.api.Assertions.*;
+
import com.gemstone.gemfire.internal.AvailablePort;
import com.gemstone.gemfire.management.DiskStoreMXBean;
import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
@@ -26,8 +28,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
@Category(IntegrationTest.class)
public class DiskStoreMXBeanSecurityJUnitTest {
private static int jmxManagerPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
@@ -69,7 +69,7 @@ public class DiskStoreMXBeanSecurityJUnitTest {
@Test
@JMXConnectionConfiguration(user = "data-user", password = "1234567")
public void testNoAccess() throws Exception {
- assertThatThrownBy(() -> bean.flush()).isInstanceOf(SecurityException.class).hasMessageContaining("DATA:MANAGE");
+ assertThatThrownBy(() -> bean.flush()).hasMessageContaining("DATA:MANAGE");
assertThatThrownBy(() -> bean.forceCompaction()).hasMessageContaining("DATA:MANAGE");
assertThatThrownBy(() -> bean.forceRoll()).hasMessageContaining("DATA:MANAGE");
assertThatThrownBy(() -> bean.getCompactionThreshold()).hasMessageContaining("CLUSTER:READ");
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GatewaySenderMBeanSecurityTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GatewaySenderMBeanSecurityTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GatewaySenderMBeanSecurityTest.java
index 33758b7..3a9412d 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GatewaySenderMBeanSecurityTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GatewaySenderMBeanSecurityTest.java
@@ -16,6 +16,11 @@
*/
package com.gemstone.gemfire.management.internal.security;
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import javax.management.ObjectName;
+
import com.gemstone.gemfire.internal.AvailablePort;
import com.gemstone.gemfire.management.GatewaySenderMXBean;
import com.gemstone.gemfire.management.ManagementService;
@@ -29,11 +34,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import javax.management.ObjectName;
-
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.Mockito.*;
-
@Category(IntegrationTest.class)
public class GatewaySenderMBeanSecurityTest {
private static int jmxManagerPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
@@ -88,18 +88,18 @@ public class GatewaySenderMBeanSecurityTest {
@Test
@JMXConnectionConfiguration(user = "stranger", password = "1234567")
public void testNoAccess() throws Exception {
- assertThatThrownBy(() -> bean.getAlertThreshold()).hasMessageStartingWith("Access Denied: Not authorized for CLUSTER:READ");
- assertThatThrownBy(() -> bean.getAverageDistributionTimePerBatch()).hasMessageStartingWith("Access Denied: Not authorized for CLUSTER:READ");
- assertThatThrownBy(() -> bean.getBatchSize()).hasMessageStartingWith("Access Denied: Not authorized for CLUSTER:READ");
- assertThatThrownBy(() -> bean.getMaximumQueueMemory()).hasMessageStartingWith("Access Denied: Not authorized for CLUSTER:READ");
- assertThatThrownBy(() -> bean.getOrderPolicy()).hasMessageStartingWith("Access Denied: Not authorized for CLUSTER:READ");
- assertThatThrownBy(() -> bean.isBatchConflationEnabled()).hasMessageStartingWith("Access Denied: Not authorized for CLUSTER:READ");
- assertThatThrownBy(() -> bean.isManualStart()).hasMessageStartingWith("Access Denied: Not authorized for CLUSTER:READ");
- assertThatThrownBy(() -> bean.pause()).hasMessageStartingWith("Access Denied: Not authorized for DATA:MANAGE");
- assertThatThrownBy(() -> bean.rebalance()).hasMessageStartingWith("Access Denied: Not authorized for DATA:MANAGE");
- assertThatThrownBy(() -> bean.resume()).hasMessageStartingWith("Access Denied: Not authorized for DATA:MANAGE");
- assertThatThrownBy(() -> bean.start()).hasMessageStartingWith("Access Denied: Not authorized for DATA:MANAGE");
- assertThatThrownBy(() -> bean.stop()).hasMessageStartingWith("Access Denied: Not authorized for DATA:MANAGE");
+ assertThatThrownBy(() -> bean.getAlertThreshold()).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> bean.getAverageDistributionTimePerBatch()).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> bean.getBatchSize()).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> bean.getMaximumQueueMemory()).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> bean.getOrderPolicy()).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> bean.isBatchConflationEnabled()).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> bean.isManualStart()).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> bean.pause()).hasMessageContaining("DATA:MANAGE");
+ assertThatThrownBy(() -> bean.rebalance()).hasMessageContaining("DATA:MANAGE");
+ assertThatThrownBy(() -> bean.resume()).hasMessageContaining("DATA:MANAGE");
+ assertThatThrownBy(() -> bean.start()).hasMessageContaining("DATA:MANAGE");
+ assertThatThrownBy(() -> bean.stop()).hasMessageContaining("DATA:MANAGE");
}
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsSecurityTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsSecurityTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsSecurityTest.java
index 4184597..5149883 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsSecurityTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsSecurityTest.java
@@ -2,17 +2,28 @@ package com.gemstone.gemfire.management.internal.security;
import static org.junit.Assert.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
import com.gemstone.gemfire.internal.AvailablePortHelper;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.management.cli.Result;
import com.gemstone.gemfire.management.internal.cli.HeadlessGfsh;
import com.gemstone.gemfire.management.internal.cli.result.CommandResult;
+import com.gemstone.gemfire.management.internal.cli.result.ErrorResultData;
+import com.gemstone.gemfire.management.internal.cli.result.ResultBuilder;
import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
@Category(IntegrationTest.class)
+@RunWith(Parameterized.class)
public class GfshCommandsSecurityTest {
private static int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
private static int jmxPort = ports[0];
@@ -25,7 +36,19 @@ public class GfshCommandsSecurityTest {
jmxPort, httpPort, "cacheServer.json");
@Rule
- public GfshShellConnectionRule gfshConnection = new GfshShellConnectionRule(jmxPort, httpPort, true);
+ public GfshShellConnectionRule gfshConnection = null;
+
+ public GfshCommandsSecurityTest(boolean useHttp){
+ gfshConnection = new GfshShellConnectionRule(jmxPort, httpPort, useHttp);
+ }
+
+ @Parameterized.Parameters
+ public static Collection parameters() {
+ return Arrays.asList(new Object[][] {
+ { false}, // useHttp=false,
+ { true } // useHttp=true,
+ });
+ }
@Before
public void before(){
@@ -46,34 +69,78 @@ public class GfshCommandsSecurityTest {
@Test
@JMXConnectionConfiguration(user = "cluster-reader", password = "1234567")
- public void testAuthorized() throws Exception{
- CommandResult result = null;
-// List<TestCommand> commands = TestCommand.getCommandsOfPermission("DATA:READ");
-// for(TestCommand command:commands){
-// System.out.println("Processing command: "+command.getCommand());
-// gfsh.executeCommand(command.getCommand());
-// result = (CommandResult)gfsh.getResult();
-// System.out.println(result);
-// }
-//
-// List<TestCommand> others = TestCommand.getCommands();
-// others.removeAll(commands);
-// for(TestCommand command:others){
-// gfsh.executeCommand(command.getCommand());
-// result = (CommandResult)gfsh.getResult();
-// System.out.println(result);
-// }
- gfsh.executeCommand("describe config --member=Member1");
- result = (CommandResult)gfsh.getResult();
- System.out.println("result is: "+ result);
+ public void testClusterReader() throws Exception{
+ runCommandsWithAndWithout("CLUSTER:READ");
}
@Test
- @JMXConnectionConfiguration(user = "cluster-reader", password = "1234567")
- public void testNotAuthorized() throws Exception{
- CommandResult result = null;
- gfsh.executeCommand("alter runtime --member=server1 --log-level=finest --enable-statistics=true");
- result = (CommandResult)gfsh.getResult();
- System.out.println("result is: "+ result);
+ @JMXConnectionConfiguration(user = "cluster-writer", password = "1234567")
+ public void testClusterWriter() throws Exception{
+ runCommandsWithAndWithout("CLUSTER:WRITE");
+ }
+
+ @Test
+ @JMXConnectionConfiguration(user = "cluster-manager", password = "1234567")
+ public void testClusterManager() throws Exception{
+ runCommandsWithAndWithout("CLUSTER:MANAGE");
+ }
+
+ @Test
+ @JMXConnectionConfiguration(user = "data-reader", password = "1234567")
+ public void testDataReader() throws Exception{
+ runCommandsWithAndWithout("DATA:READ");
+ }
+
+ @Test
+ @JMXConnectionConfiguration(user = "data-writer", password = "1234567")
+ public void testDataWriter() throws Exception{
+ runCommandsWithAndWithout("DATA:WRITE");
+ }
+
+ @Test
+ @JMXConnectionConfiguration(user = "data-manager", password = "1234567")
+ public void testDataManager() throws Exception{
+ runCommandsWithAndWithout("DATA:MANAGE");
+ }
+
+
+ private void runCommandsWithAndWithout(String permission) throws Exception{
+ List<TestCommand> permitted = TestCommand.getCommandsOfPermission(permission);
+ for(TestCommand clusterRead:permitted) {
+ LogService.getLogger().info("Processing authorized command: "+clusterRead.getCommand());gfsh.executeCommand(clusterRead.getCommand());
+ CommandResult result = (CommandResult) gfsh.getResult();
+ assertNotNull(result);
+
+ if(result.getResultData() instanceof ErrorResultData) {
+ assertNotEquals(ResultBuilder.ERRORCODE_UNAUTHORIZED, ((ErrorResultData) result.getResultData()).getErrorCode());
+ }
+ else{
+ assertEquals(Result.Status.OK, result.getStatus()) ;
+ }
+ }
+
+ List<TestCommand> others = TestCommand.getCommands();
+ others.removeAll(permitted);
+ for(TestCommand other:others) {
+ // skip no permission commands
+ if(other.getPermission()==null)
+ continue;
+
+ LogService.getLogger().info("Processing unauthorized command: "+other.getCommand());
+ gfsh.executeCommand(other.getCommand());
+ CommandResult result = (CommandResult) gfsh.getResult();
+ int errorCode = ((ErrorResultData) result.getResultData()).getErrorCode();
+
+ // for some commands there are pre execution checks to check for user input error, will skip those commands
+ if(errorCode==ResultBuilder.ERRORCODE_USER_ERROR){
+ LogService.getLogger().info("Skip user error: "+result.getContent());
+ continue;
+ }
+
+ assertEquals(ResultBuilder.ERRORCODE_UNAUTHORIZED, ((ErrorResultData) result.getResultData()).getErrorCode());
+ assertTrue(result.getContent().toString().contains(other.getPermission()));
+ }
}
+
+
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshShellConnectionRule.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshShellConnectionRule.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshShellConnectionRule.java
index 5bd5672..17549d5 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshShellConnectionRule.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshShellConnectionRule.java
@@ -20,6 +20,8 @@ import com.gemstone.gemfire.management.internal.cli.CliUtil;
import com.gemstone.gemfire.management.internal.cli.HeadlessGfsh;
import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings;
import com.gemstone.gemfire.management.internal.cli.result.CommandResult;
+import com.gemstone.gemfire.management.internal.cli.result.ErrorResultData;
+import com.gemstone.gemfire.management.internal.cli.result.ResultBuilder;
import com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder;
import com.gemstone.gemfire.test.junit.rules.DescribedExternalResource;
import org.junit.runner.Description;
@@ -55,29 +57,27 @@ public class GfshShellConnectionRule extends DescribedExternalResource {
String shellId = getClass().getSimpleName() + "_" + description.getMethodName();
gfsh = new HeadlessGfsh(shellId, 30);
- final CommandStringBuilder command = new CommandStringBuilder(CliStrings.CONNECT);
- command.addOption(CliStrings.CONNECT__USERNAME, config.user());
- command.addOption(CliStrings.CONNECT__PASSWORD, config.password());
+ final CommandStringBuilder connectCommand = new CommandStringBuilder(CliStrings.CONNECT);
+ connectCommand.addOption(CliStrings.CONNECT__USERNAME, config.user());
+ connectCommand.addOption(CliStrings.CONNECT__PASSWORD, config.password());
String endpoint;
if (useHttp) {
endpoint = "http://localhost:" + httpPort + "/gemfire/v1";
- command.addOption(CliStrings.CONNECT__USE_HTTP, Boolean.TRUE.toString());
- command.addOption(CliStrings.CONNECT__URL, endpoint);
+ connectCommand.addOption(CliStrings.CONNECT__USE_HTTP, Boolean.TRUE.toString());
+ connectCommand.addOption(CliStrings.CONNECT__URL, endpoint);
} else {
endpoint = "localhost[" + jmxPort + "]";
- command.addOption(CliStrings.CONNECT__JMX_MANAGER, endpoint);
+ connectCommand.addOption(CliStrings.CONNECT__JMX_MANAGER, endpoint);
}
System.out.println(getClass().getSimpleName()+" using endpoint: "+endpoint);
- gfsh.executeCommand(command.toString());
+ gfsh.executeCommand(connectCommand.toString());
CommandResult result = (CommandResult) gfsh.getResult();
-
- String message = result.getContent().toString();
- if(message.contains("Authentication Failed Wrong username/password") ||
- message.contains("The HTTP request failed with: 403 - Access Denied")){
- this.authenticated = false;
+ if(result.getResultData() instanceof ErrorResultData) {
+ ErrorResultData errorResultData = (ErrorResultData) result.getResultData();
+ this.authenticated = !(errorResultData.getErrorCode() == ResultBuilder.ERRORCODE_CONNECTION_ERROR);
}
else{
this.authenticated = true;
@@ -90,6 +90,7 @@ public class GfshShellConnectionRule extends DescribedExternalResource {
protected void after(Description description) throws Throwable {
if (gfsh != null) {
gfsh.clearEvents();
+ gfsh.executeCommand("disconnect");
gfsh.executeCommand("exit");
gfsh.terminate();
gfsh.setThreadLocalInstance();
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/JSONAuthorization.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/JSONAuthorization.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/JSONAuthorization.java
index 9e931ad..48e0a39 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/JSONAuthorization.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/JSONAuthorization.java
@@ -16,10 +16,24 @@
*/
package com.gemstone.gemfire.management.internal.security;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import javax.management.remote.JMXPrincipal;
+
import com.gemstone.gemfire.LogWriter;
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.cache.operations.OperationContext.Resource;
import com.gemstone.gemfire.distributed.DistributedMember;
import com.gemstone.gemfire.internal.logging.LogService;
import com.gemstone.gemfire.security.AccessControl;
@@ -31,22 +45,6 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
-import javax.management.remote.JMXPrincipal;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import static com.gemstone.gemfire.cache.operations.OperationContext.Resource;
-
public class JSONAuthorization implements AccessControl, Authenticator {
static class Permission {
@@ -188,7 +186,7 @@ public class JSONAuthorization implements AccessControl, Authenticator {
}
@Override
- public boolean authorizeOperation(String arg0, OperationContext context) {
+ public boolean authorizeOperation(String region, OperationContext context) {
if (principal == null)
return false;
@@ -204,28 +202,12 @@ public class JSONAuthorization implements AccessControl, Authenticator {
if (context.getResource() == perm.getResource() && context.getOperationCode() == perm.getOperationCode()) {
LogService.getLogger().info("Found permission " + perm);
- //if this is only for JMX aurthorization, we've found the permission needed, i.e, this operation is authorized
- if(!(context instanceof CLIOperationContext)){
+ //no need to further check the rgionName
+ if(context.getRegionName()==null){
return true;
}
- // If this is a Command operation context, we need to further check if the region is allowed in this role
- CLIOperationContext ctx = (CLIOperationContext) context;
-
- String region = ctx.getCommandOptions().get("region");
- if(region==null) {
- region = ctx.getCommandOptions().get("include-region");
- }
- if(region==null) {
- String query = ctx.getCommandOptions().get("query");
- if(query!=null) {
- Matcher matcher = Pattern.compile("/\\s*(\\w+)").matcher(query);
- if (matcher.find())
- region = matcher.group(1);
- }
- }
-
- if(role.regionNames == null || region == null || role.regionNames.contains(region)){
+ if(role.regionNames == null || role.regionNames.contains(context.getRegionName())){
// if regionName is null, i.e. all regions are allowed
return true;
}
@@ -251,7 +233,6 @@ public class JSONAuthorization implements AccessControl, Authenticator {
LogService.getLogger().info("User=" + user + " pwd=" + pwd);
if (user != null && !userObj.pwd.equals(pwd) && !"".equals(user))
throw new AuthenticationFailedException("Wrong username/password");
- LogService.getLogger().info("Authentication successful!! for " + user);
return new JMXPrincipal(user);
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/JsonAuthorizationCacheStartRule.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/JsonAuthorizationCacheStartRule.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/JsonAuthorizationCacheStartRule.java
index 1dd865f..e6654d5 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/JsonAuthorizationCacheStartRule.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/JsonAuthorizationCacheStartRule.java
@@ -16,13 +16,13 @@
*/
package com.gemstone.gemfire.management.internal.security;
+import java.util.Properties;
+
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.CacheFactory;
import com.gemstone.gemfire.distributed.internal.DistributionConfig;
import org.junit.rules.ExternalResource;
-import java.util.Properties;
-
public class JsonAuthorizationCacheStartRule extends ExternalResource {
private Cache cache;
private int jmxManagerPort = 0;
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/LockServiceMBeanAuthorizationJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/LockServiceMBeanAuthorizationJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/LockServiceMBeanAuthorizationJUnitTest.java
index 5fa7012..b4b3f72 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/LockServiceMBeanAuthorizationJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/LockServiceMBeanAuthorizationJUnitTest.java
@@ -16,6 +16,8 @@
*/
package com.gemstone.gemfire.management.internal.security;
+import static org.assertj.core.api.Assertions.*;
+
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
import com.gemstone.gemfire.distributed.internal.locks.DLockService;
@@ -30,8 +32,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
@Category(IntegrationTest.class)
public class LockServiceMBeanAuthorizationJUnitTest {
private static int jmxManagerPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
@@ -74,17 +74,17 @@ public class LockServiceMBeanAuthorizationJUnitTest {
@Test
@JMXConnectionConfiguration(user = "cluster-admin", password = "1234567")
public void testSomeAccess() throws Exception {
- assertThatThrownBy(() -> lockServiceMBean.becomeLockGrantor()).isInstanceOf(SecurityException.class);
+ assertThatThrownBy(() -> lockServiceMBean.becomeLockGrantor());
lockServiceMBean.getMemberCount();
}
@Test
@JMXConnectionConfiguration(user = "data-user", password = "1234567")
public void testNoAccess() throws Exception {
- assertThatThrownBy(() -> lockServiceMBean.becomeLockGrantor()).isInstanceOf(SecurityException.class).hasMessageContaining("DATA:MANAGE");
- assertThatThrownBy(() -> lockServiceMBean.fetchGrantorMember()).isInstanceOf(SecurityException.class).hasMessageContaining("CLUSTER:READ");
- assertThatThrownBy(() -> lockServiceMBean.getMemberCount()).isInstanceOf(SecurityException.class).hasMessageContaining("CLUSTER:READ");
- assertThatThrownBy(() -> lockServiceMBean.isDistributed()).isInstanceOf(SecurityException.class).hasMessageContaining("CLUSTER:READ");
- assertThatThrownBy(() -> lockServiceMBean.listThreadsHoldingLock()).isInstanceOf(SecurityException.class).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> lockServiceMBean.becomeLockGrantor()).hasMessageContaining("DATA:MANAGE");
+ assertThatThrownBy(() -> lockServiceMBean.fetchGrantorMember()).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> lockServiceMBean.getMemberCount()).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> lockServiceMBean.isDistributed()).hasMessageContaining("CLUSTER:READ");
+ assertThatThrownBy(() -> lockServiceMBean.listThreadsHoldingLock()).hasMessageContaining("CLUSTER:READ");
}
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/MBeanServerConnectionRule.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/MBeanServerConnectionRule.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/MBeanServerConnectionRule.java
index 78b3283..51cc6b8 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/MBeanServerConnectionRule.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/MBeanServerConnectionRule.java
@@ -16,9 +16,12 @@
*/
package com.gemstone.gemfire.management.internal.security;
-import com.gemstone.gemfire.test.junit.rules.DescribedExternalResource;
-import org.junit.runner.Description;
+import static org.junit.Assert.*;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
import javax.management.JMX;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
@@ -29,12 +32,9 @@ import javax.management.QueryExp;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import static org.junit.Assert.assertEquals;
+import com.gemstone.gemfire.test.junit.rules.DescribedExternalResource;
+import org.junit.runner.Description;
/**
* Class which eases the creation of MBeans for security testing. When combined with {@link JMXConnectionConfiguration}
@@ -123,6 +123,7 @@ public class MBeanServerConnectionRule extends DescribedExternalResource {
jmxConnector.close();
jmxConnector = null;
}
+
con = null;
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c733f0c2/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/ManagerMBeanAuthorizationJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/ManagerMBeanAuthorizationJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/ManagerMBeanAuthorizationJUnitTest.java
index efbdbc7..2548d21 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/ManagerMBeanAuthorizationJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/ManagerMBeanAuthorizationJUnitTest.java
@@ -16,6 +16,12 @@
*/
package com.gemstone.gemfire.management.internal.security;
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import java.lang.management.ManagementFactory;
+import javax.management.ObjectName;
+
import com.gemstone.gemfire.internal.AvailablePort;
import com.gemstone.gemfire.management.ManagerMXBean;
import com.gemstone.gemfire.management.internal.beans.ManagerMBean;
@@ -27,12 +33,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import javax.management.ObjectName;
-import java.lang.management.ManagementFactory;
-
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.Mockito.mock;
-
@Category(IntegrationTest.class)
public class ManagerMBeanAuthorizationJUnitTest {
private static int jmxManagerPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
@@ -71,8 +71,8 @@ public class ManagerMBeanAuthorizationJUnitTest {
@Test
@JMXConnectionConfiguration(user = "data-admin", password = "1234567")
public void testSomeAccess() throws Exception {
- assertThatThrownBy(() -> managerMXBean.start()).isInstanceOf(SecurityException.class).hasMessageContaining("CLUSTER:MANAGE");
- assertThatThrownBy(() -> managerMXBean.getPulseURL()).isInstanceOf(SecurityException.class).hasMessageContaining("CLUSTER:WRITE");
+ assertThatThrownBy(() -> managerMXBean.start()).hasMessageContaining("CLUSTER:MANAGE");
+ assertThatThrownBy(() -> managerMXBean.getPulseURL()).hasMessageContaining("CLUSTER:WRITE");
managerMXBean.isRunning();
}
}