Skip to content

Commit

Permalink
Add RAL ACL object to support grant/revoke ral_operate (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
RaigorJiang authored Nov 1, 2024
1 parent 095708e commit 130a617
Show file tree
Hide file tree
Showing 14 changed files with 35 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,5 @@ public AuthorityRuleConfiguration(final Collection<UserConfiguration> users, fin
this.authenticators = authenticators;
this.defaultAuthenticator = defaultAuthenticator;
this.subject = subject;

// TODO when grant super to user, set admin to true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ public final class ACLOperationExtractor {
* @return ACL operation
*/
public static ACLOperation extract(final SQLStatement sqlStatement) {
if (sqlStatement instanceof MySQLShowDatabasesStatement) {
return ACLOperation.SHOW_DB;
}
if (sqlStatement instanceof DMLStatement) {
return extractDML((DMLStatement) sqlStatement);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ private Collection<String> fillInDistSQLPrivileges(final GrantLevelSegment level
}

private String getDistSQLPrivilege(final GrantLevelSegment level, final ACLOperation operation, final String aclObjectType) {
if (ACLOperation.CREATE_USER == operation) {
if (ACLOperation.CREATE_USER == operation || ACLOperation.RAL_OPERATE == operation) {
return operation.name();
}
String databasePrivilege = null == level ? AuthorityConstants.PRIVILEGE_WILDCARD : level.getDatabaseName();
Expand All @@ -258,7 +258,7 @@ private void updatePrivileges(final Map<ACLSubject, Collection<String>> privileg
private void updatePrivileges(final Map<ACLSubject, Collection<String>> privileges, final Collection<ACLSubject> toBeGrantedSubjects, final Collection<String> toBeGrantedPrivileges) {
for (ACLSubject each : toBeGrantedSubjects) {
Collection<String> userOrRolePrivileges = privileges.getOrDefault(each, new LinkedList<>());
userOrRolePrivileges.addAll(toBeGrantedPrivileges);
toBeGrantedPrivileges.stream().filter(privilege -> !userOrRolePrivileges.contains(privilege)).forEach(userOrRolePrivileges::add);
privileges.put(each, userOrRolePrivileges);
}
}
Expand All @@ -270,7 +270,7 @@ private void updateRoles(final Map<GranteeSubject, Collection<RoleSubject>> conf
for (ACLSubject each : toBeGrantedUsers) {
ShardingSpherePreconditions.checkState(each instanceof GranteeSubject, () -> new RoleToRoleException(toBeGrantedRoles.iterator().next().getRoleName(), each.toString()));
Collection<RoleSubject> userRoles = configuredUserRoles.getOrDefault(each, new LinkedList<>());
userRoles.addAll(toBeGrantedRoles);
toBeGrantedRoles.stream().filter(role -> !userRoles.contains(role)).forEach(userRoles::add);
configuredUserRoles.put((GranteeSubject) each, userRoles);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ private String getPrivilegeWithoutColumn(final GrantLevelSegment level, final Di
}

private String getDistSQLPrivilege(final GrantLevelSegment level, final ACLOperation operation, final String aclObject) {
if (ACLOperation.CREATE_USER == operation) {
if (ACLOperation.CREATE_USER == operation || ACLOperation.RAL_OPERATE == operation) {
return operation.name();
}
String dbPrivilege = null == level ? AuthorityConstants.PRIVILEGE_WILDCARD : level.getDatabaseName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ void assertExecuteWithDuplicatedUser() {
when(rule.getConfiguration()).thenReturn(ruleConfig);
when(rule.getGrantees()).thenReturn(ruleConfig.getUsers().stream().map(each -> new Grantee(each.getUsername(), each.getHostname())).collect(Collectors.toList()));
executor.setRule(rule);
CreateDistUserStatement sqlStatement = new CreateDistUserStatement(Collections.singleton(new DistUserSegment("root", "", null, "root", false)), Collections.emptyList(), false);
CreateDistUserStatement sqlStatement = new CreateDistUserStatement(Collections.singleton(new DistUserSegment("root", "", null, "root", false)), false);
assertThrows(DuplicateGranteeException.class, () -> executor.checkBeforeUpdate(sqlStatement));
}

@Test
void assertExecuteWithDuplicatedRole() {
CreateDistUserStatement sqlStatement = new CreateDistUserStatement(Collections.singleton(new DistUserSegment("existed_role", "", null, "foo", false)), Collections.emptyList(), false);
CreateDistUserStatement sqlStatement = new CreateDistUserStatement(Collections.singleton(new DistUserSegment("existed_role", "", null, "foo", false)), false);
AuthorityRule rule = mock(AuthorityRule.class);
AuthorityRuleConfiguration ruleConfig = createCurrentRuleConfiguration();
when(rule.getConfiguration()).thenReturn(ruleConfig);
Expand All @@ -69,7 +69,7 @@ void assertExecuteWithDuplicatedRole() {

@Test
void assertExecute() {
CreateDistUserStatement sqlStatement = new CreateDistUserStatement(Collections.singleton(new DistUserSegment("sharding", "%", null, "foo", false)), Collections.emptyList(), false);
CreateDistUserStatement sqlStatement = new CreateDistUserStatement(Collections.singleton(new DistUserSegment("sharding", "%", null, "foo", false)), false);
AuthorityRule rule = mock(AuthorityRule.class);
AuthorityRuleConfiguration ruleConfig = createCurrentRuleConfiguration();
when(rule.getConfiguration()).thenReturn(ruleConfig);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ ifNotExists
;

createUserEntry
: userName_ (IDENTIFIED BY password_)? # createUserEntryIdentifiedBy
| userName_ IDENTIFIED WITH plugin AS string_ # createUserEntryIdentifiedWith
: userName_ IDENTIFIED BY password_ # createUserEntryIdentifiedBy
;

createUserList
Expand All @@ -68,11 +67,6 @@ createUserList

alterUserEntry
: userName_ IDENTIFIED BY password_ # alterUserEntryIdentifiedBy
| userName_ IDENTIFIED WITH plugin AS string_ # alterUserEntryIdentifiedWith
;

defaultRoleClause
: DEFAULT ROLE roleName_ (COMMA_ roleName_)*
;

userIdentifierOrText
Expand Down Expand Up @@ -160,14 +154,6 @@ plugin
: textOrIdentifier
;

authenticatorDefinition
: authenticatorName LP_ authAlgorithmDefinition RP_
;

authenticatorName
: IDENTIFIER_
;

authAlgorithmDefinition
: TYPE LP_ NAME EQ_ typeName propertiesDefinition? RP_
;
Expand All @@ -176,10 +162,6 @@ typeName
: IDENTIFIER_
;

string_
: STRING_
;

textOrIdentifier
: IDENTIFIER_ | STRING_
;
Expand All @@ -205,6 +187,7 @@ distSQLACLOperation

distSQLACLOperationWithoutObjectType
: CREATE_USER
| RAL_OPERATE
;

aclObjectType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ CREATE_USER
: C R E A T E UL_ U S E R
;

RAL_OPERATE
: R A L UL_ O P E R A T E
;

DATABASES
: D A T A B A S E S
;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ alterPrivilegeProvider
;

createDistUser
: CREATE DIST USER ifNotExists? createUserList defaultRoleClause?
: CREATE DIST USER ifNotExists? createUserList
;

alterDistUser
Expand Down Expand Up @@ -77,31 +77,3 @@ showDistUsers
showDistRoles
: SHOW DIST ROLES
;

createAuthenticator
: CREATE AUTHENTICATOR authenticatorDefinition
;

alterAuthenticator
: ALTER AUTHENTICATOR authenticatorDefinition
;

dropAuthenticator
: DROP AUTHENTICATOR authenticatorName (COMMA_ authenticatorName)*
;

createDefaultAuthenticator
: CREATE DEFAULT AUTHENTICATOR authenticatorName
;

alterDefaultAuthenticator
: ALTER DEFAULT AUTHENTICATOR authenticatorName
;

dropDefaultAuthenticator
: DROP DEFAULT AUTHENTICATOR
;

showAuthenticators
: SHOW AUTHENTICATORS
;
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,5 @@ execute
| showDistGrants
| showDistUsers
| showDistRoles
| showAuthenticators
| createAuthenticator
| alterAuthenticator
| dropAuthenticator
| createDefaultAuthenticator
| alterDefaultAuthenticator
| dropDefaultAuthenticator
) SEMI_? EOF
;
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,17 @@
import com.sphereex.dbplusengine.authority.distsql.statement.user.DropDistUserStatement;
import com.sphereex.dbplusengine.authority.distsql.statement.user.ShowDistUsersStatement;
import com.sphereex.dbplusengine.authority.model.operation.ACLOperation;
import org.antlr.v4.runtime.RuleContext;
import org.antlr.v4.runtime.tree.ParseTree;
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementBaseVisitor;
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.AlterPrivilegeProviderContext;
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.AlterUserEntryIdentifiedByContext;
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.AlterUserEntryIdentifiedWithContext;
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.AuthAlgorithmDefinitionContext;
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.ColumnNamesContext;
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.CreateDistRoleContext;
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.CreateDistUserContext;
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.CreateUserEntryIdentifiedByContext;
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.CreateUserEntryIdentifiedWithContext;
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.DistSQLOperationContext;
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.DistSQLOperationWithoutObjectTypeContext;
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.DropDistRoleContext;
Expand Down Expand Up @@ -85,7 +81,6 @@
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.StaticPrivilegeUpdateContext;
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.StaticPrivilegeUsageContext;
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.StorageUnitContext;
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.String_Context;
import org.apache.shardingsphere.distsql.parser.autogen.SphereExAuthorityDistSQLStatementParser.UserName_Context;
import org.apache.shardingsphere.distsql.segment.AlgorithmSegment;
import org.apache.shardingsphere.sql.parser.api.ASTNode;
Expand All @@ -107,10 +102,7 @@ public final class SphereExAuthorityDistSQLStatementVisitor extends SphereExAuth
@Override
public ASTNode visitCreateDistUser(final CreateDistUserContext ctx) {
Collection<DistUserSegment> users = ctx.createUserList().createUserEntry().stream().map(each -> (DistUserSegment) visit(each)).collect(Collectors.toList());
Collection<String> defaultRoles = null == ctx.defaultRoleClause()
? Collections.emptyList()
: ctx.defaultRoleClause().roleName_().stream().map(RuleContext::getText).collect(Collectors.toList());
return new CreateDistUserStatement(users, defaultRoles, null != ctx.ifNotExists());
return new CreateDistUserStatement(users, null != ctx.ifNotExists());
}

@Override
Expand All @@ -121,30 +113,11 @@ public ASTNode visitCreateUserEntryIdentifiedBy(final CreateUserEntryIdentifiedB
return new DistUserSegment(user, host, null, auth, false);
}

@Override
public ASTNode visitCreateUserEntryIdentifiedWith(final CreateUserEntryIdentifiedWithContext 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 DistUserSegment(user, host, ctx.plugin().getText(), ((StringLiteralValue) visit(ctx.string_())).getValue(), true);
}

@Override
public ASTNode visitUserName_(final UserName_Context ctx) {
String user = getIdentifierValue(ctx.userIdentifierOrText().textOrIdentifier(0));
String host = null == ctx.userIdentifierOrText().AT_() ? null : getIdentifierValue(ctx.userIdentifierOrText().textOrIdentifier(1));
return new DistUserSegment(user, host, null, null, false);
}

@Override
public ASTNode visitPassword_(final Password_Context ctx) {
return new StringLiteralValue(ctx.getText());
}

@Override
public ASTNode visitString_(final String_Context ctx) {
return new StringLiteralValue(ctx.getText());
}

@Override
public ASTNode visitAlterDistUser(final AlterDistUserContext ctx) {
return new AlterDistUserStatement((DistUserSegment) visit(ctx.alterUserEntry()), null != ctx.ifExists());
Expand All @@ -158,13 +131,6 @@ public ASTNode visitAlterUserEntryIdentifiedBy(final AlterUserEntryIdentifiedByC
return new DistUserSegment(user, host, null, auth, false);
}

@Override
public ASTNode visitAlterUserEntryIdentifiedWith(final AlterUserEntryIdentifiedWithContext 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 DistUserSegment(user, host, ctx.plugin().getText(), ((StringLiteralValue) visit(ctx.string_())).getValue(), 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());
Expand Down Expand Up @@ -352,6 +318,13 @@ public ASTNode visitShowDistGrants(final ShowDistGrantsContext ctx) {
return new ShowDistGrantsStatement((DistUserSegment) visit(ctx.userName_()), ctx.roleName_().stream().map(each -> new IdentifierValue(each.getText()).getValue()).collect(Collectors.toList()));
}

@Override
public ASTNode visitUserName_(final UserName_Context ctx) {
String user = getIdentifierValue(ctx.userIdentifierOrText().textOrIdentifier(0));
String host = null == ctx.userIdentifierOrText().AT_() ? null : getIdentifierValue(ctx.userIdentifierOrText().textOrIdentifier(1));
return new DistUserSegment(user, host, null, null, false);
}

@Override
public ASTNode visitShowDistUsers(final ShowDistUsersContext ctx) {
return new ShowDistUsersStatement();
Expand All @@ -362,11 +335,6 @@ public ASTNode visitShowDistRoles(final ShowDistRolesContext ctx) {
return new ShowDistRolesStatement();
}

@Override
public ASTNode visitAuthAlgorithmDefinition(final AuthAlgorithmDefinitionContext ctx) {
return new AlgorithmSegment(getIdentifierValue(ctx.typeName()), getProperties(ctx.propertiesDefinition()));
}

@Override
public ASTNode visitAlterPrivilegeProvider(final AlterPrivilegeProviderContext ctx) {
return new AlterPrivilegeProviderStatement((AlgorithmSegment) visit(ctx.algorithmDefinition()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.distsql.segment.AlgorithmSegment;
import org.apache.shardingsphere.distsql.statement.rdl.rule.global.GlobalRuleDefinitionStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.dcl.DCLStatement;

/**
* Alter privilege provider statement.
*/
@RequiredArgsConstructor
@Getter
public final class AlterPrivilegeProviderStatement extends GlobalRuleDefinitionStatement {
public final class AlterPrivilegeProviderStatement extends GlobalRuleDefinitionStatement implements DCLStatement {

private final AlgorithmSegment provider;
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,5 @@ public final class CreateDistUserStatement extends GlobalRuleDefinitionStatement

private final Collection<DistUserSegment> users;

private final Collection<String> defaultRoles;

private final boolean ifNotExists;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.sphereex.dbplusengine.authority.obj.domain.DCLACLObject;
import com.sphereex.dbplusengine.authority.obj.domain.DistSQLACLObject;
import com.sphereex.dbplusengine.authority.obj.domain.ProjectionACLObject;
import com.sphereex.dbplusengine.authority.obj.domain.RALACLObject;
import com.sphereex.dbplusengine.authority.obj.domain.TableACLObject;
import com.sphereex.dbplusengine.authority.provider.enterprise.shiro.EnterpriseRealm;
import com.sphereex.dbplusengine.authority.provider.enterprise.shiro.permission.EnterpriseColumnPermission;
Expand Down Expand Up @@ -70,13 +71,16 @@ public boolean hasPrivileges(final ACLObject aclObject, final ACLOperation opera
TableACLObject tableACLObject = (TableACLObject) aclObject;
return owner.isPermitted(new EnterpriseTablePermission(tableACLObject.getDatabase(), tableACLObject.getTable(), operation.name().toLowerCase()));
}
if (aclObject instanceof DCLACLObject) {
return owner.isPermitted(new EnterpriseDCLPermission(operation.name().toLowerCase()));
}
if (aclObject instanceof RALACLObject) {
return owner.isPermitted(new EnterpriseDCLPermission(operation.name().toLowerCase()));
}
if (aclObject instanceof DistSQLACLObject) {
DistSQLACLObject distSQLACLObject = (DistSQLACLObject) aclObject;
return owner.isPermitted(new EnterpriseDistSQLPermission(distSQLACLObject.getDatabase(), distSQLACLObject.getResource(), distSQLACLObject.getType(), operation.name().toLowerCase()));
}
if (aclObject instanceof DCLACLObject) {
return owner.isPermitted(new EnterpriseDCLPermission(operation.name().toLowerCase()));
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ public final class DefaultLoggingRuleConfigurationBuilder implements DefaultGlob
@SuppressWarnings("unchecked")
@Override
public LoggingRuleConfiguration build() {
return new LoggingRuleConfiguration(Collections.emptyList(), Collections.emptySet());
ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
return TypedSPILoader.findService(ShardingSphereLogBuilder.class, loggerFactory.getClass())
.map(optional -> new LoggingRuleConfiguration(optional.getDefaultLoggers(loggerFactory), optional.getDefaultAppenders(loggerFactory)))
.orElseGet(() -> new LoggingRuleConfiguration(Collections.emptyList(), Collections.emptySet()));
}

@Override
Expand Down

0 comments on commit 130a617

Please sign in to comment.