This is an automated email from the ASF dual-hosted git repository.
jianglongtao 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 372efb89fb3 Add SELECT privilege check for MySQL when register or
alter storage unit (#32185)
372efb89fb3 is described below
commit 372efb89fb3de8c1de669f09530f4ecf4a2f8da8
Author: Raigor <[email protected]>
AuthorDate: Fri Jul 19 12:02:40 2024 +0800
Add SELECT privilege check for MySQL when register or alter storage unit
(#32185)
* Add SELECT privilege check when register or alter storage unit
* Update error message for select privilege
---
.../CheckDatabaseEnvironmentFailedException.java | 2 +-
.../MissingRequiredPrivilegeException.java | 2 +-
.../exception/MissingRequiredUserException.java | 2 +-
.../checker/MySQLDatabaseEnvironmentChecker.java | 28 ++++++++++++++++------
.../rdl/resource/AlterStorageUnitExecutor.java | 10 +++++++-
.../rdl/resource/RegisterStorageUnitExecutor.java | 10 +++++++-
6 files changed, 42 insertions(+), 12 deletions(-)
diff --git
a/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/CheckDatabaseEnvironmentFailedException.java
b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/CheckDatabaseEnvironmentFailedException.java
index 40d2f4de3ed..ffa2387a35d 100644
---
a/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/CheckDatabaseEnvironmentFailedException.java
+++
b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/CheckDatabaseEnvironmentFailedException.java
@@ -30,6 +30,6 @@ public final class CheckDatabaseEnvironmentFailedException
extends MetaDataSQLEx
private static final long serialVersionUID = 3913140870320566898L;
public CheckDatabaseEnvironmentFailedException(final SQLException cause) {
- super(XOpenSQLState.CONNECTION_EXCEPTION, 5, "Check database
environment failed.", cause);
+ super(XOpenSQLState.CONNECTION_EXCEPTION, 5, "Check database
environment failed", cause);
}
}
diff --git
a/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/MissingRequiredPrivilegeException.java
b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/MissingRequiredPrivilegeException.java
index 5600f116b84..0acc5b92c75 100644
---
a/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/MissingRequiredPrivilegeException.java
+++
b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/MissingRequiredPrivilegeException.java
@@ -30,6 +30,6 @@ public final class MissingRequiredPrivilegeException extends
MetaDataSQLExceptio
private static final long serialVersionUID = 3755362278200749857L;
public MissingRequiredPrivilegeException(final Collection<String>
privileges) {
- super(XOpenSQLState.PRIVILEGE_NOT_GRANTED, 6, "Missing required
privilege(s) `%s`.", privileges);
+ super(XOpenSQLState.PRIVILEGE_NOT_GRANTED, 6, "Missing required
privilege(s) `%s`", privileges);
}
}
diff --git
a/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/MissingRequiredUserException.java
b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/MissingRequiredUserException.java
index f611d8bc31a..ff9769970db 100644
---
a/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/MissingRequiredUserException.java
+++
b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/MissingRequiredUserException.java
@@ -28,6 +28,6 @@ public final class MissingRequiredUserException extends
MetaDataSQLException {
private static final long serialVersionUID = -656859547059598488L;
public MissingRequiredUserException(final String username) {
- super(XOpenSQLState.NOT_FOUND, 7, "User '%s' does exist.", username);
+ super(XOpenSQLState.NOT_FOUND, 7, "User '%s' does exist", username);
}
}
diff --git
a/infra/database/type/mysql/src/main/java/org/apache/shardingsphere/infra/database/mysql/checker/MySQLDatabaseEnvironmentChecker.java
b/infra/database/type/mysql/src/main/java/org/apache/shardingsphere/infra/database/mysql/checker/MySQLDatabaseEnvironmentChecker.java
index 12e21f7c8d0..b35a39d401d 100644
---
a/infra/database/type/mysql/src/main/java/org/apache/shardingsphere/infra/database/mysql/checker/MySQLDatabaseEnvironmentChecker.java
+++
b/infra/database/type/mysql/src/main/java/org/apache/shardingsphere/infra/database/mysql/checker/MySQLDatabaseEnvironmentChecker.java
@@ -53,8 +53,6 @@ public final class MySQLDatabaseEnvironmentChecker implements
DialectDatabaseEnv
private static final String[][] XA_REQUIRED_PRIVILEGES = {{"ALL
PRIVILEGES", "ON *.*"}, {"XA_RECOVER_ADMIN", "ON *.*"}};
- private static final Map<PrivilegeCheckType, String[][]>
REQUIRED_PRIVILEGES = new EnumMap<>(PrivilegeCheckType.class);
-
private static final Map<PrivilegeCheckType, Collection<String>>
REQUIRED_PRIVILEGES_FOR_MESSAGE = new EnumMap<>(PrivilegeCheckType.class);
private static final Map<String, String> REQUIRED_VARIABLES = new
HashMap<>(3, 1F);
@@ -62,9 +60,8 @@ public final class MySQLDatabaseEnvironmentChecker implements
DialectDatabaseEnv
private static final String SHOW_VARIABLES_SQL;
static {
- REQUIRED_PRIVILEGES.put(PrivilegeCheckType.PIPELINE,
PIPELINE_REQUIRED_PRIVILEGES);
REQUIRED_PRIVILEGES_FOR_MESSAGE.put(PrivilegeCheckType.PIPELINE,
Arrays.asList("REPLICATION SLAVE", "REPLICATION CLIENT"));
- REQUIRED_PRIVILEGES.put(PrivilegeCheckType.XA, XA_REQUIRED_PRIVILEGES);
+ REQUIRED_PRIVILEGES_FOR_MESSAGE.put(PrivilegeCheckType.SELECT,
Collections.singleton("SELECT ON DATABASE"));
REQUIRED_PRIVILEGES_FOR_MESSAGE.put(PrivilegeCheckType.XA,
Collections.singleton("XA_RECOVER_ADMIN"));
REQUIRED_VARIABLES.put("LOG_BIN", "ON");
REQUIRED_VARIABLES.put("BINLOG_FORMAT", "ROW");
@@ -91,7 +88,7 @@ public final class MySQLDatabaseEnvironmentChecker implements
DialectDatabaseEnv
ResultSet resultSet = preparedStatement.executeQuery()) {
while (resultSet.next()) {
String privilege = resultSet.getString(1).toUpperCase();
- if (matchPrivileges(privilege,
REQUIRED_PRIVILEGES.get(privilegeCheckType))) {
+ if (matchPrivileges(privilege,
getRequiredPrivileges(connection, privilegeCheckType))) {
return;
}
}
@@ -101,8 +98,25 @@ public final class MySQLDatabaseEnvironmentChecker
implements DialectDatabaseEnv
throw new
MissingRequiredPrivilegeException(REQUIRED_PRIVILEGES_FOR_MESSAGE.get(privilegeCheckType));
}
- private boolean matchPrivileges(final String privilege, final String[][]
requiredPrivileges) {
- return Arrays.stream(requiredPrivileges).anyMatch(each ->
Arrays.stream(each).allMatch(privilege::contains));
+ private String[][] getRequiredPrivileges(final Connection connection,
final PrivilegeCheckType privilegeCheckType) throws SQLException {
+ switch (privilegeCheckType) {
+ case PIPELINE:
+ return PIPELINE_REQUIRED_PRIVILEGES;
+ case SELECT:
+ return getSelectRequiredPrivilege(connection);
+ case XA:
+ return XA_REQUIRED_PRIVILEGES;
+ default:
+ return new String[0][0];
+ }
+ }
+
+ private String[][] getSelectRequiredPrivilege(final Connection connection)
throws SQLException {
+ return new String[][]{{"ALL PRIVILEGES", "ON *.*"}, {"SELECT", "ON
*.*"}, {"SELECT", String.format("ON `%s`.*",
connection.getCatalog()).toUpperCase()}};
+ }
+
+ private boolean matchPrivileges(final String grantedPrivileges, final
String[][] requiredPrivileges) {
+ return Arrays.stream(requiredPrivileges).anyMatch(each ->
Arrays.stream(each).allMatch(grantedPrivileges::contains));
}
@Override
diff --git
a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/AlterStorageUnitExecutor.java
b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/AlterStorageUnitExecutor.java
index e8880c38ff6..ebff6bf9090 100644
---
a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/AlterStorageUnitExecutor.java
+++
b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/AlterStorageUnitExecutor.java
@@ -65,7 +65,7 @@ public final class AlterStorageUnitExecutor implements
DistSQLUpdateExecutor<Alt
public void executeUpdate(final AlterStorageUnitStatement sqlStatement,
final ContextManager contextManager) {
checkBefore(sqlStatement);
Map<String, DataSourcePoolProperties> propsMap =
DataSourceSegmentsConverter.convert(database.getProtocolType(),
sqlStatement.getStorageUnits());
- validateHandler.validate(propsMap,
sqlStatement.getExpectedPrivileges().stream().map(each ->
PrivilegeCheckType.valueOf(each.toUpperCase())).collect(Collectors.toSet()));
+ validateHandler.validate(propsMap,
getExpectedPrivileges(sqlStatement));
try {
MetaDataContexts originalMetaDataContexts =
contextManager.getMetaDataContexts();
contextManager.getPersistServiceFacade().getMetaDataManagerPersistService().alterStorageUnits(database.getName(),
propsMap);
@@ -116,6 +116,14 @@ public final class AlterStorageUnitExecutor implements
DistSQLUpdateExecutor<Alt
return Objects.equals(hostName, connectionProps.getHostname()) &&
Objects.equals(port, String.valueOf(connectionProps.getPort())) &&
Objects.equals(database, connectionProps.getCatalog());
}
+ private Collection<PrivilegeCheckType> getExpectedPrivileges(final
AlterStorageUnitStatement sqlStatement) {
+ Collection<PrivilegeCheckType> result =
sqlStatement.getExpectedPrivileges().stream().map(each ->
PrivilegeCheckType.valueOf(each.toUpperCase())).collect(Collectors.toSet());
+ if (result.isEmpty()) {
+ result.add(PrivilegeCheckType.SELECT);
+ }
+ return result;
+ }
+
@Override
public Class<AlterStorageUnitStatement> getType() {
return AlterStorageUnitStatement.class;
diff --git
a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/RegisterStorageUnitExecutor.java
b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/RegisterStorageUnitExecutor.java
index 9a748961b18..0ccef4fcabb 100644
---
a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/RegisterStorageUnitExecutor.java
+++
b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/RegisterStorageUnitExecutor.java
@@ -67,7 +67,7 @@ public final class RegisterStorageUnitExecutor implements
DistSQLUpdateExecutor<
if (propsMap.isEmpty()) {
return;
}
- validateHandler.validate(propsMap,
sqlStatement.getExpectedPrivileges().stream().map(each ->
PrivilegeCheckType.valueOf(each.toUpperCase())).collect(Collectors.toSet()));
+ validateHandler.validate(propsMap,
getExpectedPrivileges(sqlStatement));
try {
MetaDataContexts originalMetaDataContexts =
contextManager.getMetaDataContexts();
contextManager.getPersistServiceFacade().getMetaDataManagerPersistService().registerStorageUnits(database.getName(),
propsMap);
@@ -113,6 +113,14 @@ public final class RegisterStorageUnitExecutor implements
DistSQLUpdateExecutor<
return
database.getRuleMetaData().getAttributes(DataSourceMapperRuleAttribute.class).stream().flatMap(each
-> each.getDataSourceMapper().keySet().stream()).collect(Collectors.toList());
}
+ private Collection<PrivilegeCheckType> getExpectedPrivileges(final
RegisterStorageUnitStatement sqlStatement) {
+ Collection<PrivilegeCheckType> result =
sqlStatement.getExpectedPrivileges().stream().map(each ->
PrivilegeCheckType.valueOf(each.toUpperCase())).collect(Collectors.toSet());
+ if (result.isEmpty()) {
+ result.add(PrivilegeCheckType.SELECT);
+ }
+ return result;
+ }
+
@Override
public Class<RegisterStorageUnitStatement> getType() {
return RegisterStorageUnitStatement.class;