You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2023/02/11 10:47:36 UTC

[shardingsphere] branch master updated: Add authority rule on XXXAuthenticationHandler.getAuthenticator (#24119)

This is an automated email from the ASF dual-hosted git repository.

duanzhengqiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 04b6898c92d Add authority rule on XXXAuthenticationHandler.getAuthenticator (#24119)
04b6898c92d is described below

commit 04b6898c92d2fd99db0d2dce55c14cd97dbc341e
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Sat Feb 11 18:47:28 2023 +0800

    Add authority rule on XXXAuthenticationHandler.getAuthenticator (#24119)
---
 .../swapper/YamlPluginsConfigurationSwapperTest.java    | 17 +++++++++--------
 .../mysql/authentication/MySQLAuthenticationEngine.java |  4 +++-
 .../authentication/MySQLAuthenticationHandler.java      | 12 +++++++-----
 .../authentication/MySQLAuthenticationEngineTest.java   |  3 ++-
 .../authentication/MySQLAuthenticationHandlerTest.java  |  2 +-
 .../authentication/PostgreSQLAuthenticationEngine.java  |  5 ++++-
 .../authentication/PostgreSQLAuthenticationHandler.java | 12 +++++++-----
 .../PostgreSQLAuthenticationEngineTest.java             | 14 +++++++-------
 .../PostgreSQLAuthenticationHandlerTest.java            |  2 +-
 9 files changed, 41 insertions(+), 30 deletions(-)

diff --git a/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/config/yaml/swapper/YamlPluginsConfigurationSwapperTest.java b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/config/yaml/swapper/YamlPluginsConfigurationSwapperTest.java
index e04ad486473..8f21a54e4ec 100644
--- a/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/config/yaml/swapper/YamlPluginsConfigurationSwapperTest.java
+++ b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/config/yaml/swapper/YamlPluginsConfigurationSwapperTest.java
@@ -39,9 +39,9 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertNull;
 
 public final class YamlPluginsConfigurationSwapperTest {
-
+    
     private static final String CONFIG_PATH = "/conf/agent.yaml";
-
+    
     @Test
     public void assertSwap() throws IOException {
         YamlAgentConfiguration yamlAgentConfiguration = getAgentConfiguration();
@@ -52,19 +52,20 @@ public final class YamlPluginsConfigurationSwapperTest {
         assertMetricsPluginConfiguration(pluginConfigurationMap.get("MetricsFixture"));
         assertTracingPluginConfiguration(pluginConfigurationMap.get("TracingFixture"));
     }
-
+    
     private YamlAgentConfiguration getAgentConfiguration() throws UnsupportedEncodingException, FileNotFoundException {
         FileInputStream fileInputStream = new FileInputStream(new File(getResourceURL(), CONFIG_PATH));
         InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
         return new Yaml().loadAs(inputStreamReader, YamlAgentConfiguration.class);
     }
-
+    
     private String getResourceURL() throws UnsupportedEncodingException {
         return URLDecoder.decode(
                 Objects.requireNonNull(YamlPluginsConfigurationSwapper.class.getClassLoader().getResource(""))
-                        .getFile(), "UTF8");
+                        .getFile(),
+                "UTF8");
     }
-
+    
     private void assertLogFixturePluginConfiguration(final PluginConfiguration pluginConfiguration) {
         assertNull(pluginConfiguration.getHost());
         assertThat(pluginConfiguration.getPort(), is(0));
@@ -72,7 +73,7 @@ public final class YamlPluginsConfigurationSwapperTest {
         assertThat(pluginConfiguration.getProps().size(), is(1));
         assertThat(pluginConfiguration.getProps().getProperty("logging_key"), is("logging_value"));
     }
-
+    
     private void assertMetricsPluginConfiguration(final PluginConfiguration pluginConfiguration) {
         assertThat(pluginConfiguration.getHost(), is("metrics.host"));
         assertThat(pluginConfiguration.getPort(), is(1));
@@ -80,7 +81,7 @@ public final class YamlPluginsConfigurationSwapperTest {
         assertThat(pluginConfiguration.getProps().size(), is(1));
         assertThat(pluginConfiguration.getProps().getProperty("metrics_key"), is("metrics_value"));
     }
-
+    
     private void assertTracingPluginConfiguration(final PluginConfiguration pluginConfiguration) {
         assertThat(pluginConfiguration.getHost(), is("tracing.host"));
         assertThat(pluginConfiguration.getPort(), is(2));
diff --git a/proxy/frontend/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationEngine.java b/proxy/frontend/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationEngine.java
index 08550808cbd..c9517ec843d 100644
--- a/proxy/frontend/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationEngine.java
+++ b/proxy/frontend/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationEngine.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.proxy.frontend.mysql.authentication;
 
 import com.google.common.base.Strings;
 import io.netty.channel.ChannelHandlerContext;
+import org.apache.shardingsphere.authority.rule.AuthorityRule;
 import org.apache.shardingsphere.db.protocol.CommonConstants;
 import org.apache.shardingsphere.db.protocol.mysql.constant.MySQLCapabilityFlag;
 import org.apache.shardingsphere.db.protocol.mysql.constant.MySQLCharacterSet;
@@ -102,7 +103,8 @@ public final class MySQLAuthenticationEngine implements AuthenticationEngine {
             context.close();
             return AuthenticationResultBuilder.continued();
         }
-        MySQLAuthenticator authenticator = authenticationHandler.getAuthenticator(new Grantee(packet.getUsername(), getHostAddress(context)));
+        AuthorityRule rule = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(AuthorityRule.class);
+        MySQLAuthenticator authenticator = authenticationHandler.getAuthenticator(rule, new Grantee(packet.getUsername(), getHostAddress(context)));
         if (isClientPluginAuth(packet) && !authenticator.getAuthenticationMethodName().equals(packet.getAuthPluginName())) {
             connectionPhase = MySQLConnectionPhase.AUTHENTICATION_METHOD_MISMATCH;
             context.writeAndFlush(new MySQLAuthSwitchRequestPacket(authenticator.getAuthenticationMethodName(), authenticationHandler.getAuthPluginData()));
diff --git a/proxy/frontend/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationHandler.java b/proxy/frontend/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationHandler.java
index 8cf729cbf0b..609acf5fa94 100644
--- a/proxy/frontend/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationHandler.java
+++ b/proxy/frontend/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationHandler.java
@@ -48,22 +48,24 @@ public final class MySQLAuthenticationHandler {
      * @return login success or failure
      */
     public Optional<MySQLVendorError> login(final String username, final String hostname, final byte[] authenticationResponse, final String databaseName) {
-        AuthorityRule authorityRule = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(AuthorityRule.class);
+        AuthorityRule rule = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(AuthorityRule.class);
         Grantee grantee = new Grantee(username, hostname);
-        Optional<ShardingSphereUser> user = authorityRule.findUser(grantee);
-        if (!user.isPresent() || !getAuthenticator(grantee).authenticate(user.get(), authenticationResponse)) {
+        Optional<ShardingSphereUser> user = rule.findUser(grantee);
+        if (!user.isPresent() || !getAuthenticator(rule, grantee).authenticate(user.get(), authenticationResponse)) {
             return Optional.of(MySQLVendorError.ER_ACCESS_DENIED_ERROR);
         }
-        return null == databaseName || new AuthorityChecker(authorityRule, grantee).isAuthorized(databaseName) ? Optional.empty() : Optional.of(MySQLVendorError.ER_DBACCESS_DENIED_ERROR);
+        return null == databaseName || new AuthorityChecker(rule, grantee).isAuthorized(databaseName) ? Optional.empty() : Optional.of(MySQLVendorError.ER_DBACCESS_DENIED_ERROR);
     }
     
     /**
      * Get authenticator.
      *
+     * @param rule authority rule
      * @param grantee grantee
      * @return authenticator
      */
-    public MySQLAuthenticator getAuthenticator(final Grantee grantee) {
+    public MySQLAuthenticator getAuthenticator(final AuthorityRule rule, final Grantee grantee) {
+        // TODO use authority rule and grantee to determine authentication method
         return new MySQLNativePasswordAuthenticator(authPluginData);
     }
 }
diff --git a/proxy/frontend/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationEngineTest.java b/proxy/frontend/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationEngineTest.java
index 39a4e6de662..6099b4834c6 100644
--- a/proxy/frontend/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationEngineTest.java
+++ b/proxy/frontend/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationEngineTest.java
@@ -92,6 +92,7 @@ public final class MySQLAuthenticationEngineTest extends ProxyContextRestorer {
     @SuppressWarnings("unchecked")
     @Test
     public void assertAuthenticationMethodMismatch() {
+        setMetaDataContexts();
         setConnectionPhase(MySQLConnectionPhase.AUTH_PHASE_FAST_PATH);
         MySQLPacketPayload payload = mock(MySQLPacketPayload.class);
         ChannelHandlerContext channelHandlerContext = mock(ChannelHandlerContext.class);
@@ -104,7 +105,7 @@ public final class MySQLAuthenticationEngineTest extends ProxyContextRestorer {
         when(payload.readInt1()).thenReturn(1);
         when(payload.readInt4()).thenReturn(MySQLCapabilityFlag.CLIENT_PLUGIN_AUTH.getValue());
         when(payload.readStringNul()).thenReturn("root");
-        when(authenticationHandler.getAuthenticator(any())).thenReturn(new MySQLNativePasswordAuthenticator(mock(MySQLAuthPluginData.class)));
+        when(authenticationHandler.getAuthenticator(any(), any())).thenReturn(new MySQLNativePasswordAuthenticator(mock(MySQLAuthPluginData.class)));
         authenticationEngine.authenticate(channelHandlerContext, payload);
         assertThat(getConnectionPhase(), is(MySQLConnectionPhase.AUTHENTICATION_METHOD_MISMATCH));
     }
diff --git a/proxy/frontend/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationHandlerTest.java b/proxy/frontend/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationHandlerTest.java
index bc2d121e4ae..8041a668779 100644
--- a/proxy/frontend/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationHandlerTest.java
+++ b/proxy/frontend/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationHandlerTest.java
@@ -121,7 +121,7 @@ public final class MySQLAuthenticationHandlerTest extends ProxyContextRestorer {
     
     @Test
     public void assertGetAuthenticator() {
-        MySQLAuthenticator authenticator = authenticationHandler.getAuthenticator(new Grantee("root", ""));
+        MySQLAuthenticator authenticator = authenticationHandler.getAuthenticator(mock(AuthorityRule.class), new Grantee("root", ""));
         assertThat(authenticator, instanceOf(MySQLNativePasswordAuthenticator.class));
         assertThat(authenticator.getAuthenticationMethodName(), is(MySQLAuthenticationMethod.SECURE_PASSWORD_AUTHENTICATION.getMethodName()));
     }
diff --git a/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java b/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
index af527b83d49..564b11ffacb 100644
--- a/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
+++ b/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.proxy.frontend.postgresql.authentication;
 
 import com.google.common.base.Strings;
 import io.netty.channel.ChannelHandlerContext;
+import org.apache.shardingsphere.authority.rule.AuthorityRule;
 import org.apache.shardingsphere.db.protocol.CommonConstants;
 import org.apache.shardingsphere.db.protocol.payload.PacketPayload;
 import org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLAuthenticationMethod;
@@ -38,6 +39,7 @@ import org.apache.shardingsphere.db.protocol.postgresql.payload.PostgreSQLPacket
 import org.apache.shardingsphere.dialect.postgresql.exception.authority.EmptyUsernameException;
 import org.apache.shardingsphere.dialect.postgresql.exception.protocol.ProtocolViolationException;
 import org.apache.shardingsphere.infra.metadata.user.Grantee;
+import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import org.apache.shardingsphere.proxy.backend.handler.admin.postgresql.PostgreSQLCharacterSets;
 import org.apache.shardingsphere.proxy.frontend.authentication.AuthenticationEngine;
 import org.apache.shardingsphere.proxy.frontend.authentication.AuthenticationResult;
@@ -112,7 +114,8 @@ public final class PostgreSQLAuthenticationEngine implements AuthenticationEngin
     }
     
     private PostgreSQLIdentifierPacket getIdentifierPacket(final String username) {
-        PostgreSQLAuthenticator authenticator = authenticationHandler.getAuthenticator(new Grantee(username, ""));
+        AuthorityRule rule = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(AuthorityRule.class);
+        PostgreSQLAuthenticator authenticator = authenticationHandler.getAuthenticator(rule, new Grantee(username, ""));
         if (PostgreSQLAuthenticationMethod.PASSWORD.getMethodName().equals(authenticator.getAuthenticationMethodName())) {
             return new PostgreSQLPasswordAuthenticationPacket();
         }
diff --git a/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandler.java b/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandler.java
index 58b8bd52cbe..5591b96e6f5 100644
--- a/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandler.java
+++ b/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandler.java
@@ -49,23 +49,25 @@ public final class PostgreSQLAuthenticationHandler {
      */
     public void login(final String username, final String databaseName, final byte[] md5Salt, final PostgreSQLPasswordMessagePacket passwordMessagePacket) {
         ShardingSpherePreconditions.checkState(Strings.isNullOrEmpty(databaseName) || ProxyContext.getInstance().databaseExists(databaseName), () -> new UnknownDatabaseException(databaseName));
-        AuthorityRule authorityRule = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(AuthorityRule.class);
+        AuthorityRule rule = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(AuthorityRule.class);
         Grantee grantee = new Grantee(username, "%");
-        Optional<ShardingSphereUser> user = authorityRule.findUser(grantee);
+        Optional<ShardingSphereUser> user = rule.findUser(grantee);
         ShardingSpherePreconditions.checkState(user.isPresent(), () -> new UnknownUsernameException(username));
-        ShardingSpherePreconditions.checkState(getAuthenticator(grantee).authenticate(user.get(), new Object[]{passwordMessagePacket.getDigest(), md5Salt}),
+        ShardingSpherePreconditions.checkState(getAuthenticator(rule, grantee).authenticate(user.get(), new Object[]{passwordMessagePacket.getDigest(), md5Salt}),
                 () -> new InvalidPasswordException(username));
-        ShardingSpherePreconditions.checkState(null == databaseName || new AuthorityChecker(authorityRule, grantee).isAuthorized(databaseName),
+        ShardingSpherePreconditions.checkState(null == databaseName || new AuthorityChecker(rule, grantee).isAuthorized(databaseName),
                 () -> new PrivilegeNotGrantedException(username, databaseName));
     }
     
     /**
      * Get authenticator.
      *
+     * @param rule authority rule
      * @param grantee username
      * @return authenticator
      */
-    public PostgreSQLAuthenticator getAuthenticator(final Grantee grantee) {
+    public PostgreSQLAuthenticator getAuthenticator(final AuthorityRule rule, final Grantee grantee) {
+        // TODO use authority rule and grantee to determine authentication method
         return new PostgreSQLMD5PasswordAuthenticator();
     }
 }
diff --git a/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngineTest.java b/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngineTest.java
index 2f54ae9bdd5..4351fb62d9b 100644
--- a/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngineTest.java
+++ b/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngineTest.java
@@ -59,7 +59,6 @@ import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Properties;
 
-import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertFalse;
@@ -129,14 +128,9 @@ public final class PostgreSQLAuthenticationEngineTest extends ProxyContextRestor
         assertLogin("wrong" + password);
     }
     
-    @Test
-    public void assertGetIdentifierPacket() throws ReflectiveOperationException {
-        assertThat(Plugins.getMemberAccessor().invoke(PostgreSQLAuthenticationEngine.class.getDeclaredMethod("getIdentifierPacket", String.class), new PostgreSQLAuthenticationEngine(), username),
-                instanceOf(PostgreSQLMD5PasswordAuthenticationPacket.class));
-    }
-    
     @SneakyThrows(ReflectiveOperationException.class)
     private void assertLogin(final String inputPassword) {
+        mockInitProxyContext();
         PostgreSQLPacketPayload payload = new PostgreSQLPacketPayload(createByteBuf(16, 128), StandardCharsets.UTF_8);
         payload.writeInt4(64);
         payload.writeInt4(196608);
@@ -166,6 +160,12 @@ public final class PostgreSQLAuthenticationEngineTest extends ProxyContextRestor
         assertThat(actual.isFinished(), is(password.equals(inputPassword)));
     }
     
+    private void mockInitProxyContext() {
+        ContextManager contextManager = mock(ContextManager.class, RETURNS_DEEP_STUBS);
+        when(contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData()).thenReturn(new ShardingSphereRuleMetaData(Collections.singleton(mock(AuthorityRule.class))));
+        ProxyContext.init(contextManager);
+    }
+    
     private ByteBuf createByteBuf(final int initialCapacity, final int maxCapacity) {
         return new UnpooledHeapByteBuf(UnpooledByteBufAllocator.DEFAULT, initialCapacity, maxCapacity);
     }
diff --git a/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandlerTest.java b/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandlerTest.java
index 6835b026cf2..784b2f702de 100644
--- a/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandlerTest.java
+++ b/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandlerTest.java
@@ -112,7 +112,7 @@ public final class PostgreSQLAuthenticationHandlerTest extends ProxyContextResto
     
     @Test
     public void assertGetAuthenticator() {
-        PostgreSQLAuthenticator authenticator = new PostgreSQLAuthenticationHandler().getAuthenticator(new Grantee(username, ""));
+        PostgreSQLAuthenticator authenticator = new PostgreSQLAuthenticationHandler().getAuthenticator(mock(AuthorityRule.class), new Grantee(username, ""));
         assertThat(authenticator, instanceOf(PostgreSQLMD5PasswordAuthenticator.class));
         assertThat(authenticator.getAuthenticationMethodName(), is(PostgreSQLAuthenticationMethod.MD5.getMethodName()));
     }