Skip to content

Commit

Permalink
resource_control: introduce privilege RESOURCE_GROUP_USER to restrict…
Browse files Browse the repository at this point in the history
… the switch of resource group (#53483)

close #53440
  • Loading branch information
glorv committed Jun 14, 2024
1 parent b4563c0 commit 29fc940
Show file tree
Hide file tree
Showing 11 changed files with 297 additions and 205 deletions.
2 changes: 1 addition & 1 deletion pkg/planner/core/expression_rewriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -1681,7 +1681,7 @@ func (er *expressionRewriter) rewriteVariable(planCtx *exprRewriterPlanCtx, v *a
}
if sem.IsEnabled() && sem.IsInvisibleSysVar(sysVar.Name) {
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("RESTRICTED_VARIABLES_ADMIN")
planCtx.builder.visitInfo = appendDynamicVisitInfo(planCtx.builder.visitInfo, "RESTRICTED_VARIABLES_ADMIN", false, err)
planCtx.builder.visitInfo = appendDynamicVisitInfo(planCtx.builder.visitInfo, []string{"RESTRICTED_VARIABLES_ADMIN"}, false, err)
}
if v.ExplicitScope && !sysVar.HasNoneScope() {
if v.IsGlobal && !(sysVar.HasGlobalScope() || sysVar.HasInstanceScope()) {
Expand Down
4 changes: 2 additions & 2 deletions pkg/planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -7288,10 +7288,10 @@ func collectTableName(node ast.ResultSetNode, updatableName *map[string]bool, in
}
}

func appendDynamicVisitInfo(vi []visitInfo, priv string, withGrant bool, err error) []visitInfo {
func appendDynamicVisitInfo(vi []visitInfo, privs []string, withGrant bool, err error) []visitInfo {
return append(vi, visitInfo{
privilege: mysql.ExtendedPriv,
dynamicPriv: priv,
dynamicPrivs: privs,
dynamicWithGrant: withGrant,
err: err,
})
Expand Down
322 changes: 161 additions & 161 deletions pkg/planner/core/logical_plans_test.go

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions pkg/planner/core/optimizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,16 @@ func BuildLogicalPlanForTest(ctx context.Context, sctx sessionctx.Context, node
func CheckPrivilege(activeRoles []*auth.RoleIdentity, pm privilege.Manager, vs []visitInfo) error {
for _, v := range vs {
if v.privilege == mysql.ExtendedPriv {
if !pm.RequestDynamicVerification(activeRoles, v.dynamicPriv, v.dynamicWithGrant) {
hasPriv := false
for _, priv := range v.dynamicPrivs {
hasPriv = hasPriv || pm.RequestDynamicVerification(activeRoles, priv, v.dynamicWithGrant)
if hasPriv {
break
}
}
if !hasPriv {
if v.err == nil {
return plannererrors.ErrPrivilegeCheckFail.GenWithStackByArgs(v.dynamicPriv)
return plannererrors.ErrPrivilegeCheckFail.GenWithStackByArgs(v.dynamicPrivs)
}
return v.err
}
Expand Down
67 changes: 42 additions & 25 deletions pkg/planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"encoding/binary"
"fmt"
"math"
"reflect"
"strconv"
"strings"

Expand Down Expand Up @@ -72,16 +73,29 @@ import (
)

type visitInfo struct {
privilege mysql.PrivilegeType
db string
table string
column string
err error
alterWritable bool
dynamicPriv string
privilege mysql.PrivilegeType
db string
table string
column string
err error
alterWritable bool
// if multiple privileges is provided, user should
// have at least one privilege to pass the check.
dynamicPrivs []string
dynamicWithGrant bool
}

func (v *visitInfo) Equals(other *visitInfo) bool {
return v.privilege == other.privilege &&
v.db == other.db &&
v.table == other.table &&
v.column == other.column &&
v.err == other.err &&
v.alterWritable == other.alterWritable &&
reflect.DeepEqual(v.dynamicPrivs, other.dynamicPrivs) &&
v.dynamicWithGrant == other.dynamicWithGrant
}

// clauseCode indicates in which clause the column is currently.
type clauseCode int

Expand Down Expand Up @@ -654,11 +668,11 @@ func (b *PlanBuilder) buildSet(ctx context.Context, v *ast.SetStmt) (base.Plan,
for _, vars := range v.Variables {
if vars.IsGlobal {
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or SYSTEM_VARIABLES_ADMIN")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "SYSTEM_VARIABLES_ADMIN", false, err)
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, []string{"SYSTEM_VARIABLES_ADMIN"}, false, err)
}
if sem.IsEnabled() && sem.IsInvisibleSysVar(strings.ToLower(vars.Name)) {
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("RESTRICTED_VARIABLES_ADMIN")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "RESTRICTED_VARIABLES_ADMIN", false, err)
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, []string{"RESTRICTED_VARIABLES_ADMIN"}, false, err)
}
assign := &expression.VarAssignment{
Name: vars.Name,
Expand Down Expand Up @@ -3167,10 +3181,10 @@ func (b *PlanBuilder) buildShow(ctx context.Context, show *ast.ShowStmt) (base.P
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.ShowViewPriv, show.Table.Schema.L, show.Table.Name.L, "", err)
case ast.ShowBackups:
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or BACKUP_ADMIN")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "BACKUP_ADMIN", false, err)
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, []string{"BACKUP_ADMIN"}, false, err)
case ast.ShowRestores:
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or RESTORE_ADMIN")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "RESTORE_ADMIN", false, err)
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, []string{"RESTORE_ADMIN"}, false, err)
case ast.ShowTableNextRowId:
p := &ShowNextRowID{TableName: show.Table}
p.setSchemaAndNames(buildShowNextRowID())
Expand Down Expand Up @@ -3288,28 +3302,28 @@ func (b *PlanBuilder) buildSimple(ctx context.Context, node ast.StmtNode) (base.
p.setSchemaAndNames(buildBRIESchema(raw.Kind))
if raw.Kind == ast.BRIEKindRestore {
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or RESTORE_ADMIN")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "RESTORE_ADMIN", false, err)
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, []string{"RESTORE_ADMIN"}, false, err)
} else {
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or BACKUP_ADMIN")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "BACKUP_ADMIN", false, err)
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, []string{"BACKUP_ADMIN"}, false, err)
}
case *ast.CalibrateResourceStmt:
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or RESOURCE_GROUP_ADMIN")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "RESOURCE_GROUP_ADMIN", false, err)
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, []string{"RESOURCE_GROUP_ADMIN"}, false, err)
p.setSchemaAndNames(buildCalibrateResourceSchema())
case *ast.AddQueryWatchStmt:
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or RESOURCE_GROUP_ADMIN")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "RESOURCE_GROUP_ADMIN", false, err)
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, []string{"RESOURCE_GROUP_ADMIN"}, false, err)
p.setSchemaAndNames(buildAddQueryWatchSchema())
case *ast.DropQueryWatchStmt:
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or RESOURCE_GROUP_ADMIN")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "RESOURCE_GROUP_ADMIN", false, err)
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, []string{"RESOURCE_GROUP_ADMIN"}, false, err)
case *ast.GrantRoleStmt:
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or ROLE_ADMIN")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "ROLE_ADMIN", false, err)
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, []string{"ROLE_ADMIN"}, false, err)
case *ast.RevokeRoleStmt:
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or ROLE_ADMIN")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "ROLE_ADMIN", false, err)
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, []string{"ROLE_ADMIN"}, false, err)
// Check if any of the users are RESTRICTED
for _, user := range raw.Users {
b.visitInfo = appendVisitInfoIsRestrictedUser(b.visitInfo, b.ctx, user, "RESTRICTED_USER_ADMIN")
Expand All @@ -3330,13 +3344,13 @@ func (b *PlanBuilder) buildSimple(ctx context.Context, node ast.StmtNode) (base.
loginUser := b.ctx.GetSessionVars().User
if pi.User != loginUser.Username {
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or CONNECTION_ADMIN")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "CONNECTION_ADMIN", false, err)
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, []string{"CONNECTION_ADMIN"}, false, err)
b.visitInfo = appendVisitInfoIsRestrictedUser(b.visitInfo, b.ctx, &auth.UserIdentity{Username: pi.User, Hostname: pi.Host}, "RESTRICTED_CONNECTION_ADMIN")
}
} else if raw.ConnectionID == domain.GetDomain(b.ctx).GetAutoAnalyzeProcID() {
// Only the users with SUPER or CONNECTION_ADMIN privilege can kill auto analyze.
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or CONNECTION_ADMIN")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "CONNECTION_ADMIN", false, err)
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, []string{"CONNECTION_ADMIN"}, false, err)
}
}
case *ast.UseStmt:
Expand Down Expand Up @@ -3381,6 +3395,9 @@ func (b *PlanBuilder) buildSimple(ctx context.Context, node ast.StmtNode) (base.
}
p.StaleTxnStartTS = startTS
}
case *ast.SetResourceGroupStmt:
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or RESOURCE_GROUP_ADMIN or RESOURCE_GROUP_USER")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, []string{"RESOURCE_GROUP_ADMIN", "RESOURCE_GROUP_USER"}, false, err)
}
return p, nil
}
Expand All @@ -3402,7 +3419,7 @@ func collectVisitInfoFromRevokeStmt(sctx base.PlanContext, vi []visitInfo, stmt
var allPrivs []mysql.PrivilegeType
for _, item := range stmt.Privs {
if item.Priv == mysql.ExtendedPriv {
vi = appendDynamicVisitInfo(vi, strings.ToUpper(item.Name), true, nil) // verified in MySQL: requires the dynamic grant option to revoke.
vi = appendDynamicVisitInfo(vi, []string{strings.ToUpper(item.Name)}, true, nil) // verified in MySQL: requires the dynamic grant option to revoke.
continue
}
nonDynamicPrivilege = true
Expand Down Expand Up @@ -3444,7 +3461,7 @@ func appendVisitInfoIsRestrictedUser(visitInfo []visitInfo, sctx base.PlanContex
checker := privilege.GetPrivilegeManager(sctx)
if checker != nil && checker.RequestDynamicVerificationWithUser("RESTRICTED_USER_ADMIN", false, user) {
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs(priv)
visitInfo = appendDynamicVisitInfo(visitInfo, priv, false, err)
visitInfo = appendDynamicVisitInfo(visitInfo, []string{priv}, false, err)
}
return visitInfo
}
Expand Down Expand Up @@ -3479,7 +3496,7 @@ func collectVisitInfoFromGrantStmt(sctx base.PlanContext, vi []visitInfo, stmt *
// with dynamic privileges.

err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("GRANT OPTION")
vi = appendDynamicVisitInfo(vi, item.Name, true, err)
vi = appendDynamicVisitInfo(vi, []string{item.Name}, true, err)
continue
}
nonDynamicPrivilege = true
Expand Down Expand Up @@ -4843,10 +4860,10 @@ func (b *PlanBuilder) buildDDL(ctx context.Context, node ast.DDLNode) (base.Plan
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SuperPriv, "", "", "", nil)
case *ast.DropPlacementPolicyStmt, *ast.CreatePlacementPolicyStmt, *ast.AlterPlacementPolicyStmt:
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or PLACEMENT_ADMIN")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "PLACEMENT_ADMIN", false, err)
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, []string{"PLACEMENT_ADMIN"}, false, err)
case *ast.CreateResourceGroupStmt, *ast.DropResourceGroupStmt, *ast.AlterResourceGroupStmt:
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or RESOURCE_GROUP_ADMIN")
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, "RESOURCE_GROUP_ADMIN", false, err)
b.visitInfo = appendDynamicVisitInfo(b.visitInfo, []string{"RESOURCE_GROUP_ADMIN"}, false, err)
case *ast.OptimizeTableStmt:
return nil, dbterror.ErrGeneralUnsupportedDDL.GenWithStack("OPTIMIZE TABLE is not supported")
}
Expand Down
22 changes: 17 additions & 5 deletions pkg/planner/optimize.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,23 @@ func Optimize(ctx context.Context, sctx sessionctx.Context, node ast.Node, is in
// Override the resource group if the hint is set.
if retErr == nil && sessVars.StmtCtx.StmtHints.HasResourceGroup {
if variable.EnableResourceControl.Load() {
sessVars.StmtCtx.ResourceGroupName = sessVars.StmtCtx.StmtHints.ResourceGroup
// if we are in a txn, should update the txn resource name to let the txn
// commit with the hint resource group.
if txn, err := sctx.Txn(false); err == nil && txn != nil && txn.Valid() {
kv.SetTxnResourceGroup(txn, sessVars.StmtCtx.ResourceGroupName)
checker := privilege.GetPrivilegeManager(sctx)
hasPriv := true
if checker != nil {
hasRgAdminPriv := checker.RequestDynamicVerification(sctx.GetSessionVars().ActiveRoles, "RESOURCE_GROUP_ADMIN", false)
hasRgUserPriv := checker.RequestDynamicVerification(sctx.GetSessionVars().ActiveRoles, "RESOURCE_GROUP_USER", false)
hasPriv = hasRgAdminPriv || hasRgUserPriv
}
if hasPriv {
sessVars.StmtCtx.ResourceGroupName = sessVars.StmtCtx.StmtHints.ResourceGroup
// if we are in a txn, should update the txn resource name to let the txn
// commit with the hint resource group.
if txn, err := sctx.Txn(false); err == nil && txn != nil && txn.Valid() {
kv.SetTxnResourceGroup(txn, sessVars.StmtCtx.ResourceGroupName)
}
} else {
err := plannererrors.ErrSpecificAccessDenied.GenWithStackByArgs("SUPER or RESOURCE_GROUP_ADMIN or RESOURCE_GROUP_USER")
sessVars.StmtCtx.AppendWarning(err)
}
} else {
err := infoschema.ErrResourceGroupSupportDisabled
Expand Down
3 changes: 2 additions & 1 deletion pkg/privilege/privileges/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -1125,7 +1125,7 @@ func (p *MySQLPrivilege) HasExplicitlyGrantedDynamicPrivilege(activeRoles []*aut
}

// RequestDynamicVerification checks all roles for a specific DYNAMIC privilege.
func (p *MySQLPrivilege) RequestDynamicVerification(activeRoles []*auth.RoleIdentity, user, host, privName string, withGrant bool) bool {
func (p *MySQLPrivilege) RequestDynamicVerification(activeRoles []*auth.RoleIdentity, user, host string, privName string, withGrant bool) bool {
privName = strings.ToUpper(privName)
if p.HasExplicitlyGrantedDynamicPrivilege(activeRoles, user, host, privName, withGrant) {
return true
Expand All @@ -1135,6 +1135,7 @@ func (p *MySQLPrivilege) RequestDynamicVerification(activeRoles []*auth.RoleIden
if sem.IsEnabled() && sem.IsRestrictedPrivilege(privName) {
return false
}

// For compatibility reasons, the SUPER privilege also has all DYNAMIC privileges granted to it (dynamic privs are a super replacement)
// This may be changed in future, but will require a bootstrap task to assign all dynamic privileges
// to users with SUPER, otherwise tasks such as BACKUP and ROLE_ADMIN will start to fail.
Expand Down
1 change: 1 addition & 0 deletions pkg/privilege/privileges/privileges.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ var dynamicPrivs = []string{
"RESTRICTED_CONNECTION_ADMIN", // Can not be killed by PROCESS/CONNECTION_ADMIN privilege
"RESTRICTED_REPLICA_WRITER_ADMIN", // Can write to the sever even when tidb_restriced_read_only is turned on.
"RESOURCE_GROUP_ADMIN", // Create/Drop/Alter RESOURCE GROUP
"RESOURCE_GROUP_USER", // Can change the resource group of current session.
}
var dynamicPrivLock sync.Mutex
var defaultTokenLife = 15 * time.Minute
Expand Down
1 change: 1 addition & 0 deletions tests/integrationtest/r/executor/executor.result
Original file line number Diff line number Diff line change
Expand Up @@ -3220,6 +3220,7 @@ RESTRICTED_USER_ADMIN Server Admin
RESTRICTED_CONNECTION_ADMIN Server Admin
RESTRICTED_REPLICA_WRITER_ADMIN Server Admin
RESOURCE_GROUP_ADMIN Server Admin
RESOURCE_GROUP_USER Server Admin
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t InnoDB 10 Compact 0 0 0 0 0 0 NULL 0 NULL NULL utf8mb4_bin
Expand Down
34 changes: 31 additions & 3 deletions tests/integrationtest/r/privilege/privileges.result
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,52 @@ drop placement policy if exists x;
create placement policy x PRIMARY_REGION="cn-east-1" REGIONS="cn-east-1";
drop placement policy if exists x;
drop user placement_user;
CREATE USER resource_group_admin;
CREATE USER resource_group_user;
set @@global.tidb_enable_resource_control = 1;
CREATE RESOURCE GROUP test RU_PER_SEC = 666;
Error 1227 (42000): Access denied; you need (at least one of) the SUPER or RESOURCE_GROUP_ADMIN privilege(s) for this operation
GRANT RESOURCE_GROUP_ADMIN ON *.* TO resource_group_user;
CREATE DATABASE IF NOT EXISTS test_rc;
CREATE TABLE test_rc.t(id int);
INSERT INTO test_rc.t VALUES (1);
GRANT RESOURCE_GROUP_ADMIN ON *.* TO resource_group_admin;
SHOW GRANTS FOR resource_group_admin;
Grants for resource_group_admin@%
GRANT USAGE ON *.* TO 'resource_group_admin'@'%'
GRANT RESOURCE_GROUP_ADMIN ON *.* TO 'resource_group_admin'@'%'
GRANT RESOURCE_GROUP_USER ON *.* TO resource_group_user;
SHOW GRANTS FOR resource_group_user;
Grants for resource_group_user@%
GRANT USAGE ON *.* TO 'resource_group_user'@'%'
GRANT RESOURCE_GROUP_ADMIN ON *.* TO 'resource_group_user'@'%'
GRANT RESOURCE_GROUP_USER ON *.* TO 'resource_group_user'@'%'
GRANT SELECT on test_rc.* TO resource_group_admin;
GRANT SELECT on test_rc.* TO resource_group_user;
CREATE RESOURCE GROUP test RU_PER_SEC = 666;
CREATE RESOURCE GROUP test2 RU_PER_SEC = 999;
ALTER RESOURCE GROUP test2 RU_PER_SEC = 1000;
DROP RESOURCE GROUP test2;
REVOKE RESOURCE_GROUP_ADMIN ON *.* FROM resource_group_user;
SELECT /*+ RESOURCE_GROUP(test) */ * from test_rc.t;
id
1
SET RESOURCE GROUP test;
SELECT /*+ RESOURCE_GROUP(test) */ * from test_rc.t;
id
1
SET RESOURCE GROUP test;
REVOKE RESOURCE_GROUP_ADMIN ON *.* FROM resource_group_admin;
REVOKE RESOURCE_GROUP_USER ON *.* FROM resource_group_user;
ALTER RESOURCE GROUP test RU_PER_SEC = 667;
Error 1227 (42000): Access denied; you need (at least one of) the SUPER or RESOURCE_GROUP_ADMIN privilege(s) for this operation
DROP RESOURCE GROUP test;
Error 1227 (42000): Access denied; you need (at least one of) the SUPER or RESOURCE_GROUP_ADMIN privilege(s) for this operation
SET RESOURCE GROUP test;
Error 1227 (42000): Access denied; you need (at least one of) the SUPER or RESOURCE_GROUP_ADMIN or RESOURCE_GROUP_USER privilege(s) for this operation
SELECT /*+ RESOURCE_GROUP(test) */ * from test_rc.t;
id
1
REVOKE SELECT on test_rc.* FROM resource_group_admin;
REVOKE SELECT on test_rc.* FROM resource_group_user;
DROP DATABASE test_rc;
CREATE SCHEMA IF NOT EXISTS privilege__privileges;
USE privilege__privileges;
CREATE TABLE reftest (a int);
Expand Down
35 changes: 30 additions & 5 deletions tests/integrationtest/t/privilege/privileges.test
Original file line number Diff line number Diff line change
Expand Up @@ -85,35 +85,60 @@ connection default;
drop user placement_user;

# TestResourceGroupAdminDynamicPriv
CREATE USER resource_group_admin;
CREATE USER resource_group_user;
# This should be the default value in the future, so we do not need to set if for testing?
set @@global.tidb_enable_resource_control = 1;

connect (resource_group_admin,localhost,resource_group_admin,,);
connect (resource_group_user,localhost,resource_group_user,,);
connection resource_group_user;

connection resource_group_admin;
--error 1227
CREATE RESOURCE GROUP test RU_PER_SEC = 666;

connection default;
GRANT RESOURCE_GROUP_ADMIN ON *.* TO resource_group_user;
CREATE DATABASE IF NOT EXISTS test_rc;
CREATE TABLE test_rc.t(id int);
INSERT INTO test_rc.t VALUES (1);
GRANT RESOURCE_GROUP_ADMIN ON *.* TO resource_group_admin;
SHOW GRANTS FOR resource_group_admin;
GRANT RESOURCE_GROUP_USER ON *.* TO resource_group_user;
SHOW GRANTS FOR resource_group_user;
GRANT SELECT on test_rc.* TO resource_group_admin;
GRANT SELECT on test_rc.* TO resource_group_user;

connection resource_group_user;
connection resource_group_admin;
CREATE RESOURCE GROUP test RU_PER_SEC = 666;
CREATE RESOURCE GROUP test2 RU_PER_SEC = 999;
ALTER RESOURCE GROUP test2 RU_PER_SEC = 1000;
DROP RESOURCE GROUP test2;
SELECT /*+ RESOURCE_GROUP(test) */ * from test_rc.t;
SET RESOURCE GROUP test;

connection resource_group_user;
SELECT /*+ RESOURCE_GROUP(test) */ * from test_rc.t;
SET RESOURCE GROUP test;

connection default;
REVOKE RESOURCE_GROUP_ADMIN ON *.* FROM resource_group_user;
REVOKE RESOURCE_GROUP_ADMIN ON *.* FROM resource_group_admin;
REVOKE RESOURCE_GROUP_USER ON *.* FROM resource_group_user;

connection resource_group_user;
connection resource_group_admin;
--error 1227
ALTER RESOURCE GROUP test RU_PER_SEC = 667;
--error 1227
DROP RESOURCE GROUP test;
--error 1227
SET RESOURCE GROUP test;
SELECT /*+ RESOURCE_GROUP(test) */ * from test_rc.t;

disconnect resource_group_admin;
disconnect resource_group_user;
connection default;
REVOKE SELECT on test_rc.* FROM resource_group_admin;
REVOKE SELECT on test_rc.* FROM resource_group_user;
DROP DATABASE test_rc;

# TestGrantReferences
CREATE SCHEMA IF NOT EXISTS privilege__privileges;
Expand Down

0 comments on commit 29fc940

Please sign in to comment.