diff --git a/pkg/frontend/authenticate2.go b/pkg/frontend/authenticate2.go index b4f1c3c9b32f2..c371364b18547 100644 --- a/pkg/frontend/authenticate2.go +++ b/pkg/frontend/authenticate2.go @@ -331,37 +331,70 @@ func canWriteProtectedDatabase(ses *Session) bool { } func normalizeProtectedDatabaseName(ses *Session, dbName string) string { + dbName = strings.TrimSpace(dbName) + if protectedDatabaseNamesAreLowerCased(ses) { + dbName = strings.ToLower(dbName) + } + return dbName +} + +func resolveProtectedDatabaseRuntimeTarget(ses *Session, dbName string) string { dbName = strings.TrimSpace(dbName) if dbName == "" && ses != nil { dbName = ses.GetDatabaseName() } + if protectedDatabaseNamesAreLowerCased(ses) { + dbName = strings.ToLower(dbName) + } return dbName } -func getProtectedDatabaseSet(ses *Session) map[string]struct{} { +func protectedDatabaseNamesAreLowerCased(ses *Session) bool { if ses == nil { - return nil + return false } - value, err := ses.GetGlobalSysVar(ProtectedDatabases) + value, err := ses.GetSessionSysVar("lower_case_table_names") if err != nil { - return nil + return true } - raw, ok := value.(string) - if !ok || strings.TrimSpace(raw) == "" { + lowerCaseTableNames, ok := value.(int64) + return ok && lowerCaseTableNames != 0 +} + +func protectedDatabaseSetFromString(ses *Session, raw string) map[string]struct{} { + if strings.TrimSpace(raw) == "" { return nil } protected := make(map[string]struct{}) for _, part := range strings.Split(raw, ",") { - dbName := strings.TrimSpace(part) + dbName := normalizeProtectedDatabaseName(ses, part) if dbName != "" { protected[dbName] = struct{}{} } } + if len(protected) == 0 { + return nil + } return protected } +func getProtectedDatabaseSet(ses *Session) map[string]struct{} { + if ses == nil { + return nil + } + value, err := ses.GetGlobalSysVar(ProtectedDatabases) + if err != nil { + return nil + } + raw, ok := value.(string) + if !ok || strings.TrimSpace(raw) == "" { + return nil + } + return protectedDatabaseSetFromString(ses, raw) +} + func isProtectedDatabase(ses *Session, dbName string) bool { - dbName = normalizeProtectedDatabaseName(ses, dbName) + dbName = resolveProtectedDatabaseRuntimeTarget(ses, dbName) if dbName == "" { return false } @@ -393,7 +426,7 @@ func checkProtectedDatabaseWriteWithSet(ctx context.Context, ses *Session, prote return true } for _, dbName := range dbNames { - dbName = normalizeProtectedDatabaseName(ses, dbName) + dbName = resolveProtectedDatabaseRuntimeTarget(ses, dbName) if dbName == "" { continue } diff --git a/pkg/frontend/protected_database_test.go b/pkg/frontend/protected_database_test.go index 4fd1e2c52e5e6..ff494ec6eafda 100644 --- a/pkg/frontend/protected_database_test.go +++ b/pkg/frontend/protected_database_test.go @@ -18,6 +18,8 @@ import ( "context" "testing" + "github.com/matrixorigin/matrixone/pkg/sql/parsers" + "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect" "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" "github.com/stretchr/testify/require" ) @@ -30,6 +32,37 @@ func protectedTargetsFromStatement(stmt tree.Statement) []string { return determinePrivilegeSetOfStatement(stmt).writeDatabaseTargets } +func newProtectedDatabaseTestSessionWithCurrentDB(dbName string) *Session { + proto := &MysqlProtocolImpl{} + ses := &Session{feSessionImpl: feSessionImpl{respr: NewMysqlResp(proto)}} + ses.respr.SetStr(DBNAME, dbName) + return ses +} + +func TestProtectedDatabaseSetFromString(t *testing.T) { + require.Nil(t, protectedDatabaseSetFromString(nil, "")) + require.Nil(t, protectedDatabaseSetFromString(nil, " , , ")) + require.Equal(t, map[string]struct{}{"db1": {}, "CamelDB": {}}, protectedDatabaseSetFromString(nil, " db1, CamelDB ")) + require.Equal(t, map[string]struct{}{"db1": {}, "cameldb": {}}, protectedDatabaseSetFromString(&Session{}, " db1, CamelDB ")) + + ses := newProtectedDatabaseTestSessionWithCurrentDB("current_db") + require.Equal(t, "", normalizeProtectedDatabaseName(ses, "")) + require.Nil(t, protectedDatabaseSetFromString(ses, ",")) + require.Equal(t, map[string]struct{}{"db1": {}}, protectedDatabaseSetFromString(ses, "db1,")) +} + +func TestProtectedDatabaseWriteTargetsFromDataBranchKeepsPrivileges(t *testing.T) { + tableStmt := &tree.DataBranchCreateTable{} + tableStmt.CreateTable.Table = testTableName("dst_db", "dst_tbl") + tablePriv := determinePrivilegeSetOfStatement(tableStmt) + require.Equal(t, []string{"dst_db"}, tablePriv.writeDatabaseTargets) + + databaseStmt := tree.NewDataBranchCreateDatabase() + databaseStmt.DstDatabase = tree.Identifier("dst_db") + databasePriv := determinePrivilegeSetOfStatement(databaseStmt) + require.Equal(t, []string{"dst_db"}, databasePriv.writeDatabaseTargets) +} + func TestProtectedDatabaseWriteTargetsFromClone(t *testing.T) { cloneTable := tree.NewCloneTable() cloneTable.CreateTable.Table = testTableName("dst_db", "dst_tbl") @@ -78,23 +111,71 @@ func TestPrivilegeTipWritesDatabase(t *testing.T) { require.True(t, privilegeTipWritesDatabase(privilegeTips{typ: PrivilegeTypeDelete})) } -func TestProtectedDatabaseNameKeepsOriginalCase(t *testing.T) { - protectedDatabases := map[string]struct{}{"CamelDB": {}} +func TestProtectedDatabaseNameFollowsLowerCaseTableNames(t *testing.T) { + ses := &Session{} + protectedDatabases := protectedDatabaseSetFromString(ses, "CamelDB") + + require.False(t, checkProtectedDatabaseWriteWithSet(context.Background(), ses, protectedDatabases, "CamelDB")) + require.False(t, checkProtectedDatabaseWriteWithSet(context.Background(), ses, protectedDatabases, "cameldb")) - require.False(t, checkProtectedDatabaseWriteWithSet(context.Background(), nil, protectedDatabases, "CamelDB")) - require.True(t, checkProtectedDatabaseWriteWithSet(context.Background(), nil, protectedDatabases, "camedb")) + caseSensitiveSes := &Session{ + feSessionImpl: feSessionImpl{ + sesSysVars: &SystemVariables{mp: map[string]interface{}{"lower_case_table_names": int64(0)}}, + }, + } + caseSensitiveProtectedDatabases := protectedDatabaseSetFromString(caseSensitiveSes, "CamelDB") + require.False(t, checkProtectedDatabaseWriteWithSet(context.Background(), caseSensitiveSes, caseSensitiveProtectedDatabases, "CamelDB")) + require.True(t, checkProtectedDatabaseWriteWithSet(context.Background(), caseSensitiveSes, caseSensitiveProtectedDatabases, "cameldb")) + + caseInsensitivePreserveNameSes := &Session{ + feSessionImpl: feSessionImpl{ + sesSysVars: &SystemVariables{mp: map[string]interface{}{"lower_case_table_names": int64(2)}}, + }, + } + caseInsensitivePreserveNameProtectedDatabases := protectedDatabaseSetFromString(caseInsensitivePreserveNameSes, "CamelDB") + require.False(t, checkProtectedDatabaseWriteWithSet(context.Background(), caseInsensitivePreserveNameSes, caseInsensitivePreserveNameProtectedDatabases, "CamelDB")) + require.False(t, checkProtectedDatabaseWriteWithSet(context.Background(), caseInsensitivePreserveNameSes, caseInsensitivePreserveNameProtectedDatabases, "cameldb")) } func TestCheckProtectedDatabaseWriteWithSet(t *testing.T) { ctx := context.Background() - protectedDatabases := map[string]struct{}{"protected_db": {}, "CamelDB": {}} + ses := &Session{} + protectedDatabases := protectedDatabaseSetFromString(ses, "protected_db,CamelDB") require.True(t, checkProtectedDatabaseWriteWithSet(ctx, nil, nil, "protected_db")) require.True(t, checkProtectedDatabaseWriteWithSet(ctx, nil, protectedDatabases)) require.True(t, checkProtectedDatabaseWriteWithSet(ctx, nil, protectedDatabases, "normal_db")) - require.False(t, checkProtectedDatabaseWriteWithSet(ctx, nil, protectedDatabases, "normal_db", "protected_db")) - require.False(t, checkProtectedDatabaseWriteWithSet(ctx, nil, protectedDatabases, " CamelDB ")) - require.True(t, checkProtectedDatabaseWriteWithSet(ctx, nil, protectedDatabases, "cameldb")) + require.False(t, checkProtectedDatabaseWriteWithSet(ctx, ses, protectedDatabases, "normal_db", "protected_db")) + require.False(t, checkProtectedDatabaseWriteWithSet(ctx, ses, protectedDatabases, " CamelDB ")) + require.False(t, checkProtectedDatabaseWriteWithSet(ctx, ses, protectedDatabases, "cameldb")) +} + +func TestCheckProtectedDatabaseWriteWithSetUsesCurrentDatabaseForEmptyTarget(t *testing.T) { + ctx := context.Background() + ses := newProtectedDatabaseTestSessionWithCurrentDB("protected_db") + protectedDatabases := protectedDatabaseSetFromString(ses, "protected_db") + + require.False(t, checkProtectedDatabaseWriteWithSet(ctx, ses, protectedDatabases, "")) +} + +func TestUnqualifiedProtectedDatabaseWritesUseCurrentDatabase(t *testing.T) { + ctx := context.Background() + ses := newProtectedDatabaseTestSessionWithCurrentDB("protected_db") + protectedDatabases := protectedDatabaseSetFromString(ses, "protected_db") + + testCases := []string{ + "create table t (a int)", + "drop table t", + "create table t as select 1", + } + + for _, sql := range testCases { + t.Run(sql, func(t *testing.T) { + stmt, err := parsers.ParseOne(ctx, dialect.MYSQL, sql, 1) + require.NoError(t, err) + require.False(t, checkProtectedDatabaseWriteWithSet(ctx, ses, protectedDatabases, protectedTargetsFromStatement(stmt)...)) + }) + } } func TestCanWriteProtectedDatabase(t *testing.T) { diff --git a/pkg/frontend/types.go b/pkg/frontend/types.go index a228ac8d04f3e..b8be313c1a0a7 100644 --- a/pkg/frontend/types.go +++ b/pkg/frontend/types.go @@ -1370,9 +1370,9 @@ func (ses *Session) SetGlobalSysVar(ctx context.Context, name string, val interf } if name == ProtectedDatabases { - if newValue, ok := val.(string); ok && strings.TrimSpace(newValue) == "" { + if newValue, ok := val.(string); ok && len(protectedDatabaseSetFromString(ses, newValue)) == 0 { oldValue, _ := ses.GetGlobalSysVar(name) - if oldString, ok := oldValue.(string); ok && strings.TrimSpace(oldString) != "" { + if oldString, ok := oldValue.(string); ok && len(protectedDatabaseSetFromString(ses, oldString)) != 0 { return moerr.NewInternalErrorNoCtx("protected_databases cannot be cleared directly") } } diff --git a/test/distributed/cases/tenant/privilege/protected_database.result b/test/distributed/cases/tenant/privilege/protected_database.result index c05018bb6c966..881d0d71f3678 100644 --- a/test/distributed/cases/tenant/privilege/protected_database.result +++ b/test/distributed/cases/tenant/privilege/protected_database.result @@ -1,47 +1,210 @@ set global enable_privilege_cache = off; drop database if exists protected_bvt_sys; -set global protected_databases = 'protected_bvt_sys'; +drop database if exists protected_bvt_sys_normal; +drop database if exists protected_bvt_sys_new; +drop user if exists protected_bvt_sys_user; +drop role if exists protected_bvt_sys_writer; +set global protected_databases = 'protected_bvt_sys,protected_bvt_sys_new'; +select @@global.protected_databases; +➤ @@protected_databases[12,0,0] 𝄀 +protected_bvt_sys,protected_bvt_sys_new create database protected_bvt_sys; -create table protected_bvt_sys.t1(a int); -drop table protected_bvt_sys.t1; +create table protected_bvt_sys.t1(a int primary key, b int); +insert into protected_bvt_sys.t1 values(1, 1); +create role protected_bvt_sys_writer; +grant create database,drop database on account * to protected_bvt_sys_writer; +grant all on database protected_bvt_sys to protected_bvt_sys_writer; +grant ownership on database protected_bvt_sys to protected_bvt_sys_writer; +grant all on table protected_bvt_sys.* to protected_bvt_sys_writer with grant option; +grant ownership on table protected_bvt_sys.t1 to protected_bvt_sys_writer; +create user protected_bvt_sys_user identified by '111' default role protected_bvt_sys_writer; +set enable_privilege_cache = off; +select a from protected_bvt_sys.t1; +➤ a[4,32,0] 𝄀 +1 +create database protected_bvt_sys_normal; +drop database protected_bvt_sys_normal; +set global protected_databases = 'protected_bvt_sys_user_try'; +internal error: do not have privilege to execute the statement +create database protected_bvt_sys_new; +internal error: do not have privilege to execute the statement +create table protected_bvt_sys.t2(a int); +internal error: do not have privilege to execute the statement +insert into protected_bvt_sys.t1 values(2, 2); +internal error: do not have privilege to execute the statement +drop database protected_bvt_sys; +internal error: do not have privilege to execute the statement +drop user if exists protected_bvt_sys_user; +drop role if exists protected_bvt_sys_writer; drop database protected_bvt_sys; set global protected_databases = 'protected_bvt_unused'; drop account if exists protected_bvt_acc; create account protected_bvt_acc ADMIN_NAME 'admin' IDENTIFIED BY '111'; +set enable_privilege_cache = off; set global protected_databases = 'protected_bvt_db,protected_bvt_new,protected_bvt_clone,CamelDB'; set global protected_databases = ''; internal error: protected_databases cannot be cleared directly +set global protected_databases = ','; +internal error: protected_databases cannot be cleared directly +select @@global.protected_databases; +➤ @@protected_databases[12,0,0] 𝄀 +protected_bvt_db,protected_bvt_new,protected_bvt_clone,CamelDB +set global protected_databases = 'protected_bvt_db,protected_bvt_new,protected_bvt_clone,CamelDB'; create database protected_bvt_db; -create table protected_bvt_db.t1(a int); -insert into protected_bvt_db.t1 values(1); +create database protected_bvt_later; +create table protected_bvt_db.t1(a int primary key, b int); +insert into protected_bvt_db.t1 values(1, 1); +create index protected_bvt_idx on protected_bvt_db.t1(b); create view protected_bvt_db.v1 as select * from protected_bvt_db.t1; +create table protected_bvt_db.pk_single(id int primary key, v varchar(10)); +insert into protected_bvt_db.pk_single values(1, 'a'); +create table protected_bvt_db.pk_compound(k1 int, k2 int, v varchar(10), primary key(k1, k2)); +insert into protected_bvt_db.pk_compound values(1, 1, 'a'); +create table protected_bvt_db.auto_pk(id int auto_increment primary key, v varchar(10)); +insert into protected_bvt_db.auto_pk(v) values('a'); +create table protected_bvt_db.uk_table(id int primary key, email varchar(20), unique key uk_email(email), key idx_email(email)); +insert into protected_bvt_db.uk_table values(1, 'a@b'); +create table protected_bvt_db.part_hash(id int, v varchar(10)) partition by hash(id) partitions 4; +insert into protected_bvt_db.part_hash values(1, 'a'); +create table protected_bvt_db.part_range(id int, v varchar(10)) partition by range(id)( +partition p0 values less than (10), +partition p1 values less than (maxvalue) +); +insert into protected_bvt_db.part_range values(1, 'a'); +create table protected_bvt_db.fk_parent(id int primary key, name varchar(10)); +create table protected_bvt_db.fk_child(id int primary key, parent_id int, constraint fk_child_parent foreign key(parent_id) references protected_bvt_db.fk_parent(id)); +insert into protected_bvt_db.fk_parent values(1, 'p1'); +insert into protected_bvt_db.fk_child values(1, 1); +create table protected_bvt_db.fk_self(id int primary key, parent_id int, constraint fk_self_parent foreign key(parent_id) references protected_bvt_db.fk_self(id)); +create table protected_bvt_later.t1(a int); +insert into protected_bvt_later.t1 values(10); create role protected_bvt_writer; grant create database,drop database on account * to protected_bvt_writer; grant all on database protected_bvt_db to protected_bvt_writer; -grant all on table protected_bvt_db.* to protected_bvt_writer; +grant ownership on database protected_bvt_db to protected_bvt_writer; +grant all on table protected_bvt_db.* to protected_bvt_writer with grant option; +grant ownership on table protected_bvt_db.t1 to protected_bvt_writer; +grant all on database protected_bvt_later to protected_bvt_writer; +grant all on table protected_bvt_later.* to protected_bvt_writer; +grant connect on account * to protected_bvt_writer; create user protected_bvt_user identified by '111' default role protected_bvt_writer; -select * from protected_bvt_db.t1; +set enable_privilege_cache = off; +set global protected_databases = 'protected_bvt_db,protected_bvt_new,protected_bvt_clone,CamelDB,protected_bvt_later'; +set enable_privilege_cache = off; +select @@global.protected_databases; +➤ @@protected_databases[12,0,0] 𝄀 +protected_bvt_db,protected_bvt_new,protected_bvt_clone,CamelDB,protected_bvt_later +select database(); +➤ database()[12,-1,0] 𝄀 + +use protected_bvt_later; +select a from t1; +➤ a[4,32,0] 𝄀 +10 +set enable_privilege_cache = off; +use protected_bvt_db; +show tables; +➤ Tables_in_protected_bvt_db[12,-1,0] 𝄀 +auto_pk 𝄀 +fk_child 𝄀 +fk_parent 𝄀 +fk_self 𝄀 +part_hash 𝄀 +part_range 𝄀 +pk_compound 𝄀 +pk_single 𝄀 +t1 𝄀 +uk_table 𝄀 +v1 +select a from t1; +➤ a[4,32,0] 𝄀 +1 +select a from protected_bvt_db.t1; +➤ a[4,32,0] 𝄀 +1 +select a from protected_bvt_db.v1; ➤ a[4,32,0] 𝄀 1 +set enable_privilege_cache = off; +create sequence protected_bvt_db.s1; +create function protected_bvt_db.f1(a int) returns int language sql as '$1 + 1'; +create procedure protected_bvt_db.p1() 'begin select 1; end'; +set enable_privilege_cache = off; create database protected_bvt_normal; drop database protected_bvt_normal; create database protected_bvt_new; internal error: do not have privilege to execute the statement create table protected_bvt_db.t2(a int); internal error: do not have privilege to execute the statement +create external table protected_bvt_db.ext1(a int) infile{"filepath"='$resources/external_table_file/extable.csv'} fields terminated by ',' lines terminated by '\n'; +internal error: do not have privilege to execute the statement +create dynamic table protected_bvt_db.dt1 as select * from protected_bvt_db.t1; +internal error: do not have privilege to execute the statement create view protected_bvt_db.v2 as select * from protected_bvt_db.t1; internal error: do not have privilege to execute the statement +alter view protected_bvt_db.v1 as select a from protected_bvt_db.t1; +internal error: do not have privilege to execute the statement drop view protected_bvt_db.v1; internal error: do not have privilege to execute the statement -alter table protected_bvt_db.t1 add column b int; +alter database protected_bvt_db set mysql_compatibility_mode = '0.8.0'; +internal error: do not have privilege to execute the statement +alter table protected_bvt_db.t1 add column c int; internal error: do not have privilege to execute the statement rename table protected_bvt_db.t1 to protected_bvt_db.t2; internal error: do not have privilege to execute the statement +create index protected_bvt_idx2 on protected_bvt_db.t1(b); +internal error: do not have privilege to execute the statement +drop index protected_bvt_idx on protected_bvt_db.t1; +internal error: do not have privilege to execute the statement create table protected_bvt_db.t_clone clone protected_bvt_db.t1; internal error: do not have privilege to execute the statement create database protected_bvt_clone clone protected_bvt_db; internal error: do not have privilege to execute the statement -insert into protected_bvt_db.t1 values(2); +create sequence protected_bvt_db.s2; +internal error: do not have privilege to execute the statement +alter sequence protected_bvt_db.s1 increment by 2; +internal error: do not have privilege to execute the statement +drop sequence protected_bvt_db.s1; +internal error: do not have privilege to execute the statement +create function protected_bvt_db.f2(a int) returns int language sql as '$1 + 1'; +internal error: do not have privilege to execute the statement +drop function protected_bvt_db.f1(int); +internal error: do not have privilege to execute the statement +create procedure protected_bvt_db.p2() 'begin select 1; end'; +internal error: do not have privilege to execute the statement +drop procedure protected_bvt_db.p1; +internal error: do not have privilege to execute the statement +create connector for protected_bvt_db.conn1 with ("type"='kafka', "topic"='t1', "partition"='0', "value"='json', "bootstrap.servers"='127.0.0.1:9092'); +internal error: do not have privilege to execute the statement +insert into protected_bvt_db.t1 values(2, 2); +internal error: do not have privilege to execute the statement +replace into protected_bvt_db.t1 values(2, 2); +internal error: do not have privilege to execute the statement +update protected_bvt_db.t1 set a = 3 where a = 1; +internal error: do not have privilege to execute the statement +delete from protected_bvt_db.t1 where a = 1; +internal error: do not have privilege to execute the statement +insert into protected_bvt_db.pk_single values(2, 'b'); +internal error: do not have privilege to execute the statement +update protected_bvt_db.pk_compound set v = 'b' where k1 = 1 and k2 = 1; +internal error: do not have privilege to execute the statement +insert into protected_bvt_db.auto_pk(v) values('b'); +internal error: do not have privilege to execute the statement +insert into protected_bvt_db.uk_table values(2, 'c@d'); +internal error: do not have privilege to execute the statement +insert into protected_bvt_db.part_hash values(2, 'b'); +internal error: do not have privilege to execute the statement +truncate table protected_bvt_db.part_range; +internal error: do not have privilege to execute the statement +insert into protected_bvt_db.fk_child values(2, 1); +internal error: do not have privilege to execute the statement +delete from protected_bvt_db.fk_parent where id = 1; +internal error: do not have privilege to execute the statement +alter table protected_bvt_db.fk_child drop foreign key fk_child_parent; +internal error: do not have privilege to execute the statement +drop table protected_bvt_db.fk_child; +internal error: do not have privilege to execute the statement +insert into protected_bvt_db.fk_self values(2, 1); internal error: do not have privilege to execute the statement truncate table protected_bvt_db.t1; internal error: do not have privilege to execute the statement @@ -49,11 +212,53 @@ drop table protected_bvt_db.t1; internal error: do not have privilege to execute the statement drop database protected_bvt_db; internal error: do not have privilege to execute the statement +set enable_privilege_cache = off; +select @@global.protected_databases; +➤ @@protected_databases[12,0,0] 𝄀 +protected_bvt_db,protected_bvt_new,protected_bvt_clone,CamelDB,protected_bvt_later +select database(); +➤ database()[12,-1,0] 𝄀 +protected_bvt_later +create table t2(a int); +internal error: do not have privilege to execute the statement +drop table t1; +internal error: do not have privilege to execute the statement +create table t_ctas as select * from t1; +internal error: do not have privilege to execute the statement +set enable_privilege_cache = off; +insert into protected_bvt_later.t1 values(11); +internal error: do not have privilege to execute the statement +drop database protected_bvt_later; +internal error: do not have privilege to execute the statement +create database `CamelDB`; +internal error: do not have privilege to execute the statement create database `cameldb`; -drop database `cameldb`; +internal error: do not have privilege to execute the statement +drop database if exists `cameldb`; +internal error: do not have privilege to execute the statement +set enable_privilege_cache = off; +set global lower_case_table_names = 0; +set global protected_databases = 'ProtectedCaseDB'; +set enable_privilege_cache = off; +select @@lower_case_table_names; +➤ @@lower_case_table_names[12,0,0] 𝄀 +1 +create database `protectedcasedb`; +internal error: do not have privilege to execute the statement +drop database `protectedcasedb`; +internal error: do not have privilege to execute the statement +create database `ProtectedCaseDB`; +internal error: do not have privilege to execute the statement +drop database `ProtectedCaseDB`; +internal error: do not have privilege to execute the statement +set enable_privilege_cache = off; +set global lower_case_table_names = 1; drop user if exists protected_bvt_user; drop role if exists protected_bvt_writer; drop database protected_bvt_db; +drop database protected_bvt_later; +drop database if exists `CamelDB`; set global protected_databases = 'protected_bvt_unused'; +set global lower_case_table_names = 1; drop account protected_bvt_acc; set global enable_privilege_cache = on; diff --git a/test/distributed/cases/tenant/privilege/protected_database.sql b/test/distributed/cases/tenant/privilege/protected_database.sql index 8fca84b95aca2..cc0a3debfe514 100644 --- a/test/distributed/cases/tenant/privilege/protected_database.sql +++ b/test/distributed/cases/tenant/privilege/protected_database.sql @@ -1,10 +1,35 @@ set global enable_privilege_cache = off; drop database if exists protected_bvt_sys; -set global protected_databases = 'protected_bvt_sys'; +drop database if exists protected_bvt_sys_normal; +drop database if exists protected_bvt_sys_new; +drop user if exists protected_bvt_sys_user; +drop role if exists protected_bvt_sys_writer; +set global protected_databases = 'protected_bvt_sys,protected_bvt_sys_new'; +select @@global.protected_databases; create database protected_bvt_sys; -create table protected_bvt_sys.t1(a int); -drop table protected_bvt_sys.t1; +create table protected_bvt_sys.t1(a int primary key, b int); +insert into protected_bvt_sys.t1 values(1, 1); +create role protected_bvt_sys_writer; +grant create database,drop database on account * to protected_bvt_sys_writer; +grant all on database protected_bvt_sys to protected_bvt_sys_writer; +grant ownership on database protected_bvt_sys to protected_bvt_sys_writer; +grant all on table protected_bvt_sys.* to protected_bvt_sys_writer with grant option; +grant ownership on table protected_bvt_sys.t1 to protected_bvt_sys_writer; +create user protected_bvt_sys_user identified by '111' default role protected_bvt_sys_writer; +-- @session:id=3&user=sys:protected_bvt_sys_user:protected_bvt_sys_writer&password=111 +set enable_privilege_cache = off; +select a from protected_bvt_sys.t1; +create database protected_bvt_sys_normal; +drop database protected_bvt_sys_normal; +set global protected_databases = 'protected_bvt_sys_user_try'; +create database protected_bvt_sys_new; +create table protected_bvt_sys.t2(a int); +insert into protected_bvt_sys.t1 values(2, 2); +drop database protected_bvt_sys; +-- @session +drop user if exists protected_bvt_sys_user; +drop role if exists protected_bvt_sys_writer; drop database protected_bvt_sys; set global protected_databases = 'protected_bvt_unused'; @@ -12,45 +37,170 @@ drop account if exists protected_bvt_acc; create account protected_bvt_acc ADMIN_NAME 'admin' IDENTIFIED BY '111'; -- @session:id=1&user=protected_bvt_acc:admin&password=111 +set enable_privilege_cache = off; set global protected_databases = 'protected_bvt_db,protected_bvt_new,protected_bvt_clone,CamelDB'; set global protected_databases = ''; +set global protected_databases = ','; +select @@global.protected_databases; +set global protected_databases = 'protected_bvt_db,protected_bvt_new,protected_bvt_clone,CamelDB'; create database protected_bvt_db; -create table protected_bvt_db.t1(a int); -insert into protected_bvt_db.t1 values(1); +create database protected_bvt_later; +create table protected_bvt_db.t1(a int primary key, b int); +insert into protected_bvt_db.t1 values(1, 1); +create index protected_bvt_idx on protected_bvt_db.t1(b); create view protected_bvt_db.v1 as select * from protected_bvt_db.t1; +create table protected_bvt_db.pk_single(id int primary key, v varchar(10)); +insert into protected_bvt_db.pk_single values(1, 'a'); +create table protected_bvt_db.pk_compound(k1 int, k2 int, v varchar(10), primary key(k1, k2)); +insert into protected_bvt_db.pk_compound values(1, 1, 'a'); +create table protected_bvt_db.auto_pk(id int auto_increment primary key, v varchar(10)); +insert into protected_bvt_db.auto_pk(v) values('a'); +create table protected_bvt_db.uk_table(id int primary key, email varchar(20), unique key uk_email(email), key idx_email(email)); +insert into protected_bvt_db.uk_table values(1, 'a@b'); +create table protected_bvt_db.part_hash(id int, v varchar(10)) partition by hash(id) partitions 4; +insert into protected_bvt_db.part_hash values(1, 'a'); +create table protected_bvt_db.part_range(id int, v varchar(10)) partition by range(id)( + partition p0 values less than (10), + partition p1 values less than (maxvalue) +); +insert into protected_bvt_db.part_range values(1, 'a'); +create table protected_bvt_db.fk_parent(id int primary key, name varchar(10)); +create table protected_bvt_db.fk_child(id int primary key, parent_id int, constraint fk_child_parent foreign key(parent_id) references protected_bvt_db.fk_parent(id)); +insert into protected_bvt_db.fk_parent values(1, 'p1'); +insert into protected_bvt_db.fk_child values(1, 1); +create table protected_bvt_db.fk_self(id int primary key, parent_id int, constraint fk_self_parent foreign key(parent_id) references protected_bvt_db.fk_self(id)); +create table protected_bvt_later.t1(a int); +insert into protected_bvt_later.t1 values(10); create role protected_bvt_writer; grant create database,drop database on account * to protected_bvt_writer; grant all on database protected_bvt_db to protected_bvt_writer; -grant all on table protected_bvt_db.* to protected_bvt_writer; +grant ownership on database protected_bvt_db to protected_bvt_writer; +grant all on table protected_bvt_db.* to protected_bvt_writer with grant option; +grant ownership on table protected_bvt_db.t1 to protected_bvt_writer; +grant all on database protected_bvt_later to protected_bvt_writer; +grant all on table protected_bvt_later.* to protected_bvt_writer; +grant connect on account * to protected_bvt_writer; + create user protected_bvt_user identified by '111' default role protected_bvt_writer; + +-- @session:id=1&user=protected_bvt_acc:admin&password=111 +set enable_privilege_cache = off; +set global protected_databases = 'protected_bvt_db,protected_bvt_new,protected_bvt_clone,CamelDB,protected_bvt_later'; +-- @session + +-- @session:id=4&user=protected_bvt_acc:protected_bvt_user:protected_bvt_writer&password=111 +set enable_privilege_cache = off; +select @@global.protected_databases; +select database(); +use protected_bvt_later; +select a from t1; -- @session -- @session:id=2&user=protected_bvt_acc:protected_bvt_user:protected_bvt_writer&password=111 -select * from protected_bvt_db.t1; +set enable_privilege_cache = off; +use protected_bvt_db; +show tables; +select a from t1; +select a from protected_bvt_db.t1; +select a from protected_bvt_db.v1; +-- @session + +-- @session:id=1&user=protected_bvt_acc:admin&password=111 +set enable_privilege_cache = off; +create sequence protected_bvt_db.s1; +create function protected_bvt_db.f1(a int) returns int language sql as '$1 + 1'; +create procedure protected_bvt_db.p1() 'begin select 1; end'; +-- @session + +-- @session:id=2&user=protected_bvt_acc:protected_bvt_user:protected_bvt_writer&password=111 +set enable_privilege_cache = off; create database protected_bvt_normal; drop database protected_bvt_normal; create database protected_bvt_new; create table protected_bvt_db.t2(a int); +create external table protected_bvt_db.ext1(a int) infile{"filepath"='$resources/external_table_file/extable.csv'} fields terminated by ',' lines terminated by '\n'; +create dynamic table protected_bvt_db.dt1 as select * from protected_bvt_db.t1; create view protected_bvt_db.v2 as select * from protected_bvt_db.t1; +alter view protected_bvt_db.v1 as select a from protected_bvt_db.t1; drop view protected_bvt_db.v1; -alter table protected_bvt_db.t1 add column b int; +alter database protected_bvt_db set mysql_compatibility_mode = '0.8.0'; +alter table protected_bvt_db.t1 add column c int; rename table protected_bvt_db.t1 to protected_bvt_db.t2; +create index protected_bvt_idx2 on protected_bvt_db.t1(b); +drop index protected_bvt_idx on protected_bvt_db.t1; create table protected_bvt_db.t_clone clone protected_bvt_db.t1; create database protected_bvt_clone clone protected_bvt_db; -insert into protected_bvt_db.t1 values(2); +create sequence protected_bvt_db.s2; +alter sequence protected_bvt_db.s1 increment by 2; +drop sequence protected_bvt_db.s1; +create function protected_bvt_db.f2(a int) returns int language sql as '$1 + 1'; +drop function protected_bvt_db.f1(int); +create procedure protected_bvt_db.p2() 'begin select 1; end'; +drop procedure protected_bvt_db.p1; +create connector for protected_bvt_db.conn1 with ("type"='kafka', "topic"='t1', "partition"='0', "value"='json', "bootstrap.servers"='127.0.0.1:9092'); +insert into protected_bvt_db.t1 values(2, 2); +replace into protected_bvt_db.t1 values(2, 2); +update protected_bvt_db.t1 set a = 3 where a = 1; +delete from protected_bvt_db.t1 where a = 1; +insert into protected_bvt_db.pk_single values(2, 'b'); +update protected_bvt_db.pk_compound set v = 'b' where k1 = 1 and k2 = 1; +insert into protected_bvt_db.auto_pk(v) values('b'); +insert into protected_bvt_db.uk_table values(2, 'c@d'); +insert into protected_bvt_db.part_hash values(2, 'b'); +truncate table protected_bvt_db.part_range; +insert into protected_bvt_db.fk_child values(2, 1); +delete from protected_bvt_db.fk_parent where id = 1; +alter table protected_bvt_db.fk_child drop foreign key fk_child_parent; +drop table protected_bvt_db.fk_child; +insert into protected_bvt_db.fk_self values(2, 1); truncate table protected_bvt_db.t1; drop table protected_bvt_db.t1; drop database protected_bvt_db; + +-- @session:id=4&user=protected_bvt_acc:protected_bvt_user:protected_bvt_writer&password=111 +set enable_privilege_cache = off; +select @@global.protected_databases; +select database(); +create table t2(a int); +drop table t1; +create table t_ctas as select * from t1; +-- @session + +-- @session:id=2&user=protected_bvt_acc:protected_bvt_user:protected_bvt_writer&password=111 +set enable_privilege_cache = off; +insert into protected_bvt_later.t1 values(11); +drop database protected_bvt_later; +create database `CamelDB`; create database `cameldb`; -drop database `cameldb`; +drop database if exists `cameldb`; +-- @session + +-- @session:id=1&user=protected_bvt_acc:admin&password=111 +set enable_privilege_cache = off; +set global lower_case_table_names = 0; +set global protected_databases = 'ProtectedCaseDB'; +-- @session + +-- @session:id=3&user=protected_bvt_acc:protected_bvt_user:protected_bvt_writer&password=111 +set enable_privilege_cache = off; +select @@lower_case_table_names; +create database `protectedcasedb`; +drop database `protectedcasedb`; +create database `ProtectedCaseDB`; +drop database `ProtectedCaseDB`; -- @session -- @session:id=1&user=protected_bvt_acc:admin&password=111 +set enable_privilege_cache = off; +set global lower_case_table_names = 1; drop user if exists protected_bvt_user; drop role if exists protected_bvt_writer; drop database protected_bvt_db; +drop database protected_bvt_later; +drop database if exists `CamelDB`; set global protected_databases = 'protected_bvt_unused'; -- @session +set global lower_case_table_names = 1; drop account protected_bvt_acc; -set global enable_privilege_cache = on; +set global enable_privilege_cache = on; \ No newline at end of file