This is an automated email from the ASF dual-hosted git repository. jiangmaolin pushed a commit to branch dev-5.5.1 in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
commit 8324e65d342a14e41a68d4bc2df587bc1ec275b0 Author: Raigor <[email protected]> AuthorDate: Fri Nov 1 11:33:40 2024 +0800 Fix privilege check in CreateDatabaseBackendHandler (#32) --- .../RALACLObject.java} | 25 ++-------------- .../type/dal/dialect/MySQLACLObjectExtractor.java | 25 +++++++++++++++- .../extractor/type/ddl/DDLACLObjectExtractor.java | 15 ++++++++++ .../type/CreateDatabaseACLObjectExtractor.java} | 20 ++++++------- .../type/CreateIndexACLObjectExtractor.java} | 23 ++++++++------ .../type/DropIndexACLObjectExtractor.java} | 17 ++++++----- .../type/distsql/DistSQLACLObjectExtractor.java | 7 +++++ .../authority/operation/ACLOperationExtractor.java | 16 ++++++++-- .../cases/show-dist-users-current-config.yaml | 1 + .../src/test/resources/cases/show-dist-users.xml | 2 +- .../proxy/backend/connector/DatabaseConnector.java | 35 ++++++++++++++++++++++ .../connector/ProxyDatabaseConnectionManager.java | 22 ++++++++++++++ .../database/CreateDatabaseBackendHandler.java | 7 ++--- .../database/CreateDatabaseBackendHandlerTest.java | 16 ++++++++-- .../DatabaseOperateBackendHandlerFactoryTest.java | 1 + .../database/DropDatabaseBackendHandlerTest.java | 7 ++++- .../admin/executor/ShowTablesExecutorTest.java | 3 ++ 17 files changed, 180 insertions(+), 62 deletions(-) diff --git a/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/dal/dialect/MySQLACLObjectExtractor.java b/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/domain/RALACLObject.java similarity index 52% copy from kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/dal/dialect/MySQLACLObjectExtractor.java copy to kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/domain/RALACLObject.java index 5bf40fd7a7f..3995a355339 100644 --- a/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/dal/dialect/MySQLACLObjectExtractor.java +++ b/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/domain/RALACLObject.java @@ -15,31 +15,12 @@ * limitations under the License. */ -package com.sphereex.dbplusengine.authority.obj.extractor.type.dal.dialect; +package com.sphereex.dbplusengine.authority.obj.domain; import com.sphereex.dbplusengine.authority.model.obj.ACLObject; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.apache.shardingsphere.sql.parser.statement.mysql.MySQLStatement; - -import java.util.Collection; -import java.util.Collections; /** - * MySQL ACL object extractor. + * RAL ACL object. */ -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class MySQLACLObjectExtractor { - - /** - * Extract ACL objects for MySQL statement. - * - * @param currentDatabase current database name - * @param sqlStatement MySQL statement - * @return extracted ACL objects - */ - public static Collection<ACLObject> extract(final String currentDatabase, final MySQLStatement sqlStatement) { - // TODO - return Collections.emptyList(); - } +public final class RALACLObject implements ACLObject { } diff --git a/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/dal/dialect/MySQLACLObjectExtractor.java b/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/dal/dialect/MySQLACLObjectExtractor.java index 5bf40fd7a7f..17d45cae812 100644 --- a/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/dal/dialect/MySQLACLObjectExtractor.java +++ b/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/dal/dialect/MySQLACLObjectExtractor.java @@ -18,9 +18,12 @@ package com.sphereex.dbplusengine.authority.obj.extractor.type.dal.dialect; import com.sphereex.dbplusengine.authority.model.obj.ACLObject; +import com.sphereex.dbplusengine.authority.obj.domain.TableACLObject; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.apache.shardingsphere.sql.parser.statement.mysql.MySQLStatement; +import org.apache.shardingsphere.sql.parser.statement.mysql.dal.MySQLShowCreateTableStatement; +import org.apache.shardingsphere.sql.parser.statement.mysql.ddl.MySQLDropIndexStatement; import java.util.Collection; import java.util.Collections; @@ -39,7 +42,27 @@ public final class MySQLACLObjectExtractor { * @return extracted ACL objects */ public static Collection<ACLObject> extract(final String currentDatabase, final MySQLStatement sqlStatement) { - // TODO + if (sqlStatement instanceof MySQLShowCreateTableStatement) { + return extractSowCreateTableStatement(currentDatabase, (MySQLShowCreateTableStatement) sqlStatement); + } + if (sqlStatement instanceof MySQLDropIndexStatement) { + return extractDropIndexStatement(currentDatabase, (MySQLDropIndexStatement) sqlStatement); + } return Collections.emptyList(); } + + private static Collection<ACLObject> extractSowCreateTableStatement(final String currentDatabase, final MySQLShowCreateTableStatement sqlStatement) { + String database = sqlStatement.getTable().getOwner().map(optional -> optional.getIdentifier().getValue()).orElse(currentDatabase); + String table = sqlStatement.getTable().getTableName().getIdentifier().getValue(); + return Collections.singleton(new TableACLObject(database, table)); + } + + private static Collection<ACLObject> extractDropIndexStatement(final String currentDatabase, final MySQLDropIndexStatement sqlStatement) { + if (!sqlStatement.getSimpleTable().isPresent()) { + return Collections.emptyList(); + } + String database = sqlStatement.getSimpleTable().get().getOwner().map(optional -> optional.getIdentifier().getValue()).orElse(currentDatabase); + String table = sqlStatement.getSimpleTable().get().getTableName().getIdentifier().getValue(); + return Collections.singleton(new TableACLObject(database, table)); + } } diff --git a/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/ddl/DDLACLObjectExtractor.java b/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/ddl/DDLACLObjectExtractor.java index 4bd9d9e0185..322425284ed 100644 --- a/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/ddl/DDLACLObjectExtractor.java +++ b/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/ddl/DDLACLObjectExtractor.java @@ -19,16 +19,22 @@ package com.sphereex.dbplusengine.authority.obj.extractor.type.ddl; import com.sphereex.dbplusengine.authority.model.obj.ACLObject; import com.sphereex.dbplusengine.authority.obj.extractor.type.ddl.type.AlterTableACLObjectExtractor; +import com.sphereex.dbplusengine.authority.obj.extractor.type.ddl.type.CreateDatabaseACLObjectExtractor; +import com.sphereex.dbplusengine.authority.obj.extractor.type.ddl.type.CreateIndexACLObjectExtractor; import com.sphereex.dbplusengine.authority.obj.extractor.type.ddl.type.CreateTableACLObjectExtractor; import com.sphereex.dbplusengine.authority.obj.extractor.type.ddl.type.DropDatabaseACLObjectExtractor; +import com.sphereex.dbplusengine.authority.obj.extractor.type.ddl.type.DropIndexACLObjectExtractor; import com.sphereex.dbplusengine.authority.obj.extractor.type.ddl.type.DropTableACLObjectExtractor; import com.sphereex.dbplusengine.authority.obj.extractor.type.ddl.type.TruncateTableACLObjectExtractor; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.AlterTableStatement; +import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateDatabaseStatement; +import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateIndexStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateTableStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropDatabaseStatement; +import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropIndexStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropTableStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.TruncateStatement; @@ -58,9 +64,18 @@ public final class DDLACLObjectExtractor { if (sqlStatement instanceof DropTableStatement) { return DropTableACLObjectExtractor.extract(currentDatabase, (DropTableStatement) sqlStatement); } + if (sqlStatement instanceof CreateIndexStatement) { + return CreateIndexACLObjectExtractor.extract(currentDatabase, (CreateIndexStatement) sqlStatement); + } + if (sqlStatement instanceof DropIndexStatement) { + return DropIndexACLObjectExtractor.extract(currentDatabase, (DropIndexStatement) sqlStatement); + } if (sqlStatement instanceof TruncateStatement) { return TruncateTableACLObjectExtractor.extract(currentDatabase, (TruncateStatement) sqlStatement); } + if (sqlStatement instanceof CreateDatabaseStatement) { + return CreateDatabaseACLObjectExtractor.extract((CreateDatabaseStatement) sqlStatement); + } if (sqlStatement instanceof DropDatabaseStatement) { return DropDatabaseACLObjectExtractor.extract((DropDatabaseStatement) sqlStatement); } diff --git a/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/dal/dialect/MySQLACLObjectExtractor.java b/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/ddl/type/CreateDatabaseACLObjectExtractor.java similarity index 64% copy from kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/dal/dialect/MySQLACLObjectExtractor.java copy to kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/ddl/type/CreateDatabaseACLObjectExtractor.java index 5bf40fd7a7f..92f9097040b 100644 --- a/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/dal/dialect/MySQLACLObjectExtractor.java +++ b/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/ddl/type/CreateDatabaseACLObjectExtractor.java @@ -15,31 +15,31 @@ * limitations under the License. */ -package com.sphereex.dbplusengine.authority.obj.extractor.type.dal.dialect; +package com.sphereex.dbplusengine.authority.obj.extractor.type.ddl.type; import com.sphereex.dbplusengine.authority.model.obj.ACLObject; +import com.sphereex.dbplusengine.authority.obj.domain.TableACLObject; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import org.apache.shardingsphere.sql.parser.statement.mysql.MySQLStatement; +import org.apache.shardingsphere.authority.constant.AuthorityConstants; +import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateDatabaseStatement; import java.util.Collection; import java.util.Collections; /** - * MySQL ACL object extractor. + * Create database ACL object extractor. */ @NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class MySQLACLObjectExtractor { +public final class CreateDatabaseACLObjectExtractor { /** - * Extract ACL objects for MySQL statement. + * Extract ACL objects. * - * @param currentDatabase current database name - * @param sqlStatement MySQL statement + * @param sqlStatement create database statement * @return extracted ACL objects */ - public static Collection<ACLObject> extract(final String currentDatabase, final MySQLStatement sqlStatement) { - // TODO - return Collections.emptyList(); + public static Collection<ACLObject> extract(final CreateDatabaseStatement sqlStatement) { + return Collections.singleton(new TableACLObject(sqlStatement.getDatabaseName(), AuthorityConstants.PRIVILEGE_WILDCARD)); } } diff --git a/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/dal/dialect/MySQLACLObjectExtractor.java b/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/ddl/type/CreateIndexACLObjectExtractor.java similarity index 61% copy from kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/dal/dialect/MySQLACLObjectExtractor.java copy to kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/ddl/type/CreateIndexACLObjectExtractor.java index 5bf40fd7a7f..8a1d8f7f2c9 100644 --- a/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/dal/dialect/MySQLACLObjectExtractor.java +++ b/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/ddl/type/CreateIndexACLObjectExtractor.java @@ -15,31 +15,36 @@ * limitations under the License. */ -package com.sphereex.dbplusengine.authority.obj.extractor.type.dal.dialect; +package com.sphereex.dbplusengine.authority.obj.extractor.type.ddl.type; import com.sphereex.dbplusengine.authority.model.obj.ACLObject; +import com.sphereex.dbplusengine.authority.obj.domain.TableACLObject; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import org.apache.shardingsphere.sql.parser.statement.mysql.MySQLStatement; +import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateIndexStatement; import java.util.Collection; import java.util.Collections; /** - * MySQL ACL object extractor. + * Create index ACL object extractor. */ @NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class MySQLACLObjectExtractor { +public final class CreateIndexACLObjectExtractor { /** - * Extract ACL objects for MySQL statement. + * Extract ACL objects. * * @param currentDatabase current database name - * @param sqlStatement MySQL statement + * @param sqlStatement create index statement * @return extracted ACL objects */ - public static Collection<ACLObject> extract(final String currentDatabase, final MySQLStatement sqlStatement) { - // TODO - return Collections.emptyList(); + public static Collection<ACLObject> extract(final String currentDatabase, final CreateIndexStatement sqlStatement) { + if (null == sqlStatement.getTable()) { + return Collections.emptyList(); + } + String database = sqlStatement.getTable().getOwner().map(optional -> optional.getIdentifier().getValue()).orElse(currentDatabase); + String table = sqlStatement.getTable().getTableName().getIdentifier().getValue(); + return Collections.singleton(new TableACLObject(database, table)); } } diff --git a/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/dal/dialect/MySQLACLObjectExtractor.java b/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/ddl/type/DropIndexACLObjectExtractor.java similarity index 70% copy from kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/dal/dialect/MySQLACLObjectExtractor.java copy to kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/ddl/type/DropIndexACLObjectExtractor.java index 5bf40fd7a7f..d6e8fc1f93e 100644 --- a/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/dal/dialect/MySQLACLObjectExtractor.java +++ b/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/ddl/type/DropIndexACLObjectExtractor.java @@ -15,31 +15,32 @@ * limitations under the License. */ -package com.sphereex.dbplusengine.authority.obj.extractor.type.dal.dialect; +package com.sphereex.dbplusengine.authority.obj.extractor.type.ddl.type; import com.sphereex.dbplusengine.authority.model.obj.ACLObject; +import com.sphereex.dbplusengine.authority.obj.extractor.type.dal.dialect.MySQLACLObjectExtractor; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropIndexStatement; import org.apache.shardingsphere.sql.parser.statement.mysql.MySQLStatement; import java.util.Collection; import java.util.Collections; /** - * MySQL ACL object extractor. + * Drop index ACL object extractor. */ @NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class MySQLACLObjectExtractor { +public final class DropIndexACLObjectExtractor { /** - * Extract ACL objects for MySQL statement. + * Extract ACL objects. * * @param currentDatabase current database name - * @param sqlStatement MySQL statement + * @param sqlStatement drop index statement * @return extracted ACL objects */ - public static Collection<ACLObject> extract(final String currentDatabase, final MySQLStatement sqlStatement) { - // TODO - return Collections.emptyList(); + public static Collection<ACLObject> extract(final String currentDatabase, final DropIndexStatement sqlStatement) { + return sqlStatement instanceof MySQLStatement ? MySQLACLObjectExtractor.extract(currentDatabase, (MySQLStatement) sqlStatement) : Collections.emptyList(); } } diff --git a/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/distsql/DistSQLACLObjectExtractor.java b/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/distsql/DistSQLACLObjectExtractor.java index 3f6b28b3ab9..6211b9b3655 100644 --- a/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/distsql/DistSQLACLObjectExtractor.java +++ b/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/obj/extractor/type/distsql/DistSQLACLObjectExtractor.java @@ -20,12 +20,16 @@ package com.sphereex.dbplusengine.authority.obj.extractor.type.distsql; import com.sphereex.dbplusengine.authority.model.obj.ACLObject; import com.sphereex.dbplusengine.authority.obj.domain.DCLACLObject; import com.sphereex.dbplusengine.authority.obj.domain.DistSQLACLObject; +import com.sphereex.dbplusengine.authority.obj.domain.RALACLObject; import com.sphereex.dbplusengine.distsql.acl.DistSQLACLObjectUtils; import com.sphereex.dbplusengine.distsql.extractor.DistSQLResourceIdentifierExtractor; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.apache.shardingsphere.authority.constant.AuthorityConstants; import org.apache.shardingsphere.distsql.statement.DistSQLStatement; +import org.apache.shardingsphere.distsql.statement.ral.RALStatement; +import org.apache.shardingsphere.distsql.statement.rdl.rule.global.GlobalRuleDefinitionStatement; +import org.apache.shardingsphere.distsql.statement.rql.rule.global.ShowGlobalRulesStatement; import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; import org.apache.shardingsphere.sql.parser.statement.core.statement.dcl.DCLStatement; @@ -51,6 +55,9 @@ public final class DistSQLACLObjectExtractor { if (sqlStatement instanceof DCLStatement) { return Collections.singleton(new DCLACLObject()); } + if (sqlStatement instanceof RALStatement || sqlStatement instanceof ShowGlobalRulesStatement || sqlStatement instanceof GlobalRuleDefinitionStatement) { + return Collections.singleton(new RALACLObject()); + } Collection<String> aclObjectNames = TypedSPILoader.findService(DistSQLResourceIdentifierExtractor.class, sqlStatement.getClass()) .map(optional -> optional.extract(sqlStatement)).orElse(Collections.emptyList()); String aclObjectTypeName = DistSQLACLObjectUtils.getACLObject(sqlStatement.getClass()); diff --git a/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/operation/ACLOperationExtractor.java b/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/operation/ACLOperationExtractor.java index d71aad4d7e3..b7474f492e0 100644 --- a/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/operation/ACLOperationExtractor.java +++ b/kernel/authority/core/src/main/java/com/sphereex/dbplusengine/authority/operation/ACLOperationExtractor.java @@ -22,25 +22,31 @@ import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.apache.shardingsphere.distsql.statement.DistSQLStatement; import org.apache.shardingsphere.distsql.statement.ral.RALStatement; +import org.apache.shardingsphere.distsql.statement.rdl.resource.unit.type.AlterStorageUnitStatement; import org.apache.shardingsphere.distsql.statement.rdl.resource.unit.type.RegisterStorageUnitStatement; import org.apache.shardingsphere.distsql.statement.rdl.resource.unit.type.UnregisterStorageUnitStatement; import org.apache.shardingsphere.distsql.statement.rdl.rule.database.type.AlterRuleStatement; import org.apache.shardingsphere.distsql.statement.rdl.rule.database.type.CreateRuleStatement; import org.apache.shardingsphere.distsql.statement.rdl.rule.database.type.DropRuleStatement; +import org.apache.shardingsphere.distsql.statement.rdl.rule.global.GlobalRuleDefinitionStatement; import org.apache.shardingsphere.distsql.statement.rql.resource.ShowStorageUnitsStatement; import org.apache.shardingsphere.distsql.statement.rql.rule.database.ShowDatabaseRulesStatement; +import org.apache.shardingsphere.distsql.statement.rql.rule.global.ShowGlobalRulesStatement; import org.apache.shardingsphere.distsql.statement.rul.sql.FormatStatement; import org.apache.shardingsphere.distsql.statement.rul.sql.ParseStatement; import org.apache.shardingsphere.distsql.statement.rul.sql.PreviewStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.dcl.DCLStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.AlterDatabaseStatement; +import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.AlterIndexStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.AlterTableStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateDatabaseStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateFunctionStatement; +import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateIndexStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateTableStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DDLStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropDatabaseStatement; +import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropIndexStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropTableStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.TruncateStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.DMLStatement; @@ -102,7 +108,7 @@ public final class ACLOperationExtractor { if (sqlStatement instanceof AlterDatabaseStatement) { return ACLOperation.ALTER_ANY_DATABASE; } - if (sqlStatement instanceof AlterTableStatement) { + if (sqlStatement instanceof AlterTableStatement || isIndexDDLStatement(sqlStatement)) { return ACLOperation.ALTER; } if (sqlStatement instanceof CreateFunctionStatement) { @@ -114,6 +120,10 @@ public final class ACLOperationExtractor { return ACLOperation.UNKNOWN; } + private static boolean isIndexDDLStatement(final SQLStatement sqlStatement) { + return sqlStatement instanceof CreateIndexStatement || sqlStatement instanceof AlterIndexStatement || sqlStatement instanceof DropIndexStatement; + } + private static ACLOperation extractDistSQL(final DistSQLStatement sqlStatement) { if (sqlStatement instanceof CreateRuleStatement) { return ACLOperation.CREATE_RULE; @@ -127,7 +137,7 @@ public final class ACLOperationExtractor { if (sqlStatement instanceof ShowDatabaseRulesStatement || sqlStatement instanceof ShowStorageUnitsStatement) { return ACLOperation.SHOW_RULES; } - if (sqlStatement instanceof RegisterStorageUnitStatement) { + if (sqlStatement instanceof RegisterStorageUnitStatement || sqlStatement instanceof AlterStorageUnitStatement) { return ACLOperation.REGISTER; } if (sqlStatement instanceof UnregisterStorageUnitStatement) { @@ -145,7 +155,7 @@ public final class ACLOperationExtractor { if (sqlStatement instanceof ParseStatement) { return ACLOperation.PARSE; } - if (sqlStatement instanceof RALStatement) { + if (sqlStatement instanceof RALStatement || sqlStatement instanceof ShowGlobalRulesStatement || sqlStatement instanceof GlobalRuleDefinitionStatement) { return ACLOperation.RAL_OPERATE; } return ACLOperation.UNKNOWN; diff --git a/kernel/authority/distsql/handler/src/test/resources/cases/show-dist-users-current-config.yaml b/kernel/authority/distsql/handler/src/test/resources/cases/show-dist-users-current-config.yaml index aaf25b0fb62..7cafac73832 100644 --- a/kernel/authority/distsql/handler/src/test/resources/cases/show-dist-users-current-config.yaml +++ b/kernel/authority/distsql/handler/src/test/resources/cases/show-dist-users-current-config.yaml @@ -21,4 +21,5 @@ rules: users: - user: root@% password: 123456 + admin: true #SPEX ADDED: END diff --git a/kernel/authority/distsql/handler/src/test/resources/cases/show-dist-users.xml b/kernel/authority/distsql/handler/src/test/resources/cases/show-dist-users.xml index 29266eece37..31f2fd34f2a 100644 --- a/kernel/authority/distsql/handler/src/test/resources/cases/show-dist-users.xml +++ b/kernel/authority/distsql/handler/src/test/resources/cases/show-dist-users.xml @@ -19,7 +19,7 @@ <distsql-rule-query-executor-test-cases> <test-case dist-sql="SHOW DIST USERS" current-rule-config-yaml-file="cases/show-dist-users-current-config.yaml"> <expected-query-result-rows> - <expected-query-result-row>%|root</expected-query-result-row> + <expected-query-result-row>%|root|Y</expected-query-result-row> </expected-query-result-rows> </test-case> </distsql-rule-query-executor-test-cases> diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java index b0dafc57849..10c02521cea 100644 --- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java +++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java @@ -17,6 +17,7 @@ package org.apache.shardingsphere.proxy.backend.connector; +import com.sphereex.dbplusengine.SphereEx; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.apache.shardingsphere.infra.binder.context.aware.CursorAware; @@ -398,6 +399,12 @@ public final class DatabaseConnector implements DatabaseBackendHandler { try { each.close(); } catch (final SQLException ex) { + // SPEX ADDED: BEGIN + if (isClosed(each)) { + log.info("ResultSet is already closed", ex); + continue; + } + // SPEX ADDED: END result.add(ex); } } @@ -412,6 +419,12 @@ public final class DatabaseConnector implements DatabaseBackendHandler { each.cancel(); each.close(); } catch (final SQLException ex) { + // SPEX ADDED: BEGIN + if (isClosed(each)) { + log.info("Statement is already closed", ex); + continue; + } + // SPEX ADDED: END result.add(ex); } } @@ -419,6 +432,28 @@ public final class DatabaseConnector implements DatabaseBackendHandler { return result; } + @SphereEx + private boolean isClosed(final ResultSet resultSet) { + try { + if (resultSet.isClosed()) { + return true; + } + } catch (final SQLException ignored) { + } + return false; + } + + @SphereEx + private boolean isClosed(final Statement statement) { + try { + if (statement.isClosed()) { + return true; + } + } catch (final SQLException ignored) { + } + return false; + } + private Optional<SQLException> closeSQLFederationEngine() { if (null != proxySQLExecutor.getSqlFederationEngine()) { try { diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/ProxyDatabaseConnectionManager.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/ProxyDatabaseConnectionManager.java index 9ff69eb0ccd..bbda0bd7328 100644 --- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/ProxyDatabaseConnectionManager.java +++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/ProxyDatabaseConnectionManager.java @@ -20,8 +20,10 @@ package org.apache.shardingsphere.proxy.backend.connector; import com.google.common.base.Preconditions; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; +import com.sphereex.dbplusengine.SphereEx; import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.shardingsphere.infra.database.core.type.DatabaseType; import org.apache.shardingsphere.infra.executor.sql.execute.engine.ConnectionMode; import org.apache.shardingsphere.infra.executor.sql.prepare.driver.DatabaseConnectionManager; @@ -53,6 +55,9 @@ import java.util.concurrent.atomic.AtomicBoolean; /** * Database connection manager of ShardingSphere-Proxy. */ +// SPEX ADDED: BEGIN +@Slf4j +// SPEX ADDED: END @RequiredArgsConstructor @Getter public final class ProxyDatabaseConnectionManager implements DatabaseConnectionManager<Connection> { @@ -328,6 +333,12 @@ public final class ProxyDatabaseConnectionManager implements DatabaseConnectionM } each.close(); } catch (final SQLException ex) { + // SPEX ADDED: BEGIN + if (isClosed(each)) { + log.info("Connection is already closed", ex); + continue; + } + // SPEX ADDED: END result.add(ex); } } @@ -339,6 +350,17 @@ public final class ProxyDatabaseConnectionManager implements DatabaseConnectionM return result; } + @SphereEx + private boolean isClosed(final Connection connection) { + try { + if (connection.isClosed()) { + return true; + } + } catch (final SQLException ignored) { + } + return false; + } + private void resetSessionVariablesIfNecessary(final Collection<Connection> values, final Collection<SQLException> exceptions) { if (connectionSession.getRequiredSessionVariableRecorder().isEmpty() || values.isEmpty()) { return; diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/database/CreateDatabaseBackendHandler.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/database/CreateDatabaseBackendHandler.java index 2b7e15cf900..1b5e0cf6033 100644 --- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/database/CreateDatabaseBackendHandler.java +++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/database/CreateDatabaseBackendHandler.java @@ -18,11 +18,9 @@ package org.apache.shardingsphere.proxy.backend.handler.database; import com.sphereex.dbplusengine.SphereEx; -import com.sphereex.dbplusengine.authority.exception.access.UnauthorizedDatabaseException; import lombok.RequiredArgsConstructor; import org.apache.shardingsphere.authority.checker.AuthorityChecker; import org.apache.shardingsphere.authority.rule.AuthorityRule; -import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions; import org.apache.shardingsphere.infra.exception.dialect.exception.syntax.database.DatabaseCreateExistsException; import org.apache.shardingsphere.proxy.backend.context.ProxyContext; import org.apache.shardingsphere.proxy.backend.handler.ProxyBackendHandler; @@ -49,8 +47,9 @@ public final class CreateDatabaseBackendHandler implements ProxyBackendHandler { check(sqlStatement); // SPEX ADDED: BEGIN AuthorityRule authorityRule = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(AuthorityRule.class); - ShardingSpherePreconditions.checkState(new AuthorityChecker(authorityRule, connectionSession.getConnectionContext().getGrantee()).isAuthorized(sqlStatement.getDatabaseName()), - () -> new UnauthorizedDatabaseException(connectionSession.getConnectionContext().getGrantee(), sqlStatement.getDatabaseName())); + AuthorityChecker authorityChecker = new AuthorityChecker(authorityRule, connectionSession.getConnectionContext().getGrantee()); + authorityChecker.checkPrivileges(null, sqlStatement); + // SPEX ADDED: END ProxyContext.getInstance().getContextManager().getPersistServiceFacade().getMetaDataManagerPersistService().createDatabase(sqlStatement.getDatabaseName()); return new UpdateResponseHeader(sqlStatement); } diff --git a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/database/CreateDatabaseBackendHandlerTest.java b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/database/CreateDatabaseBackendHandlerTest.java index 5aa1945aad7..82d780d9ead 100644 --- a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/database/CreateDatabaseBackendHandlerTest.java +++ b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/database/CreateDatabaseBackendHandlerTest.java @@ -19,13 +19,15 @@ package org.apache.shardingsphere.proxy.backend.handler.database; import com.sphereex.dbplusengine.SphereEx; import com.sphereex.dbplusengine.SphereEx.Type; -import com.sphereex.dbplusengine.authority.exception.access.UnauthorizedDatabaseException; +import com.sphereex.dbplusengine.authority.exception.access.UnauthorizedOperationException; +import com.sphereex.dbplusengine.authority.provider.enterprise.privilege.EnterprisePermittedPrivileges; import org.apache.shardingsphere.authority.rule.AuthorityRule; import org.apache.shardingsphere.infra.config.props.temporary.TemporaryConfigurationProperties; import org.apache.shardingsphere.infra.exception.dialect.exception.syntax.database.DatabaseCreateExistsException; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; import org.apache.shardingsphere.infra.metadata.user.Grantee; +import org.apache.shardingsphere.infra.metadata.user.ShardingSphereUser; import org.apache.shardingsphere.mode.manager.ContextManager; import org.apache.shardingsphere.mode.metadata.MetaDataContexts; import org.apache.shardingsphere.proxy.backend.context.ProxyContext; @@ -42,6 +44,7 @@ import org.mockito.Mock; import java.sql.SQLException; import java.util.Collections; +import java.util.Optional; import java.util.Properties; import static org.hamcrest.CoreMatchers.instanceOf; @@ -100,11 +103,18 @@ class CreateDatabaseBackendHandlerTest { @SphereEx @Test void assertExecuteCreateNotAuthorizedDatabase() { - when(connectionSession.getConnectionContext().getGrantee()).thenReturn(new Grantee("foo", "")); + Grantee grantee = new Grantee("foo", ""); + when(connectionSession.getConnectionContext().getGrantee()).thenReturn(grantee); when(statement.getDatabaseName()).thenReturn("foo_db"); ContextManager contextManager = mockContextManager(); when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager); - assertThrows(UnauthorizedDatabaseException.class, () -> handler.execute()); + AuthorityRule authorityRule = mock(AuthorityRule.class, RETURNS_DEEP_STUBS); + RuleMetaData globalRuleMetaData = new RuleMetaData(Collections.singleton(authorityRule)); + when(contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData()).thenReturn(globalRuleMetaData); + ShardingSphereUser user = mock(ShardingSphereUser.class); + when(authorityRule.findUser(grantee)).thenReturn(Optional.of(user)); + when(authorityRule.findPrivileges(grantee)).thenReturn(Optional.of(mock(EnterprisePermittedPrivileges.class))); + assertThrows(UnauthorizedOperationException.class, () -> handler.execute()); } private ContextManager mockContextManager() { diff --git a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/database/DatabaseOperateBackendHandlerFactoryTest.java b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/database/DatabaseOperateBackendHandlerFactoryTest.java index c237b69a5c4..2e3bb9f2628 100644 --- a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/database/DatabaseOperateBackendHandlerFactoryTest.java +++ b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/database/DatabaseOperateBackendHandlerFactoryTest.java @@ -86,6 +86,7 @@ class DatabaseOperateBackendHandlerFactoryTest { when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager); when(ProxyContext.getInstance().databaseExists("foo_db")).thenReturn(true); // SPEX ADDED: BEGIN + when(connectionSession.getConnectionContext().getGrantee()).thenReturn(null); when(contextManager.isMetaDataConsistent()).thenReturn(true); // SPEX ADDED: END } diff --git a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/database/DropDatabaseBackendHandlerTest.java b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/database/DropDatabaseBackendHandlerTest.java index ff24b8c44e2..f140cd0f98b 100644 --- a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/database/DropDatabaseBackendHandlerTest.java +++ b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/database/DropDatabaseBackendHandlerTest.java @@ -18,8 +18,9 @@ package org.apache.shardingsphere.proxy.backend.handler.database; import org.apache.shardingsphere.authority.rule.AuthorityRule; -import org.apache.shardingsphere.infra.exception.dialect.exception.syntax.database.DatabaseDropNotExistsException; +import org.apache.shardingsphere.infra.config.props.temporary.TemporaryConfigurationProperties; import org.apache.shardingsphere.infra.database.core.type.DatabaseType; +import org.apache.shardingsphere.infra.exception.dialect.exception.syntax.database.DatabaseDropNotExistsException; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; @@ -44,6 +45,7 @@ import java.sql.SQLException; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Properties; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.MatcherAssert.assertThat; @@ -88,6 +90,9 @@ class DropDatabaseBackendHandlerTest { when(metaDataContexts.getMetaData().getDatabase("foo_db")).thenReturn(database); when(metaDataContexts.getMetaData().getDatabase("bar_db")).thenReturn(database); when(metaDataContexts.getMetaData().getDatabase("test_not_exist_db")).thenReturn(database); + // SPEX ADDED: BEGIN + when(metaDataContexts.getMetaData().getTemporaryProps()).thenReturn(new TemporaryConfigurationProperties(new Properties())); + // SPEX ADDED: END when(metaDataContexts.getMetaData().getGlobalRuleMetaData()).thenReturn(new RuleMetaData(Collections.singleton(mock(AuthorityRule.class)))); ContextManager result = mock(ContextManager.class, RETURNS_DEEP_STUBS); when(result.getMetaDataContexts()).thenReturn(metaDataContexts); diff --git a/proxy/backend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/ShowTablesExecutorTest.java b/proxy/backend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/ShowTablesExecutorTest.java index d6b0330bda6..1b1aecf3903 100644 --- a/proxy/backend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/ShowTablesExecutorTest.java +++ b/proxy/backend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/ShowTablesExecutorTest.java @@ -224,6 +224,9 @@ class ShowTablesExecutorTest { private ConnectionSession mockConnectionSession() { ConnectionSession result = mock(ConnectionSession.class, RETURNS_DEEP_STUBS); when(result.getUsedDatabaseName()).thenReturn(String.format(DATABASE_PATTERN, 0)); + // SPEX ADDED: BEGIN + when(result.getConnectionContext().getGrantee()).thenReturn(null); + // SPEX ADDED: END return result; } }
