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

totalo 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 025966c078c Add UnauthorizedOperationException to decouple audit 
exception and authority exception (#23814)
025966c078c is described below

commit 025966c078c0d4e231da4eb6cdba57e4d47786bb
Author: Liang Zhang <[email protected]>
AuthorDate: Mon Jan 30 09:03:57 2023 +0800

    Add UnauthorizedOperationException to decouple audit exception and 
authority exception (#23814)
    
    * Add UnauthorizedOperationException to decouple audit exception and 
authority exception
    
    * Add UnauthorizedOperationException to decouple audit exception and 
authority exception
    
    * Add UnauthorizedOperationException to decouple audit exception and 
authority exception
    
    * Refactor AuthorityChecker
    
    * Refactor AuthorityChecker
---
 .../user-manual/error-code/sql-error-code.cn.md    |  9 ++++-
 .../user-manual/error-code/sql-error-code.en.md    |  6 +++
 .../hint/SQLHintDataSourceNotExistsException.java  |  2 +-
 .../authority/checker/AuthorityChecker.java        | 46 +++++++++++-----------
 .../exception/UnauthorizedOperationException.java  | 12 +++---
 .../authority/checker/AuthorityCheckerTest.java    | 14 +++----
 .../handler/ProxyBackendHandlerFactory.java        |  2 +-
 .../authentication/MySQLAuthenticationHandler.java |  2 +-
 .../OpenGaussAuthenticationHandler.java            |  2 +-
 .../PostgreSQLAuthenticationHandler.java           |  2 +-
 .../DefaultPipelineDataSourceManagerTest.java      |  2 -
 11 files changed, 53 insertions(+), 46 deletions(-)

diff --git a/docs/document/content/user-manual/error-code/sql-error-code.cn.md 
b/docs/document/content/user-manual/error-code/sql-error-code.cn.md
index 626354b7f7e..cdb54cda0ce 100644
--- a/docs/document/content/user-manual/error-code/sql-error-code.cn.md
+++ b/docs/document/content/user-manual/error-code/sql-error-code.cn.md
@@ -82,7 +82,13 @@ SQL 错误码以标准的 SQL State,Vendor Code 和详细错误信息提供,
 | SQL State | Vendor Code | 错误信息 |
 | --------- | ----------- | ------ |
 | 44000     | 16000       | SQL audit failed, error message: %s. |
-| 44000     | 16001       | Hint datasource: %s is not exist. |
+| 44000     | 16001       | Hint data source: %s is not exist. |
+
+### 权限
+
+| SQL State | Vendor Code | 错误信息 |
+| --------- | ----------- | ------ |
+| 44000     | 16500       | Access denied for operation `%s`. |
 
 ### 集群
 
@@ -229,7 +235,6 @@ SQL 错误码以标准的 SQL State,Vendor Code 和详细错误信息提供,
 | 44000     | 20383       | Group name in MGR is not same with configured one 
\`%s\` in database \`%s\`. |
 | 42S01     | 20390       | MySQL Duplicate primary data source in database 
\`%s\`. |
 
-
 ### SQL 方言转换
 
 | SQL State | Vendor Code | 错误信息 |
diff --git a/docs/document/content/user-manual/error-code/sql-error-code.en.md 
b/docs/document/content/user-manual/error-code/sql-error-code.en.md
index 3c174ed241c..f8b13c497a1 100644
--- a/docs/document/content/user-manual/error-code/sql-error-code.en.md
+++ b/docs/document/content/user-manual/error-code/sql-error-code.en.md
@@ -84,6 +84,12 @@ SQL error codes provide by standard `SQL State`, `Vendor 
Code` and `Reason`, whi
 | 44000     | 16000       | SQL audit failed, error message: %s. |
 | 44000     | 16001       | Hint datasource: %s is not exist. |
 
+### Authority
+
+| SQL State | Vendor Code | Reason |
+| --------- | ----------- | ------ |
+| 44000     | 16500       | Access denied for operation `%s`. |
+
 ### Cluster
 
 | SQL State | Vendor Code | Reason |
diff --git 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintDataSourceNotExistsException.java
 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintDataSourceNotExistsException.java
index e463d6aa3ea..6a2f9b0f0c0 100644
--- 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintDataSourceNotExistsException.java
+++ 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintDataSourceNotExistsException.java
@@ -30,6 +30,6 @@ public final class SQLHintDataSourceNotExistsException 
extends KernelSQLExceptio
     private static final int KERNEL_CODE = 6;
     
     public SQLHintDataSourceNotExistsException(final String errorMessage) {
-        super(XOpenSQLState.CHECK_OPTION_VIOLATION, KERNEL_CODE, 1, "Hint 
datasource: %s is not exist.", errorMessage);
+        super(XOpenSQLState.CHECK_OPTION_VIOLATION, KERNEL_CODE, 1, "Hint data 
source: %s is not exist.", errorMessage);
     }
 }
diff --git 
a/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/checker/AuthorityChecker.java
 
b/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/checker/AuthorityChecker.java
index c1ce6a4dc9e..81e743d5218 100644
--- 
a/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/checker/AuthorityChecker.java
+++ 
b/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/checker/AuthorityChecker.java
@@ -18,12 +18,11 @@
 package org.apache.shardingsphere.authority.checker;
 
 import lombok.RequiredArgsConstructor;
+import 
org.apache.shardingsphere.authority.exception.UnauthorizedOperationException;
 import org.apache.shardingsphere.authority.model.PrivilegeType;
 import org.apache.shardingsphere.authority.model.ShardingSpherePrivileges;
 import org.apache.shardingsphere.authority.rule.AuthorityRule;
-import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
-import 
org.apache.shardingsphere.infra.executor.audit.exception.SQLAuditException;
-import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import 
org.apache.shardingsphere.dialect.exception.syntax.database.UnknownDatabaseException;
 import org.apache.shardingsphere.infra.metadata.user.Grantee;
 import 
org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
@@ -58,43 +57,42 @@ public final class AuthorityChecker {
     private final Grantee grantee;
     
     /**
-     * Check database authority.
-     * 
-     * @param databaseName database name
-     * @return authorized or not
+     * Check Authentication with cipher.
+     *
+     * @param validator validator
+     * @param cipher cipher
+     * @return authenticated or not
      */
-    public boolean isAuthorized(final String databaseName) {
-        return null == grantee || rule.findPrivileges(grantee).map(optional -> 
optional.hasPrivileges(databaseName)).orElse(false);
+    public boolean isAuthenticated(final BiPredicate<Object, Object> 
validator, final Object cipher) {
+        return rule.findUser(grantee).filter(optional -> 
validator.test(optional, cipher)).isPresent();
     }
     
     /**
-     * Check authority with cipher.
+     * Check database authority.
      * 
-     * @param validator validator
-     * @param cipher cipher
+     * @param databaseName database name
      * @return authorized or not
      */
-    public boolean isAuthorized(final BiPredicate<Object, Object> validator, 
final Object cipher) {
-        return rule.findUser(grantee).filter(optional -> 
validator.test(optional, cipher)).isPresent();
+    public boolean isAuthorized(final String databaseName) {
+        return null == grantee || rule.findPrivileges(grantee).map(optional -> 
optional.hasPrivileges(databaseName)).orElse(false);
     }
     
     /**
-     * Check SQL authority.
+     * Check privileges.
      *
-     * @param sqlStatementContext SQL statement context
-     * @param database current database
+     * @param databaseName database name
+     * @param sqlStatement SQL statement
      */
-    public void isAuthorized(final SQLStatementContext<?> sqlStatementContext, 
final ShardingSphereDatabase database) {
+    public void checkPrivileges(final String databaseName, final SQLStatement 
sqlStatement) {
         if (null == grantee) {
             return;
         }
         Optional<ShardingSpherePrivileges> privileges = 
rule.findPrivileges(grantee);
-        ShardingSpherePreconditions.checkState(privileges.isPresent(), () -> 
new SQLAuditException(String.format("Access denied for user '%s'@'%s'", 
grantee.getUsername(), grantee.getHostname())));
-        ShardingSpherePreconditions.checkState(null == database || 
privileges.filter(optional -> 
optional.hasPrivileges(database.getName())).isPresent(),
-                () -> new SQLAuditException(String.format("Unknown database 
'%s'", null == database ? null : database.getName())));
-        PrivilegeType privilegeType = 
getPrivilege(sqlStatementContext.getSqlStatement());
-        boolean hasPrivileges = 
privileges.get().hasPrivileges(Collections.singleton(privilegeType));
-        ShardingSpherePreconditions.checkState(hasPrivileges, () -> new 
SQLAuditException(String.format("Access denied for operation %s", null == 
privilegeType ? "" : privilegeType.name())));
+        ShardingSpherePreconditions.checkState(null == databaseName || 
privileges.filter(optional -> optional.hasPrivileges(databaseName)).isPresent(),
+                () -> new UnknownDatabaseException(databaseName));
+        PrivilegeType privilegeType = getPrivilege(sqlStatement);
+        ShardingSpherePreconditions.checkState(privileges.isPresent() && 
privileges.get().hasPrivileges(Collections.singleton(privilegeType)),
+                () -> new UnauthorizedOperationException(null == privilegeType 
? "" : privilegeType.name()));
     }
     
     private PrivilegeType getPrivilege(final SQLStatement sqlStatement) {
diff --git 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintDataSourceNotExistsException.java
 
b/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/exception/UnauthorizedOperationException.java
similarity index 74%
copy from 
infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintDataSourceNotExistsException.java
copy to 
kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/exception/UnauthorizedOperationException.java
index e463d6aa3ea..2d4ba47e8ee 100644
--- 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintDataSourceNotExistsException.java
+++ 
b/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/exception/UnauthorizedOperationException.java
@@ -15,21 +15,21 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.infra.hint;
+package org.apache.shardingsphere.authority.exception;
 
 import 
org.apache.shardingsphere.infra.util.exception.external.sql.sqlstate.XOpenSQLState;
 import 
org.apache.shardingsphere.infra.util.exception.external.sql.type.kernel.KernelSQLException;
 
 /**
- * SQL Hint data source not exists exception.
+ * Unauthorized operation exception.
  */
-public final class SQLHintDataSourceNotExistsException extends 
KernelSQLException {
+public final class UnauthorizedOperationException extends KernelSQLException {
     
-    private static final long serialVersionUID = -8222967059220727514L;
+    private static final long serialVersionUID = -182093939317068572L;
     
     private static final int KERNEL_CODE = 6;
     
-    public SQLHintDataSourceNotExistsException(final String errorMessage) {
-        super(XOpenSQLState.CHECK_OPTION_VIOLATION, KERNEL_CODE, 1, "Hint 
datasource: %s is not exist.", errorMessage);
+    public UnauthorizedOperationException(final String operation) {
+        super(XOpenSQLState.CHECK_OPTION_VIOLATION, KERNEL_CODE, 500, "Access 
denied for operation `%s`.", operation);
     }
 }
diff --git 
a/kernel/authority/core/src/test/java/org/apache/shardingsphere/authority/checker/AuthorityCheckerTest.java
 
b/kernel/authority/core/src/test/java/org/apache/shardingsphere/authority/checker/AuthorityCheckerTest.java
index f469f758ca0..30920cce4a1 100644
--- 
a/kernel/authority/core/src/test/java/org/apache/shardingsphere/authority/checker/AuthorityCheckerTest.java
+++ 
b/kernel/authority/core/src/test/java/org/apache/shardingsphere/authority/checker/AuthorityCheckerTest.java
@@ -19,12 +19,12 @@ package org.apache.shardingsphere.authority.checker;
 
 import org.apache.shardingsphere.authority.config.AuthorityRuleConfiguration;
 import org.apache.shardingsphere.authority.rule.AuthorityRule;
-import 
org.apache.shardingsphere.infra.binder.statement.ddl.CreateTableStatementContext;
-import 
org.apache.shardingsphere.infra.binder.statement.dml.InsertStatementContext;
-import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
 import org.apache.shardingsphere.infra.config.algorithm.AlgorithmConfiguration;
 import org.apache.shardingsphere.infra.metadata.user.Grantee;
 import org.apache.shardingsphere.infra.metadata.user.ShardingSphereUser;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.CreateTableStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.InsertStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 import org.junit.Test;
 
 import java.util.Collection;
@@ -44,12 +44,12 @@ public final class AuthorityCheckerTest {
     }
     
     @Test
-    public void assertCheck() {
+    public void assertCheckPrivileges() {
         Collection<ShardingSphereUser> users = Collections.singleton(new 
ShardingSphereUser("root", "", "localhost"));
         AuthorityRule rule = new AuthorityRule(new 
AuthorityRuleConfiguration(users, new AlgorithmConfiguration("ALL_PERMITTED", 
new Properties())), Collections.emptyMap());
         AuthorityChecker authorityChecker = new AuthorityChecker(rule, new 
Grantee("root", "localhost"));
-        authorityChecker.isAuthorized(mock(SelectStatementContext.class), 
null);
-        authorityChecker.isAuthorized(mock(InsertStatementContext.class), 
null);
-        authorityChecker.isAuthorized(mock(CreateTableStatementContext.class), 
null);
+        authorityChecker.checkPrivileges(null, mock(SelectStatement.class));
+        authorityChecker.checkPrivileges(null, mock(InsertStatement.class));
+        authorityChecker.checkPrivileges(null, 
mock(CreateTableStatement.class));
     }
 }
diff --git 
a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactory.java
 
b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactory.java
index 6e233082981..50c00200b27 100644
--- 
a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactory.java
+++ 
b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactory.java
@@ -162,7 +162,7 @@ public final class ProxyBackendHandlerFactory {
                 : connectionSession.getDatabaseName();
         AuthorityRule authorityRule = 
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(AuthorityRule.class);
         ShardingSphereDatabase database = 
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getDatabase(databaseName);
-        new AuthorityChecker(authorityRule, 
connectionSession.getGrantee()).isAuthorized(sqlStatementContext, database);
+        new AuthorityChecker(authorityRule, 
connectionSession.getGrantee()).checkPrivileges(databaseName, 
sqlStatementContext.getSqlStatement());
         SQLAuditEngine.audit(sqlStatementContext, queryContext.getParameters(),
                 
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData(),
 database, connectionSession.getGrantee());
         backendHandler = 
DatabaseAdminBackendHandlerFactory.newInstance(databaseType, 
sqlStatementContext, connectionSession);
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 1de8b70caf0..f94554f8fa5 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
@@ -52,7 +52,7 @@ public final class MySQLAuthenticationHandler {
         Grantee grantee = new Grantee(username, hostname);
         AuthorityChecker authorityChecker = new 
AuthorityChecker(authorityRule, grantee);
         MySQLAuthenticator authenticator = getAuthenticator(username, 
hostname);
-        if (!authorityChecker.isAuthorized((a, b) -> 
authenticator.authenticate((ShardingSphereUser) a, (byte[]) b), 
authenticationResponse)) {
+        if (!authorityChecker.isAuthenticated((a, b) -> 
authenticator.authenticate((ShardingSphereUser) a, (byte[]) b), 
authenticationResponse)) {
             return Optional.of(MySQLVendorError.ER_ACCESS_DENIED_ERROR);
         }
         return null == databaseName || 
authorityChecker.isAuthorized(databaseName) ? Optional.empty() : 
Optional.of(MySQLVendorError.ER_DBACCESS_DENIED_ERROR);
diff --git 
a/proxy/frontend/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/authentication/OpenGaussAuthenticationHandler.java
 
b/proxy/frontend/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/authentication/OpenGaussAuthenticationHandler.java
index aab6c3e7c1d..13168188502 100644
--- 
a/proxy/frontend/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/authentication/OpenGaussAuthenticationHandler.java
+++ 
b/proxy/frontend/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/authentication/OpenGaussAuthenticationHandler.java
@@ -109,7 +109,7 @@ public final class OpenGaussAuthenticationHandler {
         Grantee grantee = new Grantee(username, "%");
         
ShardingSpherePreconditions.checkState(authorityRule.findUser(grantee).isPresent(),
 () -> new UnknownUsernameException(username));
         AuthorityChecker authorityChecker = new 
AuthorityChecker(authorityRule, grantee);
-        if (!authorityChecker.isAuthorized((a, b) -> 
isPasswordRight((ShardingSphereUser) a, (Object[]) b), new 
Object[]{passwordMessagePacket.getDigest(), salt, nonce, serverIteration})) {
+        if (!authorityChecker.isAuthenticated((a, b) -> 
isPasswordRight((ShardingSphereUser) a, (Object[]) b), new 
Object[]{passwordMessagePacket.getDigest(), salt, nonce, serverIteration})) {
             throw new InvalidPasswordException(username);
         }
         ShardingSpherePreconditions.checkState(null == databaseName || 
authorityChecker.isAuthorized(databaseName), () -> new 
PrivilegeNotGrantedException(username, databaseName));
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 0ee28f33326..333ef2f02e2 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
@@ -52,7 +52,7 @@ public final class PostgreSQLAuthenticationHandler {
         
ShardingSpherePreconditions.checkState(authorityRule.findUser(grantee).isPresent(),
 () -> new UnknownUsernameException(username));
         AuthorityChecker authorityChecker = new 
AuthorityChecker(authorityRule, grantee);
         PostgreSQLAuthenticator authenticator = getAuthenticator(username, 
grantee.getHostname());
-        if (!authorityChecker.isAuthorized((a, b) -> 
authenticator.authenticate((ShardingSphereUser) a, (Object[]) b), new 
Object[]{passwordMessagePacket.getDigest(), md5Salt})) {
+        if (!authorityChecker.isAuthenticated((a, b) -> 
authenticator.authenticate((ShardingSphereUser) a, (Object[]) b), new 
Object[]{passwordMessagePacket.getDigest(), md5Salt})) {
             throw new InvalidPasswordException(username);
         }
         ShardingSpherePreconditions.checkState(null == databaseName || 
authorityChecker.isAuthorized(databaseName), () -> new 
PrivilegeNotGrantedException(username, databaseName));
diff --git 
a/test/it/pipeline/src/test/java/org/apache/shardingsphere/test/it/data/pipeline/core/datasource/DefaultPipelineDataSourceManagerTest.java
 
b/test/it/pipeline/src/test/java/org/apache/shardingsphere/test/it/data/pipeline/core/datasource/DefaultPipelineDataSourceManagerTest.java
index 2a3393f6c28..e078e1ab3db 100644
--- 
a/test/it/pipeline/src/test/java/org/apache/shardingsphere/test/it/data/pipeline/core/datasource/DefaultPipelineDataSourceManagerTest.java
+++ 
b/test/it/pipeline/src/test/java/org/apache/shardingsphere/test/it/data/pipeline/core/datasource/DefaultPipelineDataSourceManagerTest.java
@@ -35,7 +35,6 @@ import java.util.Map;
 import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 public final class DefaultPipelineDataSourceManagerTest {
@@ -67,7 +66,6 @@ public final class DefaultPipelineDataSourceManagerTest {
             
dataSourceManager.getDataSource(PipelineDataSourceConfigurationFactory.newInstance(jobConfig.getSource().getType(),
 jobConfig.getSource().getParameter()));
             
dataSourceManager.getDataSource(PipelineDataSourceConfigurationFactory.newInstance(jobConfig.getTarget().getType(),
 jobConfig.getTarget().getParameter()));
             Map<?, ?> cachedDataSources = (Map<?, ?>) 
Plugins.getMemberAccessor().get(DefaultPipelineDataSourceManager.class.getDeclaredField("cachedDataSources"),
 dataSourceManager);
-            assertNotNull(cachedDataSources);
             assertThat(cachedDataSources.size(), is(2));
             dataSourceManager.close();
             assertTrue(cachedDataSources.isEmpty());

Reply via email to