This is an automated email from the ASF dual-hosted git repository.
zhangliang 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 fd0baad6dd0 Add authority check on MySQLShowCreateDatabaseExecutor
(#36862)
fd0baad6dd0 is described below
commit fd0baad6dd0ff2ff1d7349ad2736d9df98b83dfa
Author: Liang Zhang <[email protected]>
AuthorDate: Sun Oct 12 23:52:53 2025 +0800
Add authority check on MySQLShowCreateDatabaseExecutor (#36862)
* Add authority check on MySQLShowCreateDatabaseExecutor
* Add authority check on MySQLShowCreateDatabaseExecutor
---
RELEASE-NOTES.md | 3 +-
.../show/MySQLShowCreateDatabaseExecutor.java | 9 ++++--
.../show/MySQLShowCreateDatabaseExecutorTest.java | 37 ++++++++++++++++++++--
3 files changed, 43 insertions(+), 6 deletions(-)
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index 66ab17992e0..c709e1bc3ab 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -42,7 +42,8 @@
1. SQL Router: Improve support for executing tableless SQL with single data
source - [#35659](https://github.com/apache/shardingsphere/pull/35659)
1. DistSQL: Add job sharding nodes info to the query results of `SHOW
MIGRATION LIST` - [#35053](https://github.com/apache/shardingsphere/pull/35053)
1. DistSQL: Add DistSQL for query storage units which used in single rule -
[#35131](https://github.com/apache/shardingsphere/pull/35131)
-1. Proxy: Implement write bool binary data type for PostgreSQL protocol-
[#35831](https://github.com/apache/shardingsphere/pull/35831)
+1. Proxy: Implement write bool binary data type for PostgreSQL protocol -
[#35831](https://github.com/apache/shardingsphere/pull/35831)
+1. Proxy: Add authority check on SQL `SHOW CREATE DATABASE` for MySQL -
[#36862](https://github.com/apache/shardingsphere/pull/36862)
1. Encrypt: Use EncryptDerivedColumnSuffix to enhance encrypt table subquery
rewrite logic - [#34829](https://github.com/apache/shardingsphere/pull/34829)
1. Encrypt: Add quotes to encrypt rewrite derived columns -
[#34950](https://github.com/apache/shardingsphere/pull/34950)
1. Encrypt: Support NOT LIKE operator in encryption feature -
[#35984](https://github.com/apache/shardingsphere/pull/35984)
diff --git
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/show/MySQLShowCreateDatabaseExecutor.java
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/show/MySQLShowCreateDatabaseExecutor.java
index 10e7e3236a3..1002d54f637 100644
---
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/show/MySQLShowCreateDatabaseExecutor.java
+++
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/show/MySQLShowCreateDatabaseExecutor.java
@@ -19,6 +19,8 @@ package
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.sho
import lombok.Getter;
import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.authority.checker.AuthorityChecker;
+import org.apache.shardingsphere.authority.rule.AuthorityRule;
import
org.apache.shardingsphere.database.exception.core.exception.syntax.database.UnknownDatabaseException;
import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
import
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResult;
@@ -55,7 +57,7 @@ public final class MySQLShowCreateDatabaseExecutor implements
DatabaseAdminQuery
@Override
public void execute(final ConnectionSession connectionSession, final
ShardingSphereMetaData metaData) {
queryResultMetaData = createQueryResultMetaData();
- mergedResult = new
TransparentMergedResult(getQueryResult(sqlStatement.getDatabaseName(),
metaData));
+ mergedResult = new
TransparentMergedResult(getQueryResult(connectionSession,
sqlStatement.getDatabaseName(), metaData));
}
private QueryResultMetaData createQueryResultMetaData() {
@@ -65,8 +67,11 @@ public final class MySQLShowCreateDatabaseExecutor
implements DatabaseAdminQuery
return new RawQueryResultMetaData(columnMetaData);
}
- private QueryResult getQueryResult(final String databaseName, final
ShardingSphereMetaData metaData) {
+ private QueryResult getQueryResult(final ConnectionSession
connectionSession, final String databaseName, final ShardingSphereMetaData
metaData) {
ShardingSpherePreconditions.checkState(metaData.containsDatabase(databaseName),
() -> new UnknownDatabaseException(databaseName));
+ AuthorityRule authorityRule =
metaData.getGlobalRuleMetaData().getSingleRule(AuthorityRule.class);
+ AuthorityChecker authorityChecker = new
AuthorityChecker(authorityRule,
connectionSession.getConnectionContext().getGrantee());
+
ShardingSpherePreconditions.checkState(authorityChecker.isAuthorized(databaseName),
() -> new UnknownDatabaseException(databaseName));
List<MemoryQueryResultDataRow> rows = Collections.singletonList(new
MemoryQueryResultDataRow(Arrays.asList(databaseName, String.format("CREATE
DATABASE `%s`;", databaseName))));
return new RawMemoryQueryResult(queryResultMetaData, rows);
}
diff --git
a/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/show/MySQLShowCreateDatabaseExecutorTest.java
b/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/show/MySQLShowCreateDatabaseExecutorTest.java
index 53b9887638d..a72bf2880ae 100644
---
a/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/show/MySQLShowCreateDatabaseExecutorTest.java
+++
b/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/show/MySQLShowCreateDatabaseExecutorTest.java
@@ -17,13 +17,19 @@
package
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.show;
+import org.apache.shardingsphere.authority.rule.AuthorityRule;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import
org.apache.shardingsphere.database.exception.core.exception.syntax.database.UnknownDatabaseException;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
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;
+import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
import
org.apache.shardingsphere.sql.parser.statement.mysql.dal.show.database.MySQLShowCreateDatabaseStatement;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.sql.SQLException;
@@ -32,23 +38,48 @@ import java.util.Collections;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class MySQLShowCreateDatabaseExecutorTest {
private final DatabaseType databaseType =
TypedSPILoader.getService(DatabaseType.class, "MySQL");
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private ConnectionSession connectionSession;
+
@Test
- void assertExecute() throws SQLException {
+ void assertExecuteWithExistedDatabase() throws SQLException {
MySQLShowCreateDatabaseStatement sqlStatement = new
MySQLShowCreateDatabaseStatement(databaseType, "foo_db");
MySQLShowCreateDatabaseExecutor executor = new
MySQLShowCreateDatabaseExecutor(sqlStatement);
- executor.execute(mock(),
- new ShardingSphereMetaData(Collections.singleton(new
ShardingSphereDatabase("foo_db", databaseType, mock(), mock(),
Collections.emptyList())), mock(), mock(), mock()));
+
when(connectionSession.getConnectionContext().getGrantee()).thenReturn(null);
+ executor.execute(connectionSession, mockMetaData());
assertThat(executor.getQueryResultMetaData().getColumnCount(), is(2));
assertTrue(executor.getMergedResult().next());
assertThat(executor.getMergedResult().getValue(1, Object.class),
is("foo_db"));
assertFalse(executor.getMergedResult().next());
}
+
+ @Test
+ void assertExecuteWithNotExistedDatabase() {
+ MySQLShowCreateDatabaseStatement sqlStatement = new
MySQLShowCreateDatabaseStatement(databaseType, "bar_db");
+ MySQLShowCreateDatabaseExecutor executor = new
MySQLShowCreateDatabaseExecutor(sqlStatement);
+ assertThrows(UnknownDatabaseException.class, () ->
executor.execute(connectionSession, mockMetaData()));
+ }
+
+ @Test
+ void assertExecuteWithUnauthorizedDatabase() {
+ MySQLShowCreateDatabaseStatement sqlStatement = new
MySQLShowCreateDatabaseStatement(databaseType, "foo_db");
+ MySQLShowCreateDatabaseExecutor executor = new
MySQLShowCreateDatabaseExecutor(sqlStatement);
+ assertThrows(UnknownDatabaseException.class, () ->
executor.execute(connectionSession, mockMetaData()));
+ }
+
+ private ShardingSphereMetaData mockMetaData() {
+ AuthorityRule rule = mock(AuthorityRule.class);
+ return new ShardingSphereMetaData(
+ Collections.singleton(new ShardingSphereDatabase("foo_db",
databaseType, mock(), mock(), Collections.emptyList())), mock(), new
RuleMetaData(Collections.singleton(rule)), mock());
+ }
}