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 BAA3C200B5E for ; Wed, 10 Aug 2016 21:41:08 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id B92E5160AB1; Wed, 10 Aug 2016 19:41:08 +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 6AB1D160A8F for ; Wed, 10 Aug 2016 21:41:06 +0200 (CEST) Received: (qmail 55556 invoked by uid 500); 10 Aug 2016 19:41:05 -0000 Mailing-List: contact commits-help@geode.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@geode.incubator.apache.org Delivered-To: mailing list commits@geode.incubator.apache.org Received: (qmail 55541 invoked by uid 99); 10 Aug 2016 19:41:05 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 10 Aug 2016 19:41:05 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id F2C421A139E for ; Wed, 10 Aug 2016 19:41:04 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -4.646 X-Spam-Level: X-Spam-Status: No, score=-4.646 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-1.426] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id 1deIxQaKPyr6 for ; Wed, 10 Aug 2016 19:40:54 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with SMTP id DC6F760E10 for ; Wed, 10 Aug 2016 19:40:48 +0000 (UTC) Received: (qmail 50415 invoked by uid 99); 10 Aug 2016 19:40:47 -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; Wed, 10 Aug 2016 19:40:47 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 9EE97E69A8; Wed, 10 Aug 2016 19:40:47 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: udo@apache.org To: commits@geode.incubator.apache.org Date: Wed, 10 Aug 2016 19:41:13 -0000 Message-Id: <9b9e7636325b423baf0c161e1f42888a@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [27/50] [abbrv] incubator-geode git commit: GEODE-1712: introduce SecurityService interface for mocking archived-at: Wed, 10 Aug 2016 19:41:08 -0000 http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/UnregisterInterestList.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/UnregisterInterestList.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/UnregisterInterestList.java index 7cb29d4..3c21408 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/UnregisterInterestList.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/UnregisterInterestList.java @@ -34,7 +34,6 @@ import com.gemstone.gemfire.internal.cache.tier.sockets.Part; import com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection; import com.gemstone.gemfire.internal.i18n.LocalizedStrings; import com.gemstone.gemfire.internal.security.AuthorizeRequest; -import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; import com.gemstone.gemfire.security.NotAuthorizedException; @@ -118,7 +117,14 @@ public class UnregisterInterestList extends BaseCommand { return; } - GeodeSecurityUtil.authorizeRegionRead(regionName); + try { + this.securityService.authorizeRegionRead(regionName); + } catch (NotAuthorizedException ex) { + writeException(msg, ex, false, servConn); + servConn.setAsTrue(RESPONDED); + return; + } + AuthorizeRequest authzRequest = servConn.getAuthzRequest(); if (authzRequest != null) { http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java index 958fc7a..a9c2162 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java @@ -60,7 +60,7 @@ import com.gemstone.gemfire.security.NotAuthorizedException; public class GeodeSecurityUtil { - private static Logger logger = LogService.getLogger(); + private static Logger logger = LogService.getLogger(LogService.SECURITY_LOGGER_NAME); private static PostProcessor postProcessor; private static SecurityManager securityManager; http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java new file mode 100644 index 0000000..50cf07c --- /dev/null +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java @@ -0,0 +1,158 @@ +package com.gemstone.gemfire.internal.security; + +import java.util.Properties; +import java.util.concurrent.Callable; + +import org.apache.geode.security.ResourcePermission; +import org.apache.logging.log4j.Logger; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.util.ThreadState; + +import com.gemstone.gemfire.internal.logging.LogService; +import com.gemstone.gemfire.management.internal.security.ResourceOperation; + +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; + } + + @Override + public ThreadState bindSubject(final Subject subject) { + return GeodeSecurityUtil.bindSubject(subject); + } + + @Override + public Subject getSubject() { + return GeodeSecurityUtil.getSubject(); + } + + @Override + public Subject login(final String username, final String password) { + return GeodeSecurityUtil.login(username, password); + } + + @Override + public void logout() { + GeodeSecurityUtil.logout(); + } + + @Override + public Callable associateWith(final Callable callable) { + return GeodeSecurityUtil.associateWith(callable); + } + + @Override + public void authorize(final ResourceOperation resourceOperation) { + GeodeSecurityUtil.authorize(resourceOperation); + } + + @Override + public void authorizeClusterManage() { + GeodeSecurityUtil.authorizeClusterManage(); + } + + @Override + public void authorizeClusterWrite() { + GeodeSecurityUtil.authorizeClusterWrite(); + } + + @Override + public void authorizeClusterRead() { + GeodeSecurityUtil.authorizeClusterRead(); + } + + @Override + public void authorizeDataManage() { + GeodeSecurityUtil.authorizeDataManage(); + } + + @Override + public void authorizeDataWrite() { + GeodeSecurityUtil.authorizeDataWrite(); + } + + @Override + public void authorizeDataRead() { + GeodeSecurityUtil.authorizeDataRead(); + } + + @Override + public void authorizeRegionManage(final String regionName) { + GeodeSecurityUtil.authorizeRegionManage(regionName); + } + + @Override + public void authorizeRegionManage(final String regionName, final String key) { + GeodeSecurityUtil.authorizeRegionManage(regionName, key); + } + + @Override + public void authorizeRegionWrite(final String regionName) { + GeodeSecurityUtil.authorizeRegionWrite(regionName); + } + + @Override + public void authorizeRegionWrite(final String regionName, final String key) { + GeodeSecurityUtil.authorizeRegionWrite(regionName, key); + } + + @Override + public void authorizeRegionRead(final String regionName) { + GeodeSecurityUtil.authorizeRegionRead(regionName); + } + + @Override + public void authorizeRegionRead(final String regionName, final String key) { + GeodeSecurityUtil.authorizeRegionRead(regionName, key); + } + + @Override + public void authorize(final String resource, final String operation) { + GeodeSecurityUtil.authorize(resource, operation); + } + + @Override + public void authorize(final ResourcePermission context) { + GeodeSecurityUtil.authorize(context); + } + + @Override + public void initSecurity(final Properties securityProps) { + GeodeSecurityUtil.initSecurity(securityProps); + } + + @Override + public void close() { + GeodeSecurityUtil.close(); + } + + @Override + public boolean needPostProcess() { + return GeodeSecurityUtil.needPostProcess(); + } + + @Override + public Object postProcess(final String regionPath, final Object key, final Object value, final boolean valueIsSerialized) { + return GeodeSecurityUtil.postProcess(regionPath, key, value, valueIsSerialized); + } + + @Override + public boolean isClientSecurityRequired() { + return GeodeSecurityUtil.isClientSecurityRequired(); + } + + @Override + public boolean isPeerSecurityRequired() { + return GeodeSecurityUtil.isPeerSecurityRequired(); + } + + @Override + public boolean isIntegratedSecurity() { + return GeodeSecurityUtil.isIntegratedSecurity(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java new file mode 100644 index 0000000..76e607e --- /dev/null +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gemstone.gemfire.internal.security; + +import java.util.Properties; +import java.util.concurrent.Callable; + +import com.gemstone.gemfire.management.internal.security.ResourceOperation; + +import org.apache.geode.security.ResourcePermission; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.util.ThreadState; + +public interface SecurityService { + + ThreadState bindSubject(Subject subject); + Subject getSubject(); + Subject login(String username, String password); + void logout(); + Callable associateWith(Callable callable); + void authorize(ResourceOperation resourceOperation); + void authorizeClusterManage(); + void authorizeClusterWrite(); + void authorizeClusterRead(); + void authorizeDataManage(); + void authorizeDataWrite(); + void authorizeDataRead(); + void authorizeRegionManage(String regionName); + void authorizeRegionManage(String regionName, String key); + void authorizeRegionWrite(String regionName); + void authorizeRegionWrite(String regionName, String key); + void authorizeRegionRead(String regionName); + void authorizeRegionRead(String regionName, String key); + void authorize(String resource, String operation); + void authorize(ResourcePermission context); + void initSecurity(Properties securityProps); + void close(); + boolean needPostProcess(); + Object postProcess(String regionPath, Object key, Object value, boolean valueIsSerialized); + boolean isClientSecurityRequired(); + boolean isPeerSecurityRequired(); + boolean isIntegratedSecurity(); +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java index 99511e7..75148da 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java @@ -73,7 +73,11 @@ public class CustomAuthRealm extends AuthorizingRealm { Principal principal = securityManager.authenticate(credentialProps); - return new SimpleAuthenticationInfo(principal, authToken.getPassword(), REALM_NAME); + try { + return new SimpleAuthenticationInfo(principal, authToken.getPassword(), REALM_NAME); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("failed for " + username + " " + password, e); + } } @Override http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/JMXShiroAuthenticator.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/JMXShiroAuthenticator.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/JMXShiroAuthenticator.java index c51244e..fe895d4 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/JMXShiroAuthenticator.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/JMXShiroAuthenticator.java @@ -28,7 +28,8 @@ import javax.management.remote.JMXConnectionNotification; import javax.management.remote.JMXPrincipal; import javax.security.auth.Subject; -import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; +import com.gemstone.gemfire.internal.security.IntegratedSecurityService; +import com.gemstone.gemfire.internal.security.SecurityService; import com.gemstone.gemfire.management.internal.security.ResourceConstants; import com.gemstone.gemfire.security.AuthenticationFailedException; @@ -38,6 +39,8 @@ import com.gemstone.gemfire.security.AuthenticationFailedException; public class JMXShiroAuthenticator implements JMXAuthenticator, NotificationListener { + private SecurityService securityService = IntegratedSecurityService.getSecurityService(); + @Override public Subject authenticate(Object credentials) { String username = null, password = null; @@ -52,7 +55,7 @@ public class JMXShiroAuthenticator implements JMXAuthenticator, NotificationList throw new AuthenticationFailedException(MISSING_CREDENTIALS_MESSAGE); } - org.apache.shiro.subject.Subject shiroSubject = GeodeSecurityUtil.login(username, password); + org.apache.shiro.subject.Subject shiroSubject = this.securityService.login(username, password); Principal principal; if(shiroSubject==null){ @@ -72,7 +75,7 @@ public class JMXShiroAuthenticator implements JMXAuthenticator, NotificationList JMXConnectionNotification cxNotification = (JMXConnectionNotification) notification; String type = cxNotification.getType(); if (JMXConnectionNotification.CLOSED.equals(type)) { - GeodeSecurityUtil.logout(); + this.securityService.logout(); } } } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/main/java/com/gemstone/gemfire/management/internal/SystemManagementService.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/SystemManagementService.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/SystemManagementService.java index dbdd575..7963814 100755 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/SystemManagementService.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/SystemManagementService.java @@ -37,7 +37,8 @@ import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedM import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; import com.gemstone.gemfire.internal.i18n.LocalizedStrings; import com.gemstone.gemfire.internal.logging.LogService; -import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; +import com.gemstone.gemfire.internal.security.IntegratedSecurityService; +import com.gemstone.gemfire.internal.security.SecurityService; import com.gemstone.gemfire.management.AlreadyRunningException; import com.gemstone.gemfire.management.AsyncEventQueueMXBean; import com.gemstone.gemfire.management.CacheServerMXBean; @@ -67,6 +68,8 @@ import com.gemstone.gemfire.management.membership.MembershipListener; public final class SystemManagementService extends BaseManagementService { private static final Logger logger = LogService.getLogger(); + private SecurityService securityService = IntegratedSecurityService.getSecurityService(); + /** * The concrete implementation of DistributedSystem that provides * internal-only functionality. @@ -151,7 +154,7 @@ public final class SystemManagementService extends BaseManagementService { this.jmxAdapter = new MBeanJMXAdapter(); this.repo = new ManagementResourceRepo(); - GeodeSecurityUtil.initSecurity(system.getConfig().getSecurityProps()); + this.securityService.initSecurity(system.getConfig().getSecurityProps()); this.notificationHub = new NotificationHub(repo); if (system.getConfig().getJmxManager()) { @@ -273,7 +276,7 @@ public final class SystemManagementService extends BaseManagementService { } // clean out Shiro's thread local content - GeodeSecurityUtil.close(); + this.securityService.close(); getGemFireCacheImpl().getJmxManagerAdvisor().broadcastChange(); instances.remove(cache); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/CreateAlterDestroyRegionCommands.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/CreateAlterDestroyRegionCommands.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/CreateAlterDestroyRegionCommands.java index aedf9d6..4aa8263 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/CreateAlterDestroyRegionCommands.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/CreateAlterDestroyRegionCommands.java @@ -55,7 +55,8 @@ import com.gemstone.gemfire.internal.ClassPathLoader; import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; import com.gemstone.gemfire.internal.i18n.LocalizedStrings; import com.gemstone.gemfire.internal.lang.StringUtils; -import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; +import com.gemstone.gemfire.internal.security.IntegratedSecurityService; +import com.gemstone.gemfire.internal.security.SecurityService; import com.gemstone.gemfire.management.DistributedRegionMXBean; import com.gemstone.gemfire.management.DistributedSystemMXBean; import com.gemstone.gemfire.management.ManagementService; @@ -92,6 +93,8 @@ import org.apache.geode.security.ResourcePermission.Resource; */ public class CreateAlterDestroyRegionCommands extends AbstractCommandsSupport { public static final Set PERSISTENT_OVERFLOW_SHORTCUTS = new TreeSet(); + + private SecurityService securityService = IntegratedSecurityService.getSecurityService(); static { PERSISTENT_OVERFLOW_SHORTCUTS.add(RegionShortcut.PARTITION_PERSISTENT); @@ -532,7 +535,7 @@ public class CreateAlterDestroyRegionCommands extends AbstractCommandsSupport { Result result = null; XmlEntity xmlEntity = null; - GeodeSecurityUtil.authorizeRegionManage(regionPath); + this.securityService.authorizeRegionManage(regionPath); try { Cache cache = CacheFactory.getAnyInstance(); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java index 4b39c4a..e648f2c 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java @@ -16,6 +16,7 @@ */ package com.gemstone.gemfire.management.internal.cli.commands; +import java.security.Security; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; @@ -54,7 +55,8 @@ import com.gemstone.gemfire.cache.execute.ResultCollector; import com.gemstone.gemfire.cache.partition.PartitionRebalanceInfo; import com.gemstone.gemfire.distributed.DistributedMember; import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; -import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; +import com.gemstone.gemfire.internal.security.IntegratedSecurityService; +import com.gemstone.gemfire.internal.security.SecurityService; import com.gemstone.gemfire.management.DistributedRegionMXBean; import com.gemstone.gemfire.management.ManagementService; import com.gemstone.gemfire.management.cli.CliMetaData; @@ -90,6 +92,8 @@ public class DataCommands implements CommandMarker { private final ExportDataFunction exportDataFunction = new ExportDataFunction(); private final ImportDataFunction importDataFunction = new ImportDataFunction(); + private SecurityService securityService = IntegratedSecurityService.getSecurityService(); + private Gfsh getGfsh() { return Gfsh.getCurrentInstance(); } @@ -841,7 +845,7 @@ public class DataCommands implements CommandMarker { @CliOption(key = CliStrings.EXPORT_DATA__FILE, unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE, mandatory = true, help = CliStrings.EXPORT_DATA__FILE__HELP) String filePath, @CliOption(key = CliStrings.EXPORT_DATA__MEMBER, unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE, optionContext = ConverterHint.MEMBERIDNAME, mandatory = true, help = CliStrings.EXPORT_DATA__MEMBER__HELP) String memberNameOrId) { - GeodeSecurityUtil.authorizeRegionRead(regionName); + this.securityService.authorizeRegionRead(regionName); final Cache cache = CacheFactory.getAnyInstance(); final DistributedMember targetMember = CliUtil .getDistributedMemberByNameOrId(memberNameOrId); @@ -898,7 +902,7 @@ public class DataCommands implements CommandMarker { @CliOption(key = CliStrings.IMPORT_DATA__FILE, mandatory = true, unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE, help = CliStrings.IMPORT_DATA__FILE__HELP) String filePath, @CliOption(key = CliStrings.IMPORT_DATA__MEMBER, mandatory = true, unspecifiedDefaultValue = CliMetaData.ANNOTATION_NULL_VALUE, optionContext = ConverterHint.MEMBERIDNAME, help = CliStrings.IMPORT_DATA__MEMBER__HELP) String memberNameOrId) { - GeodeSecurityUtil.authorizeRegionWrite(regionName); + this.securityService.authorizeRegionWrite(regionName); Result result = null; @@ -959,7 +963,7 @@ public class DataCommands implements CommandMarker { @CliOption(key = { CliStrings.PUT__VALUEKLASS }, help = CliStrings.PUT__VALUEKLASS__HELP) String valueClass, @CliOption(key = { CliStrings.PUT__PUTIFABSENT }, help = CliStrings.PUT__PUTIFABSENT__HELP, unspecifiedDefaultValue = "false") boolean putIfAbsent) { - GeodeSecurityUtil.authorizeRegionWrite(regionPath); + this.securityService.authorizeRegionWrite(regionPath); Cache cache = CacheFactory.getAnyInstance(); DataCommandResult dataResult = null; if (regionPath == null || regionPath.isEmpty()) { @@ -1027,7 +1031,7 @@ public class DataCommands implements CommandMarker { @CliOption(key = { CliStrings.GET__VALUEKLASS }, help = CliStrings.GET__VALUEKLASS__HELP) String valueClass, @CliOption(key = CliStrings.GET__LOAD, unspecifiedDefaultValue = "true", specifiedDefaultValue = "true", help = CliStrings.GET__LOAD__HELP) Boolean loadOnCacheMiss) { - GeodeSecurityUtil.authorizeRegionRead(regionPath, key); + this.securityService.authorizeRegionRead(regionPath, key); Cache cache = CacheFactory.getAnyInstance(); DataCommandResult dataResult = null; @@ -1084,7 +1088,7 @@ public class DataCommands implements CommandMarker { @CliOption(key = { CliStrings.LOCATE_ENTRY__VALUEKLASS }, help = CliStrings.LOCATE_ENTRY__VALUEKLASS__HELP) String valueClass, @CliOption(key = { CliStrings.LOCATE_ENTRY__RECURSIVE }, help = CliStrings.LOCATE_ENTRY__RECURSIVE__HELP, unspecifiedDefaultValue = "false") boolean recursive) { - GeodeSecurityUtil.authorizeRegionRead(regionPath, key); + this.securityService.authorizeRegionRead(regionPath, key); DataCommandResult dataResult = null; @@ -1148,10 +1152,10 @@ public class DataCommands implements CommandMarker { } if(removeAllKeys){ - GeodeSecurityUtil.authorizeRegionWrite(regionPath); + this.securityService.authorizeRegionWrite(regionPath); } else { - GeodeSecurityUtil.authorizeRegionWrite(regionPath, key); + this.securityService.authorizeRegionWrite(regionPath, key); } @SuppressWarnings("rawtypes") http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/IndexCommands.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/IndexCommands.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/IndexCommands.java index 7abe6a1..ff39d2f 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/IndexCommands.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/IndexCommands.java @@ -35,7 +35,8 @@ import com.gemstone.gemfire.cache.execute.ResultCollector; import com.gemstone.gemfire.distributed.DistributedMember; import com.gemstone.gemfire.internal.cache.execute.AbstractExecution; import com.gemstone.gemfire.internal.lang.StringUtils; -import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; +import com.gemstone.gemfire.internal.security.IntegratedSecurityService; +import com.gemstone.gemfire.internal.security.SecurityService; import com.gemstone.gemfire.management.cli.CliMetaData; import com.gemstone.gemfire.management.cli.ConverterHint; import com.gemstone.gemfire.management.cli.Result; @@ -80,6 +81,8 @@ public class IndexCommands extends AbstractCommandsSupport { private static final CreateDefinedIndexesFunction createDefinedIndexesFunction = new CreateDefinedIndexesFunction(); private static final Set indexDefinitions = Collections.synchronizedSet(new HashSet()); + private SecurityService securityService = IntegratedSecurityService.getSecurityService(); + @Override protected Set getMembers(final Cache cache) { // TODO determine what this does (as it is untested and unmockable!) @@ -206,7 +209,7 @@ public class IndexCommands extends AbstractCommandsSupport { Result result = null; XmlEntity xmlEntity = null; - GeodeSecurityUtil.authorizeRegionManage(regionPath); + this.securityService.authorizeRegionManage(regionPath); try { final Cache cache = CacheFactory.getAnyInstance(); @@ -360,10 +363,10 @@ public class IndexCommands extends AbstractCommandsSupport { // If a regionName is specified, then authorize data manage on the regionName, otherwise, it requires data manage permission on all regions if (!StringUtils.isBlank(regionPath)) { regionName = regionPath.startsWith("/") ? regionPath.substring(1) : regionPath; - GeodeSecurityUtil.authorizeRegionManage(regionName); + this.securityService.authorizeRegionManage(regionName); } else{ - GeodeSecurityUtil.authorizeDataManage(); + this.securityService.authorizeDataManage(); } IndexInfo indexInfo = new IndexInfo(indexName, regionName); @@ -488,7 +491,7 @@ public class IndexCommands extends AbstractCommandsSupport { Result result = null; XmlEntity xmlEntity = null; - GeodeSecurityUtil.authorizeRegionManage(regionPath); + this.securityService.authorizeRegionManage(regionPath); int idxType = IndexInfo.RANGE_INDEX; http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java index 724a1d4..1ff98eb 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java @@ -61,7 +61,8 @@ import com.gemstone.gemfire.internal.InternalEntity; import com.gemstone.gemfire.internal.NanoTimer; import com.gemstone.gemfire.internal.cache.PartitionedRegion; import com.gemstone.gemfire.internal.logging.LogService; -import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; +import com.gemstone.gemfire.internal.security.IntegratedSecurityService; +import com.gemstone.gemfire.internal.security.SecurityService; import com.gemstone.gemfire.management.cli.Result; import com.gemstone.gemfire.management.internal.cli.CliUtil; import com.gemstone.gemfire.management.internal.cli.commands.DataCommands; @@ -97,6 +98,8 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt protected static final String SELECT_STEP_END = "SELECT_END"; protected static final String SELECT_STEP_EXEC = "SELECT_EXEC"; private static final int NESTED_JSON_LENGTH = 20; + + protected SecurityService securityService = IntegratedSecurityService.getSecurityService(); @Override public String getId() { @@ -252,7 +255,7 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt for (Iterator iter = selectResults.iterator(); iter.hasNext();) { Object object = iter.next(); // Post processing - object = GeodeSecurityUtil.postProcess(null, null, object, false); + object = this.securityService.postProcess(null, null, object, false); if (object instanceof Struct) { StructImpl impl = (StructImpl) object; @@ -457,7 +460,7 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt // run it through post processor. region.get will return the deserialized object already, so we don't need to // deserialize it anymore to pass it to the postProcessor - value = GeodeSecurityUtil.postProcess(regionName, keyObject, value, false); + value = this.securityService.postProcess(regionName, keyObject, value, false); if (logger.isDebugEnabled()) logger.debug("Get for key {} value {}", key, value); @@ -876,6 +879,8 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt private static final long serialVersionUID = 1L; + private SecurityService securityService = IntegratedSecurityService.getSecurityService(); + public SelectExecStep(Object[] arguments) { super(SELECT_STEP_EXEC, arguments); } @@ -929,7 +934,7 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt // authorize data read on these regions for(String region:regions){ - GeodeSecurityUtil.authorizeRegionRead(region); + this.securityService.authorizeRegionRead(region); } regionsInQuery = Collections.unmodifiableSet(regions); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/remote/CommandProcessor.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/remote/CommandProcessor.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/remote/CommandProcessor.java index 790dd6c..751920b 100755 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/remote/CommandProcessor.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/remote/CommandProcessor.java @@ -21,7 +21,8 @@ import java.lang.reflect.Method; import java.util.Map; import java.util.Properties; -import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; +import com.gemstone.gemfire.internal.security.IntegratedSecurityService; +import com.gemstone.gemfire.internal.security.SecurityService; import com.gemstone.gemfire.management.cli.CommandProcessingException; import com.gemstone.gemfire.management.cli.CommandStatement; import com.gemstone.gemfire.management.cli.Result; @@ -53,6 +54,8 @@ public class CommandProcessor { private volatile boolean isStopped = false; + private SecurityService securityService = IntegratedSecurityService.getSecurityService(); + public CommandProcessor() throws ClassNotFoundException, IOException { this(null); } @@ -110,7 +113,7 @@ public class CommandProcessor { //do general authorization check here Method method = parseResult.getMethod(); ResourceOperation resourceOperation = method.getAnnotation(ResourceOperation.class); - GeodeSecurityUtil.authorize(resourceOperation); + this.securityService.authorize(resourceOperation); result = executionStrategy.execute(parseResult); if (result instanceof Result) { http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/main/java/com/gemstone/gemfire/management/internal/security/AccessControlMBean.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/security/AccessControlMBean.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/security/AccessControlMBean.java index 1306fc0..8167da1 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/security/AccessControlMBean.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/security/AccessControlMBean.java @@ -16,8 +16,9 @@ */ package com.gemstone.gemfire.management.internal.security; +import com.gemstone.gemfire.internal.security.IntegratedSecurityService; +import com.gemstone.gemfire.internal.security.SecurityService; import com.gemstone.gemfire.security.GemFireSecurityException; -import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; /** * AccessControlMBean Implementation. This retrieves JMXPrincipal from AccessController @@ -27,10 +28,12 @@ import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; */ public class AccessControlMBean implements AccessControlMXBean { + private SecurityService securityService = IntegratedSecurityService.getSecurityService(); + @Override public boolean authorize(String resource, String permission) { try { - GeodeSecurityUtil.authorize(resource, permission); + this.securityService.authorize(resource, permission); return true; } catch (GemFireSecurityException e){ http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/main/java/com/gemstone/gemfire/management/internal/security/MBeanServerWrapper.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/security/MBeanServerWrapper.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/security/MBeanServerWrapper.java index 4bed2d5..7fcf922 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/security/MBeanServerWrapper.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/security/MBeanServerWrapper.java @@ -44,6 +44,8 @@ import javax.management.ReflectionException; import javax.management.loading.ClassLoaderRepository; import javax.management.remote.MBeanServerForwarder; +import com.gemstone.gemfire.internal.security.IntegratedSecurityService; +import com.gemstone.gemfire.internal.security.SecurityService; import com.gemstone.gemfire.management.internal.ManagementConstants; import com.gemstone.gemfire.security.GemFireSecurityException; import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; @@ -58,6 +60,8 @@ import org.apache.geode.security.ResourcePermission; public class MBeanServerWrapper implements MBeanServerForwarder { private MBeanServer mbs; + private SecurityService securityService = IntegratedSecurityService.getSecurityService(); + public MBeanServerWrapper(){ } @@ -147,7 +151,7 @@ public class MBeanServerWrapper implements MBeanServerForwarder { public Object getAttribute(ObjectName name, String attribute) throws MBeanException, InstanceNotFoundException, ReflectionException { ResourcePermission ctx = getOperationContext(name, attribute, false); - GeodeSecurityUtil.authorize(ctx); + this.securityService.authorize(ctx); Object result; try { result = mbs.getAttribute(name, attribute); @@ -177,7 +181,7 @@ public class MBeanServerWrapper implements MBeanServerForwarder { public void setAttribute(ObjectName name, Attribute attribute) throws InstanceNotFoundException, AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException { ResourcePermission ctx = getOperationContext(name, attribute.getName(), false); - GeodeSecurityUtil.authorize(ctx); + this.securityService.authorize(ctx); mbs.setAttribute(name, attribute); } @@ -200,7 +204,7 @@ public class MBeanServerWrapper implements MBeanServerForwarder { throws InstanceNotFoundException, MBeanException, ReflectionException { ResourcePermission ctx = getOperationContext(name, operationName, true); - GeodeSecurityUtil.authorize(ctx); + this.securityService.authorize(ctx); Object result = mbs.invoke(name, operationName, params, signature); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/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 0d94c7f..35ee68a 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 @@ -38,7 +38,8 @@ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; import com.gemstone.gemfire.internal.lang.StringUtils; import com.gemstone.gemfire.internal.logging.LogService; import com.gemstone.gemfire.internal.logging.log4j.LogMarker; -import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; +import com.gemstone.gemfire.internal.security.IntegratedSecurityService; +import com.gemstone.gemfire.internal.security.SecurityService; import com.gemstone.gemfire.internal.util.ArrayUtils; import com.gemstone.gemfire.management.DistributedSystemMXBean; import com.gemstone.gemfire.management.ManagementService; @@ -86,7 +87,7 @@ public abstract class AbstractCommandsController { private MemberMXBean managingMemberMXBeanProxy; - +private SecurityService securityService = IntegratedSecurityService.getSecurityService(); private Class accessControlKlass; @@ -554,7 +555,7 @@ public abstract class AbstractCommandsController { return new ResponseEntity(result, HttpStatus.OK); } }; - return GeodeSecurityUtil.associateWith(callable); + return this.securityService.associateWith(callable); } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/support/LoginHandlerInterceptor.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/support/LoginHandlerInterceptor.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/support/LoginHandlerInterceptor.java index 52cce90..efdda18 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/support/LoginHandlerInterceptor.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/web/controllers/support/LoginHandlerInterceptor.java @@ -16,6 +16,7 @@ */ package com.gemstone.gemfire.management.internal.web.controllers.support; +import java.awt.PrintGraphics; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; @@ -26,7 +27,8 @@ import javax.servlet.http.HttpServletResponse; import com.gemstone.gemfire.cache.Cache; import com.gemstone.gemfire.distributed.internal.DistributionConfig; import com.gemstone.gemfire.internal.logging.LogService; -import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; +import com.gemstone.gemfire.internal.security.IntegratedSecurityService; +import com.gemstone.gemfire.internal.security.SecurityService; import com.gemstone.gemfire.management.internal.cli.multistep.CLIMultiStepHelper; import com.gemstone.gemfire.management.internal.security.ResourceConstants; import com.gemstone.gemfire.management.internal.web.util.UriUtils; @@ -53,6 +55,8 @@ public class LoginHandlerInterceptor extends HandlerInterceptorAdapter { private Authenticator auth = null; + private SecurityService securityService = IntegratedSecurityService.getSecurityService(); + private static final ThreadLocal> ENV = new ThreadLocal>() { @Override protected Map initialValue() { @@ -101,7 +105,7 @@ public class LoginHandlerInterceptor extends HandlerInterceptorAdapter { String username = requestParameterValues.get(ResourceConstants.USER_NAME); String password = requestParameterValues.get(ResourceConstants.PASSWORD); - GeodeSecurityUtil.login(username, password); + this.securityService.login(username, password); ENV.set(requestParameterValues); @@ -117,7 +121,7 @@ public class LoginHandlerInterceptor extends HandlerInterceptorAdapter { throws Exception { afterConcurrentHandlingStarted(request, response, handler); - GeodeSecurityUtil.logout(); + this.securityService.logout(); } @Override http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/AbstractGMSAuthenticatorTestCase.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/AbstractGMSAuthenticatorTestCase.java b/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/AbstractGMSAuthenticatorTestCase.java new file mode 100644 index 0000000..5b6c4f5 --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/AbstractGMSAuthenticatorTestCase.java @@ -0,0 +1,303 @@ +/* + * 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.distributed.internal.membership.gms.auth; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.*; +import static org.mockito.Mockito.*; + +import java.security.Principal; +import java.util.Properties; + +import com.gemstone.gemfire.LogWriter; +import com.gemstone.gemfire.distributed.DistributedMember; +import com.gemstone.gemfire.distributed.internal.DistributionConfig; +import com.gemstone.gemfire.distributed.internal.membership.gms.ServiceConfig; +import com.gemstone.gemfire.distributed.internal.membership.gms.Services; +import com.gemstone.gemfire.internal.logging.InternalLogWriter; +import com.gemstone.gemfire.internal.security.SecurityService; +import com.gemstone.gemfire.security.AuthInitialize; +import com.gemstone.gemfire.security.AuthenticationFailedException; +import com.gemstone.gemfire.security.Authenticator; + +import org.apache.shiro.subject.Subject; +import org.junit.Before; +import org.junit.BeforeClass; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public abstract class AbstractGMSAuthenticatorTestCase { + + @Mock + protected SecurityService securityService; + @Mock + protected Properties props; + @Mock + protected Properties securityProps; + @Mock + protected Services services; + @Mock + protected DistributedMember member; + @Mock + protected Subject subject; + + @Mock + private ServiceConfig serviceConfig; + @Mock + private DistributionConfig distributionConfig; + + @InjectMocks + protected GMSAuthenticator authenticator; + + + @Before + public void setUp() throws Exception { + clearStatics(); + MockitoAnnotations.initMocks(this); + + props = new Properties(); + securityProps = new Properties(); + + when(securityService.isIntegratedSecurity()).thenReturn(isIntegratedSecurity()); + when(securityService.isPeerSecurityRequired()).thenReturn(true); + when(securityService.login(anyString(), anyString())).thenReturn(subject); + when(distributionConfig.getSecurityProps()).thenReturn(securityProps); + when(serviceConfig.getDistributionConfig()).thenReturn(distributionConfig); + when(services.getSecurityLogWriter()).thenReturn(mock(InternalLogWriter.class)); + when(services.getConfig()).thenReturn(serviceConfig); + + authenticator.init(services); + } + + protected abstract boolean isIntegratedSecurity(); + + private static void clearStatics() { + SpyAuthInit.clear(); + SpyAuthenticator.clear(); + } + + protected static final class AuthInitCreateReturnsNull implements AuthInitialize { + + public static AuthInitialize create() { + return null; + } + + @Override + public void init(LogWriter systemLogger, LogWriter securityLogger) throws AuthenticationFailedException { + } + + @Override + public Properties getCredentials(Properties props, DistributedMember server, boolean isPeer) throws AuthenticationFailedException { + throw new AuthenticationFailedException("expected get credential error"); + } + + @Override + public void close() { + } + } + + protected static final class SpyAuthInit implements AuthInitialize { + + private static SpyAuthInit instance = null; + private static int createCount = 0; + + boolean closed = false; + + static void clear() { + instance = null; + createCount = 0; + } + + public static void setAuthInitialize(SpyAuthInit auth) { + instance = auth; + } + + public static AuthInitialize create() { + createCount++; + return instance; + } + + @Override + public Properties getCredentials(Properties props, DistributedMember server, boolean isPeer) throws AuthenticationFailedException { + return props; + } + + @Override + public void close() { + closed = true; + } + + public boolean isClosed() { + return closed; + } + + public static int getCreateCount() { + return createCount; + } + + @Override + public void init(LogWriter systemLogger, LogWriter securityLogger) throws AuthenticationFailedException { + } + } + + protected static final class AuthInitGetCredentialsAndInitThrow implements AuthInitialize { + + public static AuthInitialize create() { + return new AuthInitGetCredentialsAndInitThrow(); + } + + @Override + public void init(LogWriter systemLogger, LogWriter securityLogger) throws AuthenticationFailedException { + throw new AuthenticationFailedException("expected init error"); + } + + @Override + public Properties getCredentials(Properties props, DistributedMember server, boolean isPeer) throws AuthenticationFailedException { + throw new AuthenticationFailedException("expected get credential error"); + } + + @Override + public void close() { + } + } + + protected static final class AuthInitGetCredentialsThrows implements AuthInitialize { + + public static AuthInitialize create() { + return new AuthInitGetCredentialsThrows(); + } + + @Override + public void init(LogWriter systemLogger, LogWriter securityLogger) throws AuthenticationFailedException { + } + + @Override + public Properties getCredentials(Properties props, DistributedMember server, boolean isPeer) throws AuthenticationFailedException { + throw new AuthenticationFailedException("expected get credential error"); + } + + @Override + public void close() { + } + } + + protected static final class AuthenticatorReturnsNulls implements Authenticator { + + public static Authenticator create() { + return null; + } + + @Override + public void init(Properties securityProps, LogWriter systemLogger, LogWriter securityLogger) throws AuthenticationFailedException { + } + + @Override + public Principal authenticate(Properties props, DistributedMember member) throws AuthenticationFailedException { + return null; + } + + @Override + public void close() { + } + } + + protected static final class AuthenticatorInitThrows implements Authenticator { + + public static Authenticator create() { + return new AuthenticatorInitThrows(); + } + + @Override + public void init(Properties securityProps, LogWriter systemLogger, LogWriter securityLogger) throws AuthenticationFailedException { + throw new AuthenticationFailedException("expected init error"); + } + + @Override + public Principal authenticate(Properties props, DistributedMember member) throws AuthenticationFailedException { + return null; + } + + @Override + public void close() { + } + } + + protected static final class AuthenticatorAuthenticateThrows implements Authenticator { + + public static Authenticator create() { + return new AuthenticatorAuthenticateThrows(); + } + + @Override + public Principal authenticate(Properties props, DistributedMember member) throws AuthenticationFailedException { + throw new AuthenticationFailedException("expected authenticate error"); + } + + @Override + public void init(Properties securityProps, LogWriter systemLogger, LogWriter securityLogger) throws AuthenticationFailedException { + } + + @Override + public void close() { + } + } + + protected static final class SpyAuthenticator implements Authenticator { + + private static Authenticator instance = null; + private static int createCount = 0; + + private boolean closed = false; + + static void clear() { + instance = null; + createCount = 0; + } + + public static void setAuthenticator(Authenticator auth) { + instance = auth; + } + + public static Authenticator create() { + createCount++; + return instance; + } + + @Override + public Principal authenticate(Properties props, DistributedMember member) throws AuthenticationFailedException { + return null; + } + + @Override + public void close() { + closed = true; + } + + public boolean isClosed() { + return closed; + } + + public static int getCreateCount() { + return createCount; + } + + @Override + public void init(Properties securityProps, LogWriter systemLogger, LogWriter securityLogger) throws AuthenticationFailedException { + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticatorJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticatorJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticatorJUnitTest.java deleted file mode 100644 index 18152b0..0000000 --- a/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticatorJUnitTest.java +++ /dev/null @@ -1,338 +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 com.gemstone.gemfire.distributed.internal.membership.gms.auth; - -import static com.gemstone.gemfire.distributed.ConfigurationProperties.*; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; - -import java.security.Principal; -import java.util.Properties; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.contrib.java.lang.system.RestoreSystemProperties; -import org.junit.experimental.categories.Category; - -import com.gemstone.gemfire.LogWriter; -import com.gemstone.gemfire.distributed.DistributedMember; -import com.gemstone.gemfire.distributed.internal.DistributionConfig; -import com.gemstone.gemfire.distributed.internal.membership.gms.ServiceConfig; -import com.gemstone.gemfire.distributed.internal.membership.gms.Services; -import com.gemstone.gemfire.internal.logging.InternalLogWriter; -import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; -import com.gemstone.gemfire.security.AuthInitialize; -import com.gemstone.gemfire.security.AuthenticationFailedException; -import com.gemstone.gemfire.security.Authenticator; -import com.gemstone.gemfire.security.GemFireSecurityException; -import com.gemstone.gemfire.test.junit.categories.SecurityTest; -import com.gemstone.gemfire.test.junit.categories.UnitTest; - -@Category({ UnitTest.class, SecurityTest.class }) -public class GMSAuthenticatorJUnitTest { - - private String prefix; - private Properties props; - protected Properties securityProps; - private Services services; - private GMSAuthenticator authenticator; - private DistributedMember member; - - @Rule - public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties(); - - @Before - public void setUp() throws Exception { - prefix = getClass().getName() + "$"; - props = new Properties(); - securityProps = new Properties(); - authenticator = new GMSAuthenticator(); - - services = mock(Services.class); - InternalLogWriter securityLog = mock(InternalLogWriter.class); - when(services.getSecurityLogWriter()).thenReturn(mock(InternalLogWriter.class)); - - DistributionConfig distributionConfig = mock(DistributionConfig.class); - when(distributionConfig.getSecurityProps()).thenReturn(securityProps); - - ServiceConfig serviceConfig = mock(ServiceConfig.class); - when(serviceConfig.getDistributionConfig()).thenReturn(distributionConfig); - - services = mock(Services.class); - when(services.getSecurityLogWriter()).thenReturn(securityLog); - when(services.getConfig()).thenReturn(serviceConfig); - - authenticator.init(services); - GeodeSecurityUtil.initSecurity(securityProps); - member = mock(DistributedMember.class); - } - - @Test - public void testGetCredentialNormal() throws Exception { - props.setProperty(SECURITY_PEER_AUTH_INIT, prefix + "TestAuthInit2.create"); - TestAuthInit2 auth = new TestAuthInit2(); - assertFalse(auth.isClosed()); - TestAuthInit2.setAuthInitialize(auth); - Properties credential = authenticator.getCredentials(member, props); - assertTrue(props == credential); - assertTrue(auth.isClosed()); - assertTrue(TestAuthInit2.getCreateCount() == 1); - } - - @Test - public void testGetCredentialWithNoAuth() throws Exception { - Properties credential = authenticator.getCredentials(member, props); - assertNull(credential); - } - - @Test - public void testGetCredentialWithEmptyAuth() throws Exception { - props.setProperty(SECURITY_PEER_AUTH_INIT, ""); - Properties credential = authenticator.getCredentials(member, props); - assertNull(credential); - } - - @Test - public void testGetCredentialWithNotExistAuth() throws Exception { - props.setProperty(SECURITY_PEER_AUTH_INIT, prefix + "NotExistAuth.create"); - verifyNegativeGetCredential(props, "Instance could not be obtained"); - } - - @Test - public void testGetCredentialWithNullAuth() throws Exception { - props.setProperty(SECURITY_PEER_AUTH_INIT, prefix + "TestAuthInit1.create"); - verifyNegativeGetCredential(props, "Instance could not be obtained"); - } - - @Test - public void testGetCredentialWithInitError() throws Exception { - props.setProperty(SECURITY_PEER_AUTH_INIT, prefix + "TestAuthInit3.create"); - verifyNegativeGetCredential(props, "expected init error"); - } - - @Test - public void testGetCredentialWithError() throws Exception { - props.setProperty(SECURITY_PEER_AUTH_INIT, prefix + "TestAuthInit4.create"); - verifyNegativeGetCredential(props, "expected get credential error"); - } - - private void verifyNegativeGetCredential(Properties props, String expectedError) throws Exception { - try { - authenticator.getCredentials(member, props); - fail("should catch: " + expectedError); - } catch (GemFireSecurityException expected) { - assertTrue(expected.getMessage().startsWith(expectedError)); - } - } - - @Test - public void testAuthenticatorNormal() throws Exception { - props.setProperty(SECURITY_PEER_AUTHENTICATOR, prefix + "TestAuthenticator4.create"); - GeodeSecurityUtil.initSecurity(props); - TestAuthenticator4 auth = new TestAuthenticator4(); - assertFalse(auth.isClosed()); - TestAuthenticator4.setAuthenticator(auth); - String result = authenticator.authenticate(member, props, props, member); - assertNull(result); - assertTrue(auth.isClosed()); - assertTrue(TestAuthenticator4.getCreateCount() == 1); - } - - @Test - public void testAuthenticatorWithNoAuth() throws Exception { - String result = authenticator.authenticate(member, props, props, member); - assertNull(result); - } - - @Test - public void testAuthenticatorWithEmptyAuth() throws Exception { - props.setProperty(SECURITY_PEER_AUTHENTICATOR, ""); - GeodeSecurityUtil.initSecurity(props); - String result = authenticator.authenticate(member, props, props, member); - assertNull(result); - } - - @Test - public void testAuthenticatorWithNotExistAuth() throws Exception { - props.setProperty(SECURITY_PEER_AUTHENTICATOR, prefix + "NotExistAuth.create"); - GeodeSecurityUtil.initSecurity(props); - verifyNegativeAuthenticate(props, props, "Authentication failed. See coordinator"); - } - - @Test - public void testAuthenticatorWithNullAuth() throws Exception { - props.setProperty(SECURITY_PEER_AUTHENTICATOR, prefix + "TestAuthenticator1.create"); - GeodeSecurityUtil.initSecurity(props); - verifyNegativeAuthenticate(props, props, "Authentication failed. See coordinator"); - } - - @Test - public void testAuthenticatorWithNullCredential() throws Exception { - props.setProperty(SECURITY_PEER_AUTHENTICATOR, prefix + "TestAuthenticator1.create"); - GeodeSecurityUtil.initSecurity(props); - verifyNegativeAuthenticate(null, props, "Failed to find credentials from"); - } - - @Test - public void testAuthenticatorWithAuthInitFailure() throws Exception { - props.setProperty(SECURITY_PEER_AUTHENTICATOR, prefix + "TestAuthenticator2.create"); - GeodeSecurityUtil.initSecurity(props); - verifyNegativeAuthenticate(props, props, "Authentication failed. See coordinator"); - } - - @Test - public void testAuthenticatorWithAuthFailure() throws Exception { - props.setProperty(SECURITY_PEER_AUTHENTICATOR, prefix + "TestAuthenticator3.create"); - GeodeSecurityUtil.initSecurity(props); - verifyNegativeAuthenticate(props, props, "Authentication failed. See coordinator"); - } - - void verifyNegativeAuthenticate(Properties credential, Properties props, String expectedError) throws Exception { - String result = authenticator.authenticate(member, credential, props, member); - assertTrue(result, result.startsWith(expectedError)); - } - - public static class TestAuthInit1 implements AuthInitialize { - public static AuthInitialize create() { - return null; - } - @Override - public void init(LogWriter systemLogger, LogWriter securityLogger) throws AuthenticationFailedException { - } - @Override - public Properties getCredentials(Properties props, DistributedMember server, boolean isPeer) throws AuthenticationFailedException { - throw new AuthenticationFailedException("expected get credential error"); - } - @Override - public void close() { - } - } - - public static class TestAuthInit2 extends TestAuthInit1 { - - private static TestAuthInit2 instance = null; - private static int createCount = 0; - - boolean closed = false; - - public static void setAuthInitialize(TestAuthInit2 auth) { - instance = auth; - } - public static AuthInitialize create() { - createCount ++; - return instance; - } - @Override - public Properties getCredentials(Properties props, DistributedMember server, boolean isPeer) throws AuthenticationFailedException { - return props; - } - @Override - public void close() { - closed = true; - } - public boolean isClosed() { - return closed; - } - public static int getCreateCount() { - return createCount; - } - } - - // used by reflection by test - public static class TestAuthInit3 extends TestAuthInit1 { - public static AuthInitialize create() { - return new TestAuthInit3(); - } - @Override - public void init(LogWriter systemLogger, LogWriter securityLogger) throws AuthenticationFailedException { - throw new AuthenticationFailedException("expected init error"); - } - } - - public static class TestAuthInit4 extends TestAuthInit1 { - public static AuthInitialize create() { - return new TestAuthInit4(); - } - } - - public static class TestAuthenticator1 implements Authenticator { - public static Authenticator create() { - return null; - } - @Override - public void init(Properties securityProps, LogWriter systemLogger, LogWriter securityLogger) throws AuthenticationFailedException { - } - @Override - public Principal authenticate(Properties props, DistributedMember member) throws AuthenticationFailedException { - return null; - } - @Override - public void close() { - } - } - - public static class TestAuthenticator2 extends TestAuthenticator1 { - public static Authenticator create() { - return new TestAuthenticator2(); - } - @Override - public void init(Properties securityProps, LogWriter systemLogger, LogWriter securityLogger) throws AuthenticationFailedException { - throw new AuthenticationFailedException("expected init error"); - } - } - - public static class TestAuthenticator3 extends TestAuthenticator1 { - public static Authenticator create() { - return new TestAuthenticator3(); - } - @Override - public Principal authenticate(Properties props, DistributedMember member) throws AuthenticationFailedException { - throw new AuthenticationFailedException("expected authenticate error"); - } - } - - public static class TestAuthenticator4 extends TestAuthenticator1 { - - private static Authenticator instance = null; - private static int createCount = 0; - - private boolean closed = false; - - public static void setAuthenticator(Authenticator auth) { - instance = auth; - } - public static Authenticator create() { - createCount ++; - return instance; - } - @Override - public Principal authenticate(Properties props, DistributedMember member) throws AuthenticationFailedException { - return null; - } - @Override - public void close() { - closed = true; - } - public boolean isClosed() { - return closed; - } - public static int getCreateCount() { - return createCount; - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticatorWithAuthenticatorTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticatorWithAuthenticatorTest.java b/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticatorWithAuthenticatorTest.java new file mode 100644 index 0000000..0abf295 --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticatorWithAuthenticatorTest.java @@ -0,0 +1,186 @@ +/* + * 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.distributed.internal.membership.gms.auth; + +import static com.gemstone.gemfire.distributed.ConfigurationProperties.*; +import static org.assertj.core.api.Assertions.*; + +import java.util.Properties; + +import com.gemstone.gemfire.test.junit.categories.SecurityTest; +import com.gemstone.gemfire.test.junit.categories.UnitTest; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +/** + * Unit tests GMSAuthenticator using old security. + */ +@Category({ UnitTest.class, SecurityTest.class }) +public class GMSAuthenticatorWithAuthenticatorTest extends AbstractGMSAuthenticatorTestCase { + + @Override + protected boolean isIntegratedSecurity() { + return false; + } + + @Test + public void nullAuthenticatorShouldReturnNull() throws Exception { + assertThat(securityProps).doesNotContainKey(SECURITY_PEER_AUTHENTICATOR); + String result = authenticator.authenticate(member, securityProps, securityProps, member); + // assertThat(result).isNull(); NOTE: old security used to return null + assertThat(result).contains("Authentication failed"); + } + + @Test + public void emptyAuthenticatorShouldReturnNull() throws Exception { + securityProps.setProperty(SECURITY_PEER_AUTHENTICATOR, ""); + String result = authenticator.authenticate(member, securityProps, securityProps, member); + // assertThat(result).isNull(); NOTE: old security used to return null + assertThat(result).contains("Authentication failed"); + } + + @Test + public void shouldGetSecurityPropsFromDistributionConfig() throws Exception { + securityProps.setProperty(SECURITY_PEER_AUTH_INIT, "dummy1"); + securityProps.setProperty(SECURITY_PEER_AUTHENTICATOR, "dummy2"); + + Properties secProps = authenticator.getSecurityProps(); + + assertThat(secProps.size()).isEqualTo(2); + assertThat(secProps.getProperty(SECURITY_PEER_AUTH_INIT)).isEqualTo("dummy1"); + assertThat(secProps.getProperty(SECURITY_PEER_AUTHENTICATOR)).isEqualTo("dummy2"); + } + + @Test + public void usesPeerAuthInitToGetCredentials() throws Exception { + props.setProperty(SECURITY_PEER_AUTH_INIT, SpyAuthInit.class.getName() + ".create"); + + SpyAuthInit auth = new SpyAuthInit(); + assertThat(auth.isClosed()).isFalse(); + + SpyAuthInit.setAuthInitialize(auth); + Properties credentials = authenticator.getCredentials(member, props); + + assertThat(credentials).isEqualTo(props); + assertThat(auth.isClosed()).isTrue(); + assertThat(SpyAuthInit.getCreateCount()).isEqualTo(1); + } + + @Test + public void getCredentialsShouldReturnNullIfNoPeerAuthInit() throws Exception { + Properties credentials = authenticator.getCredentials(member, props); + assertThat(credentials).isNull(); + } + + @Test + public void getCredentialsShouldReturnNullIfEmptyPeerAuthInit() throws Exception { + props.setProperty(SECURITY_PEER_AUTH_INIT, ""); + Properties credentials = authenticator.getCredentials(member, props); + assertThat(credentials).isNull(); + } + + @Test + public void getCredentialsShouldThrowIfPeerAuthInitDoesNotExist() throws Exception { + String authInit = getClass().getName() + "$NotExistAuth.create"; + props.setProperty(SECURITY_PEER_AUTH_INIT, authInit); + assertThatThrownBy(() -> authenticator.getCredentials(member, props)).hasMessageContaining("Instance could not be obtained from"); + } + + @Test + public void getCredentialsShouldThrowIfPeerAuthInitCreateReturnsNull() throws Exception { + props.setProperty(SECURITY_PEER_AUTH_INIT, AuthInitCreateReturnsNull.class.getName() + ".create"); + assertThatThrownBy(() -> authenticator.getCredentials(member, props)).hasMessageContaining("Instance could not be obtained from"); + } + + @Test + public void getCredentialsShouldThrowIfPeerAuthInitGetCredentialsAndInitThrow() throws Exception { + props.setProperty(SECURITY_PEER_AUTH_INIT, AuthInitGetCredentialsAndInitThrow.class.getName() + ".create"); + assertThatThrownBy(() -> authenticator.getCredentials(member, props)).hasMessageContaining("expected init error"); + } + + @Test + public void getCredentialsShouldThrowIfPeerAuthInitGetCredentialsThrows() throws Exception { + props.setProperty(SECURITY_PEER_AUTH_INIT, AuthInitGetCredentialsThrows.class.getName() + ".create"); + assertThatThrownBy(() -> authenticator.getCredentials(member, props)).hasMessageContaining("expected get credential error"); + } + + @Test + public void authenticateShouldReturnNullIfSuccessful() throws Exception { + props.setProperty(SECURITY_PEER_AUTHENTICATOR, SpyAuthenticator.class.getName() + ".create"); + + SpyAuthenticator auth = new SpyAuthenticator(); + assertThat(auth.isClosed()).isFalse(); + + SpyAuthenticator.setAuthenticator(auth); + String result = authenticator.authenticate(member, props, props, member); + + assertThat(result).isNull(); + assertThat(auth.isClosed()).isTrue(); + assertThat(SpyAuthenticator.getCreateCount() == 1).isTrue(); + } + + @Test + public void authenticateShouldReturnNullIfPeerAuthenticatorIsNull() throws Exception { + String result = authenticator.authenticate(member, props, props, member); + //assertThat(result).isNull(); // NOTE: old security used to return null + assertThat(result).contains("Authentication failed. See coordinator [member] logs for details."); + } + + @Test + public void authenticateShouldReturnNullIfPeerAuthenticatorIsEmpty() throws Exception { + props.setProperty(SECURITY_PEER_AUTHENTICATOR, ""); + String result = authenticator.authenticate(member, props, props, member); + //assertThat(result).isNull(); // NOTE: old security used to return null + assertThat(result).contains("Authentication failed. See coordinator [member] logs for details."); + } + + @Test + public void authenticateShouldReturnFailureMessageIfPeerAuthenticatorDoesNotExist() throws Exception { + props.setProperty(SECURITY_PEER_AUTHENTICATOR, getClass().getName() + "$NotExistAuth.create"); + String result = authenticator.authenticate(member, props, props, member); + assertThat(result).startsWith("Authentication failed. See coordinator"); + } + + @Test + public void authenticateShouldReturnFailureMessageIfAuthenticateReturnsNull() throws Exception { + props.setProperty(SECURITY_PEER_AUTHENTICATOR, AuthenticatorReturnsNulls.class.getName() + ".create"); + String result = authenticator.authenticate(member, props, props, member); + assertThat(result).startsWith("Authentication failed. See coordinator"); + } + + @Test + public void authenticateShouldReturnFailureMessageIfNullCredentials() throws Exception { + props.setProperty(SECURITY_PEER_AUTHENTICATOR, AuthenticatorReturnsNulls.class.getName() + ".create"); + String result = authenticator.authenticate(member, null, props, member); + assertThat(result).startsWith("Failed to find credentials from"); + } + + @Test + public void authenticateShouldReturnFailureMessageIfAuthenticateInitThrows() throws Exception { + props.setProperty(SECURITY_PEER_AUTHENTICATOR, AuthenticatorInitThrows.class.getName() + ".create"); + String result = authenticator.authenticate(member, props, props, member); + assertThat(result).startsWith("Authentication failed. See coordinator"); + } + + @Test + public void authenticateShouldReturnFailureMessageIfAuthenticateThrows() throws Exception { + props.setProperty(SECURITY_PEER_AUTHENTICATOR, AuthenticatorAuthenticateThrows.class.getName() + ".create"); + String result = authenticator.authenticate(member, props, props, member); + assertThat(result).startsWith("Authentication failed. See coordinator"); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticatorWithSecurityManagerTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticatorWithSecurityManagerTest.java b/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticatorWithSecurityManagerTest.java new file mode 100644 index 0000000..b00b3ff --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticatorWithSecurityManagerTest.java @@ -0,0 +1,152 @@ +/* + * 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.distributed.internal.membership.gms.auth; + +import static com.gemstone.gemfire.distributed.ConfigurationProperties.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Properties; + +import com.gemstone.gemfire.security.GemFireSecurityException; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; +import com.gemstone.gemfire.test.junit.categories.UnitTest; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +/** + * Unit tests GMSAuthenticator using new integrated security. + */ +@Category({ UnitTest.class, SecurityTest.class }) +public class GMSAuthenticatorWithSecurityManagerTest extends AbstractGMSAuthenticatorTestCase { + + @Override + protected boolean isIntegratedSecurity() { + return true; + } + + @Test + public void nullManagerShouldReturnNull() throws Exception { + assertThat(securityProps).doesNotContainKey(SECURITY_MANAGER); + String result = authenticator.authenticate(member, securityProps, securityProps, member); + assertThat(result).isNull(); + } + + @Test + public void emptyAuthenticatorShouldReturnNull() throws Exception { + securityProps.setProperty(SECURITY_MANAGER, ""); + String result = authenticator.authenticate(member, securityProps, securityProps, member); + assertThat(result).isNull(); + } + + @Test + public void shouldGetSecurityPropsFromDistributionConfig() throws Exception { + securityProps.setProperty(SECURITY_PEER_AUTH_INIT, "dummy1"); + securityProps.setProperty(SECURITY_MANAGER, "dummy2"); + + Properties secProps = authenticator.getSecurityProps(); + + assertThat(secProps.size()).isEqualTo(2); + assertThat(secProps.getProperty(SECURITY_PEER_AUTH_INIT)).isEqualTo("dummy1"); + assertThat(secProps.getProperty(SECURITY_MANAGER)).isEqualTo("dummy2"); + } + + @Test + public void usesPeerAuthInitToGetCredentials() throws Exception { + props.setProperty(SECURITY_PEER_AUTH_INIT, SpyAuthInit.class.getName() + ".create"); + props.setProperty(SECURITY_MANAGER, "dummy"); + + SpyAuthInit auth = new SpyAuthInit(); + assertThat(auth.isClosed()).isFalse(); + + SpyAuthInit.setAuthInitialize(auth); + Properties credentials = authenticator.getCredentials(member, props); + + assertThat(credentials).isEqualTo(props); + assertThat(auth.isClosed()).isTrue(); + assertThat(SpyAuthInit.getCreateCount() == 1).isTrue(); + } + + @Test + public void getCredentialsShouldReturnNullIfNoPeerAuthInit() throws Exception { + Properties credentials = authenticator.getCredentials(member, props); + assertThat(credentials).isNull(); + } + + @Test + public void getCredentialsShouldReturnNullIfEmptyPeerAuthInit() throws Exception { + props.setProperty(SECURITY_PEER_AUTH_INIT, ""); + Properties credentials = authenticator.getCredentials(member, props); + assertThat(credentials).isNull(); + } + + @Test + public void getCredentialsShouldThrowIfPeerAuthInitDoesNotExist() throws Exception { + String authInit = getClass().getName() + "$NotExistAuth.create"; + props.setProperty(SECURITY_PEER_AUTH_INIT, authInit); + assertThatThrownBy(() -> authenticator.getCredentials(member, props)).hasMessageContaining("Instance could not be obtained"); + } + + @Test + public void getCredentialsShouldThrowIfPeerAuthInitCreateReturnsNull() throws Exception { + props.setProperty(SECURITY_PEER_AUTH_INIT, AuthInitCreateReturnsNull.class.getName() + ".create"); + assertThatThrownBy(() -> authenticator.getCredentials(member, props)).hasMessageContaining("Instance could not be obtained from"); + } + + @Test + public void getCredentialsShouldThrowIfPeerAuthInitGetCredentialsAndInitThrow() throws Exception { + props.setProperty(SECURITY_PEER_AUTH_INIT, AuthInitGetCredentialsAndInitThrow.class.getName() + ".create"); + assertThatThrownBy(() -> authenticator.getCredentials(member, props)).hasMessage("expected init error"); + } + + @Test + public void getCredentialsShouldThrowIfPeerAuthInitGetCredentialsThrows() throws Exception { + props.setProperty(SECURITY_PEER_AUTH_INIT, AuthInitGetCredentialsThrows.class.getName() + ".create"); + assertThatThrownBy(() -> authenticator.getCredentials(member, props)).hasMessage("expected get credential error"); + } + + @Test + public void authenticateShouldReturnNullIfSuccessful() throws Exception { + props.setProperty(SECURITY_MANAGER, "dummy"); + String result = authenticator.authenticate(member, props, props, member); + assertThat(result).isNull(); + } + + @Test + public void authenticateShouldReturnNullIfNoSecurityManager() throws Exception { + String result = authenticator.authenticate(member, props, props, member); + assertThat(result).isNull(); + } + + @Test + public void authenticateShouldReturnFailureMessageIfLoginThrows() throws Exception { + when(securityService.login(anyString(), anyString())).thenThrow(new GemFireSecurityException("dummy")); + props.setProperty(SECURITY_MANAGER, "dummy"); + String result = authenticator.authenticate(member, props, props, member); + assertThat(result).startsWith("Authentication failed. See coordinator"); + } + + @Test + public void authenticateShouldReturnFailureMessageIfNullCredentials() throws Exception { + props.setProperty(SECURITY_MANAGER, "dummy"); + String result = authenticator.authenticate(member, null, props, member); + assertThat(result).startsWith("Failed to find credentials from"); + } + +} + http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/f93b7485/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/ContainsKey66Test.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/ContainsKey66Test.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/ContainsKey66Test.java new file mode 100644 index 0000000..e17ee18 --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/ContainsKey66Test.java @@ -0,0 +1,156 @@ +/* + * 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.internal.cache.tier.sockets.command; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Matchers.*; +import static org.mockito.Mockito.*; + +import java.util.Properties; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.internal.cache.LocalRegion; +import com.gemstone.gemfire.internal.cache.tier.sockets.CacheServerStats; +import com.gemstone.gemfire.internal.cache.tier.sockets.Message; +import com.gemstone.gemfire.internal.cache.tier.sockets.Part; +import com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection; +import com.gemstone.gemfire.internal.security.AuthorizeRequest; +import com.gemstone.gemfire.internal.security.SecurityService; +import com.gemstone.gemfire.security.NotAuthorizedException; +import com.gemstone.gemfire.test.junit.categories.UnitTest; + +@Category(UnitTest.class) +public class ContainsKey66Test { + + private static final String REGION_NAME = "region1"; + private static final String KEY = "key1"; + + @Mock + private SecurityService securityService; + @Mock + private Message message; + @Mock + private ServerConnection serverConnection; + @Mock + private AuthorizeRequest authzRequest; + @Mock + private LocalRegion region; + @Mock + private Cache cache; + @Mock + private CacheServerStats cacheServerStats; + @Mock + private Message responseMessage; + @Mock + private Message errorResponseMessage; + @Mock + private Part regionNamePart; + @Mock + private Part keyPart; + @Mock + private Part modePart; + @InjectMocks + private ContainsKey66 containsKey66; + + @Before + public void setUp() throws Exception { + this.containsKey66 = new ContainsKey66(); + MockitoAnnotations.initMocks(this); + + when(this.region.containsKey(eq(REGION_NAME))).thenReturn(true); + + when(this.cache.getRegion(isA(String.class))).thenReturn(this.region); + + when(this.serverConnection.getCache()).thenReturn(this.cache); + when(this.serverConnection.getCacheServerStats()).thenReturn(this.cacheServerStats); + when(this.serverConnection.getErrorResponseMessage()).thenReturn(this.errorResponseMessage); + when(this.serverConnection.getResponseMessage()).thenReturn(this.responseMessage); + when(this.serverConnection.getAuthzRequest()).thenReturn(this.authzRequest); + + when(this.regionNamePart.getString()).thenReturn(REGION_NAME); + + when(this.keyPart.getStringOrObject()).thenReturn(KEY); + when(this.modePart.getInt()).thenReturn(0); + + when(this.message.getPart(eq(0))).thenReturn(this.regionNamePart); + when(this.message.getPart(eq(1))).thenReturn(this.keyPart); + when(this.message.getPart(eq(2))).thenReturn(this.modePart); + } + + @Test + public void noSecurityShouldSucceed() throws Exception { + when(this.securityService.isClientSecurityRequired()).thenReturn(false); + + this.containsKey66.cmdExecute(this.message, this.serverConnection, 0); + + verify(this.responseMessage).send(this.serverConnection); + } + + @Test + public void integratedSecurityShouldSucceedIfAuthorized() throws Exception { + when(this.securityService.isClientSecurityRequired()).thenReturn(true); + when(this.securityService.isIntegratedSecurity()).thenReturn(true); + + this.containsKey66.cmdExecute(this.message, this.serverConnection, 0); + + verify(this.securityService).authorizeRegionRead(eq(REGION_NAME), eq(KEY)); + verify(this.responseMessage).send(this.serverConnection); + } + + @Test + public void integratedSecurityShouldFailIfNotAuthorized() throws Exception { + when(this.securityService.isClientSecurityRequired()).thenReturn(true); + when(this.securityService.isIntegratedSecurity()).thenReturn(true); + doThrow(new NotAuthorizedException("")).when(this.securityService).authorizeRegionRead(eq(REGION_NAME), eq(KEY)); + + this.containsKey66.cmdExecute(this.message, this.serverConnection, 0); + + verify(this.securityService).authorizeRegionRead(eq(REGION_NAME), eq(KEY)); + verify(this.errorResponseMessage).send(eq(this.serverConnection)); + } + + @Test + public void oldSecurityShouldSucceedIfAuthorized() throws Exception { + when(this.securityService.isClientSecurityRequired()).thenReturn(true); + when(this.securityService.isIntegratedSecurity()).thenReturn(false); + + this.containsKey66.cmdExecute(this.message, this.serverConnection, 0); + + verify(this.authzRequest).containsKeyAuthorize(eq(REGION_NAME), eq(KEY)); + verify(this.responseMessage).send(this.serverConnection); + } + + @Test + public void oldSecurityShouldFailIfNotAuthorized() throws Exception { + when(this.securityService.isClientSecurityRequired()).thenReturn(true); + when(this.securityService.isIntegratedSecurity()).thenReturn(false); + doThrow(new NotAuthorizedException("")).when(this.authzRequest).containsKeyAuthorize(eq(REGION_NAME), eq(KEY)); + + this.containsKey66.cmdExecute(this.message, this.serverConnection, 0); + + verify(this.authzRequest).containsKeyAuthorize(eq(REGION_NAME), eq(KEY)); + verify(this.errorResponseMessage).send(eq(this.serverConnection)); + } + +}