Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id CBFC8200C8F for ; Fri, 9 Jun 2017 19:17:30 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id CAA13160BCA; Fri, 9 Jun 2017 17:17:30 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 79204160BEB for ; Fri, 9 Jun 2017 19:17:28 +0200 (CEST) Received: (qmail 10719 invoked by uid 500); 9 Jun 2017 17:17:27 -0000 Mailing-List: contact commits-help@geode.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@geode.apache.org Delivered-To: mailing list commits@geode.apache.org Received: (qmail 10539 invoked by uid 99); 9 Jun 2017 17:17:27 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 09 Jun 2017 17:17:27 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id C3279E1863; Fri, 9 Jun 2017 17:17:26 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: klund@apache.org To: commits@geode.apache.org Date: Fri, 09 Jun 2017 17:17:31 -0000 Message-Id: <4ea6360b7fa44e0cbd0ac438c757ca20@git.apache.org> In-Reply-To: <065dd4a60cb24943b237eae43837cc1d@git.apache.org> References: <065dd4a60cb24943b237eae43837cc1d@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [06/11] geode git commit: GEODE-2632: use immutable SecurityService impls to improve performance archived-at: Fri, 09 Jun 2017 17:17:30 -0000 http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/internal/security/EnabledSecurityService.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/security/EnabledSecurityService.java b/geode-core/src/main/java/org/apache/geode/internal/security/EnabledSecurityService.java new file mode 100644 index 0000000..f971dee --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/security/EnabledSecurityService.java @@ -0,0 +1,387 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package org.apache.geode.internal.security; + +import org.apache.commons.lang.SerializationException; +import org.apache.commons.lang.StringUtils; +import org.apache.geode.GemFireIOException; +import org.apache.geode.internal.cache.EntryEventImpl; +import org.apache.geode.internal.logging.LogService; +import org.apache.geode.internal.security.shiro.GeodeAuthenticationToken; +import org.apache.geode.internal.security.shiro.RealmInitializer; +import org.apache.geode.internal.security.shiro.ShiroPrincipal; +import org.apache.geode.internal.util.BlobHelper; +import org.apache.geode.management.internal.security.ResourceOperation; +import org.apache.geode.security.AuthenticationFailedException; +import org.apache.geode.security.GemFireSecurityException; +import org.apache.geode.security.NotAuthorizedException; +import org.apache.geode.security.PostProcessor; +import org.apache.geode.security.ResourcePermission; +import org.apache.geode.security.ResourcePermission.Operation; +import org.apache.geode.security.ResourcePermission.Resource; +import org.apache.geode.security.SecurityManager; +import org.apache.logging.log4j.Logger; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.ShiroException; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.subject.support.SubjectThreadState; +import org.apache.shiro.util.ThreadContext; +import org.apache.shiro.util.ThreadState; + +import java.io.IOException; +import java.io.Serializable; +import java.security.AccessController; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.Callable; + +/** + * Security service with SecurityManager and an optional PostProcessor. + */ +public class EnabledSecurityService implements SecurityService { + private static Logger logger = LogService.getLogger(LogService.SECURITY_LOGGER_NAME); + + private final SecurityManager securityManager; + + private final PostProcessor postProcessor; + + EnabledSecurityService(final SecurityManager securityManager, final PostProcessor postProcessor, + final RealmInitializer realmInitializer) { + this.securityManager = securityManager; + this.postProcessor = postProcessor; + realmInitializer.initialize(this.securityManager); + } + + @Override + public void initSecurity(final Properties securityProps) { + this.securityManager.init(securityProps); + if (this.postProcessor != null) { + this.postProcessor.init(securityProps); + } + } + + /** + * It first looks the shiro subject in AccessControlContext since JMX will use multiple threads to + * process operations from the same client, then it looks into Shiro's thead context. + * + * @return the shiro subject, null if security is not enabled + */ + @Override + public Subject getSubject() { + Subject currentUser; + + // First try get the principal out of AccessControlContext instead of Shiro's Thread context + // since threads can be shared between JMX clients. + javax.security.auth.Subject jmxSubject = + javax.security.auth.Subject.getSubject(AccessController.getContext()); + + if (jmxSubject != null) { + Set principals = jmxSubject.getPrincipals(ShiroPrincipal.class); + if (!principals.isEmpty()) { + ShiroPrincipal principal = principals.iterator().next(); + currentUser = principal.getSubject(); + ThreadContext.bind(currentUser); + return currentUser; + } + } + + // in other cases like rest call, client operations, we get it from the current thread + currentUser = SecurityUtils.getSubject(); + + if (currentUser == null || currentUser.getPrincipal() == null) { + throw new GemFireSecurityException("Error: Anonymous User"); + } + + return currentUser; + } + + /** + * @return null if security is not enabled, otherwise return a shiro subject + */ + @Override + public Subject login(final Properties credentials) { + if (credentials == null) { + return null; + } + + // this makes sure it starts with a clean user object + ThreadContext.remove(); + + Subject currentUser = SecurityUtils.getSubject(); + GeodeAuthenticationToken token = new GeodeAuthenticationToken(credentials); + try { + logger.info("Logging in " + token.getPrincipal()); + currentUser.login(token); + } catch (ShiroException e) { + logger.info(e.getMessage(), e); + throw new AuthenticationFailedException( + "Authentication error. Please check your credentials.", e); + } + + return currentUser; + } + + @Override + public void logout() { + Subject currentUser = getSubject(); + if (currentUser == null) { + return; + } + + try { + logger.info("Logging out " + currentUser.getPrincipal()); + currentUser.logout(); + } catch (ShiroException e) { + logger.info(e.getMessage(), e); + throw new GemFireSecurityException(e.getMessage(), e); + } + + // clean out Shiro's thread local content + ThreadContext.remove(); + } + + @Override + public Callable associateWith(final Callable callable) { + Subject currentUser = getSubject(); + if (currentUser == null) { + return callable; + } + + return currentUser.associateWith(callable); + } + + /** + * Binds the passed-in subject to the executing thread. Usage: + * + *
+   * ThreadState state = null;
+   * try {
+   *   state = securityService.bindSubject(subject);
+   *   // do the rest of the work as this subject
+   * } finally {
+   *   if (state != null)
+   *     state.clear();
+   * }
+   * 
+ */ + @Override + public ThreadState bindSubject(final Subject subject) { + if (subject == null) { + return null; + } + + ThreadState threadState = new SubjectThreadState(subject); + threadState.bind(); + return threadState; + } + + @Override + public void authorize(final ResourceOperation resourceOperation) { + if (resourceOperation == null) { + return; + } + + authorize(resourceOperation.resource().name(), resourceOperation.operation().name(), null); + } + + @Override + public void authorizeClusterManage() { + authorize("CLUSTER", "MANAGE"); + } + + @Override + public void authorizeClusterWrite() { + authorize("CLUSTER", "WRITE"); + } + + @Override + public void authorizeClusterRead() { + authorize("CLUSTER", "READ"); + } + + @Override + public void authorizeDataManage() { + authorize("DATA", "MANAGE"); + } + + @Override + public void authorizeDataWrite() { + authorize("DATA", "WRITE"); + } + + @Override + public void authorizeDataRead() { + authorize("DATA", "READ"); + } + + @Override + public void authorizeRegionManage(final String regionName) { + authorize("DATA", "MANAGE", regionName); + } + + @Override + public void authorizeRegionManage(final String regionName, final String key) { + authorize("DATA", "MANAGE", regionName, key); + } + + @Override + public void authorizeRegionWrite(final String regionName) { + authorize("DATA", "WRITE", regionName); + } + + @Override + public void authorizeRegionWrite(final String regionName, final String key) { + authorize("DATA", "WRITE", regionName, key); + } + + @Override + public void authorizeRegionRead(final String regionName) { + authorize("DATA", "READ", regionName); + } + + @Override + public void authorizeRegionRead(final String regionName, final String key) { + authorize("DATA", "READ", regionName, key); + } + + @Override + public void authorize(final String resource, final String operation) { + authorize(resource, operation, null); + } + + @Override + public void authorize(final String resource, final String operation, final String regionName) { + authorize(resource, operation, regionName, null); + } + + @Override + public void authorize(final String resource, final String operation, String regionName, + final String key) { + regionName = StringUtils.stripStart(regionName, "/"); + authorize(new ResourcePermission(resource, operation, regionName, key)); + } + + @Override + public void authorize(final ResourcePermission context) { + Subject currentUser = getSubject(); + if (currentUser == null) { + return; + } + if (context == null) { + return; + } + if (context.getResource() == Resource.NULL && context.getOperation() == Operation.NULL) { + return; + } + + try { + currentUser.checkPermission(context); + } catch (ShiroException e) { + String msg = currentUser.getPrincipal() + " not authorized for " + context; + logger.info(msg); + throw new NotAuthorizedException(msg, e); + } + } + + @Override + public void close() { + if (this.securityManager != null) { + this.securityManager.close(); + } + + if (this.postProcessor != null) { + this.postProcessor.close(); + } + + ThreadContext.remove(); + SecurityUtils.setSecurityManager(null); + } + + /** + * postProcess call already has this logic built in, you don't need to call this everytime you + * call postProcess. But if your postProcess is pretty involved with preparations and you need to + * bypass it entirely, call this first. + */ + @Override + public boolean needPostProcess() { + return this.postProcessor != null; + } + + @Override + public Object postProcess(final String regionPath, final Object key, final Object value, + final boolean valueIsSerialized) { + return postProcess(null, regionPath, key, value, valueIsSerialized); + } + + @Override + public Object postProcess(Object principal, final String regionPath, final Object key, + final Object value, final boolean valueIsSerialized) { + if (!needPostProcess()) { + return value; + } + + if (principal == null) { + Subject subject = getSubject(); + if (subject == null) { + return value; + } + principal = (Serializable) subject.getPrincipal(); + } + + String regionName = StringUtils.stripStart(regionPath, "/"); + Object newValue; + + // if the data is a byte array, but the data itself is supposed to be an object, we need to + // deserialize it before we pass it to the callback. + if (valueIsSerialized && value instanceof byte[]) { + try { + Object oldObj = EntryEventImpl.deserialize((byte[]) value); + Object newObj = this.postProcessor.processRegionValue(principal, regionName, key, oldObj); + newValue = BlobHelper.serializeToBlob(newObj); + } catch (IOException | SerializationException e) { + throw new GemFireIOException("Exception de/serializing entry value", e); + } + } else { + newValue = this.postProcessor.processRegionValue(principal, regionName, key, value); + } + + return newValue; + } + + @Override + public SecurityManager getSecurityManager() { + return this.securityManager; + } + + @Override + public PostProcessor getPostProcessor() { + return this.postProcessor; + } + + @Override + public boolean isIntegratedSecurity() { + return true; + } + + @Override + public boolean isClientSecurityRequired() { + return true; + } + + @Override + public boolean isPeerSecurityRequired() { + return true; + } +} http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/internal/security/IntegratedSecurityService.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/security/IntegratedSecurityService.java b/geode-core/src/main/java/org/apache/geode/internal/security/IntegratedSecurityService.java deleted file mode 100644 index f9fade1..0000000 --- a/geode-core/src/main/java/org/apache/geode/internal/security/IntegratedSecurityService.java +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more contributor license - * agreements. See the NOTICE file distributed with this work for additional information regarding - * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. You may obtain a - * copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ -package org.apache.geode.internal.security; - -import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_CLIENT_AUTHENTICATOR; -import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_MANAGER; -import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_PEER_AUTHENTICATOR; -import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_POST_PROCESSOR; -import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_SHIRO_INIT; - -import org.apache.commons.lang.SerializationException; -import org.apache.commons.lang.StringUtils; -import org.apache.geode.GemFireIOException; -import org.apache.geode.internal.cache.EntryEventImpl; -import org.apache.geode.internal.logging.LogService; -import org.apache.geode.internal.security.shiro.CustomAuthRealm; -import org.apache.geode.internal.security.shiro.GeodeAuthenticationToken; -import org.apache.geode.internal.security.shiro.ShiroPrincipal; -import org.apache.geode.internal.util.BlobHelper; -import org.apache.geode.management.internal.security.ResourceOperation; -import org.apache.geode.security.AuthenticationFailedException; -import org.apache.geode.security.GemFireSecurityException; -import org.apache.geode.security.NotAuthorizedException; -import org.apache.geode.security.PostProcessor; -import org.apache.geode.security.ResourcePermission; -import org.apache.geode.security.ResourcePermission.Operation; -import org.apache.geode.security.ResourcePermission.Resource; -import org.apache.geode.security.SecurityManager; -import org.apache.logging.log4j.Logger; -import org.apache.shiro.SecurityUtils; -import org.apache.shiro.ShiroException; -import org.apache.shiro.UnavailableSecurityManagerException; -import org.apache.shiro.config.Ini.Section; -import org.apache.shiro.config.IniSecurityManagerFactory; -import org.apache.shiro.mgt.DefaultSecurityManager; -import org.apache.shiro.realm.Realm; -import org.apache.shiro.session.mgt.DefaultSessionManager; -import org.apache.shiro.session.mgt.SessionManager; -import org.apache.shiro.subject.Subject; -import org.apache.shiro.subject.support.SubjectThreadState; -import org.apache.shiro.util.ThreadContext; -import org.apache.shiro.util.ThreadState; - -import java.io.IOException; -import java.io.Serializable; -import java.security.AccessController; -import java.util.Properties; -import java.util.Set; -import java.util.concurrent.Callable; - -public class IntegratedSecurityService implements SecurityService { - - private static Logger logger = LogService.getLogger(LogService.SECURITY_LOGGER_NAME); - - private static SecurityService defaultInstance = new IntegratedSecurityService(); - - public static SecurityService getSecurityService() { - return defaultInstance; - } - - private IntegratedSecurityService() {} - - private PostProcessor postProcessor; - private SecurityManager securityManager; - - private Boolean isIntegratedSecurity; - - private boolean isClientAuthenticator; // is there a SECURITY_CLIENT_AUTHENTICATOR - private boolean isPeerAuthenticator; // is there a SECURITY_PEER_AUTHENTICATOR - - /** - * It first looks the shiro subject in AccessControlContext since JMX will use multiple threads to - * process operations from the same client, then it looks into Shiro's thead context. - * - * @return the shiro subject, null if security is not enabled - */ - public Subject getSubject() { - if (!isIntegratedSecurity()) { - return null; - } - - Subject currentUser = null; - - // First try get the principal out of AccessControlContext instead of Shiro's Thread context - // since threads can be shared between JMX clients. - javax.security.auth.Subject jmxSubject = - javax.security.auth.Subject.getSubject(AccessController.getContext()); - - if (jmxSubject != null) { - Set principals = jmxSubject.getPrincipals(ShiroPrincipal.class); - if (principals.size() > 0) { - ShiroPrincipal principal = principals.iterator().next(); - currentUser = principal.getSubject(); - ThreadContext.bind(currentUser); - return currentUser; - } - } - - // in other cases like rest call, client operations, we get it from the current thread - currentUser = SecurityUtils.getSubject(); - - if (currentUser == null || currentUser.getPrincipal() == null) { - throw new GemFireSecurityException("Error: Anonymous User"); - } - - return currentUser; - } - - /** - * @return null if security is not enabled, otherwise return a shiro subject - */ - public Subject login(Properties credentials) { - if (!isIntegratedSecurity()) { - return null; - } - - if (credentials == null) - return null; - - // this makes sure it starts with a clean user object - ThreadContext.remove(); - - Subject currentUser = SecurityUtils.getSubject(); - GeodeAuthenticationToken token = new GeodeAuthenticationToken(credentials); - try { - logger.debug("Logging in " + token.getPrincipal()); - currentUser.login(token); - } catch (ShiroException e) { - logger.info(e.getMessage(), e); - throw new AuthenticationFailedException( - "Authentication error. Please check your credentials.", e); - } - - return currentUser; - } - - public void logout() { - Subject currentUser = getSubject(); - if (currentUser == null) { - return; - } - - try { - logger.debug("Logging out " + currentUser.getPrincipal()); - currentUser.logout(); - } catch (ShiroException e) { - logger.info(e.getMessage(), e); - throw new GemFireSecurityException(e.getMessage(), e); - } - // clean out Shiro's thread local content - ThreadContext.remove(); - } - - public Callable associateWith(Callable callable) { - Subject currentUser = getSubject(); - if (currentUser == null) { - return callable; - } - - return currentUser.associateWith(callable); - } - - /** - * this binds the passed-in subject to the executing thread, normally, you would do this: - * - * ThreadState state = null; try{ state = IntegratedSecurityService.bindSubject(subject); //do the - * rest of the work as this subject } finally{ if(state!=null) state.clear(); } - */ - public ThreadState bindSubject(Subject subject) { - if (subject == null) { - return null; - } - - ThreadState threadState = new SubjectThreadState(subject); - threadState.bind(); - return threadState; - } - - public void authorize(ResourceOperation resourceOperation) { - if (resourceOperation == null) { - return; - } - - authorize(resourceOperation.resource().name(), resourceOperation.operation().name(), null); - } - - public void authorizeClusterManage() { - authorize("CLUSTER", "MANAGE"); - } - - public void authorizeClusterWrite() { - authorize("CLUSTER", "WRITE"); - } - - public void authorizeClusterRead() { - authorize("CLUSTER", "READ"); - } - - public void authorizeDataManage() { - authorize("DATA", "MANAGE"); - } - - public void authorizeDataWrite() { - authorize("DATA", "WRITE"); - } - - public void authorizeDataRead() { - authorize("DATA", "READ"); - } - - public void authorizeRegionManage(String regionName) { - authorize("DATA", "MANAGE", regionName); - } - - public void authorizeRegionManage(String regionName, String key) { - authorize("DATA", "MANAGE", regionName, key); - } - - public void authorizeRegionWrite(String regionName) { - authorize("DATA", "WRITE", regionName); - } - - public void authorizeRegionWrite(String regionName, String key) { - authorize("DATA", "WRITE", regionName, key); - } - - public void authorizeRegionRead(String regionName) { - authorize("DATA", "READ", regionName); - } - - public void authorizeRegionRead(String regionName, String key) { - authorize("DATA", "READ", regionName, key); - } - - public void authorize(String resource, String operation) { - authorize(resource, operation, null); - } - - public void authorize(String resource, String operation, String regionName) { - authorize(resource, operation, regionName, null); - } - - public void authorize(String resource, String operation, String regionName, String key) { - regionName = StringUtils.stripStart(regionName, "/"); - authorize(new ResourcePermission(resource, operation, regionName, key)); - } - - public void authorize(ResourcePermission context) { - Subject currentUser = getSubject(); - if (currentUser == null) { - return; - } - - if (context == null) { - return; - } - - if (context.getResource() == Resource.NULL && context.getOperation() == Operation.NULL) { - return; - } - - try { - currentUser.checkPermission(context); - } catch (ShiroException e) { - String msg = currentUser.getPrincipal() + " not authorized for " + context; - logger.info(msg); - throw new NotAuthorizedException(msg, e); - } - } - - /** - * initialize Shiro's Security Manager and Security Utilities - */ - public void initSecurity(Properties securityProps) { - if (securityProps == null) { - return; - } - - String shiroConfig = securityProps.getProperty(SECURITY_SHIRO_INIT); - String securityManagerConfig = securityProps.getProperty(SECURITY_MANAGER); - String clientAuthenticatorConfig = securityProps.getProperty(SECURITY_CLIENT_AUTHENTICATOR); - String peerAuthenticatorConfig = securityProps.getProperty(SECURITY_PEER_AUTHENTICATOR); - - if (StringUtils.isNotBlank(shiroConfig)) { - IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:" + shiroConfig); - - // we will need to make sure that shiro uses a case sensitive permission resolver - Section main = factory.getIni().addSection("main"); - main.put("geodePermissionResolver", - "org.apache.geode.internal.security.shiro.GeodePermissionResolver"); - if (!main.containsKey("iniRealm.permissionResolver")) { - main.put("iniRealm.permissionResolver", "$geodePermissionResolver"); - } - - org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance(); - SecurityUtils.setSecurityManager(securityManager); - isIntegratedSecurity = true; - isClientAuthenticator = false; - isPeerAuthenticator = false; - } - // only set up shiro realm if user has implemented SecurityManager - else if (StringUtils.isNotBlank(securityManagerConfig)) { - SecurityManager securityManager = SecurityService - .getObjectOfTypeFromClassName(securityManagerConfig, SecurityManager.class); - securityManager.init(securityProps); - this.setSecurityManager(securityManager); - } else { - isIntegratedSecurity = null; - isClientAuthenticator = StringUtils.isNotBlank(clientAuthenticatorConfig); - isPeerAuthenticator = StringUtils.isNotBlank(peerAuthenticatorConfig); - } - - // this initializes the post processor - String customPostProcessor = securityProps.getProperty(SECURITY_POST_PROCESSOR); - if (StringUtils.isNotBlank(customPostProcessor)) { - postProcessor = - SecurityService.getObjectOfTypeFromClassName(customPostProcessor, PostProcessor.class); - postProcessor.init(securityProps); - } else { - postProcessor = null; - } - } - - public void close() { - if (securityManager != null) { - securityManager.close(); - securityManager = null; - } - - if (postProcessor != null) { - postProcessor.close(); - postProcessor = null; - } - ThreadContext.remove(); - SecurityUtils.setSecurityManager(null); - isIntegratedSecurity = null; - isClientAuthenticator = false; - isPeerAuthenticator = false; - } - - /** - * postProcess call already has this logic built in, you don't need to call this everytime you - * call postProcess. But if your postProcess is pretty involved with preparations and you need to - * bypass it entirely, call this first. - */ - public boolean needPostProcess() { - return (isIntegratedSecurity() && postProcessor != null); - } - - public Object postProcess(String regionPath, Object key, Object value, - boolean valueIsSerialized) { - return postProcess(null, regionPath, key, value, valueIsSerialized); - } - - public Object postProcess(Object principal, String regionPath, Object key, Object value, - boolean valueIsSerialized) { - if (!needPostProcess()) - return value; - - if (principal == null) { - Subject subject = getSubject(); - if (subject == null) - return value; - principal = (Serializable) subject.getPrincipal(); - } - - String regionName = StringUtils.stripStart(regionPath, "/"); - Object newValue = null; - - // if the data is a byte array, but the data itself is supposed to be an object, we need to - // desearized it before we pass - // it to the callback. - if (valueIsSerialized && value instanceof byte[]) { - try { - Object oldObj = EntryEventImpl.deserialize((byte[]) value); - Object newObj = postProcessor.processRegionValue(principal, regionName, key, oldObj); - newValue = BlobHelper.serializeToBlob(newObj); - } catch (IOException | SerializationException e) { - throw new GemFireIOException("Exception de/serializing entry value", e); - } - } else { - newValue = postProcessor.processRegionValue(principal, regionName, key, value); - } - - return newValue; - } - - public SecurityManager getSecurityManager() { - return securityManager; - } - - public void setSecurityManager(SecurityManager securityManager) { - if (securityManager == null) { - return; - } - - this.securityManager = securityManager; - Realm realm = new CustomAuthRealm(securityManager); - DefaultSecurityManager shiroManager = new DefaultSecurityManager(realm); - SecurityUtils.setSecurityManager(shiroManager); - increaseShiroGlobalSessionTimeout(shiroManager); - - isIntegratedSecurity = true; - isClientAuthenticator = false; - isPeerAuthenticator = false; - } - - private void increaseShiroGlobalSessionTimeout(final DefaultSecurityManager shiroManager) { - SessionManager sessionManager = shiroManager.getSessionManager(); - if (DefaultSessionManager.class.isInstance(sessionManager)) { - DefaultSessionManager defaultSessionManager = (DefaultSessionManager) sessionManager; - defaultSessionManager.setGlobalSessionTimeout(Long.MAX_VALUE); - long value = defaultSessionManager.getGlobalSessionTimeout(); - if (value != Long.MAX_VALUE) { - logger.error("Unable to set Shiro Global Session Timeout. Current value is '{}'.", value); - } - } else { - logger.error("Unable to set Shiro Global Session Timeout. Current SessionManager is '{}'.", - sessionManager == null ? "null" : sessionManager.getClass()); - } - } - - public PostProcessor getPostProcessor() { - return postProcessor; - } - - public void setPostProcessor(PostProcessor postProcessor) { - if (postProcessor == null) { - return; - } - - this.postProcessor = postProcessor; - } - - /** - * check if Shiro's security manager is configured - * - * @return true if configured, false if not - */ - public boolean isIntegratedSecurity() { - if (isIntegratedSecurity != null) { - return isIntegratedSecurity; - } - - try { - isIntegratedSecurity = (SecurityUtils.getSecurityManager() != null); - } catch (UnavailableSecurityManagerException e) { - isIntegratedSecurity = false; - } - return isIntegratedSecurity; - } - - public boolean isClientSecurityRequired() { - return isClientAuthenticator || isIntegratedSecurity(); - } - - public boolean isPeerSecurityRequired() { - return isPeerAuthenticator || isIntegratedSecurity(); - } -} http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/internal/security/LegacySecurityService.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/security/LegacySecurityService.java b/geode-core/src/main/java/org/apache/geode/internal/security/LegacySecurityService.java new file mode 100644 index 0000000..ef92bb7 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/security/LegacySecurityService.java @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package org.apache.geode.internal.security; + +import java.util.Properties; +import java.util.concurrent.Callable; + +import org.apache.shiro.subject.Subject; +import org.apache.shiro.util.ThreadState; + +import org.apache.geode.management.internal.security.ResourceOperation; +import org.apache.geode.security.PostProcessor; +import org.apache.geode.security.ResourcePermission; +import org.apache.geode.security.SecurityManager; + +/** + * Legacy security service with ClientAuthenticator and/or PeerAuthenticator. + */ +public class LegacySecurityService implements SecurityService { + + private final boolean hasClientAuthenticator; + + private final boolean hasPeerAuthenticator; + + LegacySecurityService(final String clientAuthenticator, final String peerAuthenticator) { + this.hasClientAuthenticator = clientAuthenticator != null; + this.hasPeerAuthenticator = peerAuthenticator != null; + } + + @Override + public void initSecurity(final Properties securityProps) { + // nothing + } + + @Override + public ThreadState bindSubject(final Subject subject) { + return null; + } + + @Override + public Subject getSubject() { + return null; + } + + @Override + public Subject login(final Properties credentials) { + return null; + } + + @Override + public void logout() { + // nothing + } + + @Override + public Callable associateWith(final Callable callable) { + return null; + } + + @Override + public void authorize(final ResourceOperation resourceOperation) { + // nothing + } + + @Override + public void authorizeClusterManage() { + // nothing + } + + @Override + public void authorizeClusterWrite() { + // nothing + } + + @Override + public void authorizeClusterRead() { + // nothing + } + + @Override + public void authorizeDataManage() { + // nothing + } + + @Override + public void authorizeDataWrite() { + // nothing + } + + @Override + public void authorizeDataRead() { + // nothing + } + + @Override + public void authorizeRegionManage(final String regionName) { + // nothing + } + + @Override + public void authorizeRegionManage(final String regionName, final String key) { + // nothing + } + + @Override + public void authorizeRegionWrite(final String regionName) { + // nothing + } + + @Override + public void authorizeRegionWrite(final String regionName, final String key) { + // nothing + } + + @Override + public void authorizeRegionRead(final String regionName) { + // nothing + } + + @Override + public void authorizeRegionRead(final String regionName, final String key) { + // nothing + } + + @Override + public void authorize(final String resource, final String operation) { + // nothing + } + + @Override + public void authorize(final String resource, final String operation, final String regionName) { + // nothing + } + + @Override + public void authorize(final String resource, final String operation, final String regionName, + final String key) { + // nothing + } + + @Override + public void authorize(final ResourcePermission context) { + // nothing + } + + @Override + public void close() { + // nothing + } + + @Override + public boolean needPostProcess() { + return false; + } + + @Override + public Object postProcess(final String regionPath, final Object key, final Object value, + final boolean valueIsSerialized) { + return value; + } + + @Override + public Object postProcess(final Object principal, final String regionPath, final Object key, + final Object value, final boolean valueIsSerialized) { + return value; + } + + @Override + public boolean isClientSecurityRequired() { + return this.hasClientAuthenticator; + } + + @Override + public boolean isIntegratedSecurity() { + return false; + } + + @Override + public boolean isPeerSecurityRequired() { + return this.hasPeerAuthenticator; + } + + @Override + public SecurityManager getSecurityManager() { + return null; + } + + @Override + public PostProcessor getPostProcessor() { + return null; + } +} http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/internal/security/SecurityService.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/security/SecurityService.java b/geode-core/src/main/java/org/apache/geode/internal/security/SecurityService.java index 14784c3..be81582 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/security/SecurityService.java +++ b/geode-core/src/main/java/org/apache/geode/internal/security/SecurityService.java @@ -14,22 +14,20 @@ */ package org.apache.geode.internal.security; -import org.apache.geode.internal.ClassLoadUtil; -import org.apache.geode.management.internal.security.ResourceConstants; import org.apache.geode.management.internal.security.ResourceOperation; -import org.apache.geode.security.GemFireSecurityException; import org.apache.geode.security.PostProcessor; import org.apache.geode.security.ResourcePermission; import org.apache.geode.security.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.ThreadState; -import java.lang.reflect.Method; import java.util.Properties; import java.util.concurrent.Callable; public interface SecurityService { + void initSecurity(Properties securityProps); + ThreadState bindSubject(Subject subject); Subject getSubject(); @@ -74,8 +72,6 @@ public interface SecurityService { void authorize(ResourcePermission context); - void initSecurity(Properties securityProps); - void close(); boolean needPostProcess(); @@ -93,91 +89,6 @@ public interface SecurityService { SecurityManager getSecurityManager(); - void setSecurityManager(SecurityManager securityManager); - PostProcessor getPostProcessor(); - void setPostProcessor(PostProcessor postProcessor); - - /** - * this method would never return null, it either throws an exception or returns an object - */ - public static T getObjectOfTypeFromClassName(String className, Class expectedClazz) { - Class actualClass = null; - try { - actualClass = ClassLoadUtil.classFromName(className); - } catch (Exception ex) { - throw new GemFireSecurityException("Instance could not be obtained, " + ex.toString(), ex); - } - - if (!expectedClazz.isAssignableFrom(actualClass)) { - throw new GemFireSecurityException( - "Instance could not be obtained. Expecting a " + expectedClazz.getName() + " class."); - } - - T actualObject = null; - try { - actualObject = (T) actualClass.newInstance(); - } catch (Exception e) { - throw new GemFireSecurityException( - "Instance could not be obtained. Error instantiating " + actualClass.getName(), e); - } - return actualObject; - } - - /** - * this method would never return null, it either throws an exception or returns an object - */ - public static T getObjectOfTypeFromFactoryMethod(String factoryMethodName, - Class expectedClazz) { - T actualObject = null; - try { - Method factoryMethod = ClassLoadUtil.methodFromName(factoryMethodName); - actualObject = (T) factoryMethod.invoke(null, (Object[]) null); - } catch (Exception e) { - throw new GemFireSecurityException("Instance could not be obtained from " + factoryMethodName, - e); - } - - if (actualObject == null) { - throw new GemFireSecurityException( - "Instance could not be obtained from " + factoryMethodName); - } - - return actualObject; - } - - /** - * this method would never return null, it either throws an exception or returns an object - * - * @return an object of type expectedClazz. This method would never return null. It either returns - * an non-null object or throws exception. - */ - public static T getObjectOfType(String classOrMethod, Class expectedClazz) { - T object = null; - try { - object = getObjectOfTypeFromClassName(classOrMethod, expectedClazz); - } catch (Exception e) { - object = getObjectOfTypeFromFactoryMethod(classOrMethod, expectedClazz); - } - return object; - } - - public static Properties getCredentials(Properties securityProps) { - Properties credentials = null; - if (securityProps.containsKey(ResourceConstants.USER_NAME) - && securityProps.containsKey(ResourceConstants.PASSWORD)) { - credentials = new Properties(); - credentials.setProperty(ResourceConstants.USER_NAME, - securityProps.getProperty(ResourceConstants.USER_NAME)); - credentials.setProperty(ResourceConstants.PASSWORD, - securityProps.getProperty(ResourceConstants.PASSWORD)); - } - return credentials; - } - - static SecurityService getSecurityService() { - return IntegratedSecurityService.getSecurityService(); - } - } http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/internal/security/SecurityServiceFactory.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/security/SecurityServiceFactory.java b/geode-core/src/main/java/org/apache/geode/internal/security/SecurityServiceFactory.java new file mode 100644 index 0000000..02f34f1 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/security/SecurityServiceFactory.java @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package org.apache.geode.internal.security; + +import static org.apache.commons.lang.StringUtils.isNotBlank; +import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_CLIENT_AUTHENTICATOR; +import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_MANAGER; +import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_PEER_AUTHENTICATOR; +import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_POST_PROCESSOR; +import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_SHIRO_INIT; + +import org.apache.geode.distributed.internal.DistributionConfig; +import org.apache.geode.internal.cache.CacheConfig; +import org.apache.geode.internal.cache.GemFireCacheImpl; +import org.apache.geode.internal.cache.InternalCache; +import org.apache.geode.internal.security.shiro.ConfigInitializer; +import org.apache.geode.internal.security.shiro.RealmInitializer; +import org.apache.geode.security.PostProcessor; +import org.apache.geode.security.SecurityManager; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.UnavailableSecurityManagerException; + +import java.util.Properties; + +public class SecurityServiceFactory { + + private SecurityServiceFactory() { + // do not instantiate + } + + public static SecurityService create(CacheConfig cacheConfig, + DistributionConfig distributionConfig) { + Properties securityConfig = getSecurityConfig(distributionConfig); + SecurityManager securityManager = + getSecurityManager(getSecurityManagerFromConfig(cacheConfig), securityConfig); + PostProcessor postProcessor = + getPostProcessor(getPostProcessorFromConfig(cacheConfig), securityConfig); + return create(distributionConfig, securityManager, postProcessor); + } + + /** + * Creates and initializes SecurityService. Initialization will invoke init on both + * SecurityManager and PostProcessor if they are specified. + */ + public static SecurityService create(DistributionConfig distributionConfig, + SecurityManager securityManager, PostProcessor postProcessor) { + Properties securityConfig = getSecurityConfig(distributionConfig); + + securityManager = getSecurityManager(securityManager, securityConfig); + postProcessor = getPostProcessor(postProcessor, securityConfig); + + SecurityService securityService = create(securityConfig, securityManager, postProcessor); + initialize(securityService, distributionConfig); + return securityService; + } + + public static SecurityService create() { + return new DisabledSecurityService(); + } + + public static SecurityService create(Properties securityConfig, SecurityManager securityManager, + PostProcessor postProcessor) { + SecurityServiceType type = determineType(securityConfig, securityManager, postProcessor); + switch (type) { + case CUSTOM: + String shiroConfig = getProperty(securityConfig, SECURITY_SHIRO_INIT); + if (isNotBlank(shiroConfig)) { + new ConfigInitializer().initialize(shiroConfig); + } + return new CustomSecurityService(postProcessor); + case ENABLED: + return new EnabledSecurityService(securityManager, postProcessor, new RealmInitializer()); + case LEGACY: + String clientAuthenticator = getProperty(securityConfig, SECURITY_CLIENT_AUTHENTICATOR); + String peerAuthenticator = getProperty(securityConfig, SECURITY_PEER_AUTHENTICATOR); + return new LegacySecurityService(clientAuthenticator, peerAuthenticator); + default: + return new DisabledSecurityService(); + } + } + + public static SecurityService findSecurityService() { + InternalCache cache = GemFireCacheImpl.getInstance(); + if (cache != null) { + return cache.getSecurityService(); + } + return SecurityServiceFactory.create(); + } + + static SecurityServiceType determineType(Properties securityConfig, + SecurityManager securityManager, PostProcessor postProcessor) { + boolean hasShiroConfig = hasProperty(securityConfig, SECURITY_SHIRO_INIT); + if (hasShiroConfig) { + return SecurityServiceType.CUSTOM; + } + + boolean hasSecurityManager = + securityManager != null || hasProperty(securityConfig, SECURITY_MANAGER); + if (hasSecurityManager) { + return SecurityServiceType.ENABLED; + } + + boolean hasClientAuthenticator = hasProperty(securityConfig, SECURITY_CLIENT_AUTHENTICATOR); + boolean hasPeerAuthenticator = hasProperty(securityConfig, SECURITY_PEER_AUTHENTICATOR); + if (hasClientAuthenticator || hasPeerAuthenticator) { + return SecurityServiceType.LEGACY; + } + + boolean isShiroInUse = isShiroInUse(); + if (isShiroInUse) { + return SecurityServiceType.CUSTOM; + } + + return SecurityServiceType.DISABLED; + } + + static SecurityManager getSecurityManager(SecurityManager securityManager, + Properties securityConfig) { + if (securityManager != null) { + return securityManager; + } + + String securityManagerConfig = getProperty(securityConfig, SECURITY_MANAGER); + if (isNotBlank(securityManagerConfig)) { + securityManager = CallbackInstantiator.getObjectOfTypeFromClassName(securityManagerConfig, + SecurityManager.class); + } + + return securityManager; + } + + static PostProcessor getPostProcessor(PostProcessor postProcessor, Properties securityConfig) { + if (postProcessor != null) { + return postProcessor; + } + + String postProcessorConfig = getProperty(securityConfig, SECURITY_POST_PROCESSOR); + if (isNotBlank(postProcessorConfig)) { + postProcessor = CallbackInstantiator.getObjectOfTypeFromClassName(postProcessorConfig, + PostProcessor.class); + } + + return postProcessor; + } + + private static boolean isShiroInUse() { + try { + return SecurityUtils.getSecurityManager() != null; + } catch (UnavailableSecurityManagerException ignore) { + return false; + } + } + + private static Properties getSecurityConfig(DistributionConfig distributionConfig) { + if (distributionConfig == null) { + return new Properties(); + } + return distributionConfig.getSecurityProps(); + } + + private static SecurityManager getSecurityManagerFromConfig(CacheConfig cacheConfig) { + if (cacheConfig == null) { + return null; + } + return cacheConfig.getSecurityManager(); + } + + private static PostProcessor getPostProcessorFromConfig(CacheConfig cacheConfig) { + if (cacheConfig == null) { + return null; + } + return cacheConfig.getPostProcessor(); + } + + private static boolean hasProperty(Properties securityConfig, String key) { + return securityConfig != null && getProperty(securityConfig, key) != null; + } + + private static String getProperty(Properties securityConfig, String key) { + if (securityConfig == null) { + return null; + } + return securityConfig.getProperty(key); + } + + private static void initialize(SecurityService securityService, + DistributionConfig distributionConfig) { + if (securityService != null && distributionConfig != null) { + securityService.initSecurity(distributionConfig.getSecurityProps()); + } + } +} http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/internal/security/SecurityServiceType.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/security/SecurityServiceType.java b/geode-core/src/main/java/org/apache/geode/internal/security/SecurityServiceType.java new file mode 100644 index 0000000..8ae76d2 --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/security/SecurityServiceType.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package org.apache.geode.internal.security; + +public enum SecurityServiceType { + /** Integrated Security is Enabled */ + ENABLED, + /** Security is Disabled */ + DISABLED, + /** Legacy Security is Enabled */ + LEGACY, + /** Shiro Config is specified */ + CUSTOM, + /** Shiro is already configured with SecurityManager */ + EXTERNAL +} http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/internal/security/shiro/ConfigInitializer.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/security/shiro/ConfigInitializer.java b/geode-core/src/main/java/org/apache/geode/internal/security/shiro/ConfigInitializer.java new file mode 100644 index 0000000..60f014b --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/security/shiro/ConfigInitializer.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package org.apache.geode.internal.security.shiro; + +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.config.Ini.Section; +import org.apache.shiro.config.IniSecurityManagerFactory; +import org.apache.shiro.mgt.SecurityManager; + +public class ConfigInitializer { + + public ConfigInitializer() { + // nothing + } + + public void initialize(String shiroConfig) { + IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:" + shiroConfig); + + // we will need to make sure that shiro uses a case sensitive permission resolver + Section main = factory.getIni().addSection("main"); + main.put("geodePermissionResolver", GeodePermissionResolver.class.getName()); + if (!main.containsKey("iniRealm.permissionResolver")) { + main.put("iniRealm.permissionResolver", "$geodePermissionResolver"); + } + + // logs "Users or Roles are already populated. Configured Ini instance will be ignored." + SecurityManager securityManager = factory.getInstance(); + SecurityUtils.setSecurityManager(securityManager); + } + +} http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/internal/security/shiro/CustomAuthRealm.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/security/shiro/CustomAuthRealm.java b/geode-core/src/main/java/org/apache/geode/internal/security/shiro/CustomAuthRealm.java index ff30882..51449fd 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/security/shiro/CustomAuthRealm.java +++ b/geode-core/src/main/java/org/apache/geode/internal/security/shiro/CustomAuthRealm.java @@ -17,6 +17,7 @@ package org.apache.geode.internal.security.shiro; import java.io.Serializable; import java.util.Properties; +import org.apache.geode.internal.security.CallbackInstantiator; import org.apache.geode.security.ResourcePermission; import org.apache.geode.security.SecurityManager; import org.apache.shiro.authc.AuthenticationException; @@ -28,8 +29,6 @@ import org.apache.shiro.authz.Permission; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; -import org.apache.geode.internal.security.SecurityService; - public class CustomAuthRealm extends AuthorizingRealm { private static final String REALM_NAME = "CUSTOMAUTHREALM"; @@ -54,8 +53,8 @@ public class CustomAuthRealm extends AuthorizingRealm { * @param securityProperties the security properties to initialize SecurityManager with */ public CustomAuthRealm(String authenticatorFactory, Properties securityProperties) { - this.securityManager = - SecurityService.getObjectOfTypeFromClassName(authenticatorFactory, SecurityManager.class); + this.securityManager = CallbackInstantiator.getObjectOfTypeFromClassName(authenticatorFactory, + SecurityManager.class); this.securityManager.init(securityProperties); } http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/internal/security/shiro/JMXShiroAuthenticator.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/security/shiro/JMXShiroAuthenticator.java b/geode-core/src/main/java/org/apache/geode/internal/security/shiro/JMXShiroAuthenticator.java index 2a641d3..4f6c3cf 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/security/shiro/JMXShiroAuthenticator.java +++ b/geode-core/src/main/java/org/apache/geode/internal/security/shiro/JMXShiroAuthenticator.java @@ -14,7 +14,11 @@ */ package org.apache.geode.internal.security.shiro; -import static org.apache.geode.management.internal.security.ResourceConstants.*; +import static org.apache.geode.management.internal.security.ResourceConstants.MISSING_CREDENTIALS_MESSAGE; + +import org.apache.geode.internal.security.SecurityService; +import org.apache.geode.management.internal.security.ResourceConstants; +import org.apache.geode.security.AuthenticationFailedException; import java.security.Principal; import java.util.Collections; @@ -26,18 +30,16 @@ import javax.management.remote.JMXConnectionNotification; import javax.management.remote.JMXPrincipal; import javax.security.auth.Subject; -import org.apache.geode.internal.security.IntegratedSecurityService; -import org.apache.geode.internal.security.SecurityService; -import org.apache.geode.management.internal.security.ResourceConstants; -import org.apache.geode.security.AuthenticationFailedException; - /** * this will make JMX authentication to use Shiro for Authentication */ - public class JMXShiroAuthenticator implements JMXAuthenticator, NotificationListener { - private SecurityService securityService = IntegratedSecurityService.getSecurityService(); + private final SecurityService securityService; + + public JMXShiroAuthenticator(SecurityService securityService) { + this.securityService = securityService; + } @Override public Subject authenticate(Object credentials) { @@ -64,8 +66,8 @@ public class JMXShiroAuthenticator implements JMXAuthenticator, NotificationList principal = new ShiroPrincipal(shiroSubject); } - return new Subject(true, Collections.singleton(principal), Collections.EMPTY_SET, - Collections.EMPTY_SET); + return new Subject(true, Collections.singleton(principal), Collections.emptySet(), + Collections.emptySet()); } @Override http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/internal/security/shiro/RealmInitializer.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/security/shiro/RealmInitializer.java b/geode-core/src/main/java/org/apache/geode/internal/security/shiro/RealmInitializer.java new file mode 100644 index 0000000..978c4dd --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/security/shiro/RealmInitializer.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package org.apache.geode.internal.security.shiro; + +import org.apache.geode.internal.logging.LogService; +import org.apache.geode.security.SecurityManager; +import org.apache.logging.log4j.Logger; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.mgt.DefaultSecurityManager; +import org.apache.shiro.realm.Realm; +import org.apache.shiro.session.mgt.DefaultSessionManager; +import org.apache.shiro.session.mgt.SessionManager; + +public class RealmInitializer { + private static Logger logger = LogService.getLogger(LogService.SECURITY_LOGGER_NAME); + + public RealmInitializer() { + // nothing + } + + public void initialize(final SecurityManager securityManager) { + Realm realm = new CustomAuthRealm(securityManager); + DefaultSecurityManager shiroManager = new DefaultSecurityManager(realm); + SecurityUtils.setSecurityManager(shiroManager); + increaseShiroGlobalSessionTimeout(shiroManager); + } + + private void increaseShiroGlobalSessionTimeout(final DefaultSecurityManager shiroManager) { + SessionManager sessionManager = shiroManager.getSessionManager(); + if (DefaultSessionManager.class.isInstance(sessionManager)) { + DefaultSessionManager defaultSessionManager = (DefaultSessionManager) sessionManager; + defaultSessionManager.setGlobalSessionTimeout(Long.MAX_VALUE); + long value = defaultSessionManager.getGlobalSessionTimeout(); + if (value != Long.MAX_VALUE) { + logger.error("Unable to set Shiro Global Session Timeout. Current value is '{}'.", value); + } + } else { + logger.error("Unable to set Shiro Global Session Timeout. Current SessionManager is '{}'.", + sessionManager == null ? "null" : sessionManager.getClass()); + } + } +} http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/management/cli/CommandService.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/cli/CommandService.java b/geode-core/src/main/java/org/apache/geode/management/cli/CommandService.java index 767cf94..55957b2 100644 --- a/geode-core/src/main/java/org/apache/geode/management/cli/CommandService.java +++ b/geode-core/src/main/java/org/apache/geode/management/cli/CommandService.java @@ -19,6 +19,7 @@ import java.util.Map; import org.apache.geode.cache.Cache; import org.apache.geode.cache.CacheClosedException; +import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.i18n.LocalizedStrings; import org.apache.geode.management.DependenciesNotFoundException; import org.apache.geode.management.internal.cli.CliUtil; @@ -124,7 +125,7 @@ public abstract class CommandService { .toLocalizedString(new Object[] {nonExistingDependency})); } - localCommandService = new MemberCommandService(cache); + localCommandService = new MemberCommandService((InternalCache) cache); } return localCommandService; http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java b/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java index 3e6e4484..554dc66 100755 --- a/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java @@ -91,7 +91,7 @@ public class ManagementAgent { private JMXConnectorServer jmxConnectorServer; private JMXShiroAuthenticator shiroAuthenticator; private final DistributionConfig config; - private SecurityService securityService = SecurityService.getSecurityService(); + private final SecurityService securityService; private boolean isHttpServiceRunning = false; /** @@ -103,8 +103,9 @@ public class ManagementAgent { private static final String PULSE_USESSL_MANAGER = "pulse.useSSL.manager"; private static final String PULSE_USESSL_LOCATOR = "pulse.useSSL.locator"; - public ManagementAgent(DistributionConfig config) { + public ManagementAgent(DistributionConfig config, SecurityService securityService) { this.config = config; + this.securityService = securityService; } public synchronized boolean isRunning() { @@ -465,14 +466,14 @@ public class ManagementAgent { }; if (securityService.isIntegratedSecurity()) { - shiroAuthenticator = new JMXShiroAuthenticator(); + shiroAuthenticator = new JMXShiroAuthenticator(this.securityService); env.put(JMXConnectorServer.AUTHENTICATOR, shiroAuthenticator); jmxConnectorServer.addNotificationListener(shiroAuthenticator, null, jmxConnectorServer.getAttributes()); // always going to assume authorization is needed as well, if no custom AccessControl, then // the CustomAuthRealm // should take care of that - MBeanServerWrapper mBeanServerWrapper = new MBeanServerWrapper(); + MBeanServerWrapper mBeanServerWrapper = new MBeanServerWrapper(this.securityService); jmxConnectorServer.setMBeanServerForwarder(mBeanServerWrapper); registerAccessControlMBean(); } else { @@ -501,7 +502,7 @@ public class ManagementAgent { private void registerAccessControlMBean() { try { - AccessControlMBean acc = new AccessControlMBean(); + AccessControlMBean acc = new AccessControlMBean(this.securityService); ObjectName accessControlMBeanON = new ObjectName(ResourceConstants.OBJECT_NAME_ACCESSCONTROL); MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer(); http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java b/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java index fc8eb97..11402f1 100755 --- a/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java @@ -144,7 +144,7 @@ public class SystemManagementService extends BaseManagementService { this.notificationHub = new NotificationHub(repo); if (system.getConfig().getJmxManager()) { - this.agent = new ManagementAgent(system.getConfig()); + this.agent = new ManagementAgent(system.getConfig(), cache.getSecurityService()); } else { this.agent = null; } http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateAlterDestroyRegionCommands.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateAlterDestroyRegionCommands.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateAlterDestroyRegionCommands.java index ad40518..270972b 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateAlterDestroyRegionCommands.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/CreateAlterDestroyRegionCommands.java @@ -31,8 +31,6 @@ import org.apache.geode.distributed.internal.membership.InternalDistributedMembe import org.apache.geode.internal.ClassPathLoader; import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.i18n.LocalizedStrings; -import org.apache.geode.internal.security.IntegratedSecurityService; -import org.apache.geode.internal.security.SecurityService; import org.apache.geode.management.DistributedRegionMXBean; import org.apache.geode.management.DistributedSystemMXBean; import org.apache.geode.management.ManagementService; @@ -53,7 +51,6 @@ import org.apache.geode.management.internal.cli.functions.RegionCreateFunction; import org.apache.geode.management.internal.cli.functions.RegionDestroyFunction; import org.apache.geode.management.internal.cli.functions.RegionFunctionArgs; import org.apache.geode.management.internal.cli.i18n.CliStrings; -import org.apache.geode.management.internal.cli.result.CommandResultException; import org.apache.geode.management.internal.cli.result.ResultBuilder; import org.apache.geode.management.internal.cli.result.TabularResultData; import org.apache.geode.management.internal.cli.util.RegionPath; @@ -89,8 +86,6 @@ public class CreateAlterDestroyRegionCommands implements GfshCommand { public static final Set PERSISTENT_OVERFLOW_SHORTCUTS = new TreeSet<>(); - private SecurityService securityService = IntegratedSecurityService.getSecurityService(); - static { PERSISTENT_OVERFLOW_SHORTCUTS.add(RegionShortcut.PARTITION_PERSISTENT); PERSISTENT_OVERFLOW_SHORTCUTS.add(RegionShortcut.PARTITION_REDUNDANT_PERSISTENT); @@ -426,7 +421,7 @@ public class CreateAlterDestroyRegionCommands implements GfshCommand { Result result; AtomicReference xmlEntity = new AtomicReference<>(); - this.securityService.authorizeRegionManage(regionPath); + getCache().getSecurityService().authorizeRegionManage(regionPath); try { InternalCache cache = getCache(); http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DataCommands.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DataCommands.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DataCommands.java index cb9c4fe..887470d 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DataCommands.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DataCommands.java @@ -33,8 +33,6 @@ import org.apache.geode.cache.execute.ResultCollector; import org.apache.geode.cache.partition.PartitionRebalanceInfo; import org.apache.geode.distributed.DistributedMember; import org.apache.geode.internal.cache.InternalCache; -import org.apache.geode.internal.security.IntegratedSecurityService; -import org.apache.geode.internal.security.SecurityService; import org.apache.geode.management.DistributedRegionMXBean; import org.apache.geode.management.ManagementService; import org.apache.geode.management.cli.CliMetaData; @@ -46,6 +44,7 @@ import org.apache.geode.management.internal.cli.LogWrapper; import org.apache.geode.management.internal.cli.domain.DataCommandRequest; import org.apache.geode.management.internal.cli.domain.DataCommandResult; import org.apache.geode.management.internal.cli.functions.DataCommandFunction; +import org.apache.geode.management.internal.cli.functions.DataCommandFunction.SelectExecStep; import org.apache.geode.management.internal.cli.functions.ExportDataFunction; import org.apache.geode.management.internal.cli.functions.ImportDataFunction; import org.apache.geode.management.internal.cli.functions.RebalanceFunction; @@ -86,13 +85,21 @@ import java.util.concurrent.TimeoutException; */ public class DataCommands implements GfshCommand { - final int resultItemCount = 9; + private final int resultItemCount = 9; private final ExportDataFunction exportDataFunction = new ExportDataFunction(); private final ImportDataFunction importDataFunction = new ImportDataFunction(); - private SecurityService securityService = IntegratedSecurityService.getSecurityService(); + @Override + public Gfsh getGfsh() { + return Gfsh.getCurrentInstance(); + } + + @Override + public InternalCache getCache() { + return (InternalCache) CacheFactory.getAnyInstance(); + } @CliCommand(value = CliStrings.REBALANCE, help = CliStrings.REBALANCE__HELP) @CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_DATA, CliStrings.TOPIC_GEODE_REGION}) @@ -146,14 +153,14 @@ public class DataCommands implements GfshCommand { return executeRebalanceWithTimeout(includeRegions, excludeRegions, simulate); } - public ExecuteRebalanceWithTimeout(String[] includedRegions, String[] excludedRegions, + ExecuteRebalanceWithTimeout(String[] includedRegions, String[] excludedRegions, boolean toSimulate) { includeRegions = includedRegions; excludeRegions = excludedRegions; simulate = toSimulate; } - public Result executeRebalanceWithTimeout(String[] includeRegions, String[] excludeRegions, + Result executeRebalanceWithTimeout(String[] includeRegions, String[] excludeRegions, boolean simulate) { Result result = null; @@ -451,14 +458,14 @@ public class DataCommands implements GfshCommand { return result; } - public boolean checkMemberPresence(DistributedMember dsMember, InternalCache cache) { + private boolean checkMemberPresence(DistributedMember dsMember, InternalCache cache) { // check if member's presence just before executing function // this is to avoid running a function on departed members #47248 Set dsMemberList = CliUtil.getAllNormalMembers(cache); return dsMemberList.contains(dsMember); } - public String listOfAllMembers(ArrayList dsMemberList) { + private String listOfAllMembers(ArrayList dsMemberList) { StringBuilder listMembersId = new StringBuilder(); for (int j = 0; j < dsMemberList.size() - 1; j++) { listMembersId.append(dsMemberList.get(j).getId()); @@ -467,7 +474,7 @@ public class DataCommands implements GfshCommand { return listMembersId.toString(); } - protected CompositeResultData toCompositeResultData(CompositeResultData rebalanceResulteData, + private CompositeResultData toCompositeResultData(CompositeResultData rebalanceResulteData, ArrayList rstlist, int index, boolean simulate, InternalCache cache) { // add only if there are any valid regions in results @@ -623,7 +630,7 @@ public class DataCommands implements GfshCommand { return rebalanceResultData; } - public DistributedMember getAssociatedMembers(String region, final InternalCache cache) { + private DistributedMember getAssociatedMembers(String region, final InternalCache cache) { DistributedRegionMXBean bean = ManagementService.getManagementService(cache).getDistributedRegionMXBean(region); @@ -741,7 +748,7 @@ public class DataCommands implements GfshCommand { optionContext = ConverterHint.MEMBERIDNAME, mandatory = true, help = CliStrings.EXPORT_DATA__MEMBER__HELP) String memberNameOrId) { - this.securityService.authorizeRegionRead(regionName); + getCache().getSecurityService().authorizeRegionRead(regionName); final DistributedMember targetMember = CliUtil.getDistributedMemberByNameOrId(memberNameOrId); Result result; @@ -799,7 +806,7 @@ public class DataCommands implements GfshCommand { @CliOption(key = CliStrings.IMPORT_DATA__INVOKE_CALLBACKS, unspecifiedDefaultValue = "false", help = CliStrings.IMPORT_DATA__INVOKE_CALLBACKS__HELP) boolean invokeCallbacks) { - this.securityService.authorizeRegionWrite(regionName); + getCache().getSecurityService().authorizeRegionWrite(regionName); Result result; @@ -860,8 +867,8 @@ public class DataCommands implements GfshCommand { @CliOption(key = {CliStrings.PUT__PUTIFABSENT}, help = CliStrings.PUT__PUTIFABSENT__HELP, unspecifiedDefaultValue = "false") boolean putIfAbsent) { - this.securityService.authorizeRegionWrite(regionPath); InternalCache cache = getCache(); + cache.getSecurityService().authorizeRegionWrite(regionPath); DataCommandResult dataResult; if (StringUtils.isEmpty(regionPath)) { return makePresentationResult(DataCommandResult.createPutResult(key, null, null, @@ -931,9 +938,9 @@ public class DataCommands implements GfshCommand { @CliOption(key = CliStrings.GET__LOAD, unspecifiedDefaultValue = "true", specifiedDefaultValue = "true", help = CliStrings.GET__LOAD__HELP) Boolean loadOnCacheMiss) { - this.securityService.authorizeRegionRead(regionPath, key); InternalCache cache = getCache(); + cache.getSecurityService().authorizeRegionRead(regionPath, key); DataCommandResult dataResult; if (StringUtils.isEmpty(regionPath)) { @@ -959,7 +966,7 @@ public class DataCommands implements GfshCommand { request.setRegionName(regionPath); request.setValueClass(valueClass); request.setLoadOnCacheMiss(loadOnCacheMiss); - Subject subject = this.securityService.getSubject(); + Subject subject = cache.getSecurityService().getSubject(); if (subject != null) { request.setPrincipal(subject.getPrincipal()); } @@ -970,7 +977,8 @@ public class DataCommands implements GfshCommand { false); } } else { - dataResult = getfn.get(null, key, keyClass, valueClass, regionPath, loadOnCacheMiss); + dataResult = getfn.get(null, key, keyClass, valueClass, regionPath, loadOnCacheMiss, + cache.getSecurityService()); } dataResult.setKeyClass(keyClass); if (valueClass != null) { @@ -996,7 +1004,7 @@ public class DataCommands implements GfshCommand { help = CliStrings.LOCATE_ENTRY__RECURSIVE__HELP, unspecifiedDefaultValue = "false") boolean recursive) { - this.securityService.authorizeRegionRead(regionPath, key); + getCache().getSecurityService().authorizeRegionRead(regionPath, key); DataCommandResult dataResult; @@ -1059,9 +1067,9 @@ public class DataCommands implements GfshCommand { } if (removeAllKeys) { - this.securityService.authorizeRegionWrite(regionPath); + cache.getSecurityService().authorizeRegionWrite(regionPath); } else { - this.securityService.authorizeRegionWrite(regionPath, key); + cache.getSecurityService().authorizeRegionWrite(regionPath, key); } @SuppressWarnings("rawtypes") @@ -1107,7 +1115,7 @@ public class DataCommands implements GfshCommand { } Object[] arguments = new Object[] {query, stepName, interactive}; - CLIStep exec = new DataCommandFunction.SelectExecStep(arguments); + CLIStep exec = new SelectExecStep(arguments); CLIStep display = new DataCommandFunction.SelectDisplayStep(arguments); CLIStep move = new DataCommandFunction.SelectMoveStep(arguments); CLIStep quit = new DataCommandFunction.SelectQuitStep(arguments); @@ -1127,14 +1135,15 @@ public class DataCommands implements GfshCommand { } private static class MemberPRInfo { - public ArrayList dsMemberList; + ArrayList dsMemberList; public String region; - public MemberPRInfo() { + MemberPRInfo() { region = ""; dsMemberList = new ArrayList<>(); } + @Override public boolean equals(Object o2) { return o2 != null && this.region.equals(((MemberPRInfo) o2).region); } http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DeployCommands.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DeployCommands.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DeployCommands.java index 30d840a..8511de8 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DeployCommands.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DeployCommands.java @@ -14,6 +14,8 @@ */ package org.apache.geode.management.internal.cli.commands; +import static org.apache.commons.io.FileUtils.ONE_MB; + import org.apache.geode.SystemFailure; import org.apache.geode.cache.execute.ResultCollector; import org.apache.geode.distributed.DistributedMember; @@ -31,7 +33,6 @@ import org.apache.geode.management.internal.cli.functions.ListDeployedFunction; import org.apache.geode.management.internal.cli.functions.UndeployFunction; import org.apache.geode.management.internal.cli.i18n.CliStrings; import org.apache.geode.management.internal.cli.remote.CommandExecutionContext; -import org.apache.geode.management.internal.cli.result.CommandResultException; import org.apache.geode.management.internal.cli.result.FileResult; import org.apache.geode.management.internal.cli.result.ResultBuilder; import org.apache.geode.management.internal.cli.result.TabularResultData; @@ -50,11 +51,9 @@ import java.util.List; import java.util.Map; import java.util.Set; - /** * Commands for deploying, un-deploying and listing files deployed using the command line shell. - *

- * + * * @see GfshCommand * @since GemFire 7.0 */ @@ -85,7 +84,7 @@ public class DeployCommands implements GfshCommand { // since deploy function can potentially do a lot of damage to security, this action should // require these following privileges - SecurityService securityService = SecurityService.getSecurityService(); + SecurityService securityService = getCache().getSecurityService(); securityService.authorizeClusterManage(); securityService.authorizeClusterWrite(); securityService.authorizeDataManage(); @@ -282,7 +281,7 @@ public class DeployCommands implements GfshCommand { return true; } - return (getGfsh() != null && getGfsh().isConnectedAndReady()); + return getGfsh() != null && getGfsh().isConnectedAndReady(); } /** @@ -296,15 +295,15 @@ public class DeployCommands implements GfshCommand { Map paramValueMap = parseResult.getParamValueStrings(); String jar = paramValueMap.get("jar"); - jar = (jar == null) ? null : jar.trim(); + jar = jar == null ? null : jar.trim(); String dir = paramValueMap.get("dir"); - dir = (dir == null) ? null : dir.trim(); + dir = dir == null ? null : dir.trim(); String group = paramValueMap.get("group"); - group = (group == null) ? null : group.trim(); + group = group == null ? null : group.trim(); - String jarOrDir = (jar != null ? jar : dir); + String jarOrDir = jar != null ? jar : dir; if (jar == null && dir == null) { return ResultBuilder.createUserErrorResult( @@ -325,7 +324,7 @@ public class DeployCommands implements GfshCommand { if (dir != null) { String message = "\nDeploying files: " + fileResult.getFormattedFileList() + "\nTotal file size is: " - + this.numFormatter.format(((double) fileResult.computeFileSizeTotal() / 1048576)) + + this.numFormatter.format((double) fileResult.computeFileSizeTotal() / ONE_MB) + "MB\n\nContinue? "; if (readYesNo(message, Response.YES) == Response.NO) { http://git-wip-us.apache.org/repos/asf/geode/blob/0211029b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GfshCommand.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GfshCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GfshCommand.java index d46024d..86296b4 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GfshCommand.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/GfshCommand.java @@ -37,8 +37,7 @@ import java.util.Set; /** * Encapsulates common functionality for implementing command classes for the Geode shell (gfsh). - *

- * + * * @see org.apache.geode.cache.Cache * @see org.apache.geode.cache.execute.FunctionService * @see org.apache.geode.distributed.DistributedMember @@ -48,13 +47,13 @@ import java.util.Set; @SuppressWarnings("unused") public interface GfshCommand extends CommandMarker { default String convertDefaultValue(final String from, final String to) { - return (CliMetaData.ANNOTATION_DEFAULT_VALUE.equals(from) ? to : from); + return CliMetaData.ANNOTATION_DEFAULT_VALUE.equals(from) ? to : from; } default String toString(final Boolean condition, final String trueValue, final String falseValue) { - return (Boolean.TRUE.equals(condition) ? StringUtils.defaultIfBlank(trueValue, "true") - : StringUtils.defaultIfBlank(falseValue, "false")); + return Boolean.TRUE.equals(condition) ? StringUtils.defaultIfBlank(trueValue, "true") + : StringUtils.defaultIfBlank(falseValue, "false"); } default String toString(final Throwable t, final boolean printStackTrace) { @@ -70,12 +69,12 @@ public interface GfshCommand extends CommandMarker { } default boolean isConnectedAndReady() { - return (getGfsh() != null && getGfsh().isConnectedAndReady()); + return getGfsh() != null && getGfsh().isConnectedAndReady(); } default ClusterConfigurationService getSharedConfiguration() { InternalLocator locator = InternalLocator.getLocator(); - return (locator == null) ? null : locator.getSharedConfiguration(); + return locator == null ? null : locator.getSharedConfiguration(); } default void persistClusterConfiguration(Result result, Runnable runnable) { @@ -92,11 +91,11 @@ public interface GfshCommand extends CommandMarker { } default boolean isDebugging() { - return (getGfsh() != null && getGfsh().getDebug()); + return getGfsh() != null && getGfsh().getDebug(); } default boolean isLogging() { - return (getGfsh() != null); + return getGfsh() != null; } default InternalCache getCache() { @@ -122,7 +121,7 @@ public interface GfshCommand extends CommandMarker { /** * Gets all members in the GemFire distributed system/cache. - * + * * @param cache the GemFire cache. * @return all members in the GemFire distributed system/cache. * @see org.apache.geode.management.internal.cli.CliUtil#getAllMembers(org.apache.geode.internal.cache.InternalCache)