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 87df9b8da9dcdd38219ea24b5b3ca572e5a1daf9 Author: Raigor <[email protected]> AuthorDate: Fri Nov 1 14:44:42 2024 +0800 Add DistSQL to set user admin (#35) --- .../authority/operation/ACLOperationExtractor.java | 1 - .../checker/AuthorityStatementExecutorChecker.java | 12 ++- .../update/AlterDistUserSetAdminExecutor.java | 108 +++++++++++++++++++++ ...dl.rule.spi.global.GlobalRuleDefinitionExecutor | 1 + .../antlr4/imports/authority/SphereExKeyword.g4 | 8 ++ .../imports/authority/SphereExRALStatement.g4 | 8 ++ .../autogen/SphereExAuthorityDistSQLStatement.g4 | 1 + .../SphereExAuthorityDistSQLStatementVisitor.java | 9 ++ .../distsql/acl/AuthorityACLObjectProvider.java | 10 +- .../user/AlterDistUserSetAdminStatement.java} | 35 ++++--- 10 files changed, 166 insertions(+), 27 deletions(-) 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 ad1bf8fd8c2..bfc1c843205 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 @@ -54,7 +54,6 @@ import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.DeleteS import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.InsertStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.SelectStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.UpdateStatement; -import org.apache.shardingsphere.sql.parser.statement.mysql.dal.MySQLShowDatabasesStatement; /** * ACL operation extractor. diff --git a/kernel/authority/distsql/handler/src/main/java/com/sphereex/dbplusengine/authority/distsql/handler/checker/AuthorityStatementExecutorChecker.java b/kernel/authority/distsql/handler/src/main/java/com/sphereex/dbplusengine/authority/distsql/handler/checker/AuthorityStatementExecutorChecker.java index 1543b4f8408..5d3ab5a43ca 100644 --- a/kernel/authority/distsql/handler/src/main/java/com/sphereex/dbplusengine/authority/distsql/handler/checker/AuthorityStatementExecutorChecker.java +++ b/kernel/authority/distsql/handler/src/main/java/com/sphereex/dbplusengine/authority/distsql/handler/checker/AuthorityStatementExecutorChecker.java @@ -114,10 +114,14 @@ public final class AuthorityStatementExecutorChecker { ShardingSpherePreconditions.checkMustEmpty(invalidDistPrivileges, () -> new UnsupportedOperationException(String.format("Unsupported privileges type %s", invalidDistPrivileges))); } + /** + * Check user have roles. + * + * @param userRoles user roles + * @param revokeRoles to be revoked roles + */ public static void checkUserHaveRole(final Collection<RoleSubject> userRoles, final Collection<RoleSubject> revokeRoles) { - revokeRoles.forEach(each -> { - ShardingSpherePreconditions.checkState(userRoles.contains(each), - () -> new UserNotHaveRoleException(each.getRoleName())); - }); + revokeRoles.forEach(each -> ShardingSpherePreconditions.checkState(userRoles.contains(each), + () -> new UserNotHaveRoleException(each.getRoleName()))); } } diff --git a/kernel/authority/distsql/handler/src/main/java/com/sphereex/dbplusengine/authority/distsql/handler/update/AlterDistUserSetAdminExecutor.java b/kernel/authority/distsql/handler/src/main/java/com/sphereex/dbplusengine/authority/distsql/handler/update/AlterDistUserSetAdminExecutor.java new file mode 100644 index 00000000000..240d0a13245 --- /dev/null +++ b/kernel/authority/distsql/handler/src/main/java/com/sphereex/dbplusengine/authority/distsql/handler/update/AlterDistUserSetAdminExecutor.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sphereex.dbplusengine.authority.distsql.handler.update; + +import com.sphereex.dbplusengine.authority.distsql.handler.converter.AuthorityStatementConverter; +import com.sphereex.dbplusengine.authority.distsql.segment.DistUserSegment; +import com.sphereex.dbplusengine.authority.distsql.statement.user.AlterDistUserSetAdminStatement; +import com.sphereex.dbplusengine.authority.exception.definition.MissingRequiredUserException; +import com.sphereex.dbplusengine.distsql.handler.aware.DistSQLExecutorGranteeAware; +import lombok.Setter; +import org.apache.shardingsphere.authority.config.AuthorityRuleConfiguration; +import org.apache.shardingsphere.authority.config.UserConfiguration; +import org.apache.shardingsphere.authority.rule.AuthorityRule; +import org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.global.GlobalRuleDefinitionExecutor; +import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions; +import org.apache.shardingsphere.infra.metadata.user.Grantee; +import org.apache.shardingsphere.infra.metadata.user.ShardingSphereUser; + +import java.util.Collection; +import java.util.Collections; +import java.util.Optional; + +/** + * Alter dist user set admin executor. + */ +@Setter +public final class AlterDistUserSetAdminExecutor implements GlobalRuleDefinitionExecutor<AlterDistUserSetAdminStatement, AuthorityRule>, DistSQLExecutorGranteeAware { + + private AuthorityRule rule; + + private Grantee grantee; + + @Override + public void checkBeforeUpdate(final AlterDistUserSetAdminStatement sqlStatement) { + if (sqlStatement.isAdmin()) { + checkNoAdmins(); + } else { + checkCurrentUserIsAdmin(); + checkTargetUserIsAdmin(sqlStatement); + } + checkUserExist(sqlStatement); + } + + private void checkNoAdmins() { + Collection<UserConfiguration> users = rule.getConfiguration().getUsers(); + ShardingSpherePreconditions.checkState(users.stream().noneMatch(UserConfiguration::isAdmin), + () -> new UnsupportedOperationException("Unsupported when there is already an admin user")); + } + + private void checkCurrentUserIsAdmin() { + Optional<ShardingSphereUser> currentUser = rule.findUser(grantee); + ShardingSpherePreconditions.checkState(currentUser.isPresent() && currentUser.get().isAdmin(), + () -> new UnsupportedOperationException("Unsupported because current user is not admin")); + } + + private void checkTargetUserIsAdmin(final AlterDistUserSetAdminStatement sqlStatement) { + Optional<Grantee> toBeAlteredGrantee = rule.getGrantees().stream().filter(each -> each.accept(new Grantee(sqlStatement.getUser().getUser(), sqlStatement.getUser().getHost()))).findFirst(); + ShardingSpherePreconditions.checkState(toBeAlteredGrantee.isPresent(), () -> new MissingRequiredUserException(Collections.singleton(grantee))); + Optional<ShardingSphereUser> toBeAlteredUser = rule.findUser(toBeAlteredGrantee.get()); + ShardingSpherePreconditions.checkState(toBeAlteredUser.isPresent(), () -> new MissingRequiredUserException(Collections.singleton(grantee))); + ShardingSpherePreconditions.checkState(toBeAlteredUser.get().isAdmin(), + () -> new UnsupportedOperationException("Unsupported because to be altered user is not admin")); + } + + private void checkUserExist(final AlterDistUserSetAdminStatement sqlStatement) { + DistUserSegment userSegment = sqlStatement.getUser(); + Grantee grantee = new Grantee(userSegment.getUser(), userSegment.getHost()); + ShardingSpherePreconditions.checkContains(rule.getGrantees(), grantee, () -> new MissingRequiredUserException(Collections.singleton(grantee))); + } + + @Override + public AuthorityRuleConfiguration buildToBeAlteredRuleConfiguration(final AlterDistUserSetAdminStatement sqlStatement) { + Optional<Grantee> toBeAlteredGrantee = rule.getGrantees().stream().filter(each -> each.accept(new Grantee(sqlStatement.getUser().getUser(), sqlStatement.getUser().getHost()))).findFirst(); + ShardingSpherePreconditions.checkState(toBeAlteredGrantee.isPresent(), () -> new MissingRequiredUserException(Collections.singleton(grantee))); + Optional<ShardingSphereUser> toBeAlteredUser = rule.findUser(toBeAlteredGrantee.get()); + ShardingSpherePreconditions.checkState(toBeAlteredUser.isPresent(), () -> new MissingRequiredUserException(Collections.singleton(grantee))); + AuthorityRuleConfiguration result = AuthorityStatementConverter.createAuthorityRuleConfiguration(rule.getConfiguration()); + result.getUsers().removeIf(each -> new Grantee(each.getUsername(), each.getHostname()).equals(toBeAlteredUser.get().getGrantee())); + result.getUsers().add(new UserConfiguration(toBeAlteredGrantee.get().getUsername(), + toBeAlteredUser.get().getPassword(), toBeAlteredGrantee.get().getHostname(), toBeAlteredUser.get().getAuthenticationMethodName(), sqlStatement.isAdmin())); + return result; + } + + @Override + public Class<AuthorityRule> getRuleClass() { + return AuthorityRule.class; + } + + @Override + public Class<AlterDistUserSetAdminStatement> getType() { + return AlterDistUserSetAdminStatement.class; + } +} diff --git a/kernel/authority/distsql/handler/src/main/resources/META-INF/services/org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.global.GlobalRuleDefinitionExecutor b/kernel/authority/distsql/handler/src/main/resources/META-INF/services/org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.global.GlobalRuleDefinitionExecutor index aa5b8eafd55..7c984459b08 100644 --- a/kernel/authority/distsql/handler/src/main/resources/META-INF/services/org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.global.GlobalRuleDefinitionExecutor +++ b/kernel/authority/distsql/handler/src/main/resources/META-INF/services/org.apache.shardingsphere.distsql.handler.engine.update.rdl.rule.spi.global.GlobalRuleDefinitionExecutor @@ -18,6 +18,7 @@ com.sphereex.dbplusengine.authority.distsql.handler.update.AlterPrivilegeProviderExecutor com.sphereex.dbplusengine.authority.distsql.handler.update.CreateDistUserExecutor com.sphereex.dbplusengine.authority.distsql.handler.update.AlterDistUserExecutor +com.sphereex.dbplusengine.authority.distsql.handler.update.AlterDistUserSetAdminExecutor com.sphereex.dbplusengine.authority.distsql.handler.update.DropDistUserExecutor com.sphereex.dbplusengine.authority.distsql.handler.update.CreateDistRoleExecutor com.sphereex.dbplusengine.authority.distsql.handler.update.DropDistRoleExecutor diff --git a/kernel/authority/distsql/parser/src/main/antlr4/imports/authority/SphereExKeyword.g4 b/kernel/authority/distsql/parser/src/main/antlr4/imports/authority/SphereExKeyword.g4 index 4bff4c7c1b0..af03e819eb0 100644 --- a/kernel/authority/distsql/parser/src/main/antlr4/imports/authority/SphereExKeyword.g4 +++ b/kernel/authority/distsql/parser/src/main/antlr4/imports/authority/SphereExKeyword.g4 @@ -254,3 +254,11 @@ FROM ALL : A L L ; + +SET + : S E T + ; + +ADMIN + : A D M I N + ; diff --git a/kernel/authority/distsql/parser/src/main/antlr4/imports/authority/SphereExRALStatement.g4 b/kernel/authority/distsql/parser/src/main/antlr4/imports/authority/SphereExRALStatement.g4 index 3867c2d85ff..e4ca06d9a0d 100644 --- a/kernel/authority/distsql/parser/src/main/antlr4/imports/authority/SphereExRALStatement.g4 +++ b/kernel/authority/distsql/parser/src/main/antlr4/imports/authority/SphereExRALStatement.g4 @@ -31,6 +31,14 @@ alterDistUser : ALTER DIST USER ifExists? alterUserEntry ; +alterDistUserSetAdmin + : ALTER DIST USER userName_ SET ADMIN EQ_ boolean_ + ; + +boolean_ + : TRUE | FALSE + ; + dropDistUser : DROP DIST USER ifExists? userList ; diff --git a/kernel/authority/distsql/parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/SphereExAuthorityDistSQLStatement.g4 b/kernel/authority/distsql/parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/SphereExAuthorityDistSQLStatement.g4 index d97e053e54e..c8f65bad782 100644 --- a/kernel/authority/distsql/parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/SphereExAuthorityDistSQLStatement.g4 +++ b/kernel/authority/distsql/parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/SphereExAuthorityDistSQLStatement.g4 @@ -23,6 +23,7 @@ execute : (alterPrivilegeProvider | createDistUser | alterDistUser + | alterDistUserSetAdmin | dropDistUser | createDistRole | dropDistRole diff --git a/kernel/authority/distsql/parser/src/main/java/com/sphereex/dbplusengine/authority/distsql/parser/core/SphereExAuthorityDistSQLStatementVisitor.java b/kernel/authority/distsql/parser/src/main/java/com/sphereex/dbplusengine/authority/distsql/parser/core/SphereExAuthorityDistSQLStatementVisitor.java index 224e3ddc722..44e2fbe5dca 100644 --- a/kernel/authority/distsql/parser/src/main/java/com/sphereex/dbplusengine/authority/distsql/parser/core/SphereExAuthorityDistSQLStatementVisitor.java +++ b/kernel/authority/distsql/parser/src/main/java/com/sphereex/dbplusengine/authority/distsql/parser/core/SphereExAuthorityDistSQLStatementVisitor.java @@ -29,6 +29,7 @@ import com.sphereex.dbplusengine.authority.distsql.statement.privilege.ShowDistG import com.sphereex.dbplusengine.authority.distsql.statement.role.CreateDistRoleStatement; import com.sphereex.dbplusengine.authority.distsql.statement.role.DropDistRoleStatement; import com.sphereex.dbplusengine.authority.distsql.statement.role.ShowDistRolesStatement; +import com.sphereex.dbplusengine.authority.distsql.statement.user.AlterDistUserSetAdminStatement; import com.sphereex.dbplusengine.authority.distsql.statement.user.AlterDistUserStatement; import com.sphereex.dbplusengine.authority.distsql.statement.user.CreateDistUserStatement; import com.sphereex.dbplusengine.authority.distsql.statement.user.DropDistUserStatement; @@ -39,6 +40,7 @@ import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQL import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.AclObjectTypeContext; import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.AlgorithmDefinitionContext; import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.AlterDistUserContext; +import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.AlterDistUserSetAdminContext; import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.AlterPrivilegeProviderContext; import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.AlterUserEntryIdentifiedByContext; import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.ColumnNamesContext; @@ -131,6 +133,13 @@ public final class SphereExAuthorityDistSQLStatementVisitor extends SphereExAuth return new DistUserSegment(user, host, null, auth, false); } + @Override + public ASTNode visitAlterDistUserSetAdmin(final AlterDistUserSetAdminContext ctx) { + String user = getIdentifierValue(ctx.userName_().userIdentifierOrText().textOrIdentifier(0)); + String host = null == ctx.userName_().userIdentifierOrText().AT_() ? null : getIdentifierValue(ctx.userName_().userIdentifierOrText().textOrIdentifier(1)); + return new AlterDistUserSetAdminStatement(new DistUserSegment(user, host, null, null, false), null != ctx.boolean_().TRUE()); + } + @Override public ASTNode visitDropDistUser(final DropDistUserContext ctx) { return new DropDistUserStatement(ctx.userList().userName_().stream().map(each -> (DistUserSegment) visit(each)).collect(Collectors.toList()), null != ctx.ifExists()); diff --git a/kernel/authority/distsql/statement/src/main/java/com/sphereex/dbplusengine/authority/distsql/acl/AuthorityACLObjectProvider.java b/kernel/authority/distsql/statement/src/main/java/com/sphereex/dbplusengine/authority/distsql/acl/AuthorityACLObjectProvider.java index b33a269c5e9..8e9ab32556c 100644 --- a/kernel/authority/distsql/statement/src/main/java/com/sphereex/dbplusengine/authority/distsql/acl/AuthorityACLObjectProvider.java +++ b/kernel/authority/distsql/statement/src/main/java/com/sphereex/dbplusengine/authority/distsql/acl/AuthorityACLObjectProvider.java @@ -17,13 +17,14 @@ package com.sphereex.dbplusengine.authority.distsql.acl; -import com.sphereex.dbplusengine.authority.distsql.statement.user.AlterDistUserStatement; +import com.sphereex.dbplusengine.authority.distsql.statement.privilege.GrantDistPrivilegesStatement; +import com.sphereex.dbplusengine.authority.distsql.statement.privilege.RevokeDistPrivilegesStatement; import com.sphereex.dbplusengine.authority.distsql.statement.role.CreateDistRoleStatement; -import com.sphereex.dbplusengine.authority.distsql.statement.user.CreateDistUserStatement; import com.sphereex.dbplusengine.authority.distsql.statement.role.DropDistRoleStatement; +import com.sphereex.dbplusengine.authority.distsql.statement.user.AlterDistUserSetAdminStatement; +import com.sphereex.dbplusengine.authority.distsql.statement.user.AlterDistUserStatement; +import com.sphereex.dbplusengine.authority.distsql.statement.user.CreateDistUserStatement; import com.sphereex.dbplusengine.authority.distsql.statement.user.DropDistUserStatement; -import com.sphereex.dbplusengine.authority.distsql.statement.privilege.GrantDistPrivilegesStatement; -import com.sphereex.dbplusengine.authority.distsql.statement.privilege.RevokeDistPrivilegesStatement; import com.sphereex.dbplusengine.distsql.acl.DistSQLACLObjectProvider; import org.apache.shardingsphere.distsql.statement.DistSQLStatement; @@ -42,6 +43,7 @@ public final class AuthorityACLObjectProvider implements DistSQLACLObjectProvide static { ACL_OBJECTS.put(CreateDistUserStatement.class, ACL_OBJECT); ACL_OBJECTS.put(AlterDistUserStatement.class, ACL_OBJECT); + ACL_OBJECTS.put(AlterDistUserSetAdminStatement.class, ACL_OBJECT); ACL_OBJECTS.put(DropDistUserStatement.class, ACL_OBJECT); ACL_OBJECTS.put(CreateDistRoleStatement.class, ACL_OBJECT); ACL_OBJECTS.put(DropDistRoleStatement.class, ACL_OBJECT); diff --git a/kernel/authority/distsql/parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/SphereExAuthorityDistSQLStatement.g4 b/kernel/authority/distsql/statement/src/main/java/com/sphereex/dbplusengine/authority/distsql/statement/user/AlterDistUserSetAdminStatement.java similarity index 54% copy from kernel/authority/distsql/parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/SphereExAuthorityDistSQLStatement.g4 copy to kernel/authority/distsql/statement/src/main/java/com/sphereex/dbplusengine/authority/distsql/statement/user/AlterDistUserSetAdminStatement.java index d97e053e54e..547ebc2780b 100644 --- a/kernel/authority/distsql/parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/SphereExAuthorityDistSQLStatement.g4 +++ b/kernel/authority/distsql/statement/src/main/java/com/sphereex/dbplusengine/authority/distsql/statement/user/AlterDistUserSetAdminStatement.java @@ -15,23 +15,22 @@ * limitations under the License. */ -grammar SphereExAuthorityDistSQLStatement; +package com.sphereex.dbplusengine.authority.distsql.statement.user; -import SphereExRALStatement; +import com.sphereex.dbplusengine.authority.distsql.segment.DistUserSegment; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.apache.shardingsphere.distsql.statement.rdl.rule.global.GlobalRuleDefinitionStatement; +import org.apache.shardingsphere.sql.parser.statement.core.statement.dcl.DCLStatement; -execute - : (alterPrivilegeProvider - | createDistUser - | alterDistUser - | dropDistUser - | createDistRole - | dropDistRole - | grantDistPrivileges - | revokeDistPrivileges - | grantDistSQLPrivileges - | revokeDistSQLPrivileges - | showDistGrants - | showDistUsers - | showDistRoles - ) SEMI_? EOF - ; +/** + * Alter dist user set admin statement. + */ +@RequiredArgsConstructor +@Getter +public final class AlterDistUserSetAdminStatement extends GlobalRuleDefinitionStatement implements DCLStatement { + + private final DistUserSegment user; + + private final boolean admin; +}
