diff --git a/privilege/privileges/cache_test.go b/privilege/privileges/cache_test.go index 937920f2dc0e6..01685af8c4271 100644 --- a/privilege/privileges/cache_test.go +++ b/privilege/privileges/cache_test.go @@ -15,235 +15,244 @@ package privileges_test import ( "fmt" + "testing" . "github.com/pingcap/check" "github.com/pingcap/parser/auth" "github.com/pingcap/parser/mysql" - "github.com/pingcap/tidb/domain" - "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/privilege/privileges" "github.com/pingcap/tidb/session" - "github.com/pingcap/tidb/store/mockstore" "github.com/pingcap/tidb/util" + "github.com/stretchr/testify/require" ) -var _ = Suite(&testCacheSuite{}) +func TestLoadUserTable(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() -type testCacheSuite struct { - store kv.Storage - domain *domain.Domain -} - -func (s *testCacheSuite) SetUpSuite(c *C) { - store, err := mockstore.NewMockStore() - session.SetSchemaLease(0) - session.DisableStats4Test() - c.Assert(err, IsNil) - s.domain, err = session.BootstrapSession(store) - c.Assert(err, IsNil) - s.store = store -} - -func (s *testCacheSuite) TearDownSuit(c *C) { - s.domain.Close() - s.store.Close() -} - -func (s *testCacheSuite) TestLoadUserTable(c *C) { - se, err := session.CreateSession4Test(s.store) - c.Assert(err, IsNil) + se, err := session.CreateSession4Test(store) + require.NoError(t, err) defer se.Close() - mustExec(c, se, "use mysql;") - mustExec(c, se, "truncate table user;") + mustExec(t, se, "use mysql;") + mustExec(t, se, "truncate table user;") var p privileges.MySQLPrivilege err = p.LoadUserTable(se) - c.Assert(err, IsNil) - c.Assert(len(p.User), Equals, 0) + require.NoError(t, err) + require.Len(t, p.User, 0) // Host | User | authentication_string | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Process_priv | Grant_priv | References_priv | Alter_priv | Show_db_priv | Super_priv | Execute_priv | Index_priv | Create_user_priv | Trigger_priv - mustExec(c, se, `INSERT INTO mysql.user (Host, User, authentication_string, Select_priv) VALUES ("%", "root", "", "Y")`) - mustExec(c, se, `INSERT INTO mysql.user (Host, User, authentication_string, Insert_priv) VALUES ("%", "root1", "admin", "Y")`) - mustExec(c, se, `INSERT INTO mysql.user (Host, User, authentication_string, Update_priv, Show_db_priv, References_priv) VALUES ("%", "root11", "", "Y", "Y", "Y")`) - mustExec(c, se, `INSERT INTO mysql.user (Host, User, authentication_string, Create_user_priv, Index_priv, Execute_priv, Create_view_priv, Show_view_priv, Show_db_priv, Super_priv, Trigger_priv) VALUES ("%", "root111", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y")`) + mustExec(t, se, `INSERT INTO mysql.user (Host, User, authentication_string, Select_priv) VALUES ("%", "root", "", "Y")`) + mustExec(t, se, `INSERT INTO mysql.user (Host, User, authentication_string, Insert_priv) VALUES ("%", "root1", "admin", "Y")`) + mustExec(t, se, `INSERT INTO mysql.user (Host, User, authentication_string, Update_priv, Show_db_priv, References_priv) VALUES ("%", "root11", "", "Y", "Y", "Y")`) + mustExec(t, se, `INSERT INTO mysql.user (Host, User, authentication_string, Create_user_priv, Index_priv, Execute_priv, Create_view_priv, Show_view_priv, Show_db_priv, Super_priv, Trigger_priv) VALUES ("%", "root111", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y")`) p = privileges.MySQLPrivilege{} err = p.LoadUserTable(se) - c.Assert(err, IsNil) - c.Assert(p.User, HasLen, len(p.UserMap)) + require.NoError(t, err) + require.Len(t, p.User, len(p.UserMap)) user := p.User - c.Assert(user[0].User, Equals, "root") - c.Assert(user[0].Privileges, Equals, mysql.SelectPriv) - c.Assert(user[1].Privileges, Equals, mysql.InsertPriv) - c.Assert(user[2].Privileges, Equals, mysql.UpdatePriv|mysql.ShowDBPriv|mysql.ReferencesPriv) - c.Assert(user[3].Privileges, Equals, mysql.CreateUserPriv|mysql.IndexPriv|mysql.ExecutePriv|mysql.CreateViewPriv|mysql.ShowViewPriv|mysql.ShowDBPriv|mysql.SuperPriv|mysql.TriggerPriv) + require.Equal(t, "root", user[0].User) + require.Equal(t, mysql.SelectPriv, user[0].Privileges) + require.Equal(t, mysql.InsertPriv, user[1].Privileges) + require.Equal(t, mysql.UpdatePriv|mysql.ShowDBPriv|mysql.ReferencesPriv, user[2].Privileges) + require.Equal(t, mysql.CreateUserPriv|mysql.IndexPriv|mysql.ExecutePriv|mysql.CreateViewPriv|mysql.ShowViewPriv|mysql.ShowDBPriv|mysql.SuperPriv|mysql.TriggerPriv, user[3].Privileges) } -func (s *testCacheSuite) TestLoadGlobalPrivTable(c *C) { - se, err := session.CreateSession4Test(s.store) - c.Assert(err, IsNil) +func TestLoadGlobalPrivTable(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se, err := session.CreateSession4Test(store) + require.NoError(t, err) defer se.Close() - mustExec(c, se, "use mysql;") - mustExec(c, se, "truncate table global_priv") + mustExec(t, se, "use mysql;") + mustExec(t, se, "truncate table global_priv") - mustExec(c, se, `INSERT INTO mysql.global_priv VALUES ("%", "tu", "{\"access\":0,\"plugin\":\"mysql_native_password\",\"ssl_type\":3, + mustExec(t, se, `INSERT INTO mysql.global_priv VALUES ("%", "tu", "{\"access\":0,\"plugin\":\"mysql_native_password\",\"ssl_type\":3, \"ssl_cipher\":\"cipher\",\"x509_subject\":\"\C=ZH1\", \"x509_issuer\":\"\C=ZH2\", \"san\":\"\IP:127.0.0.1, IP:1.1.1.1, DNS:pingcap.com, URI:spiffe://mesh.pingcap.com/ns/timesh/sa/me1\", \"password_last_changed\":1}")`) var p privileges.MySQLPrivilege err = p.LoadGlobalPrivTable(se) - c.Assert(err, IsNil) - c.Assert(p.Global["tu"][0].Host, Equals, `%`) - c.Assert(p.Global["tu"][0].User, Equals, `tu`) - c.Assert(p.Global["tu"][0].Priv.SSLType, Equals, privileges.SslTypeSpecified) - c.Assert(p.Global["tu"][0].Priv.X509Issuer, Equals, "C=ZH2") - c.Assert(p.Global["tu"][0].Priv.X509Subject, Equals, "C=ZH1") - c.Assert(p.Global["tu"][0].Priv.SAN, Equals, "IP:127.0.0.1, IP:1.1.1.1, DNS:pingcap.com, URI:spiffe://mesh.pingcap.com/ns/timesh/sa/me1") - c.Assert(len(p.Global["tu"][0].Priv.SANs[util.IP]), Equals, 2) - c.Assert(p.Global["tu"][0].Priv.SANs[util.DNS][0], Equals, "pingcap.com") - c.Assert(p.Global["tu"][0].Priv.SANs[util.URI][0], Equals, "spiffe://mesh.pingcap.com/ns/timesh/sa/me1") + require.NoError(t, err) + require.Equal(t, `%`, p.Global["tu"][0].Host) + require.Equal(t, `tu`, p.Global["tu"][0].User) + require.Equal(t, privileges.SslTypeSpecified, p.Global["tu"][0].Priv.SSLType) + require.Equal(t, "C=ZH2", p.Global["tu"][0].Priv.X509Issuer) + require.Equal(t, "C=ZH1", p.Global["tu"][0].Priv.X509Subject) + require.Equal(t, "IP:127.0.0.1, IP:1.1.1.1, DNS:pingcap.com, URI:spiffe://mesh.pingcap.com/ns/timesh/sa/me1", p.Global["tu"][0].Priv.SAN) + require.Len(t, p.Global["tu"][0].Priv.SANs[util.IP], 2) + require.Equal(t, "pingcap.com", p.Global["tu"][0].Priv.SANs[util.DNS][0]) + require.Equal(t, "spiffe://mesh.pingcap.com/ns/timesh/sa/me1", p.Global["tu"][0].Priv.SANs[util.URI][0]) } -func (s *testCacheSuite) TestLoadDBTable(c *C) { - se, err := session.CreateSession4Test(s.store) - c.Assert(err, IsNil) +func TestLoadDBTable(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se, err := session.CreateSession4Test(store) + require.NoError(t, err) defer se.Close() - mustExec(c, se, "use mysql;") - mustExec(c, se, "truncate table db;") + mustExec(t, se, "use mysql;") + mustExec(t, se, "truncate table db;") - mustExec(c, se, `INSERT INTO mysql.db (Host, DB, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv) VALUES ("%", "information_schema", "root", "Y", "Y", "Y", "Y", "Y")`) - mustExec(c, se, `INSERT INTO mysql.db (Host, DB, User, Drop_priv, Grant_priv, Index_priv, Alter_priv, Create_view_priv, Show_view_priv, Execute_priv) VALUES ("%", "mysql", "root1", "Y", "Y", "Y", "Y", "Y", "Y", "Y")`) + mustExec(t, se, `INSERT INTO mysql.db (Host, DB, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv) VALUES ("%", "information_schema", "root", "Y", "Y", "Y", "Y", "Y")`) + mustExec(t, se, `INSERT INTO mysql.db (Host, DB, User, Drop_priv, Grant_priv, Index_priv, Alter_priv, Create_view_priv, Show_view_priv, Execute_priv) VALUES ("%", "mysql", "root1", "Y", "Y", "Y", "Y", "Y", "Y", "Y")`) var p privileges.MySQLPrivilege err = p.LoadDBTable(se) - c.Assert(err, IsNil) - c.Assert(p.DB, HasLen, len(p.DBMap)) + require.NoError(t, err) + require.Len(t, p.DB, len(p.DBMap)) - c.Assert(p.DB[0].Privileges, Equals, mysql.SelectPriv|mysql.InsertPriv|mysql.UpdatePriv|mysql.DeletePriv|mysql.CreatePriv) - c.Assert(p.DB[1].Privileges, Equals, mysql.DropPriv|mysql.GrantPriv|mysql.IndexPriv|mysql.AlterPriv|mysql.CreateViewPriv|mysql.ShowViewPriv|mysql.ExecutePriv) + require.Equal(t, mysql.SelectPriv|mysql.InsertPriv|mysql.UpdatePriv|mysql.DeletePriv|mysql.CreatePriv, p.DB[0].Privileges) + require.Equal(t, mysql.DropPriv|mysql.GrantPriv|mysql.IndexPriv|mysql.AlterPriv|mysql.CreateViewPriv|mysql.ShowViewPriv|mysql.ExecutePriv, p.DB[1].Privileges) } -func (s *testCacheSuite) TestLoadTablesPrivTable(c *C) { - se, err := session.CreateSession4Test(s.store) - c.Assert(err, IsNil) +func TestLoadTablesPrivTable(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se, err := session.CreateSession4Test(store) + require.NoError(t, err) defer se.Close() - mustExec(c, se, "use mysql;") - mustExec(c, se, "truncate table tables_priv") + mustExec(t, se, "use mysql;") + mustExec(t, se, "truncate table tables_priv") - mustExec(c, se, `INSERT INTO mysql.tables_priv VALUES ("%", "db", "user", "table", "grantor", "2017-01-04 16:33:42.235831", "Grant,Index,Alter", "Insert,Update")`) + mustExec(t, se, `INSERT INTO mysql.tables_priv VALUES ("%", "db", "user", "table", "grantor", "2017-01-04 16:33:42.235831", "Grant,Index,Alter", "Insert,Update")`) var p privileges.MySQLPrivilege err = p.LoadTablesPrivTable(se) - c.Assert(err, IsNil) - c.Assert(p.TablesPriv, HasLen, len(p.TablesPrivMap)) - - c.Assert(p.TablesPriv[0].Host, Equals, `%`) - c.Assert(p.TablesPriv[0].DB, Equals, "db") - c.Assert(p.TablesPriv[0].User, Equals, "user") - c.Assert(p.TablesPriv[0].TableName, Equals, "table") - c.Assert(p.TablesPriv[0].TablePriv, Equals, mysql.GrantPriv|mysql.IndexPriv|mysql.AlterPriv) - c.Assert(p.TablesPriv[0].ColumnPriv, Equals, mysql.InsertPriv|mysql.UpdatePriv) + require.NoError(t, err) + require.Len(t, p.TablesPriv, len(p.TablesPrivMap)) + + require.Equal(t, `%`, p.TablesPriv[0].Host) + require.Equal(t, "db", p.TablesPriv[0].DB) + require.Equal(t, "user", p.TablesPriv[0].User) + require.Equal(t, "table", p.TablesPriv[0].TableName) + require.Equal(t, mysql.GrantPriv|mysql.IndexPriv|mysql.AlterPriv, p.TablesPriv[0].TablePriv) + require.Equal(t, mysql.InsertPriv|mysql.UpdatePriv, p.TablesPriv[0].ColumnPriv) } -func (s *testCacheSuite) TestLoadColumnsPrivTable(c *C) { - se, err := session.CreateSession4Test(s.store) - c.Assert(err, IsNil) +func TestLoadColumnsPrivTable(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se, err := session.CreateSession4Test(store) + require.NoError(t, err) defer se.Close() - mustExec(c, se, "use mysql;") - mustExec(c, se, "truncate table columns_priv") + mustExec(t, se, "use mysql;") + mustExec(t, se, "truncate table columns_priv") - mustExec(c, se, `INSERT INTO mysql.columns_priv VALUES ("%", "db", "user", "table", "column", "2017-01-04 16:33:42.235831", "Insert,Update")`) - mustExec(c, se, `INSERT INTO mysql.columns_priv VALUES ("127.0.0.1", "db", "user", "table", "column", "2017-01-04 16:33:42.235831", "Select")`) + mustExec(t, se, `INSERT INTO mysql.columns_priv VALUES ("%", "db", "user", "table", "column", "2017-01-04 16:33:42.235831", "Insert,Update")`) + mustExec(t, se, `INSERT INTO mysql.columns_priv VALUES ("127.0.0.1", "db", "user", "table", "column", "2017-01-04 16:33:42.235831", "Select")`) var p privileges.MySQLPrivilege err = p.LoadColumnsPrivTable(se) - c.Assert(err, IsNil) - c.Assert(p.ColumnsPriv[0].Host, Equals, `%`) - c.Assert(p.ColumnsPriv[0].DB, Equals, "db") - c.Assert(p.ColumnsPriv[0].User, Equals, "user") - c.Assert(p.ColumnsPriv[0].TableName, Equals, "table") - c.Assert(p.ColumnsPriv[0].ColumnName, Equals, "column") - c.Assert(p.ColumnsPriv[0].ColumnPriv, Equals, mysql.InsertPriv|mysql.UpdatePriv) - c.Assert(p.ColumnsPriv[1].ColumnPriv, Equals, mysql.SelectPriv) + require.NoError(t, err) + require.Equal(t, `%`, p.ColumnsPriv[0].Host) + require.Equal(t, "db", p.ColumnsPriv[0].DB) + require.Equal(t, "user", p.ColumnsPriv[0].User) + require.Equal(t, "table", p.ColumnsPriv[0].TableName) + require.Equal(t, "column", p.ColumnsPriv[0].ColumnName) + require.Equal(t, mysql.InsertPriv|mysql.UpdatePriv, p.ColumnsPriv[0].ColumnPriv) + require.Equal(t, mysql.SelectPriv, p.ColumnsPriv[1].ColumnPriv) } -func (s *testCacheSuite) TestLoadDefaultRoleTable(c *C) { - se, err := session.CreateSession4Test(s.store) - c.Assert(err, IsNil) +func TestLoadDefaultRoleTable(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se, err := session.CreateSession4Test(store) + require.NoError(t, err) defer se.Close() - mustExec(c, se, "use mysql;") - mustExec(c, se, "truncate table default_roles") + mustExec(t, se, "use mysql;") + mustExec(t, se, "truncate table default_roles") - mustExec(c, se, `INSERT INTO mysql.default_roles VALUES ("%", "test_default_roles", "localhost", "r_1")`) - mustExec(c, se, `INSERT INTO mysql.default_roles VALUES ("%", "test_default_roles", "localhost", "r_2")`) + mustExec(t, se, `INSERT INTO mysql.default_roles VALUES ("%", "test_default_roles", "localhost", "r_1")`) + mustExec(t, se, `INSERT INTO mysql.default_roles VALUES ("%", "test_default_roles", "localhost", "r_2")`) var p privileges.MySQLPrivilege err = p.LoadDefaultRoles(se) - c.Assert(err, IsNil) - c.Assert(p.DefaultRoles[0].Host, Equals, `%`) - c.Assert(p.DefaultRoles[0].User, Equals, "test_default_roles") - c.Assert(p.DefaultRoles[0].DefaultRoleHost, Equals, "localhost") - c.Assert(p.DefaultRoles[0].DefaultRoleUser, Equals, "r_1") - c.Assert(p.DefaultRoles[1].DefaultRoleHost, Equals, "localhost") + require.NoError(t, err) + require.Equal(t, `%`, p.DefaultRoles[0].Host) + require.Equal(t, "test_default_roles", p.DefaultRoles[0].User) + require.Equal(t, "localhost", p.DefaultRoles[0].DefaultRoleHost) + require.Equal(t, "r_1", p.DefaultRoles[0].DefaultRoleUser) + require.Equal(t, "localhost", p.DefaultRoles[1].DefaultRoleHost) } -func (s *testCacheSuite) TestPatternMatch(c *C) { - se, err := session.CreateSession4Test(s.store) +func TestPatternMatch(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se, err := session.CreateSession4Test(store) activeRoles := make([]*auth.RoleIdentity, 0) - c.Assert(err, IsNil) + require.NoError(t, err) defer se.Close() - mustExec(c, se, "USE MYSQL;") - mustExec(c, se, "TRUNCATE TABLE mysql.user") - mustExec(c, se, `INSERT INTO mysql.user (HOST, USER, Select_priv, Shutdown_priv) VALUES ("10.0.%", "root", "Y", "Y")`) + mustExec(t, se, "USE MYSQL;") + mustExec(t, se, "TRUNCATE TABLE mysql.user") + mustExec(t, se, `INSERT INTO mysql.user (HOST, USER, Select_priv, Shutdown_priv) VALUES ("10.0.%", "root", "Y", "Y")`) var p privileges.MySQLPrivilege err = p.LoadUserTable(se) - c.Assert(err, IsNil) - c.Assert(p.RequestVerification(activeRoles, "root", "10.0.1", "test", "", "", mysql.SelectPriv), IsTrue) - c.Assert(p.RequestVerification(activeRoles, "root", "10.0.1.118", "test", "", "", mysql.SelectPriv), IsTrue) - c.Assert(p.RequestVerification(activeRoles, "root", "localhost", "test", "", "", mysql.SelectPriv), IsFalse) - c.Assert(p.RequestVerification(activeRoles, "root", "127.0.0.1", "test", "", "", mysql.SelectPriv), IsFalse) - c.Assert(p.RequestVerification(activeRoles, "root", "114.114.114.114", "test", "", "", mysql.SelectPriv), IsFalse) - c.Assert(p.RequestVerification(activeRoles, "root", "114.114.114.114", "test", "", "", mysql.PrivilegeType(0)), IsTrue) - c.Assert(p.RequestVerification(activeRoles, "root", "10.0.1.118", "test", "", "", mysql.ShutdownPriv), IsTrue) - - mustExec(c, se, "TRUNCATE TABLE mysql.user") - mustExec(c, se, `INSERT INTO mysql.user (HOST, USER, Select_priv, Shutdown_priv) VALUES ("", "root", "Y", "N")`) + require.NoError(t, err) + require.True(t, p.RequestVerification(activeRoles, "root", "10.0.1", "test", "", "", mysql.SelectPriv)) + require.True(t, p.RequestVerification(activeRoles, "root", "10.0.1.118", "test", "", "", mysql.SelectPriv)) + require.False(t, p.RequestVerification(activeRoles, "root", "localhost", "test", "", "", mysql.SelectPriv)) + require.False(t, p.RequestVerification(activeRoles, "root", "127.0.0.1", "test", "", "", mysql.SelectPriv)) + require.False(t, p.RequestVerification(activeRoles, "root", "114.114.114.114", "test", "", "", mysql.SelectPriv)) + require.True(t, p.RequestVerification(activeRoles, "root", "114.114.114.114", "test", "", "", mysql.PrivilegeType(0))) + require.True(t, p.RequestVerification(activeRoles, "root", "10.0.1.118", "test", "", "", mysql.ShutdownPriv)) + + mustExec(t, se, "TRUNCATE TABLE mysql.user") + mustExec(t, se, `INSERT INTO mysql.user (HOST, USER, Select_priv, Shutdown_priv) VALUES ("", "root", "Y", "N")`) p = privileges.MySQLPrivilege{} err = p.LoadUserTable(se) - c.Assert(err, IsNil) - c.Assert(p.RequestVerification(activeRoles, "root", "", "test", "", "", mysql.SelectPriv), IsTrue) - c.Assert(p.RequestVerification(activeRoles, "root", "notnull", "test", "", "", mysql.SelectPriv), IsFalse) - c.Assert(p.RequestVerification(activeRoles, "root", "", "test", "", "", mysql.ShutdownPriv), IsFalse) + require.NoError(t, err) + require.True(t, p.RequestVerification(activeRoles, "root", "", "test", "", "", mysql.SelectPriv)) + require.False(t, p.RequestVerification(activeRoles, "root", "notnull", "test", "", "", mysql.SelectPriv)) + require.False(t, p.RequestVerification(activeRoles, "root", "", "test", "", "", mysql.ShutdownPriv)) // Pattern match for DB. - mustExec(c, se, "TRUNCATE TABLE mysql.user") - mustExec(c, se, "TRUNCATE TABLE mysql.db") - mustExec(c, se, `INSERT INTO mysql.db (user,host,db,select_priv) values ('genius', '%', 'te%', 'Y')`) + mustExec(t, se, "TRUNCATE TABLE mysql.user") + mustExec(t, se, "TRUNCATE TABLE mysql.db") + mustExec(t, se, `INSERT INTO mysql.db (user,host,db,select_priv) values ('genius', '%', 'te%', 'Y')`) err = p.LoadDBTable(se) - c.Assert(err, IsNil) - c.Assert(p.RequestVerification(activeRoles, "genius", "127.0.0.1", "test", "", "", mysql.SelectPriv), IsTrue) + require.NoError(t, err) + require.True(t, p.RequestVerification(activeRoles, "genius", "127.0.0.1", "test", "", "", mysql.SelectPriv)) } -func (s *testCacheSuite) TestHostMatch(c *C) { - se, err := session.CreateSession4Test(s.store) +func TestHostMatch(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se, err := session.CreateSession4Test(store) activeRoles := make([]*auth.RoleIdentity, 0) - c.Assert(err, IsNil) + require.NoError(t, err) defer se.Close() // Host name can be IPv4 address + netmask. - mustExec(c, se, "USE MYSQL;") - mustExec(c, se, "TRUNCATE TABLE mysql.user") - mustExec(c, se, `INSERT INTO mysql.user (HOST, USER, authentication_string, Select_priv, Shutdown_priv) VALUES ("172.0.0.0/255.0.0.0", "root", "", "Y", "Y")`) + mustExec(t, se, "USE MYSQL;") + mustExec(t, se, "TRUNCATE TABLE mysql.user") + mustExec(t, se, `INSERT INTO mysql.user (HOST, USER, authentication_string, Select_priv, Shutdown_priv) VALUES ("172.0.0.0/255.0.0.0", "root", "", "Y", "Y")`) var p privileges.MySQLPrivilege err = p.LoadUserTable(se) - c.Assert(err, IsNil) - c.Assert(p.RequestVerification(activeRoles, "root", "172.0.0.1", "test", "", "", mysql.SelectPriv), IsTrue) - c.Assert(p.RequestVerification(activeRoles, "root", "172.1.1.1", "test", "", "", mysql.SelectPriv), IsTrue) - c.Assert(p.RequestVerification(activeRoles, "root", "localhost", "test", "", "", mysql.SelectPriv), IsFalse) - c.Assert(p.RequestVerification(activeRoles, "root", "127.0.0.1", "test", "", "", mysql.SelectPriv), IsFalse) - c.Assert(p.RequestVerification(activeRoles, "root", "198.0.0.1", "test", "", "", mysql.SelectPriv), IsFalse) - c.Assert(p.RequestVerification(activeRoles, "root", "198.0.0.1", "test", "", "", mysql.PrivilegeType(0)), IsTrue) - c.Assert(p.RequestVerification(activeRoles, "root", "172.0.0.1", "test", "", "", mysql.ShutdownPriv), IsTrue) - mustExec(c, se, `TRUNCATE TABLE mysql.user`) + require.NoError(t, err) + require.True(t, p.RequestVerification(activeRoles, "root", "172.0.0.1", "test", "", "", mysql.SelectPriv)) + require.True(t, p.RequestVerification(activeRoles, "root", "172.1.1.1", "test", "", "", mysql.SelectPriv)) + require.False(t, p.RequestVerification(activeRoles, "root", "localhost", "test", "", "", mysql.SelectPriv)) + require.False(t, p.RequestVerification(activeRoles, "root", "127.0.0.1", "test", "", "", mysql.SelectPriv)) + require.False(t, p.RequestVerification(activeRoles, "root", "198.0.0.1", "test", "", "", mysql.SelectPriv)) + require.True(t, p.RequestVerification(activeRoles, "root", "198.0.0.1", "test", "", "", mysql.PrivilegeType(0))) + require.True(t, p.RequestVerification(activeRoles, "root", "172.0.0.1", "test", "", "", mysql.ShutdownPriv)) + mustExec(t, se, `TRUNCATE TABLE mysql.user`) // Invalid host name, the user can be created, but cannot login. cases := []string{ @@ -258,129 +267,132 @@ func (s *testCacheSuite) TestHostMatch(c *C) { } for _, IPMask := range cases { sql := fmt.Sprintf(`INSERT INTO mysql.user (HOST, USER, Select_priv, Shutdown_priv) VALUES ("%s", "root", "Y", "Y")`, IPMask) - mustExec(c, se, sql) + mustExec(t, se, sql) p = privileges.MySQLPrivilege{} err = p.LoadUserTable(se) - c.Assert(err, IsNil) - c.Assert(p.RequestVerification(activeRoles, "root", "127.0.0.1", "test", "", "", mysql.SelectPriv), IsFalse, Commentf("test case: %s", IPMask)) - c.Assert(p.RequestVerification(activeRoles, "root", "127.0.0.0", "test", "", "", mysql.SelectPriv), IsFalse, Commentf("test case: %s", IPMask)) - c.Assert(p.RequestVerification(activeRoles, "root", "localhost", "test", "", "", mysql.ShutdownPriv), IsFalse, Commentf("test case: %s", IPMask)) + require.NoError(t, err) + require.False(t, p.RequestVerification(activeRoles, "root", "127.0.0.1", "test", "", "", mysql.SelectPriv), IsFalse, Commentf("test case: %s", IPMask)) + require.False(t, p.RequestVerification(activeRoles, "root", "127.0.0.0", "test", "", "", mysql.SelectPriv), IsFalse, Commentf("test case: %s", IPMask)) + require.False(t, p.RequestVerification(activeRoles, "root", "localhost", "test", "", "", mysql.ShutdownPriv), IsFalse, Commentf("test case: %s", IPMask)) } // Netmask notation cannot be used for IPv6 addresses. - mustExec(c, se, `INSERT INTO mysql.user (HOST, USER, Select_priv, Shutdown_priv) VALUES ("2001:db8::/ffff:ffff::", "root", "Y", "Y")`) + mustExec(t, se, `INSERT INTO mysql.user (HOST, USER, Select_priv, Shutdown_priv) VALUES ("2001:db8::/ffff:ffff::", "root", "Y", "Y")`) p = privileges.MySQLPrivilege{} err = p.LoadUserTable(se) - c.Assert(err, IsNil) - c.Assert(p.RequestVerification(activeRoles, "root", "2001:db8::1234", "test", "", "", mysql.SelectPriv), IsFalse) - c.Assert(p.RequestVerification(activeRoles, "root", "2001:db8::", "test", "", "", mysql.SelectPriv), IsFalse) - c.Assert(p.RequestVerification(activeRoles, "root", "localhost", "test", "", "", mysql.ShutdownPriv), IsFalse) + require.NoError(t, err) + require.False(t, p.RequestVerification(activeRoles, "root", "2001:db8::1234", "test", "", "", mysql.SelectPriv)) + require.False(t, p.RequestVerification(activeRoles, "root", "2001:db8::", "test", "", "", mysql.SelectPriv)) + require.False(t, p.RequestVerification(activeRoles, "root", "localhost", "test", "", "", mysql.ShutdownPriv)) } -func (s *testCacheSuite) TestCaseInsensitive(c *C) { - se, err := session.CreateSession4Test(s.store) +func TestCaseInsensitive(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se, err := session.CreateSession4Test(store) activeRoles := make([]*auth.RoleIdentity, 0) - c.Assert(err, IsNil) + require.NoError(t, err) defer se.Close() - mustExec(c, se, "CREATE DATABASE TCTrain;") - mustExec(c, se, "CREATE TABLE TCTrain.TCTrainOrder (id int);") - mustExec(c, se, "TRUNCATE TABLE mysql.user") - mustExec(c, se, `INSERT INTO mysql.db VALUES ("127.0.0.1", "TCTrain", "genius", "Y", "Y", "Y", "Y", "Y", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N")`) + mustExec(t, se, "CREATE DATABASE TCTrain;") + mustExec(t, se, "CREATE TABLE TCTrain.TCTrainOrder (id int);") + mustExec(t, se, "TRUNCATE TABLE mysql.user") + mustExec(t, se, `INSERT INTO mysql.db VALUES ("127.0.0.1", "TCTrain", "genius", "Y", "Y", "Y", "Y", "Y", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N")`) var p privileges.MySQLPrivilege err = p.LoadDBTable(se) - c.Assert(err, IsNil) + require.NoError(t, err) // DB and Table names are case insensitive in MySQL. - c.Assert(p.RequestVerification(activeRoles, "genius", "127.0.0.1", "TCTrain", "TCTrainOrder", "", mysql.SelectPriv), IsTrue) - c.Assert(p.RequestVerification(activeRoles, "genius", "127.0.0.1", "TCTRAIN", "TCTRAINORDER", "", mysql.SelectPriv), IsTrue) - c.Assert(p.RequestVerification(activeRoles, "genius", "127.0.0.1", "tctrain", "tctrainorder", "", mysql.SelectPriv), IsTrue) + require.True(t, p.RequestVerification(activeRoles, "genius", "127.0.0.1", "TCTrain", "TCTrainOrder", "", mysql.SelectPriv)) + require.True(t, p.RequestVerification(activeRoles, "genius", "127.0.0.1", "TCTRAIN", "TCTRAINORDER", "", mysql.SelectPriv)) + require.True(t, p.RequestVerification(activeRoles, "genius", "127.0.0.1", "tctrain", "tctrainorder", "", mysql.SelectPriv)) } -func (s *testCacheSuite) TestLoadRoleGraph(c *C) { - se, err := session.CreateSession4Test(s.store) - c.Assert(err, IsNil) +func TestLoadRoleGraph(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se, err := session.CreateSession4Test(store) + require.NoError(t, err) defer se.Close() - mustExec(c, se, "use mysql;") - mustExec(c, se, "truncate table user;") + mustExec(t, se, "use mysql;") + mustExec(t, se, "truncate table user;") var p privileges.MySQLPrivilege err = p.LoadRoleGraph(se) - c.Assert(err, IsNil) - c.Assert(len(p.User), Equals, 0) + require.NoError(t, err) + require.Len(t, p.User, 0) - mustExec(c, se, `INSERT INTO mysql.role_edges (FROM_HOST, FROM_USER, TO_HOST, TO_USER) VALUES ("%", "r_1", "%", "user2")`) - mustExec(c, se, `INSERT INTO mysql.role_edges (FROM_HOST, FROM_USER, TO_HOST, TO_USER) VALUES ("%", "r_2", "%", "root")`) - mustExec(c, se, `INSERT INTO mysql.role_edges (FROM_HOST, FROM_USER, TO_HOST, TO_USER) VALUES ("%", "r_3", "%", "user1")`) - mustExec(c, se, `INSERT INTO mysql.role_edges (FROM_HOST, FROM_USER, TO_HOST, TO_USER) VALUES ("%", "r_4", "%", "root")`) + mustExec(t, se, `INSERT INTO mysql.role_edges (FROM_HOST, FROM_USER, TO_HOST, TO_USER) VALUES ("%", "r_1", "%", "user2")`) + mustExec(t, se, `INSERT INTO mysql.role_edges (FROM_HOST, FROM_USER, TO_HOST, TO_USER) VALUES ("%", "r_2", "%", "root")`) + mustExec(t, se, `INSERT INTO mysql.role_edges (FROM_HOST, FROM_USER, TO_HOST, TO_USER) VALUES ("%", "r_3", "%", "user1")`) + mustExec(t, se, `INSERT INTO mysql.role_edges (FROM_HOST, FROM_USER, TO_HOST, TO_USER) VALUES ("%", "r_4", "%", "root")`) p = privileges.MySQLPrivilege{} err = p.LoadRoleGraph(se) - c.Assert(err, IsNil) + require.NoError(t, err) graph := p.RoleGraph - c.Assert(graph["root@%"].Find("r_2", "%"), Equals, true) - c.Assert(graph["root@%"].Find("r_4", "%"), Equals, true) - c.Assert(graph["user2@%"].Find("r_1", "%"), Equals, true) - c.Assert(graph["user1@%"].Find("r_3", "%"), Equals, true) + require.True(t, graph["root@%"].Find("r_2", "%")) + require.True(t, graph["root@%"].Find("r_4", "%")) + require.True(t, graph["user2@%"].Find("r_1", "%")) + require.True(t, graph["user1@%"].Find("r_3", "%")) _, ok := graph["illedal"] - c.Assert(ok, Equals, false) - c.Assert(graph["root@%"].Find("r_1", "%"), Equals, false) + require.False(t, ok) + require.False(t, graph["root@%"].Find("r_1", "%")) } -func (s *testCacheSuite) TestRoleGraphBFS(c *C) { - se, err := session.CreateSession4Test(s.store) - c.Assert(err, IsNil) +func TestRoleGraphBFS(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se, err := session.CreateSession4Test(store) + require.NoError(t, err) defer se.Close() - mustExec(c, se, `CREATE ROLE r_1, r_2, r_3, r_4, r_5, r_6;`) - mustExec(c, se, `GRANT r_2 TO r_1;`) - mustExec(c, se, `GRANT r_3 TO r_2;`) - mustExec(c, se, `GRANT r_4 TO r_3;`) - mustExec(c, se, `GRANT r_1 TO r_4;`) - mustExec(c, se, `GRANT r_5 TO r_3, r_6;`) + mustExec(t, se, `CREATE ROLE r_1, r_2, r_3, r_4, r_5, r_6;`) + mustExec(t, se, `GRANT r_2 TO r_1;`) + mustExec(t, se, `GRANT r_3 TO r_2;`) + mustExec(t, se, `GRANT r_4 TO r_3;`) + mustExec(t, se, `GRANT r_1 TO r_4;`) + mustExec(t, se, `GRANT r_5 TO r_3, r_6;`) var p privileges.MySQLPrivilege err = p.LoadRoleGraph(se) - c.Assert(err, IsNil) + require.NoError(t, err) activeRoles := make([]*auth.RoleIdentity, 0) ret := p.FindAllRole(activeRoles) - c.Assert(len(ret), Equals, 0) + require.Len(t, ret, 0) activeRoles = append(activeRoles, &auth.RoleIdentity{Username: "r_1", Hostname: "%"}) ret = p.FindAllRole(activeRoles) - c.Assert(len(ret), Equals, 5) + require.Len(t, ret, 5) activeRoles = make([]*auth.RoleIdentity, 0) activeRoles = append(activeRoles, &auth.RoleIdentity{Username: "r_6", Hostname: "%"}) ret = p.FindAllRole(activeRoles) - c.Assert(len(ret), Equals, 2) + require.Len(t, ret, 2) activeRoles = make([]*auth.RoleIdentity, 0) activeRoles = append(activeRoles, &auth.RoleIdentity{Username: "r_3", Hostname: "%"}) activeRoles = append(activeRoles, &auth.RoleIdentity{Username: "r_6", Hostname: "%"}) ret = p.FindAllRole(activeRoles) - c.Assert(len(ret), Equals, 6) + require.Len(t, ret, 6) } -func (s *testCacheSuite) TestAbnormalMySQLTable(c *C) { - store, err := mockstore.NewMockStore() - c.Assert(err, IsNil) - defer func() { - err := store.Close() - c.Assert(err, IsNil) - }() - session.SetSchemaLease(0) - session.DisableStats4Test() - - dom, err := session.BootstrapSession(store) - c.Assert(err, IsNil) - defer dom.Close() +func TestAbnormalMySQLTable(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() se, err := session.CreateSession4Test(store) - c.Assert(err, IsNil) + require.NoError(t, err) defer se.Close() // Simulate the case mysql.user is synchronized from MySQL. - mustExec(c, se, "DROP TABLE mysql.user;") - mustExec(c, se, "USE mysql;") - mustExec(c, se, `CREATE TABLE user ( + mustExec(t, se, "DROP TABLE mysql.user;") + mustExec(t, se, "USE mysql;") + mustExec(t, se, `CREATE TABLE user ( Host char(60) COLLATE utf8_bin NOT NULL DEFAULT '', User char(16) COLLATE utf8_bin NOT NULL DEFAULT '', Password char(41) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', @@ -430,24 +442,25 @@ func (s *testCacheSuite) TestAbnormalMySQLTable(c *C) { password_expired enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', PRIMARY KEY (Host,User) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges';`) - mustExec(c, se, `INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'mysql_native_password','','N'); + mustExec(t, se, `INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'mysql_native_password','','N'); `) var p privileges.MySQLPrivilege err = p.LoadUserTable(se) - c.Assert(err, IsNil) + require.NoError(t, err) activeRoles := make([]*auth.RoleIdentity, 0) // MySQL mysql.user table schema is not identical to TiDB, check it doesn't break privilege. - c.Assert(p.RequestVerification(activeRoles, "root", "localhost", "test", "", "", mysql.SelectPriv), IsTrue) + require.True(t, p.RequestVerification(activeRoles, "root", "localhost", "test", "", "", mysql.SelectPriv)) // Absent of those tables doesn't cause error. - mustExec(c, se, "DROP TABLE mysql.db;") - mustExec(c, se, "DROP TABLE mysql.tables_priv;") - mustExec(c, se, "DROP TABLE mysql.columns_priv;") + mustExec(t, se, "DROP TABLE mysql.db;") + mustExec(t, se, "DROP TABLE mysql.tables_priv;") + mustExec(t, se, "DROP TABLE mysql.columns_priv;") err = p.LoadAll(se) - c.Assert(err, IsNil) + require.NoError(t, err) } -func (s *testCacheSuite) TestSortUserTable(c *C) { +func TestSortUserTable(t *testing.T) { + t.Parallel() var p privileges.MySQLPrivilege p.User = []privileges.UserRecord{ privileges.NewUserRecord(`%`, "root"), @@ -462,7 +475,7 @@ func (s *testCacheSuite) TestSortUserTable(c *C) { privileges.NewUserRecord(`%`, "jeffrey"), privileges.NewUserRecord(`%`, "root"), } - checkUserRecord(p.User, result, c) + checkUserRecord(t, p.User, result) p.User = []privileges.UserRecord{ privileges.NewUserRecord(`%`, "jeffrey"), @@ -473,7 +486,7 @@ func (s *testCacheSuite) TestSortUserTable(c *C) { privileges.NewUserRecord("h1.example.net", ""), privileges.NewUserRecord(`%`, "jeffrey"), } - checkUserRecord(p.User, result, c) + checkUserRecord(t, p.User, result) p.User = []privileges.UserRecord{ privileges.NewUserRecord(`192.168.%`, "xxx"), @@ -484,10 +497,11 @@ func (s *testCacheSuite) TestSortUserTable(c *C) { privileges.NewUserRecord(`192.168.199.%`, "xxx"), privileges.NewUserRecord(`192.168.%`, "xxx"), } - checkUserRecord(p.User, result, c) + checkUserRecord(t, p.User, result) } -func (s *testCacheSuite) TestGlobalPrivValueRequireStr(c *C) { +func TestGlobalPrivValueRequireStr(t *testing.T) { + t.Parallel() var ( none = privileges.GlobalPrivValue{SSLType: privileges.SslTypeNone} tls = privileges.GlobalPrivValue{SSLType: privileges.SslTypeAny} @@ -497,92 +511,96 @@ func (s *testCacheSuite) TestGlobalPrivValueRequireStr(c *C) { spec3 = privileges.GlobalPrivValue{SSLType: privileges.SslTypeSpecified, X509Issuer: "i1"} spec4 = privileges.GlobalPrivValue{SSLType: privileges.SslTypeSpecified} ) - c.Assert(none.RequireStr(), Equals, "NONE") - c.Assert(tls.RequireStr(), Equals, "SSL") - c.Assert(x509.RequireStr(), Equals, "X509") - c.Assert(spec.RequireStr(), Equals, "CIPHER 'c1' ISSUER 'i1' SUBJECT 's1'") - c.Assert(spec2.RequireStr(), Equals, "ISSUER 'i1' SUBJECT 's1'") - c.Assert(spec3.RequireStr(), Equals, "ISSUER 'i1'") - c.Assert(spec4.RequireStr(), Equals, "NONE") + require.Equal(t, "NONE", none.RequireStr()) + require.Equal(t, "SSL", tls.RequireStr()) + require.Equal(t, "X509", x509.RequireStr()) + require.Equal(t, "CIPHER 'c1' ISSUER 'i1' SUBJECT 's1'", spec.RequireStr()) + require.Equal(t, "ISSUER 'i1' SUBJECT 's1'", spec2.RequireStr()) + require.Equal(t, "ISSUER 'i1'", spec3.RequireStr()) + require.Equal(t, "NONE", spec4.RequireStr()) } -func checkUserRecord(x, y []privileges.UserRecord, c *C) { - c.Assert(len(x), Equals, len(y)) +func checkUserRecord(t *testing.T, x, y []privileges.UserRecord) { + require.Equal(t, len(x), len(y)) for i := 0; i < len(x); i++ { - c.Assert(x[i].User, Equals, y[i].User) - c.Assert(x[i].Host, Equals, y[i].Host) + require.Equal(t, x[i].User, y[i].User) + require.Equal(t, x[i].Host, y[i].Host) } } -func (s *testCacheSuite) TestDBIsVisible(c *C) { - se, err := session.CreateSession4Test(s.store) - c.Assert(err, IsNil) +func TestDBIsVisible(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se, err := session.CreateSession4Test(store) + require.NoError(t, err) defer se.Close() - mustExec(c, se, "create database visdb") + mustExec(t, se, "create database visdb") p := privileges.MySQLPrivilege{} err = p.LoadAll(se) - c.Assert(err, IsNil) + require.NoError(t, err) - mustExec(c, se, `INSERT INTO mysql.user (Host, User, Create_role_priv, Super_priv) VALUES ("%", "testvisdb", "Y", "Y")`) + mustExec(t, se, `INSERT INTO mysql.user (Host, User, Create_role_priv, Super_priv) VALUES ("%", "testvisdb", "Y", "Y")`) err = p.LoadUserTable(se) - c.Assert(err, IsNil) + require.NoError(t, err) isVisible := p.DBIsVisible("testvisdb", "%", "visdb") - c.Assert(isVisible, IsFalse) - mustExec(c, se, "TRUNCATE TABLE mysql.user") + require.False(t, isVisible) + mustExec(t, se, "TRUNCATE TABLE mysql.user") - mustExec(c, se, `INSERT INTO mysql.user (Host, User, Select_priv) VALUES ("%", "testvisdb2", "Y")`) + mustExec(t, se, `INSERT INTO mysql.user (Host, User, Select_priv) VALUES ("%", "testvisdb2", "Y")`) err = p.LoadUserTable(se) - c.Assert(err, IsNil) + require.NoError(t, err) isVisible = p.DBIsVisible("testvisdb2", "%", "visdb") - c.Assert(isVisible, IsTrue) - mustExec(c, se, "TRUNCATE TABLE mysql.user") + require.True(t, isVisible) + mustExec(t, se, "TRUNCATE TABLE mysql.user") - mustExec(c, se, `INSERT INTO mysql.user (Host, User, Create_priv) VALUES ("%", "testvisdb3", "Y")`) + mustExec(t, se, `INSERT INTO mysql.user (Host, User, Create_priv) VALUES ("%", "testvisdb3", "Y")`) err = p.LoadUserTable(se) - c.Assert(err, IsNil) + require.NoError(t, err) isVisible = p.DBIsVisible("testvisdb3", "%", "visdb") - c.Assert(isVisible, IsTrue) - mustExec(c, se, "TRUNCATE TABLE mysql.user") + require.True(t, isVisible) + mustExec(t, se, "TRUNCATE TABLE mysql.user") - mustExec(c, se, `INSERT INTO mysql.user (Host, User, Insert_priv) VALUES ("%", "testvisdb4", "Y")`) + mustExec(t, se, `INSERT INTO mysql.user (Host, User, Insert_priv) VALUES ("%", "testvisdb4", "Y")`) err = p.LoadUserTable(se) - c.Assert(err, IsNil) + require.NoError(t, err) isVisible = p.DBIsVisible("testvisdb4", "%", "visdb") - c.Assert(isVisible, IsTrue) - mustExec(c, se, "TRUNCATE TABLE mysql.user") + require.True(t, isVisible) + mustExec(t, se, "TRUNCATE TABLE mysql.user") - mustExec(c, se, `INSERT INTO mysql.user (Host, User, Update_priv) VALUES ("%", "testvisdb5", "Y")`) + mustExec(t, se, `INSERT INTO mysql.user (Host, User, Update_priv) VALUES ("%", "testvisdb5", "Y")`) err = p.LoadUserTable(se) - c.Assert(err, IsNil) + require.NoError(t, err) isVisible = p.DBIsVisible("testvisdb5", "%", "visdb") - c.Assert(isVisible, IsTrue) - mustExec(c, se, "TRUNCATE TABLE mysql.user") + require.True(t, isVisible) + mustExec(t, se, "TRUNCATE TABLE mysql.user") - mustExec(c, se, `INSERT INTO mysql.user (Host, User, Create_view_priv) VALUES ("%", "testvisdb6", "Y")`) + mustExec(t, se, `INSERT INTO mysql.user (Host, User, Create_view_priv) VALUES ("%", "testvisdb6", "Y")`) err = p.LoadUserTable(se) - c.Assert(err, IsNil) + require.NoError(t, err) isVisible = p.DBIsVisible("testvisdb6", "%", "visdb") - c.Assert(isVisible, IsTrue) - mustExec(c, se, "TRUNCATE TABLE mysql.user") + require.True(t, isVisible) + mustExec(t, se, "TRUNCATE TABLE mysql.user") - mustExec(c, se, `INSERT INTO mysql.user (Host, User, Trigger_priv) VALUES ("%", "testvisdb7", "Y")`) + mustExec(t, se, `INSERT INTO mysql.user (Host, User, Trigger_priv) VALUES ("%", "testvisdb7", "Y")`) err = p.LoadUserTable(se) - c.Assert(err, IsNil) + require.NoError(t, err) isVisible = p.DBIsVisible("testvisdb7", "%", "visdb") - c.Assert(isVisible, IsTrue) - mustExec(c, se, "TRUNCATE TABLE mysql.user") + require.True(t, isVisible) + mustExec(t, se, "TRUNCATE TABLE mysql.user") - mustExec(c, se, `INSERT INTO mysql.user (Host, User, References_priv) VALUES ("%", "testvisdb8", "Y")`) + mustExec(t, se, `INSERT INTO mysql.user (Host, User, References_priv) VALUES ("%", "testvisdb8", "Y")`) err = p.LoadUserTable(se) - c.Assert(err, IsNil) + require.NoError(t, err) isVisible = p.DBIsVisible("testvisdb8", "%", "visdb") - c.Assert(isVisible, IsTrue) - mustExec(c, se, "TRUNCATE TABLE mysql.user") + require.True(t, isVisible) + mustExec(t, se, "TRUNCATE TABLE mysql.user") - mustExec(c, se, `INSERT INTO mysql.user (Host, User, Execute_priv) VALUES ("%", "testvisdb9", "Y")`) + mustExec(t, se, `INSERT INTO mysql.user (Host, User, Execute_priv) VALUES ("%", "testvisdb9", "Y")`) err = p.LoadUserTable(se) - c.Assert(err, IsNil) + require.NoError(t, err) isVisible = p.DBIsVisible("testvisdb9", "%", "visdb") - c.Assert(isVisible, IsTrue) - mustExec(c, se, "TRUNCATE TABLE mysql.user") + require.True(t, isVisible) + mustExec(t, se, "TRUNCATE TABLE mysql.user") } diff --git a/privilege/privileges/main_test.go b/privilege/privileges/main_test.go new file mode 100644 index 0000000000000..0ec8d11995c16 --- /dev/null +++ b/privilege/privileges/main_test.go @@ -0,0 +1,35 @@ +// Copyright 2021 PingCAP, Inc. +// +// Licensed 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, +// See the License for the specific language governing permissions and +// limitations under the License. + +package privileges_test + +import ( + "testing" + + "github.com/pingcap/tidb/session" + "github.com/pingcap/tidb/util/testbridge" + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + opts := []goleak.Option{ + goleak.IgnoreTopFunction("go.etcd.io/etcd/pkg/logutil.(*MergeLogger).outputLoop"), + goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), + } + testbridge.WorkaroundGoCheckFlags() + + session.SetSchemaLease(0) + session.DisableStats4Test() + + goleak.VerifyTestMain(m, opts...) +} diff --git a/privilege/privileges/privileges_test.go b/privilege/privileges/privileges_test.go index d6842e5c262de..7b77b5428bddf 100644 --- a/privilege/privileges/privileges_test.go +++ b/privilege/privileges/privileges_test.go @@ -25,11 +25,9 @@ import ( "strings" "testing" - . "github.com/pingcap/check" "github.com/pingcap/parser/auth" "github.com/pingcap/parser/mysql" "github.com/pingcap/parser/terror" - "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/privilege" @@ -37,490 +35,458 @@ import ( "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/store/mockstore" + "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/sem" "github.com/pingcap/tidb/util/sqlexec" - "github.com/pingcap/tidb/util/testkit" - "github.com/pingcap/tidb/util/testleak" "github.com/pingcap/tidb/util/testutil" + "github.com/stretchr/testify/require" ) -func TestT(t *testing.T) { - CustomVerboseFlag = true - TestingT(t) -} - -var _ = Suite(&testPrivilegeSuite{}) - -type testPrivilegeSuite struct { - store kv.Storage - dom *domain.Domain - dbName string - - createDBSQL string - createDB1SQL string - dropDBSQL string - useDBSQL string - createTableSQL string - createSystemDBSQL string - createUserTableSQL string - createDBPrivTableSQL string - createTablePrivTableSQL string - createColumnPrivTableSQL string -} - -func (s *testPrivilegeSuite) SetUpSuite(c *C) { - testleak.BeforeTest() - s.dbName = "test" - s.dom, s.store = newStore(c, s.dbName) -} - -func (s *testPrivilegeSuite) TearDownSuite(c *C) { - s.dom.Close() - s.store.Close() - testleak.AfterTest(c)() -} +const dbName = "test" -func (s *testPrivilegeSuite) SetUpTest(c *C) { - se := newSession(c, s.store, s.dbName) - s.createDBSQL = fmt.Sprintf("create database if not exists %s;", s.dbName) - s.createDB1SQL = fmt.Sprintf("create database if not exists %s1;", s.dbName) - s.dropDBSQL = fmt.Sprintf("drop database if exists %s;", s.dbName) - s.useDBSQL = fmt.Sprintf("use %s;", s.dbName) - s.createTableSQL = `CREATE TABLE test(id INT NOT NULL DEFAULT 1, name varchar(255), PRIMARY KEY(id));` - - mustExec(c, se, s.createDBSQL) - mustExec(c, se, s.createDB1SQL) // create database test1 - mustExec(c, se, s.useDBSQL) - mustExec(c, se, s.createTableSQL) - - s.createSystemDBSQL = fmt.Sprintf("create database if not exists %s;", mysql.SystemDB) - s.createUserTableSQL = session.CreateUserTable - s.createDBPrivTableSQL = session.CreateDBPrivTable - s.createTablePrivTableSQL = session.CreateTablePrivTable - s.createColumnPrivTableSQL = session.CreateColumnPrivTable - - mustExec(c, se, s.createSystemDBSQL) - mustExec(c, se, s.createUserTableSQL) - mustExec(c, se, s.createDBPrivTableSQL) - mustExec(c, se, s.createTablePrivTableSQL) - mustExec(c, se, s.createColumnPrivTableSQL) -} - -func (s *testPrivilegeSuite) TearDownTest(c *C) { - // drop db - se := newSession(c, s.store, s.dbName) - mustExec(c, se, s.dropDBSQL) -} +func TestCheckDBPrivilege(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + rootSe := newSession(t, store, dbName) + mustExec(t, rootSe, `CREATE USER 'testcheck'@'localhost';`) + mustExec(t, rootSe, `CREATE USER 'testcheck_tmp'@'localhost';`) -func (s *testPrivilegeSuite) TestCheckDBPrivilege(c *C) { - rootSe := newSession(c, s.store, s.dbName) - mustExec(c, rootSe, `CREATE USER 'testcheck'@'localhost';`) - mustExec(c, rootSe, `CREATE USER 'testcheck_tmp'@'localhost';`) - - se := newSession(c, s.store, s.dbName) + se := newSession(t, store, dbName) activeRoles := make([]*auth.RoleIdentity, 0) - c.Assert(se.Auth(&auth.UserIdentity{Username: "testcheck", Hostname: "localhost"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "testcheck", Hostname: "localhost"}, nil, nil)) pc := privilege.GetPrivilegeManager(se) - c.Assert(pc.RequestVerification(activeRoles, "test", "", "", mysql.SelectPriv), IsFalse) + require.False(t, pc.RequestVerification(activeRoles, "test", "", "", mysql.SelectPriv)) - mustExec(c, rootSe, `GRANT SELECT ON *.* TO 'testcheck'@'localhost';`) - c.Assert(pc.RequestVerification(activeRoles, "test", "", "", mysql.SelectPriv), IsTrue) - c.Assert(pc.RequestVerification(activeRoles, "test", "", "", mysql.UpdatePriv), IsFalse) + mustExec(t, rootSe, `GRANT SELECT ON *.* TO 'testcheck'@'localhost';`) + require.True(t, pc.RequestVerification(activeRoles, "test", "", "", mysql.SelectPriv)) + require.False(t, pc.RequestVerification(activeRoles, "test", "", "", mysql.UpdatePriv)) - mustExec(c, rootSe, `GRANT Update ON test.* TO 'testcheck'@'localhost';`) - c.Assert(pc.RequestVerification(activeRoles, "test", "", "", mysql.UpdatePriv), IsTrue) + mustExec(t, rootSe, `GRANT Update ON test.* TO 'testcheck'@'localhost';`) + require.True(t, pc.RequestVerification(activeRoles, "test", "", "", mysql.UpdatePriv)) activeRoles = append(activeRoles, &auth.RoleIdentity{Username: "testcheck", Hostname: "localhost"}) - mustExec(c, rootSe, `GRANT 'testcheck'@'localhost' TO 'testcheck_tmp'@'localhost';`) - se2 := newSession(c, s.store, s.dbName) - c.Assert(se2.Auth(&auth.UserIdentity{Username: "testcheck_tmp", Hostname: "localhost"}, nil, nil), IsTrue) + mustExec(t, rootSe, `GRANT 'testcheck'@'localhost' TO 'testcheck_tmp'@'localhost';`) + se2 := newSession(t, store, dbName) + require.True(t, se2.Auth(&auth.UserIdentity{Username: "testcheck_tmp", Hostname: "localhost"}, nil, nil)) pc = privilege.GetPrivilegeManager(se2) - c.Assert(pc.RequestVerification(activeRoles, "test", "", "", mysql.SelectPriv), IsTrue) - c.Assert(pc.RequestVerification(activeRoles, "test", "", "", mysql.UpdatePriv), IsTrue) + require.True(t, pc.RequestVerification(activeRoles, "test", "", "", mysql.SelectPriv)) + require.True(t, pc.RequestVerification(activeRoles, "test", "", "", mysql.UpdatePriv)) } -func (s *testPrivilegeSuite) TestCheckPointGetDBPrivilege(c *C) { - rootSe := newSession(c, s.store, s.dbName) - mustExec(c, rootSe, `CREATE USER 'tester'@'localhost';`) - mustExec(c, rootSe, `GRANT SELECT,UPDATE ON test.* TO 'tester'@'localhost';`) - mustExec(c, rootSe, `flush privileges;`) - mustExec(c, rootSe, `create database test2`) - mustExec(c, rootSe, `create table test2.t(id int, v int, primary key(id))`) - mustExec(c, rootSe, `insert into test2.t(id, v) values(1, 1)`) - - se := newSession(c, s.store, s.dbName) - c.Assert(se.Auth(&auth.UserIdentity{Username: "tester", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, `use test;`) +func TestCheckPointGetDBPrivilege(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + rootSe := newSession(t, store, dbName) + mustExec(t, rootSe, `CREATE USER 'tester'@'localhost';`) + mustExec(t, rootSe, `GRANT SELECT,UPDATE ON test.* TO 'tester'@'localhost';`) + mustExec(t, rootSe, `flush privileges;`) + mustExec(t, rootSe, `create database test2`) + mustExec(t, rootSe, `create table test2.t(id int, v int, primary key(id))`) + mustExec(t, rootSe, `insert into test2.t(id, v) values(1, 1)`) + + se := newSession(t, store, dbName) + require.True(t, se.Auth(&auth.UserIdentity{Username: "tester", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, `use test;`) _, err := se.ExecuteInternal(context.Background(), `select * from test2.t where id = 1`) - c.Assert(terror.ErrorEqual(err, core.ErrTableaccessDenied), IsTrue) + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) _, err = se.ExecuteInternal(context.Background(), "update test2.t set v = 2 where id = 1") - c.Assert(terror.ErrorEqual(err, core.ErrTableaccessDenied), IsTrue) + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) } -func (s *testPrivilegeSuite) TestIssue22946(c *C) { - rootSe := newSession(c, s.store, s.dbName) - mustExec(c, rootSe, "create database db1;") - mustExec(c, rootSe, "create database db2;") - mustExec(c, rootSe, "use test;") - mustExec(c, rootSe, "create table a(id int);") - mustExec(c, rootSe, "use db1;") - mustExec(c, rootSe, "create table a(id int primary key,name varchar(20));") - mustExec(c, rootSe, "use db2;") - mustExec(c, rootSe, "create table b(id int primary key,address varchar(50));") - mustExec(c, rootSe, "CREATE USER 'delTest'@'localhost';") - mustExec(c, rootSe, "grant all on db1.* to delTest@'localhost';") - mustExec(c, rootSe, "grant all on db2.* to delTest@'localhost';") - mustExec(c, rootSe, "grant select on test.* to delTest@'localhost';") - mustExec(c, rootSe, "flush privileges;") - - se := newSession(c, s.store, s.dbName) - c.Assert(se.Auth(&auth.UserIdentity{Username: "delTest", Hostname: "localhost"}, nil, nil), IsTrue) +func TestIssue22946(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + rootSe := newSession(t, store, dbName) + mustExec(t, rootSe, "create database db1;") + mustExec(t, rootSe, "create database db2;") + mustExec(t, rootSe, "use test;") + mustExec(t, rootSe, "create table a(id int);") + mustExec(t, rootSe, "use db1;") + mustExec(t, rootSe, "create table a(id int primary key,name varchar(20));") + mustExec(t, rootSe, "use db2;") + mustExec(t, rootSe, "create table b(id int primary key,address varchar(50));") + mustExec(t, rootSe, "CREATE USER 'delTest'@'localhost';") + mustExec(t, rootSe, "grant all on db1.* to delTest@'localhost';") + mustExec(t, rootSe, "grant all on db2.* to delTest@'localhost';") + mustExec(t, rootSe, "grant select on test.* to delTest@'localhost';") + mustExec(t, rootSe, "flush privileges;") + + se := newSession(t, store, dbName) + require.True(t, se.Auth(&auth.UserIdentity{Username: "delTest", Hostname: "localhost"}, nil, nil)) _, err := se.ExecuteInternal(context.Background(), `delete from db1.a as A where exists(select 1 from db2.b as B where A.id = B.id);`) - c.Assert(err, IsNil) - mustExec(c, rootSe, "use db1;") + require.NoError(t, err) + mustExec(t, rootSe, "use db1;") _, err = se.ExecuteInternal(context.Background(), "delete from test.a as A;") - c.Assert(terror.ErrorEqual(err, core.ErrTableaccessDenied), IsTrue) + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) } -func (s *testPrivilegeSuite) TestCheckTablePrivilege(c *C) { - rootSe := newSession(c, s.store, s.dbName) - mustExec(c, rootSe, `CREATE USER 'test1'@'localhost';`) - mustExec(c, rootSe, `CREATE USER 'test1_tmp'@'localhost';`) +func TestCheckTablePrivilege(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + rootSe := newSession(t, store, dbName) + mustExec(t, rootSe, `CREATE USER 'test1'@'localhost';`) + mustExec(t, rootSe, `CREATE USER 'test1_tmp'@'localhost';`) - se := newSession(c, s.store, s.dbName) + se := newSession(t, store, dbName) activeRoles := make([]*auth.RoleIdentity, 0) - c.Assert(se.Auth(&auth.UserIdentity{Username: "test1", Hostname: "localhost"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "test1", Hostname: "localhost"}, nil, nil)) pc := privilege.GetPrivilegeManager(se) - c.Assert(pc.RequestVerification(activeRoles, "test", "test", "", mysql.SelectPriv), IsFalse) + require.False(t, pc.RequestVerification(activeRoles, "test", "test", "", mysql.SelectPriv)) - mustExec(c, rootSe, `GRANT SELECT ON *.* TO 'test1'@'localhost';`) - c.Assert(pc.RequestVerification(activeRoles, "test", "test", "", mysql.SelectPriv), IsTrue) - c.Assert(pc.RequestVerification(activeRoles, "test", "test", "", mysql.UpdatePriv), IsFalse) + mustExec(t, rootSe, `GRANT SELECT ON *.* TO 'test1'@'localhost';`) + require.True(t, pc.RequestVerification(activeRoles, "test", "test", "", mysql.SelectPriv)) + require.False(t, pc.RequestVerification(activeRoles, "test", "test", "", mysql.UpdatePriv)) - mustExec(c, rootSe, `GRANT Update ON test.* TO 'test1'@'localhost';`) - c.Assert(pc.RequestVerification(activeRoles, "test", "test", "", mysql.UpdatePriv), IsTrue) - c.Assert(pc.RequestVerification(activeRoles, "test", "test", "", mysql.IndexPriv), IsFalse) + mustExec(t, rootSe, `GRANT Update ON test.* TO 'test1'@'localhost';`) + require.True(t, pc.RequestVerification(activeRoles, "test", "test", "", mysql.UpdatePriv)) + require.False(t, pc.RequestVerification(activeRoles, "test", "test", "", mysql.IndexPriv)) activeRoles = append(activeRoles, &auth.RoleIdentity{Username: "test1", Hostname: "localhost"}) - se2 := newSession(c, s.store, s.dbName) - mustExec(c, rootSe, `GRANT 'test1'@'localhost' TO 'test1_tmp'@'localhost';`) - c.Assert(se2.Auth(&auth.UserIdentity{Username: "test1_tmp", Hostname: "localhost"}, nil, nil), IsTrue) + se2 := newSession(t, store, dbName) + mustExec(t, rootSe, `GRANT 'test1'@'localhost' TO 'test1_tmp'@'localhost';`) + require.True(t, se2.Auth(&auth.UserIdentity{Username: "test1_tmp", Hostname: "localhost"}, nil, nil)) pc2 := privilege.GetPrivilegeManager(se2) - c.Assert(pc2.RequestVerification(activeRoles, "test", "test", "", mysql.SelectPriv), IsTrue) - c.Assert(pc2.RequestVerification(activeRoles, "test", "test", "", mysql.UpdatePriv), IsTrue) - c.Assert(pc2.RequestVerification(activeRoles, "test", "test", "", mysql.IndexPriv), IsFalse) + require.True(t, pc2.RequestVerification(activeRoles, "test", "test", "", mysql.SelectPriv)) + require.True(t, pc2.RequestVerification(activeRoles, "test", "test", "", mysql.UpdatePriv)) + require.False(t, pc2.RequestVerification(activeRoles, "test", "test", "", mysql.IndexPriv)) - mustExec(c, rootSe, `GRANT Index ON test.test TO 'test1'@'localhost';`) - c.Assert(pc.RequestVerification(activeRoles, "test", "test", "", mysql.IndexPriv), IsTrue) - c.Assert(pc2.RequestVerification(activeRoles, "test", "test", "", mysql.IndexPriv), IsTrue) + mustExec(t, rootSe, `GRANT Index ON test.test TO 'test1'@'localhost';`) + require.True(t, pc.RequestVerification(activeRoles, "test", "test", "", mysql.IndexPriv)) + require.True(t, pc2.RequestVerification(activeRoles, "test", "test", "", mysql.IndexPriv)) } -func (s *testPrivilegeSuite) TestCheckViewPrivilege(c *C) { - rootSe := newSession(c, s.store, s.dbName) - mustExec(c, rootSe, `CREATE USER 'vuser'@'localhost';`) - mustExec(c, rootSe, `CREATE VIEW v AS SELECT * FROM test;`) +func TestCheckViewPrivilege(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + rootSe := newSession(t, store, dbName) + mustExec(t, rootSe, `CREATE USER 'vuser'@'localhost';`) + mustExec(t, rootSe, `CREATE VIEW v AS SELECT * FROM test;`) - se := newSession(c, s.store, s.dbName) + se := newSession(t, store, dbName) activeRoles := make([]*auth.RoleIdentity, 0) - c.Assert(se.Auth(&auth.UserIdentity{Username: "vuser", Hostname: "localhost"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "vuser", Hostname: "localhost"}, nil, nil)) pc := privilege.GetPrivilegeManager(se) - c.Assert(pc.RequestVerification(activeRoles, "test", "v", "", mysql.SelectPriv), IsFalse) + require.False(t, pc.RequestVerification(activeRoles, "test", "v", "", mysql.SelectPriv)) - mustExec(c, rootSe, `GRANT SELECT ON test.v TO 'vuser'@'localhost';`) - c.Assert(pc.RequestVerification(activeRoles, "test", "v", "", mysql.SelectPriv), IsTrue) - c.Assert(pc.RequestVerification(activeRoles, "test", "v", "", mysql.ShowViewPriv), IsFalse) + mustExec(t, rootSe, `GRANT SELECT ON test.v TO 'vuser'@'localhost';`) + require.True(t, pc.RequestVerification(activeRoles, "test", "v", "", mysql.SelectPriv)) + require.False(t, pc.RequestVerification(activeRoles, "test", "v", "", mysql.ShowViewPriv)) - mustExec(c, rootSe, `GRANT SHOW VIEW ON test.v TO 'vuser'@'localhost';`) - c.Assert(pc.RequestVerification(activeRoles, "test", "v", "", mysql.SelectPriv), IsTrue) - c.Assert(pc.RequestVerification(activeRoles, "test", "v", "", mysql.ShowViewPriv), IsTrue) + mustExec(t, rootSe, `GRANT SHOW VIEW ON test.v TO 'vuser'@'localhost';`) + require.True(t, pc.RequestVerification(activeRoles, "test", "v", "", mysql.SelectPriv)) + require.True(t, pc.RequestVerification(activeRoles, "test", "v", "", mysql.ShowViewPriv)) } -func (s *testPrivilegeSuite) TestCheckPrivilegeWithRoles(c *C) { - rootSe := newSession(c, s.store, s.dbName) - mustExec(c, rootSe, `CREATE USER 'test_role'@'localhost';`) - mustExec(c, rootSe, `CREATE ROLE r_1, r_2, r_3;`) - mustExec(c, rootSe, `GRANT r_1, r_2, r_3 TO 'test_role'@'localhost';`) - - se := newSession(c, s.store, s.dbName) - c.Assert(se.Auth(&auth.UserIdentity{Username: "test_role", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, `SET ROLE r_1, r_2;`) - mustExec(c, rootSe, `SET DEFAULT ROLE r_1 TO 'test_role'@'localhost';`) - - mustExec(c, rootSe, `GRANT SELECT ON test.* TO r_1;`) +func TestCheckPrivilegeWithRoles(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + rootSe := newSession(t, store, dbName) + mustExec(t, rootSe, `CREATE USER 'test_role'@'localhost';`) + mustExec(t, rootSe, `CREATE ROLE r_1, r_2, r_3;`) + mustExec(t, rootSe, `GRANT r_1, r_2, r_3 TO 'test_role'@'localhost';`) + + se := newSession(t, store, dbName) + require.True(t, se.Auth(&auth.UserIdentity{Username: "test_role", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, `SET ROLE r_1, r_2;`) + mustExec(t, rootSe, `SET DEFAULT ROLE r_1 TO 'test_role'@'localhost';`) + + mustExec(t, rootSe, `GRANT SELECT ON test.* TO r_1;`) pc := privilege.GetPrivilegeManager(se) activeRoles := se.GetSessionVars().ActiveRoles - c.Assert(pc.RequestVerification(activeRoles, "test", "", "", mysql.SelectPriv), IsTrue) - c.Assert(pc.RequestVerification(activeRoles, "test", "", "", mysql.UpdatePriv), IsFalse) - mustExec(c, rootSe, `GRANT UPDATE ON test.* TO r_2;`) - c.Assert(pc.RequestVerification(activeRoles, "test", "", "", mysql.UpdatePriv), IsTrue) - - mustExec(c, se, `SET ROLE NONE;`) - c.Assert(len(se.GetSessionVars().ActiveRoles), Equals, 0) - mustExec(c, se, `SET ROLE DEFAULT;`) - c.Assert(len(se.GetSessionVars().ActiveRoles), Equals, 1) - mustExec(c, se, `SET ROLE ALL;`) - c.Assert(len(se.GetSessionVars().ActiveRoles), Equals, 3) - mustExec(c, se, `SET ROLE ALL EXCEPT r_1, r_2;`) - c.Assert(len(se.GetSessionVars().ActiveRoles), Equals, 1) + require.True(t, pc.RequestVerification(activeRoles, "test", "", "", mysql.SelectPriv)) + require.False(t, pc.RequestVerification(activeRoles, "test", "", "", mysql.UpdatePriv)) + mustExec(t, rootSe, `GRANT UPDATE ON test.* TO r_2;`) + require.True(t, pc.RequestVerification(activeRoles, "test", "", "", mysql.UpdatePriv)) + + mustExec(t, se, `SET ROLE NONE;`) + require.Equal(t, 0, len(se.GetSessionVars().ActiveRoles)) + mustExec(t, se, `SET ROLE DEFAULT;`) + require.Equal(t, 1, len(se.GetSessionVars().ActiveRoles)) + mustExec(t, se, `SET ROLE ALL;`) + require.Equal(t, 3, len(se.GetSessionVars().ActiveRoles)) + mustExec(t, se, `SET ROLE ALL EXCEPT r_1, r_2;`) + require.Equal(t, 1, len(se.GetSessionVars().ActiveRoles)) } -func (s *testPrivilegeSuite) TestShowGrants(c *C) { - se := newSession(c, s.store, s.dbName) +func TestShowGrants(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se := newSession(t, store, dbName) ctx, _ := se.(sessionctx.Context) - mustExec(c, se, `CREATE USER 'show'@'localhost' identified by '123';`) - mustExec(c, se, `GRANT Index ON *.* TO 'show'@'localhost';`) + mustExec(t, se, `CREATE USER 'show'@'localhost' identified by '123';`) + mustExec(t, se, `GRANT Index ON *.* TO 'show'@'localhost';`) pc := privilege.GetPrivilegeManager(se) gs, err := pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 1) - c.Assert(gs[0], Equals, `GRANT INDEX ON *.* TO 'show'@'localhost'`) + require.NoError(t, err) + require.Len(t, gs, 1) + require.Equal(t, `GRANT INDEX ON *.* TO 'show'@'localhost'`, gs[0]) - mustExec(c, se, `GRANT Select ON *.* TO 'show'@'localhost';`) + mustExec(t, se, `GRANT Select ON *.* TO 'show'@'localhost';`) gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 1) - c.Assert(gs[0], Equals, `GRANT SELECT,INDEX ON *.* TO 'show'@'localhost'`) + require.NoError(t, err) + require.Len(t, gs, 1) + require.Equal(t, `GRANT SELECT,INDEX ON *.* TO 'show'@'localhost'`, gs[0]) // The order of privs is the same with AllGlobalPrivs - mustExec(c, se, `GRANT Update ON *.* TO 'show'@'localhost';`) + mustExec(t, se, `GRANT Update ON *.* TO 'show'@'localhost';`) gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 1) - c.Assert(gs[0], Equals, `GRANT SELECT,UPDATE,INDEX ON *.* TO 'show'@'localhost'`) + require.NoError(t, err) + require.Len(t, gs, 1) + require.Equal(t, `GRANT SELECT,UPDATE,INDEX ON *.* TO 'show'@'localhost'`, gs[0]) // All privileges - mustExec(c, se, `GRANT ALL ON *.* TO 'show'@'localhost';`) + mustExec(t, se, `GRANT ALL ON *.* TO 'show'@'localhost';`) gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 1) - c.Assert(gs[0], Equals, `GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`) + require.NoError(t, err) + require.Len(t, gs, 1) + require.Equal(t, `GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`, gs[0]) // All privileges with grant option - mustExec(c, se, `GRANT ALL ON *.* TO 'show'@'localhost' WITH GRANT OPTION;`) + mustExec(t, se, `GRANT ALL ON *.* TO 'show'@'localhost' WITH GRANT OPTION;`) gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 1) - c.Assert(gs[0], Equals, `GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost' WITH GRANT OPTION`) + require.NoError(t, err) + require.Len(t, gs, 1) + require.Equal(t, `GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost' WITH GRANT OPTION`, gs[0]) // Revoke grant option - mustExec(c, se, `REVOKE GRANT OPTION ON *.* FROM 'show'@'localhost';`) + mustExec(t, se, `REVOKE GRANT OPTION ON *.* FROM 'show'@'localhost';`) gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 1) - c.Assert(gs[0], Equals, `GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`) + require.NoError(t, err) + require.Len(t, gs, 1) + require.Equal(t, `GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`, gs[0]) // Add db scope privileges - mustExec(c, se, `GRANT Select ON test.* TO 'show'@'localhost';`) + mustExec(t, se, `GRANT Select ON test.* TO 'show'@'localhost';`) gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 2) + require.NoError(t, err) + require.Len(t, gs, 2) expected := []string{`GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`, `GRANT SELECT ON test.* TO 'show'@'localhost'`} - c.Assert(testutil.CompareUnorderedStringSlice(gs, expected), IsTrue) + require.True(t, testutil.CompareUnorderedStringSlice(gs, expected)) - mustExec(c, se, `GRANT Index ON test1.* TO 'show'@'localhost';`) + mustExec(t, se, `GRANT Index ON test1.* TO 'show'@'localhost';`) gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 3) + require.NoError(t, err) + require.Len(t, gs, 3) expected = []string{`GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`, `GRANT SELECT ON test.* TO 'show'@'localhost'`, `GRANT INDEX ON test1.* TO 'show'@'localhost'`} - c.Assert(testutil.CompareUnorderedStringSlice(gs, expected), IsTrue) + require.True(t, testutil.CompareUnorderedStringSlice(gs, expected)) - mustExec(c, se, `GRANT ALL ON test1.* TO 'show'@'localhost';`) + mustExec(t, se, `GRANT ALL ON test1.* TO 'show'@'localhost';`) gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 3) + require.NoError(t, err) + require.Len(t, gs, 3) expected = []string{`GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`, `GRANT SELECT ON test.* TO 'show'@'localhost'`, `GRANT ALL PRIVILEGES ON test1.* TO 'show'@'localhost'`} - c.Assert(testutil.CompareUnorderedStringSlice(gs, expected), IsTrue) + require.True(t, testutil.CompareUnorderedStringSlice(gs, expected)) // Add table scope privileges - mustExec(c, se, `GRANT Update ON test.test TO 'show'@'localhost';`) + mustExec(t, se, `GRANT Update ON test.test TO 'show'@'localhost';`) gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 4) + require.NoError(t, err) + require.Len(t, gs, 4) expected = []string{`GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`, `GRANT SELECT ON test.* TO 'show'@'localhost'`, `GRANT ALL PRIVILEGES ON test1.* TO 'show'@'localhost'`, `GRANT UPDATE ON test.test TO 'show'@'localhost'`} - c.Assert(testutil.CompareUnorderedStringSlice(gs, expected), IsTrue) + require.True(t, testutil.CompareUnorderedStringSlice(gs, expected)) // Expected behavior: Usage still exists after revoking all privileges - mustExec(c, se, `REVOKE ALL PRIVILEGES ON *.* FROM 'show'@'localhost'`) - mustExec(c, se, `REVOKE Select on test.* FROM 'show'@'localhost'`) - mustExec(c, se, `REVOKE ALL ON test1.* FROM 'show'@'localhost'`) - mustExec(c, se, `REVOKE UPDATE on test.test FROM 'show'@'localhost'`) + mustExec(t, se, `REVOKE ALL PRIVILEGES ON *.* FROM 'show'@'localhost'`) + mustExec(t, se, `REVOKE Select on test.* FROM 'show'@'localhost'`) + mustExec(t, se, `REVOKE ALL ON test1.* FROM 'show'@'localhost'`) + mustExec(t, se, `REVOKE UPDATE on test.test FROM 'show'@'localhost'`) gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 1) - c.Assert(gs[0], Equals, `GRANT USAGE ON *.* TO 'show'@'localhost'`) + require.NoError(t, err) + require.Len(t, gs, 1) + require.Equal(t, `GRANT USAGE ON *.* TO 'show'@'localhost'`, gs[0]) // Usage should not exist after dropping the user // Which we need privileges to do so! ctx.GetSessionVars().User = &auth.UserIdentity{Username: "root", Hostname: "localhost"} - mustExec(c, se, `DROP USER 'show'@'localhost'`) + mustExec(t, se, `DROP USER 'show'@'localhost'`) // This should now return an error _, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil) - c.Assert(err, NotNil) + require.Error(t, err) // cant show grants for non-existent - c.Assert(terror.ErrorEqual(err, privileges.ErrNonexistingGrant), IsTrue) + require.True(t, terror.ErrorEqual(err, privileges.ErrNonexistingGrant)) // Test SHOW GRANTS with USING roles. - mustExec(c, se, `CREATE ROLE 'r1', 'r2'`) - mustExec(c, se, `GRANT SELECT ON test.* TO 'r1'`) - mustExec(c, se, `GRANT INSERT, UPDATE ON test.* TO 'r2'`) - mustExec(c, se, `CREATE USER 'testrole'@'localhost' IDENTIFIED BY 'u1pass'`) - mustExec(c, se, `GRANT 'r1', 'r2' TO 'testrole'@'localhost'`) + mustExec(t, se, `CREATE ROLE 'r1', 'r2'`) + mustExec(t, se, `GRANT SELECT ON test.* TO 'r1'`) + mustExec(t, se, `GRANT INSERT, UPDATE ON test.* TO 'r2'`) + mustExec(t, se, `CREATE USER 'testrole'@'localhost' IDENTIFIED BY 'u1pass'`) + mustExec(t, se, `GRANT 'r1', 'r2' TO 'testrole'@'localhost'`) gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "testrole", Hostname: "localhost"}, nil) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 2) + require.NoError(t, err) + require.Len(t, gs, 2) roles := make([]*auth.RoleIdentity, 0) roles = append(roles, &auth.RoleIdentity{Username: "r2", Hostname: "%"}) - mustExec(c, se, `GRANT DELETE ON test.* TO 'testrole'@'localhost'`) + mustExec(t, se, `GRANT DELETE ON test.* TO 'testrole'@'localhost'`) gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "testrole", Hostname: "localhost"}, roles) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 3) + require.NoError(t, err) + require.Len(t, gs, 3) roles = append(roles, &auth.RoleIdentity{Username: "r1", Hostname: "%"}) gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "testrole", Hostname: "localhost"}, roles) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 3) - mustExec(c, se, `GRANT INSERT, DELETE ON test.test TO 'r2'`) - mustExec(c, se, `create table test.b (id int)`) - mustExec(c, se, `GRANT UPDATE ON test.b TO 'testrole'@'localhost'`) + require.NoError(t, err) + require.Len(t, gs, 3) + mustExec(t, se, `GRANT INSERT, DELETE ON test.test TO 'r2'`) + mustExec(t, se, `create table test.b (id int)`) + mustExec(t, se, `GRANT UPDATE ON test.b TO 'testrole'@'localhost'`) gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "testrole", Hostname: "localhost"}, roles) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 5) - mustExec(c, se, `DROP ROLE 'r1', 'r2'`) - mustExec(c, se, `DROP USER 'testrole'@'localhost'`) - mustExec(c, se, `CREATE ROLE 'r1', 'r2'`) - mustExec(c, se, `GRANT SELECT ON test.* TO 'r2'`) - mustExec(c, se, `CREATE USER 'testrole'@'localhost' IDENTIFIED BY 'u1pass'`) - mustExec(c, se, `GRANT 'r1' TO 'testrole'@'localhost'`) - mustExec(c, se, `GRANT 'r2' TO 'r1'`) + require.NoError(t, err) + require.Len(t, gs, 5) + mustExec(t, se, `DROP ROLE 'r1', 'r2'`) + mustExec(t, se, `DROP USER 'testrole'@'localhost'`) + mustExec(t, se, `CREATE ROLE 'r1', 'r2'`) + mustExec(t, se, `GRANT SELECT ON test.* TO 'r2'`) + mustExec(t, se, `CREATE USER 'testrole'@'localhost' IDENTIFIED BY 'u1pass'`) + mustExec(t, se, `GRANT 'r1' TO 'testrole'@'localhost'`) + mustExec(t, se, `GRANT 'r2' TO 'r1'`) gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "testrole", Hostname: "localhost"}, nil) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 2) + require.NoError(t, err) + require.Len(t, gs, 2) roles = make([]*auth.RoleIdentity, 0) roles = append(roles, &auth.RoleIdentity{Username: "r1", Hostname: "%"}) gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "testrole", Hostname: "localhost"}, roles) - c.Assert(err, IsNil) - c.Assert(gs, HasLen, 3) + require.NoError(t, err) + require.Len(t, gs, 3) } -func (s *testPrivilegeSuite) TestShowColumnGrants(c *C) { - se := newSession(c, s.store, s.dbName) - mustExec(c, se, `USE test`) - mustExec(c, se, `CREATE USER 'column'@'%'`) - mustExec(c, se, `CREATE TABLE column_table (a int, b int, c int)`) - mustExec(c, se, `GRANT Select(a),Update(a,b),Insert(c) ON test.column_table TO 'column'@'%'`) +func TestShowColumnGrants(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + se := newSession(t, store, dbName) + mustExec(t, se, `USE test`) + mustExec(t, se, `CREATE USER 'column'@'%'`) + mustExec(t, se, `CREATE TABLE column_table (a int, b int, c int)`) + mustExec(t, se, `GRANT Select(a),Update(a,b),Insert(c) ON test.column_table TO 'column'@'%'`) pc := privilege.GetPrivilegeManager(se) gs, err := pc.ShowGrants(se, &auth.UserIdentity{Username: "column", Hostname: "%"}, nil) - c.Assert(err, IsNil) - c.Assert(strings.Join(gs, " "), Equals, "GRANT USAGE ON *.* TO 'column'@'%' GRANT SELECT(a), INSERT(c), UPDATE(a, b) ON test.column_table TO 'column'@'%'") + require.NoError(t, err) + require.Equal(t, "GRANT USAGE ON *.* TO 'column'@'%' GRANT SELECT(a), INSERT(c), UPDATE(a, b) ON test.column_table TO 'column'@'%'", strings.Join(gs, " ")) } -func (s *testPrivilegeSuite) TestDropTablePriv(c *C) { - se := newSession(c, s.store, s.dbName) +func TestDropTablePrivileges(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se := newSession(t, store, dbName) ctx, _ := se.(sessionctx.Context) - mustExec(c, se, `CREATE TABLE todrop(c int);`) + mustExec(t, se, `CREATE TABLE todrop(c int);`) // ctx.GetSessionVars().User = "root@localhost" - c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, `CREATE USER 'drop'@'localhost';`) - mustExec(c, se, `GRANT Select ON test.todrop TO 'drop'@'localhost';`) + require.True(t, se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, `CREATE USER 'drop'@'localhost';`) + mustExec(t, se, `GRANT Select ON test.todrop TO 'drop'@'localhost';`) // ctx.GetSessionVars().User = "drop@localhost" - c.Assert(se.Auth(&auth.UserIdentity{Username: "drop", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, `SELECT * FROM todrop;`) + require.True(t, se.Auth(&auth.UserIdentity{Username: "drop", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, `SELECT * FROM todrop;`) _, err := se.ExecuteInternal(context.Background(), "DROP TABLE todrop;") - c.Assert(err, NotNil) + require.Error(t, err) - se = newSession(c, s.store, s.dbName) + se = newSession(t, store, dbName) ctx.GetSessionVars().User = &auth.UserIdentity{Username: "root", Hostname: "localhost"} - mustExec(c, se, `GRANT Drop ON test.todrop TO 'drop'@'localhost';`) + mustExec(t, se, `GRANT Drop ON test.todrop TO 'drop'@'localhost';`) - se = newSession(c, s.store, s.dbName) + se = newSession(t, store, dbName) ctx.GetSessionVars().User = &auth.UserIdentity{Username: "drop", Hostname: "localhost"} - mustExec(c, se, `DROP TABLE todrop;`) + mustExec(t, se, `DROP TABLE todrop;`) } -func (s *testPrivilegeSuite) TestSetPasswdStmt(c *C) { - - se := newSession(c, s.store, s.dbName) +func TestSetPasswdStmt(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + se := newSession(t, store, dbName) // high privileged user setting password for other user (passes) - mustExec(c, se, "CREATE USER 'superuser'") - mustExec(c, se, "CREATE USER 'nobodyuser'") - mustExec(c, se, "GRANT ALL ON *.* TO 'superuser'") + mustExec(t, se, "CREATE USER 'superuser'") + mustExec(t, se, "CREATE USER 'nobodyuser'") + mustExec(t, se, "GRANT ALL ON *.* TO 'superuser'") - c.Assert(se.Auth(&auth.UserIdentity{Username: "superuser", Hostname: "localhost", AuthUsername: "superuser", AuthHostname: "%"}, nil, nil), IsTrue) - mustExec(c, se, "SET PASSWORD for 'nobodyuser' = 'newpassword'") - mustExec(c, se, "SET PASSWORD for 'nobodyuser' = ''") + require.True(t, se.Auth(&auth.UserIdentity{Username: "superuser", Hostname: "localhost", AuthUsername: "superuser", AuthHostname: "%"}, nil, nil)) + mustExec(t, se, "SET PASSWORD for 'nobodyuser' = 'newpassword'") + mustExec(t, se, "SET PASSWORD for 'nobodyuser' = ''") // low privileged user trying to set password for other user (fails) - c.Assert(se.Auth(&auth.UserIdentity{Username: "nobodyuser", Hostname: "localhost", AuthUsername: "nobodyuser", AuthHostname: "%"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "nobodyuser", Hostname: "localhost", AuthUsername: "nobodyuser", AuthHostname: "%"}, nil, nil)) _, err := se.ExecuteInternal(context.Background(), "SET PASSWORD for 'superuser' = 'newpassword'") - c.Assert(err, NotNil) + require.Error(t, err) } -func (s *testPrivilegeSuite) TestAlterUserStmt(c *C) { - se := newSession(c, s.store, s.dbName) +func TestAlterUserStmt(t *testing.T) { + store, clean := newStore(t) + defer clean() + se := newSession(t, store, dbName) // high privileged user setting password for other user (passes) - mustExec(c, se, "CREATE USER superuser2, nobodyuser2, nobodyuser3, nobodyuser4, nobodyuser5, semuser1, semuser2, semuser3, semuser4") - mustExec(c, se, "GRANT ALL ON *.* TO superuser2") - mustExec(c, se, "GRANT CREATE USER ON *.* TO nobodyuser2") - mustExec(c, se, "GRANT SYSTEM_USER ON *.* TO nobodyuser4") - mustExec(c, se, "GRANT UPDATE ON mysql.user TO nobodyuser5, semuser1") - mustExec(c, se, "GRANT RESTRICTED_TABLES_ADMIN ON *.* TO semuser1") - mustExec(c, se, "GRANT RESTRICTED_USER_ADMIN ON *.* TO semuser1, semuser2, semuser3") - mustExec(c, se, "GRANT SYSTEM_USER ON *.* to semuser3") // user is both restricted + has SYSTEM_USER (or super) - - c.Assert(se.Auth(&auth.UserIdentity{Username: "superuser2", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, "ALTER USER 'nobodyuser2' IDENTIFIED BY 'newpassword'") - mustExec(c, se, "ALTER USER 'nobodyuser2' IDENTIFIED BY ''") + mustExec(t, se, "CREATE USER superuser2, nobodyuser2, nobodyuser3, nobodyuser4, nobodyuser5, semuser1, semuser2, semuser3, semuser4") + mustExec(t, se, "GRANT ALL ON *.* TO superuser2") + mustExec(t, se, "GRANT CREATE USER ON *.* TO nobodyuser2") + mustExec(t, se, "GRANT SYSTEM_USER ON *.* TO nobodyuser4") + mustExec(t, se, "GRANT UPDATE ON mysql.user TO nobodyuser5, semuser1") + mustExec(t, se, "GRANT RESTRICTED_TABLES_ADMIN ON *.* TO semuser1") + mustExec(t, se, "GRANT RESTRICTED_USER_ADMIN ON *.* TO semuser1, semuser2, semuser3") + mustExec(t, se, "GRANT SYSTEM_USER ON *.* to semuser3") // user is both restricted + has SYSTEM_USER (or super) + + require.True(t, se.Auth(&auth.UserIdentity{Username: "superuser2", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, "ALTER USER 'nobodyuser2' IDENTIFIED BY 'newpassword'") + mustExec(t, se, "ALTER USER 'nobodyuser2' IDENTIFIED BY ''") // low privileged user trying to set password for others // nobodyuser3 = SUCCESS (not a SYSTEM_USER) // nobodyuser4 = FAIL (has SYSTEM_USER) // superuser2 = FAIL (has SYSTEM_USER privilege implied by SUPER) - c.Assert(se.Auth(&auth.UserIdentity{Username: "nobodyuser2", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, "ALTER USER 'nobodyuser2' IDENTIFIED BY 'newpassword'") - mustExec(c, se, "ALTER USER 'nobodyuser2' IDENTIFIED BY ''") - mustExec(c, se, "ALTER USER 'nobodyuser3' IDENTIFIED BY ''") + require.True(t, se.Auth(&auth.UserIdentity{Username: "nobodyuser2", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, "ALTER USER 'nobodyuser2' IDENTIFIED BY 'newpassword'") + mustExec(t, se, "ALTER USER 'nobodyuser2' IDENTIFIED BY ''") + mustExec(t, se, "ALTER USER 'nobodyuser3' IDENTIFIED BY ''") _, err := se.ExecuteInternal(context.Background(), "ALTER USER 'nobodyuser4' IDENTIFIED BY 'newpassword'") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the SYSTEM_USER or SUPER privilege(s) for this operation") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the SYSTEM_USER or SUPER privilege(s) for this operation") _, err = se.ExecuteInternal(context.Background(), "ALTER USER 'superuser2' IDENTIFIED BY 'newpassword'") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the SYSTEM_USER or SUPER privilege(s) for this operation") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the SYSTEM_USER or SUPER privilege(s) for this operation") // Nobody3 has no privileges at all, but they can still alter their own password. // Any other user fails. - c.Assert(se.Auth(&auth.UserIdentity{Username: "nobodyuser3", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, "ALTER USER 'nobodyuser3' IDENTIFIED BY ''") + require.True(t, se.Auth(&auth.UserIdentity{Username: "nobodyuser3", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, "ALTER USER 'nobodyuser3' IDENTIFIED BY ''") _, err = se.ExecuteInternal(context.Background(), "ALTER USER 'nobodyuser4' IDENTIFIED BY 'newpassword'") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation") _, err = se.ExecuteInternal(context.Background(), "ALTER USER 'superuser2' IDENTIFIED BY 'newpassword'") // it checks create user before SYSTEM_USER - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation") // Nobody5 doesn't explicitly have CREATE USER, but mysql also accepts UDPATE on mysql.user // as a substitute so it can modify nobody2 and nobody3 but not nobody4 - c.Assert(se.Auth(&auth.UserIdentity{Username: "nobodyuser5", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, "ALTER USER 'nobodyuser2' IDENTIFIED BY ''") - mustExec(c, se, "ALTER USER 'nobodyuser3' IDENTIFIED BY ''") + require.True(t, se.Auth(&auth.UserIdentity{Username: "nobodyuser5", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, "ALTER USER 'nobodyuser2' IDENTIFIED BY ''") + mustExec(t, se, "ALTER USER 'nobodyuser3' IDENTIFIED BY ''") _, err = se.ExecuteInternal(context.Background(), "ALTER USER 'nobodyuser4' IDENTIFIED BY 'newpassword'") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the SYSTEM_USER or SUPER privilege(s) for this operation") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the SYSTEM_USER or SUPER privilege(s) for this operation") - c.Assert(se.Auth(&auth.UserIdentity{Username: "semuser1", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, "ALTER USER 'semuser1' IDENTIFIED BY ''") - mustExec(c, se, "ALTER USER 'semuser2' IDENTIFIED BY ''") - mustExec(c, se, "ALTER USER 'semuser3' IDENTIFIED BY ''") + require.True(t, se.Auth(&auth.UserIdentity{Username: "semuser1", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, "ALTER USER 'semuser1' IDENTIFIED BY ''") + mustExec(t, se, "ALTER USER 'semuser2' IDENTIFIED BY ''") + mustExec(t, se, "ALTER USER 'semuser3' IDENTIFIED BY ''") sem.Enable() defer sem.Disable() @@ -532,148 +498,159 @@ func (s *testPrivilegeSuite) TestAlterUserStmt(c *C) { // any request for UpdatePriv on mysql.user even if the privilege exists in the internal mysql.user table. // UpdatePriv on mysql.user - c.Assert(se.Auth(&auth.UserIdentity{Username: "nobodyuser5", Hostname: "localhost"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "nobodyuser5", Hostname: "localhost"}, nil, nil)) _, err = se.ExecuteInternal(context.Background(), "ALTER USER 'nobodyuser2' IDENTIFIED BY 'newpassword'") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation") // actual CreateUserPriv - c.Assert(se.Auth(&auth.UserIdentity{Username: "nobodyuser2", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, "ALTER USER 'nobodyuser2' IDENTIFIED BY ''") - mustExec(c, se, "ALTER USER 'nobodyuser3' IDENTIFIED BY ''") + require.True(t, se.Auth(&auth.UserIdentity{Username: "nobodyuser2", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, "ALTER USER 'nobodyuser2' IDENTIFIED BY ''") + mustExec(t, se, "ALTER USER 'nobodyuser3' IDENTIFIED BY ''") // UpdatePriv on mysql.user but also has RESTRICTED_TABLES_ADMIN - c.Assert(se.Auth(&auth.UserIdentity{Username: "semuser1", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, "ALTER USER 'nobodyuser2' IDENTIFIED BY ''") - mustExec(c, se, "ALTER USER 'nobodyuser3' IDENTIFIED BY ''") + require.True(t, se.Auth(&auth.UserIdentity{Username: "semuser1", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, "ALTER USER 'nobodyuser2' IDENTIFIED BY ''") + mustExec(t, se, "ALTER USER 'nobodyuser3' IDENTIFIED BY ''") // As it has (RESTRICTED_TABLES_ADMIN + UpdatePriv on mysql.user) + RESTRICTED_USER_ADMIN it can modify other restricted_user_admins like semuser2 // and it can modify semuser3 because RESTRICTED_USER_ADMIN does not also need SYSTEM_USER - mustExec(c, se, "ALTER USER 'semuser1' IDENTIFIED BY ''") - mustExec(c, se, "ALTER USER 'semuser2' IDENTIFIED BY ''") - mustExec(c, se, "ALTER USER 'semuser3' IDENTIFIED BY ''") + mustExec(t, se, "ALTER USER 'semuser1' IDENTIFIED BY ''") + mustExec(t, se, "ALTER USER 'semuser2' IDENTIFIED BY ''") + mustExec(t, se, "ALTER USER 'semuser3' IDENTIFIED BY ''") - c.Assert(se.Auth(&auth.UserIdentity{Username: "superuser2", Hostname: "localhost"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "superuser2", Hostname: "localhost"}, nil, nil)) _, err = se.ExecuteInternal(context.Background(), "ALTER USER 'semuser1' IDENTIFIED BY 'newpassword'") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the RESTRICTED_USER_ADMIN privilege(s) for this operation") - - c.Assert(se.Auth(&auth.UserIdentity{Username: "semuser4", Hostname: "localhost"}, nil, nil), IsTrue) + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the RESTRICTED_USER_ADMIN privilege(s) for this operation") + require.True(t, se.Auth(&auth.UserIdentity{Username: "semuser4", Hostname: "localhost"}, nil, nil)) // has restricted_user_admin but not CREATE USER or (update on mysql.user + RESTRICTED_TABLES_ADMIN) - mustExec(c, se, "ALTER USER 'semuser4' IDENTIFIED BY ''") // can modify self + mustExec(t, se, "ALTER USER 'semuser4' IDENTIFIED BY ''") // can modify self _, err = se.ExecuteInternal(context.Background(), "ALTER USER 'nobodyuser3' IDENTIFIED BY 'newpassword'") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation") _, err = se.ExecuteInternal(context.Background(), "ALTER USER 'semuser1' IDENTIFIED BY 'newpassword'") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation") _, err = se.ExecuteInternal(context.Background(), "ALTER USER 'semuser3' IDENTIFIED BY 'newpassword'") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation") } -func (s *testPrivilegeSuite) TestSelectViewSecurity(c *C) { - se := newSession(c, s.store, s.dbName) +func TestSelectViewSecurity(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se := newSession(t, store, dbName) ctx, _ := se.(sessionctx.Context) - mustExec(c, se, `CREATE TABLE viewsecurity(c int);`) + mustExec(t, se, `CREATE TABLE viewsecurity(c int);`) // ctx.GetSessionVars().User = "root@localhost" - c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, `CREATE USER 'selectusr'@'localhost';`) - mustExec(c, se, `GRANT CREATE VIEW ON test.* TO 'selectusr'@'localhost';`) - mustExec(c, se, `GRANT SELECT ON test.viewsecurity TO 'selectusr'@'localhost';`) + require.True(t, se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, `CREATE USER 'selectusr'@'localhost';`) + mustExec(t, se, `GRANT CREATE VIEW ON test.* TO 'selectusr'@'localhost';`) + mustExec(t, se, `GRANT SELECT ON test.viewsecurity TO 'selectusr'@'localhost';`) // ctx.GetSessionVars().User = "selectusr@localhost" - c.Assert(se.Auth(&auth.UserIdentity{Username: "selectusr", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, `SELECT * FROM test.viewsecurity;`) - mustExec(c, se, `CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW test.selectviewsecurity as select * FROM test.viewsecurity;`) + require.True(t, se.Auth(&auth.UserIdentity{Username: "selectusr", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, `SELECT * FROM test.viewsecurity;`) + mustExec(t, se, `CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW test.selectviewsecurity as select * FROM test.viewsecurity;`) - se = newSession(c, s.store, s.dbName) + se = newSession(t, store, dbName) ctx.GetSessionVars().User = &auth.UserIdentity{Username: "root", Hostname: "localhost"} - mustExec(c, se, "SELECT * FROM test.selectviewsecurity") - mustExec(c, se, `REVOKE Select ON test.viewsecurity FROM 'selectusr'@'localhost';`) + mustExec(t, se, "SELECT * FROM test.selectviewsecurity") + mustExec(t, se, `REVOKE Select ON test.viewsecurity FROM 'selectusr'@'localhost';`) _, err := se.ExecuteInternal(context.Background(), "select * from test.selectviewsecurity") - c.Assert(err.Error(), Equals, core.ErrViewInvalid.GenWithStackByArgs("test", "selectviewsecurity").Error()) + require.EqualError(t, err, core.ErrViewInvalid.GenWithStackByArgs("test", "selectviewsecurity").Error()) } -func (s *testPrivilegeSuite) TestRoleAdminSecurity(c *C) { - se := newSession(c, s.store, s.dbName) - mustExec(c, se, `CREATE USER 'ar1'@'localhost';`) - mustExec(c, se, `CREATE USER 'ar2'@'localhost';`) - mustExec(c, se, `GRANT ALL ON *.* to ar1@localhost`) +func TestRoleAdminSecurity(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se := newSession(t, store, dbName) + mustExec(t, se, `CREATE USER 'ar1'@'localhost';`) + mustExec(t, se, `CREATE USER 'ar2'@'localhost';`) + mustExec(t, se, `GRANT ALL ON *.* to ar1@localhost`) defer func() { - c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil), IsTrue) - mustExec(c, se, "drop user 'ar1'@'localhost'") - mustExec(c, se, "drop user 'ar2'@'localhost'") + require.True(t, se.Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + mustExec(t, se, "drop user 'ar1'@'localhost'") + mustExec(t, se, "drop user 'ar2'@'localhost'") }() - c.Assert(se.Auth(&auth.UserIdentity{Username: "ar1", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, `create role r_test1@localhost`) + require.True(t, se.Auth(&auth.UserIdentity{Username: "ar1", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, `create role r_test1@localhost`) - c.Assert(se.Auth(&auth.UserIdentity{Username: "ar2", Hostname: "localhost"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "ar2", Hostname: "localhost"}, nil, nil)) _, err := se.ExecuteInternal(context.Background(), `create role r_test2@localhost`) - c.Assert(terror.ErrorEqual(err, core.ErrSpecificAccessDenied), IsTrue) + require.True(t, terror.ErrorEqual(err, core.ErrSpecificAccessDenied)) } -func (s *testPrivilegeSuite) TestCheckCertBasedAuth(c *C) { - se := newSession(c, s.store, s.dbName) - mustExec(c, se, `CREATE USER 'r1'@'localhost';`) - mustExec(c, se, `CREATE USER 'r2'@'localhost' require none;`) - mustExec(c, se, `CREATE USER 'r3'@'localhost' require ssl;`) - mustExec(c, se, `CREATE USER 'r4'@'localhost' require x509;`) - mustExec(c, se, `CREATE USER 'r5'@'localhost' require issuer '/C=US/ST=California/L=San Francisco/O=PingCAP/OU=TiDB/CN=TiDB admin' +func TestCheckCertBasedAuth(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se := newSession(t, store, dbName) + mustExec(t, se, `CREATE USER 'r1'@'localhost';`) + mustExec(t, se, `CREATE USER 'r2'@'localhost' require none;`) + mustExec(t, se, `CREATE USER 'r3'@'localhost' require ssl;`) + mustExec(t, se, `CREATE USER 'r4'@'localhost' require x509;`) + mustExec(t, se, `CREATE USER 'r5'@'localhost' require issuer '/C=US/ST=California/L=San Francisco/O=PingCAP/OU=TiDB/CN=TiDB admin' subject '/C=ZH/ST=Beijing/L=Haidian/O=PingCAP.Inc/OU=TiDB/CN=tester1' cipher 'TLS_AES_128_GCM_SHA256'`) - mustExec(c, se, `CREATE USER 'r6'@'localhost' require issuer '/C=US/ST=California/L=San Francisco/O=PingCAP/OU=TiDB/CN=TiDB admin' + mustExec(t, se, `CREATE USER 'r6'@'localhost' require issuer '/C=US/ST=California/L=San Francisco/O=PingCAP/OU=TiDB/CN=TiDB admin' subject '/C=ZH/ST=Beijing/L=Haidian/O=PingCAP.Inc/OU=TiDB/CN=tester1'`) - mustExec(c, se, `CREATE USER 'r7_issuer_only'@'localhost' require issuer '/C=US/ST=California/L=San Francisco/O=PingCAP/OU=TiDB/CN=TiDB admin'`) - mustExec(c, se, `CREATE USER 'r8_subject_only'@'localhost' require subject '/C=ZH/ST=Beijing/L=Haidian/O=PingCAP.Inc/OU=TiDB/CN=tester1'`) - mustExec(c, se, `CREATE USER 'r9_subject_disorder'@'localhost' require subject '/ST=Beijing/C=ZH/L=Haidian/O=PingCAP.Inc/OU=TiDB/CN=tester1'`) - mustExec(c, se, `CREATE USER 'r10_issuer_disorder'@'localhost' require issuer '/ST=California/C=US/L=San Francisco/O=PingCAP/OU=TiDB/CN=TiDB admin'`) - mustExec(c, se, `CREATE USER 'r11_cipher_only'@'localhost' require cipher 'TLS_AES_256_GCM_SHA384'`) - mustExec(c, se, `CREATE USER 'r12_old_tidb_user'@'localhost'`) - mustExec(c, se, "DELETE FROM mysql.global_priv WHERE `user` = 'r12_old_tidb_user' and `host` = 'localhost'") - mustExec(c, se, `CREATE USER 'r13_broken_user'@'localhost'require issuer '/C=US/ST=California/L=San Francisco/O=PingCAP/OU=TiDB/CN=TiDB admin' + mustExec(t, se, `CREATE USER 'r7_issuer_only'@'localhost' require issuer '/C=US/ST=California/L=San Francisco/O=PingCAP/OU=TiDB/CN=TiDB admin'`) + mustExec(t, se, `CREATE USER 'r8_subject_only'@'localhost' require subject '/C=ZH/ST=Beijing/L=Haidian/O=PingCAP.Inc/OU=TiDB/CN=tester1'`) + mustExec(t, se, `CREATE USER 'r9_subject_disorder'@'localhost' require subject '/ST=Beijing/C=ZH/L=Haidian/O=PingCAP.Inc/OU=TiDB/CN=tester1'`) + mustExec(t, se, `CREATE USER 'r10_issuer_disorder'@'localhost' require issuer '/ST=California/C=US/L=San Francisco/O=PingCAP/OU=TiDB/CN=TiDB admin'`) + mustExec(t, se, `CREATE USER 'r11_cipher_only'@'localhost' require cipher 'TLS_AES_256_GCM_SHA384'`) + mustExec(t, se, `CREATE USER 'r12_old_tidb_user'@'localhost'`) + mustExec(t, se, "DELETE FROM mysql.global_priv WHERE `user` = 'r12_old_tidb_user' and `host` = 'localhost'") + mustExec(t, se, `CREATE USER 'r13_broken_user'@'localhost'require issuer '/C=US/ST=California/L=San Francisco/O=PingCAP/OU=TiDB/CN=TiDB admin' subject '/C=ZH/ST=Beijing/L=Haidian/O=PingCAP.Inc/OU=TiDB/CN=tester1'`) - mustExec(c, se, "UPDATE mysql.global_priv set priv = 'abc' where `user` = 'r13_broken_user' and `host` = 'localhost'") - mustExec(c, se, `CREATE USER 'r14_san_only_pass'@'localhost' require san 'URI:spiffe://mesh.pingcap.com/ns/timesh/sa/me1'`) - mustExec(c, se, `CREATE USER 'r15_san_only_fail'@'localhost' require san 'URI:spiffe://mesh.pingcap.com/ns/timesh/sa/me2'`) - mustExec(c, se, "flush privileges") + mustExec(t, se, "UPDATE mysql.global_priv set priv = 'abc' where `user` = 'r13_broken_user' and `host` = 'localhost'") + mustExec(t, se, `CREATE USER 'r14_san_only_pass'@'localhost' require san 'URI:spiffe://mesh.pingcap.com/ns/timesh/sa/me1'`) + mustExec(t, se, `CREATE USER 'r15_san_only_fail'@'localhost' require san 'URI:spiffe://mesh.pingcap.com/ns/timesh/sa/me2'`) + mustExec(t, se, "flush privileges") defer func() { - c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil), IsTrue) - mustExec(c, se, "drop user 'r1'@'localhost'") - mustExec(c, se, "drop user 'r2'@'localhost'") - mustExec(c, se, "drop user 'r3'@'localhost'") - mustExec(c, se, "drop user 'r4'@'localhost'") - mustExec(c, se, "drop user 'r5'@'localhost'") - mustExec(c, se, "drop user 'r6'@'localhost'") - mustExec(c, se, "drop user 'r7_issuer_only'@'localhost'") - mustExec(c, se, "drop user 'r8_subject_only'@'localhost'") - mustExec(c, se, "drop user 'r9_subject_disorder'@'localhost'") - mustExec(c, se, "drop user 'r10_issuer_disorder'@'localhost'") - mustExec(c, se, "drop user 'r11_cipher_only'@'localhost'") - mustExec(c, se, "drop user 'r12_old_tidb_user'@'localhost'") - mustExec(c, se, "drop user 'r13_broken_user'@'localhost'") - mustExec(c, se, "drop user 'r14_san_only_pass'@'localhost'") - mustExec(c, se, "drop user 'r15_san_only_fail'@'localhost'") + require.True(t, se.Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil)) + mustExec(t, se, "drop user 'r1'@'localhost'") + mustExec(t, se, "drop user 'r2'@'localhost'") + mustExec(t, se, "drop user 'r3'@'localhost'") + mustExec(t, se, "drop user 'r4'@'localhost'") + mustExec(t, se, "drop user 'r5'@'localhost'") + mustExec(t, se, "drop user 'r6'@'localhost'") + mustExec(t, se, "drop user 'r7_issuer_only'@'localhost'") + mustExec(t, se, "drop user 'r8_subject_only'@'localhost'") + mustExec(t, se, "drop user 'r9_subject_disorder'@'localhost'") + mustExec(t, se, "drop user 'r10_issuer_disorder'@'localhost'") + mustExec(t, se, "drop user 'r11_cipher_only'@'localhost'") + mustExec(t, se, "drop user 'r12_old_tidb_user'@'localhost'") + mustExec(t, se, "drop user 'r13_broken_user'@'localhost'") + mustExec(t, se, "drop user 'r14_san_only_pass'@'localhost'") + mustExec(t, se, "drop user 'r15_san_only_fail'@'localhost'") }() // test without ssl or ca - c.Assert(se.Auth(&auth.UserIdentity{Username: "r1", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r2", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r3", Hostname: "localhost"}, nil, nil), IsFalse) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r4", Hostname: "localhost"}, nil, nil), IsFalse) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil), IsFalse) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r1", Hostname: "localhost"}, nil, nil)) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r2", Hostname: "localhost"}, nil, nil)) + require.False(t, se.Auth(&auth.UserIdentity{Username: "r3", Hostname: "localhost"}, nil, nil)) + require.False(t, se.Auth(&auth.UserIdentity{Username: "r4", Hostname: "localhost"}, nil, nil)) + require.False(t, se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil)) // test use ssl without ca se.GetSessionVars().TLSConnectionState = &tls.ConnectionState{VerifiedChains: nil} - c.Assert(se.Auth(&auth.UserIdentity{Username: "r1", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r2", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r3", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r4", Hostname: "localhost"}, nil, nil), IsFalse) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil), IsFalse) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r1", Hostname: "localhost"}, nil, nil)) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r2", Hostname: "localhost"}, nil, nil)) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r3", Hostname: "localhost"}, nil, nil)) + require.False(t, se.Auth(&auth.UserIdentity{Username: "r4", Hostname: "localhost"}, nil, nil)) + require.False(t, se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil)) // test use ssl with signed but info wrong ca. se.GetSessionVars().TLSConnectionState = &tls.ConnectionState{VerifiedChains: [][]*x509.Certificate{{{}}}} - c.Assert(se.Auth(&auth.UserIdentity{Username: "r1", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r2", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r3", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r4", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil), IsFalse) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r1", Hostname: "localhost"}, nil, nil)) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r2", Hostname: "localhost"}, nil, nil)) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r3", Hostname: "localhost"}, nil, nil)) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r4", Hostname: "localhost"}, nil, nil)) + require.False(t, se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil)) // test a all pass case se.GetSessionVars().TLSConnectionState = connectionState( @@ -700,19 +677,19 @@ func (s *testPrivilegeSuite) TestCheckCertBasedAuth(c *C) { tls.TLS_AES_128_GCM_SHA256, func(cert *x509.Certificate) { var url url.URL err := url.UnmarshalBinary([]byte("spiffe://mesh.pingcap.com/ns/timesh/sa/me1")) - c.Assert(err, IsNil) + require.NoError(t, err) cert.URIs = append(cert.URIs, &url) }) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r1", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r2", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r3", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r4", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r14_san_only_pass", Hostname: "localhost"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r1", Hostname: "localhost"}, nil, nil)) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r2", Hostname: "localhost"}, nil, nil)) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r3", Hostname: "localhost"}, nil, nil)) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r4", Hostname: "localhost"}, nil, nil)) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil)) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r14_san_only_pass", Hostname: "localhost"}, nil, nil)) // test require but give nothing se.GetSessionVars().TLSConnectionState = nil - c.Assert(se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil), IsFalse) + require.False(t, se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil)) // test mismatch cipher se.GetSessionVars().TLSConnectionState = connectionState( @@ -737,9 +714,9 @@ func (s *testPrivilegeSuite) TestCheckCertBasedAuth(c *C) { }, }, tls.TLS_AES_256_GCM_SHA384) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil), IsFalse) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r6", Hostname: "localhost"}, nil, nil), IsTrue) // not require cipher - c.Assert(se.Auth(&auth.UserIdentity{Username: "r11_cipher_only", Hostname: "localhost"}, nil, nil), IsTrue) + require.False(t, se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil)) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r6", Hostname: "localhost"}, nil, nil)) // not require cipher + require.True(t, se.Auth(&auth.UserIdentity{Username: "r11_cipher_only", Hostname: "localhost"}, nil, nil)) // test only subject or only issuer se.GetSessionVars().TLSConnectionState = connectionState( @@ -764,7 +741,7 @@ func (s *testPrivilegeSuite) TestCheckCertBasedAuth(c *C) { }, }, tls.TLS_AES_128_GCM_SHA256) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r7_issuer_only", Hostname: "localhost"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r7_issuer_only", Hostname: "localhost"}, nil, nil)) se.GetSessionVars().TLSConnectionState = connectionState( pkix.Name{ Names: []pkix.AttributeTypeAndValue{ @@ -787,7 +764,7 @@ func (s *testPrivilegeSuite) TestCheckCertBasedAuth(c *C) { }, }, tls.TLS_AES_128_GCM_SHA256) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r8_subject_only", Hostname: "localhost"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r8_subject_only", Hostname: "localhost"}, nil, nil)) // test disorder issuer or subject se.GetSessionVars().TLSConnectionState = connectionState( @@ -805,7 +782,7 @@ func (s *testPrivilegeSuite) TestCheckCertBasedAuth(c *C) { }, }, tls.TLS_AES_128_GCM_SHA256) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r9_subject_disorder", Hostname: "localhost"}, nil, nil), IsFalse) + require.False(t, se.Auth(&auth.UserIdentity{Username: "r9_subject_disorder", Hostname: "localhost"}, nil, nil)) se.GetSessionVars().TLSConnectionState = connectionState( pkix.Name{ Names: []pkix.AttributeTypeAndValue{ @@ -821,14 +798,14 @@ func (s *testPrivilegeSuite) TestCheckCertBasedAuth(c *C) { Names: []pkix.AttributeTypeAndValue{}, }, tls.TLS_AES_128_GCM_SHA256) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r10_issuer_disorder", Hostname: "localhost"}, nil, nil), IsFalse) + require.False(t, se.Auth(&auth.UserIdentity{Username: "r10_issuer_disorder", Hostname: "localhost"}, nil, nil)) // test mismatch san - c.Assert(se.Auth(&auth.UserIdentity{Username: "r15_san_only_fail", Hostname: "localhost"}, nil, nil), IsFalse) + require.False(t, se.Auth(&auth.UserIdentity{Username: "r15_san_only_fail", Hostname: "localhost"}, nil, nil)) // test old data and broken data - c.Assert(se.Auth(&auth.UserIdentity{Username: "r12_old_tidb_user", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r13_broken_user", Hostname: "localhost"}, nil, nil), IsFalse) + require.True(t, se.Auth(&auth.UserIdentity{Username: "r12_old_tidb_user", Hostname: "localhost"}, nil, nil)) + require.False(t, se.Auth(&auth.UserIdentity{Username: "r13_broken_user", Hostname: "localhost"}, nil, nil)) } @@ -843,330 +820,387 @@ func connectionState(issuer, subject pkix.Name, cipher uint16, opt ...func(c *x5 } } -func (s *testPrivilegeSuite) TestCheckAuthenticate(c *C) { +func TestCheckAuthenticate(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() - se := newSession(c, s.store, s.dbName) - mustExec(c, se, `CREATE USER 'u1'@'localhost';`) - mustExec(c, se, `CREATE USER 'u2'@'localhost' identified by 'abc';`) - mustExec(c, se, `CREATE USER 'u3@example.com'@'localhost';`) - mustExec(c, se, `CREATE USER u4@localhost;`) + se := newSession(t, store, dbName) + mustExec(t, se, `CREATE USER 'u1'@'localhost';`) + mustExec(t, se, `CREATE USER 'u2'@'localhost' identified by 'abc';`) + mustExec(t, se, `CREATE USER 'u3@example.com'@'localhost';`) + mustExec(t, se, `CREATE USER u4@localhost;`) - c.Assert(se.Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "u2", Hostname: "localhost"}, nil, nil), IsFalse) + require.True(t, se.Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost"}, nil, nil)) + require.False(t, se.Auth(&auth.UserIdentity{Username: "u2", Hostname: "localhost"}, nil, nil)) salt := []byte{85, 92, 45, 22, 58, 79, 107, 6, 122, 125, 58, 80, 12, 90, 103, 32, 90, 10, 74, 82} authentication := []byte{24, 180, 183, 225, 166, 6, 81, 102, 70, 248, 199, 143, 91, 204, 169, 9, 161, 171, 203, 33} - c.Assert(se.Auth(&auth.UserIdentity{Username: "u2", Hostname: "localhost"}, authentication, salt), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "u3@example.com", Hostname: "localhost"}, nil, nil), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "u4", Hostname: "localhost"}, nil, nil), IsTrue) - - se1 := newSession(c, s.store, s.dbName) - mustExec(c, se1, "drop user 'u1'@'localhost'") - mustExec(c, se1, "drop user 'u2'@'localhost'") - mustExec(c, se1, "drop user 'u3@example.com'@'localhost'") - mustExec(c, se1, "drop user u4@localhost") - - c.Assert(se.Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost"}, nil, nil), IsFalse) - c.Assert(se.Auth(&auth.UserIdentity{Username: "u2", Hostname: "localhost"}, nil, nil), IsFalse) - c.Assert(se.Auth(&auth.UserIdentity{Username: "u3@example.com", Hostname: "localhost"}, nil, nil), IsFalse) - c.Assert(se.Auth(&auth.UserIdentity{Username: "u4", Hostname: "localhost"}, nil, nil), IsFalse) - - se2 := newSession(c, s.store, s.dbName) - mustExec(c, se2, "create role 'r1'@'localhost'") - mustExec(c, se2, "create role 'r2'@'localhost'") - mustExec(c, se2, "create role 'r3@example.com'@'localhost'") - c.Assert(se.Auth(&auth.UserIdentity{Username: "r1", Hostname: "localhost"}, nil, nil), IsFalse) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r2", Hostname: "localhost"}, nil, nil), IsFalse) - c.Assert(se.Auth(&auth.UserIdentity{Username: "r3@example.com", Hostname: "localhost"}, nil, nil), IsFalse) - - mustExec(c, se1, "drop user 'r1'@'localhost'") - mustExec(c, se1, "drop user 'r2'@'localhost'") - mustExec(c, se1, "drop user 'r3@example.com'@'localhost'") + require.True(t, se.Auth(&auth.UserIdentity{Username: "u2", Hostname: "localhost"}, authentication, salt)) + require.True(t, se.Auth(&auth.UserIdentity{Username: "u3@example.com", Hostname: "localhost"}, nil, nil)) + require.True(t, se.Auth(&auth.UserIdentity{Username: "u4", Hostname: "localhost"}, nil, nil)) + + se1 := newSession(t, store, dbName) + mustExec(t, se1, "drop user 'u1'@'localhost'") + mustExec(t, se1, "drop user 'u2'@'localhost'") + mustExec(t, se1, "drop user 'u3@example.com'@'localhost'") + mustExec(t, se1, "drop user u4@localhost") + + require.False(t, se.Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost"}, nil, nil)) + require.False(t, se.Auth(&auth.UserIdentity{Username: "u2", Hostname: "localhost"}, nil, nil)) + require.False(t, se.Auth(&auth.UserIdentity{Username: "u3@example.com", Hostname: "localhost"}, nil, nil)) + require.False(t, se.Auth(&auth.UserIdentity{Username: "u4", Hostname: "localhost"}, nil, nil)) + + se2 := newSession(t, store, dbName) + mustExec(t, se2, "create role 'r1'@'localhost'") + mustExec(t, se2, "create role 'r2'@'localhost'") + mustExec(t, se2, "create role 'r3@example.com'@'localhost'") + require.False(t, se.Auth(&auth.UserIdentity{Username: "r1", Hostname: "localhost"}, nil, nil)) + require.False(t, se.Auth(&auth.UserIdentity{Username: "r2", Hostname: "localhost"}, nil, nil)) + require.False(t, se.Auth(&auth.UserIdentity{Username: "r3@example.com", Hostname: "localhost"}, nil, nil)) + + mustExec(t, se1, "drop user 'r1'@'localhost'") + mustExec(t, se1, "drop user 'r2'@'localhost'") + mustExec(t, se1, "drop user 'r3@example.com'@'localhost'") } -func (s *testPrivilegeSuite) TestUseDB(c *C) { +func TestUseDB(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() - se := newSession(c, s.store, s.dbName) + se := newSession(t, store, dbName) // high privileged user - mustExec(c, se, "CREATE USER 'usesuper'") - mustExec(c, se, "CREATE USER 'usenobody'") - mustExec(c, se, "GRANT ALL ON *.* TO 'usesuper'") + mustExec(t, se, "CREATE USER 'usesuper'") + mustExec(t, se, "CREATE USER 'usenobody'") + mustExec(t, se, "GRANT ALL ON *.* TO 'usesuper'") // without grant option - c.Assert(se.Auth(&auth.UserIdentity{Username: "usesuper", Hostname: "localhost", AuthUsername: "usesuper", AuthHostname: "%"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "usesuper", Hostname: "localhost", AuthUsername: "usesuper", AuthHostname: "%"}, nil, nil)) _, e := se.ExecuteInternal(context.Background(), "GRANT SELECT ON mysql.* TO 'usenobody'") - c.Assert(e, NotNil) + require.Error(t, e) // with grant option - se = newSession(c, s.store, s.dbName) + se = newSession(t, store, dbName) // high privileged user - mustExec(c, se, "GRANT ALL ON *.* TO 'usesuper' WITH GRANT OPTION") - c.Assert(se.Auth(&auth.UserIdentity{Username: "usesuper", Hostname: "localhost", AuthUsername: "usesuper", AuthHostname: "%"}, nil, nil), IsTrue) - mustExec(c, se, "use mysql") + mustExec(t, se, "GRANT ALL ON *.* TO 'usesuper' WITH GRANT OPTION") + require.True(t, se.Auth(&auth.UserIdentity{Username: "usesuper", Hostname: "localhost", AuthUsername: "usesuper", AuthHostname: "%"}, nil, nil)) + mustExec(t, se, "use mysql") // low privileged user - c.Assert(se.Auth(&auth.UserIdentity{Username: "usenobody", Hostname: "localhost", AuthUsername: "usenobody", AuthHostname: "%"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "usenobody", Hostname: "localhost", AuthUsername: "usenobody", AuthHostname: "%"}, nil, nil)) _, err := se.ExecuteInternal(context.Background(), "use mysql") - c.Assert(err, NotNil) + require.Error(t, err) // try again after privilege granted - c.Assert(se.Auth(&auth.UserIdentity{Username: "usesuper", Hostname: "localhost", AuthUsername: "usesuper", AuthHostname: "%"}, nil, nil), IsTrue) - mustExec(c, se, "GRANT SELECT ON mysql.* TO 'usenobody'") - c.Assert(se.Auth(&auth.UserIdentity{Username: "usenobody", Hostname: "localhost", AuthUsername: "usenobody", AuthHostname: "%"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "usesuper", Hostname: "localhost", AuthUsername: "usesuper", AuthHostname: "%"}, nil, nil)) + mustExec(t, se, "GRANT SELECT ON mysql.* TO 'usenobody'") + require.True(t, se.Auth(&auth.UserIdentity{Username: "usenobody", Hostname: "localhost", AuthUsername: "usenobody", AuthHostname: "%"}, nil, nil)) _, err = se.ExecuteInternal(context.Background(), "use mysql") - c.Assert(err, IsNil) + require.NoError(t, err) // test `use db` for role. - c.Assert(se.Auth(&auth.UserIdentity{Username: "usesuper", Hostname: "localhost", AuthUsername: "usesuper", AuthHostname: "%"}, nil, nil), IsTrue) - mustExec(c, se, `CREATE DATABASE app_db`) - mustExec(c, se, `CREATE ROLE 'app_developer'`) - mustExec(c, se, `GRANT ALL ON app_db.* TO 'app_developer'`) - mustExec(c, se, `CREATE USER 'dev'@'localhost'`) - mustExec(c, se, `GRANT 'app_developer' TO 'dev'@'localhost'`) - mustExec(c, se, `SET DEFAULT ROLE 'app_developer' TO 'dev'@'localhost'`) - c.Assert(se.Auth(&auth.UserIdentity{Username: "dev", Hostname: "localhost", AuthUsername: "dev", AuthHostname: "localhost"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "usesuper", Hostname: "localhost", AuthUsername: "usesuper", AuthHostname: "%"}, nil, nil)) + mustExec(t, se, `CREATE DATABASE app_db`) + mustExec(t, se, `CREATE ROLE 'app_developer'`) + mustExec(t, se, `GRANT ALL ON app_db.* TO 'app_developer'`) + mustExec(t, se, `CREATE USER 'dev'@'localhost'`) + mustExec(t, se, `GRANT 'app_developer' TO 'dev'@'localhost'`) + mustExec(t, se, `SET DEFAULT ROLE 'app_developer' TO 'dev'@'localhost'`) + require.True(t, se.Auth(&auth.UserIdentity{Username: "dev", Hostname: "localhost", AuthUsername: "dev", AuthHostname: "localhost"}, nil, nil)) _, err = se.ExecuteInternal(context.Background(), "use app_db") - c.Assert(err, IsNil) + require.NoError(t, err) _, err = se.ExecuteInternal(context.Background(), "use mysql") - c.Assert(err, NotNil) + require.Error(t, err) } -func (s *testPrivilegeSuite) TestRevokePrivileges(c *C) { - se := newSession(c, s.store, s.dbName) - mustExec(c, se, "CREATE USER 'hasgrant'") - mustExec(c, se, "CREATE USER 'withoutgrant'") - mustExec(c, se, "GRANT ALL ON *.* TO 'hasgrant'") - mustExec(c, se, "GRANT ALL ON mysql.* TO 'withoutgrant'") +func TestRevokePrivileges(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se := newSession(t, store, dbName) + mustExec(t, se, "CREATE USER 'hasgrant'") + mustExec(t, se, "CREATE USER 'withoutgrant'") + mustExec(t, se, "GRANT ALL ON *.* TO 'hasgrant'") + mustExec(t, se, "GRANT ALL ON mysql.* TO 'withoutgrant'") // Without grant option - c.Assert(se.Auth(&auth.UserIdentity{Username: "hasgrant", Hostname: "localhost", AuthUsername: "hasgrant", AuthHostname: "%"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "hasgrant", Hostname: "localhost", AuthUsername: "hasgrant", AuthHostname: "%"}, nil, nil)) _, e := se.ExecuteInternal(context.Background(), "REVOKE SELECT ON mysql.* FROM 'withoutgrant'") - c.Assert(e, NotNil) + require.Error(t, e) // With grant option - se = newSession(c, s.store, s.dbName) - mustExec(c, se, "GRANT ALL ON *.* TO 'hasgrant' WITH GRANT OPTION") - c.Assert(se.Auth(&auth.UserIdentity{Username: "hasgrant", Hostname: "localhost", AuthUsername: "hasgrant", AuthHostname: "%"}, nil, nil), IsTrue) - mustExec(c, se, "REVOKE SELECT ON mysql.* FROM 'withoutgrant'") - mustExec(c, se, "REVOKE ALL ON mysql.* FROM withoutgrant") + se = newSession(t, store, dbName) + mustExec(t, se, "GRANT ALL ON *.* TO 'hasgrant' WITH GRANT OPTION") + require.True(t, se.Auth(&auth.UserIdentity{Username: "hasgrant", Hostname: "localhost", AuthUsername: "hasgrant", AuthHostname: "%"}, nil, nil)) + mustExec(t, se, "REVOKE SELECT ON mysql.* FROM 'withoutgrant'") + mustExec(t, se, "REVOKE ALL ON mysql.* FROM withoutgrant") // For issue https://github.com/pingcap/tidb/issues/23850 - mustExec(c, se, "CREATE USER u4") - mustExec(c, se, "GRANT ALL ON *.* TO u4 WITH GRANT OPTION") - c.Assert(se.Auth(&auth.UserIdentity{Username: "u4", Hostname: "localhost", AuthUsername: "u4", AuthHostname: "%"}, nil, nil), IsTrue) - mustExec(c, se, "REVOKE ALL ON *.* FROM CURRENT_USER()") + mustExec(t, se, "CREATE USER u4") + mustExec(t, se, "GRANT ALL ON *.* TO u4 WITH GRANT OPTION") + require.True(t, se.Auth(&auth.UserIdentity{Username: "u4", Hostname: "localhost", AuthUsername: "u4", AuthHostname: "%"}, nil, nil)) + mustExec(t, se, "REVOKE ALL ON *.* FROM CURRENT_USER()") } -func (s *testPrivilegeSuite) TestSetGlobal(c *C) { - se := newSession(c, s.store, s.dbName) - mustExec(c, se, `CREATE USER setglobal_a@localhost`) - mustExec(c, se, `CREATE USER setglobal_b@localhost`) - mustExec(c, se, `GRANT SUPER ON *.* to setglobal_a@localhost`) +func TestSetGlobal(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + se := newSession(t, store, dbName) + mustExec(t, se, `CREATE USER setglobal_a@localhost`) + mustExec(t, se, `CREATE USER setglobal_b@localhost`) + mustExec(t, se, `GRANT SUPER ON *.* to setglobal_a@localhost`) - c.Assert(se.Auth(&auth.UserIdentity{Username: "setglobal_a", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, `set global innodb_commit_concurrency=16`) + require.True(t, se.Auth(&auth.UserIdentity{Username: "setglobal_a", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, `set global innodb_commit_concurrency=16`) - c.Assert(se.Auth(&auth.UserIdentity{Username: "setglobal_b", Hostname: "localhost"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "setglobal_b", Hostname: "localhost"}, nil, nil)) _, err := se.ExecuteInternal(context.Background(), `set global innodb_commit_concurrency=16`) - c.Assert(terror.ErrorEqual(err, core.ErrSpecificAccessDenied), IsTrue) + require.True(t, terror.ErrorEqual(err, core.ErrSpecificAccessDenied)) } -func (s *testPrivilegeSuite) TestCreateDropUser(c *C) { - se := newSession(c, s.store, s.dbName) - mustExec(c, se, `CREATE USER tcd1, tcd2`) - mustExec(c, se, `GRANT ALL ON *.* to tcd2 WITH GRANT OPTION`) +func TestCreateDropUser(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se := newSession(t, store, dbName) + mustExec(t, se, `CREATE USER tcd1, tcd2`) + mustExec(t, se, `GRANT ALL ON *.* to tcd2 WITH GRANT OPTION`) // should fail - c.Assert(se.Auth(&auth.UserIdentity{Username: "tcd1", Hostname: "localhost", AuthUsername: "tcd1", AuthHostname: "%"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "tcd1", Hostname: "localhost", AuthUsername: "tcd1", AuthHostname: "%"}, nil, nil)) _, err := se.ExecuteInternal(context.Background(), `CREATE USER acdc`) - c.Assert(terror.ErrorEqual(err, core.ErrSpecificAccessDenied), IsTrue) + require.True(t, terror.ErrorEqual(err, core.ErrSpecificAccessDenied)) _, err = se.ExecuteInternal(context.Background(), `DROP USER tcd2`) - c.Assert(terror.ErrorEqual(err, core.ErrSpecificAccessDenied), IsTrue) + require.True(t, terror.ErrorEqual(err, core.ErrSpecificAccessDenied)) // should pass - c.Assert(se.Auth(&auth.UserIdentity{Username: "tcd2", Hostname: "localhost", AuthUsername: "tcd2", AuthHostname: "%"}, nil, nil), IsTrue) - mustExec(c, se, `DROP USER tcd1`) - mustExec(c, se, `CREATE USER tcd1`) + require.True(t, se.Auth(&auth.UserIdentity{Username: "tcd2", Hostname: "localhost", AuthUsername: "tcd2", AuthHostname: "%"}, nil, nil)) + mustExec(t, se, `DROP USER tcd1`) + mustExec(t, se, `CREATE USER tcd1`) // should pass - mustExec(c, se, `GRANT tcd2 TO tcd1`) - c.Assert(se.Auth(&auth.UserIdentity{Username: "tcd1", Hostname: "localhost", AuthUsername: "tcd1", AuthHostname: "%"}, nil, nil), IsTrue) - mustExec(c, se, `SET ROLE tcd2;`) - mustExec(c, se, `CREATE USER tcd3`) - mustExec(c, se, `DROP USER tcd3`) + mustExec(t, se, `GRANT tcd2 TO tcd1`) + require.True(t, se.Auth(&auth.UserIdentity{Username: "tcd1", Hostname: "localhost", AuthUsername: "tcd1", AuthHostname: "%"}, nil, nil)) + mustExec(t, se, `SET ROLE tcd2;`) + mustExec(t, se, `CREATE USER tcd3`) + mustExec(t, se, `DROP USER tcd3`) } -func (s *testPrivilegeSuite) TestConfigPrivilege(c *C) { - se := newSession(c, s.store, s.dbName) - mustExec(c, se, `DROP USER IF EXISTS tcd1`) - mustExec(c, se, `CREATE USER tcd1`) - mustExec(c, se, `GRANT ALL ON *.* to tcd1`) - mustExec(c, se, `DROP USER IF EXISTS tcd2`) - mustExec(c, se, `CREATE USER tcd2`) - mustExec(c, se, `GRANT ALL ON *.* to tcd2`) - mustExec(c, se, `REVOKE CONFIG ON *.* FROM tcd2`) - - c.Assert(se.Auth(&auth.UserIdentity{Username: "tcd1", Hostname: "localhost", AuthHostname: "tcd1", AuthUsername: "%"}, nil, nil), IsTrue) - mustExec(c, se, `SHOW CONFIG`) - mustExec(c, se, `SET CONFIG TIKV testkey="testval"`) - c.Assert(se.Auth(&auth.UserIdentity{Username: "tcd2", Hostname: "localhost", AuthHostname: "tcd2", AuthUsername: "%"}, nil, nil), IsTrue) +func TestConfigPrivilege(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se := newSession(t, store, dbName) + mustExec(t, se, `DROP USER IF EXISTS tcd1`) + mustExec(t, se, `CREATE USER tcd1`) + mustExec(t, se, `GRANT ALL ON *.* to tcd1`) + mustExec(t, se, `DROP USER IF EXISTS tcd2`) + mustExec(t, se, `CREATE USER tcd2`) + mustExec(t, se, `GRANT ALL ON *.* to tcd2`) + mustExec(t, se, `REVOKE CONFIG ON *.* FROM tcd2`) + + require.True(t, se.Auth(&auth.UserIdentity{Username: "tcd1", Hostname: "localhost", AuthHostname: "tcd1", AuthUsername: "%"}, nil, nil)) + mustExec(t, se, `SHOW CONFIG`) + mustExec(t, se, `SET CONFIG TIKV testkey="testval"`) + require.True(t, se.Auth(&auth.UserIdentity{Username: "tcd2", Hostname: "localhost", AuthHostname: "tcd2", AuthUsername: "%"}, nil, nil)) _, err := se.ExecuteInternal(context.Background(), `SHOW CONFIG`) - c.Assert(err, ErrorMatches, ".*you need \\(at least one of\\) the CONFIG privilege\\(s\\) for this operation") + require.Error(t, err) + require.Regexp(t, ".*you need \\(at least one of\\) the CONFIG privilege\\(s\\) for this operation", err.Error()) _, err = se.ExecuteInternal(context.Background(), `SET CONFIG TIKV testkey="testval"`) - c.Assert(err, ErrorMatches, ".*you need \\(at least one of\\) the CONFIG privilege\\(s\\) for this operation") - mustExec(c, se, `DROP USER tcd1, tcd2`) + require.Error(t, err) + require.Regexp(t, ".*you need \\(at least one of\\) the CONFIG privilege\\(s\\) for this operation", err.Error()) + mustExec(t, se, `DROP USER tcd1, tcd2`) } -func (s *testPrivilegeSuite) TestShowCreateTable(c *C) { - se := newSession(c, s.store, s.dbName) - mustExec(c, se, `CREATE USER tsct1, tsct2`) - mustExec(c, se, `GRANT select ON mysql.* to tsct2`) +func TestShowCreateTable(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se := newSession(t, store, dbName) + mustExec(t, se, `CREATE USER tsct1, tsct2`) + mustExec(t, se, `GRANT select ON mysql.* to tsct2`) // should fail - c.Assert(se.Auth(&auth.UserIdentity{Username: "tsct1", Hostname: "localhost", AuthUsername: "tsct1", AuthHostname: "%"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "tsct1", Hostname: "localhost", AuthUsername: "tsct1", AuthHostname: "%"}, nil, nil)) _, err := se.ExecuteInternal(context.Background(), `SHOW CREATE TABLE mysql.user`) - c.Assert(terror.ErrorEqual(err, core.ErrTableaccessDenied), IsTrue) + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) // should pass - c.Assert(se.Auth(&auth.UserIdentity{Username: "tsct2", Hostname: "localhost", AuthUsername: "tsct2", AuthHostname: "%"}, nil, nil), IsTrue) - mustExec(c, se, `SHOW CREATE TABLE mysql.user`) + require.True(t, se.Auth(&auth.UserIdentity{Username: "tsct2", Hostname: "localhost", AuthUsername: "tsct2", AuthHostname: "%"}, nil, nil)) + mustExec(t, se, `SHOW CREATE TABLE mysql.user`) } -func (s *testPrivilegeSuite) TestReplaceAndInsertOnDuplicate(c *C) { - se := newSession(c, s.store, s.dbName) - mustExec(c, se, `CREATE USER tr_insert`) - mustExec(c, se, `CREATE USER tr_update`) - mustExec(c, se, `CREATE USER tr_delete`) - mustExec(c, se, `CREATE TABLE t1 (a int primary key, b int)`) - mustExec(c, se, `GRANT INSERT ON t1 TO tr_insert`) - mustExec(c, se, `GRANT UPDATE ON t1 TO tr_update`) - mustExec(c, se, `GRANT DELETE ON t1 TO tr_delete`) +func TestReplaceAndInsertOnDuplicate(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se := newSession(t, store, dbName) + mustExec(t, se, `CREATE USER tr_insert`) + mustExec(t, se, `CREATE USER tr_update`) + mustExec(t, se, `CREATE USER tr_delete`) + mustExec(t, se, `CREATE TABLE t1 (a int primary key, b int)`) + mustExec(t, se, `GRANT INSERT ON t1 TO tr_insert`) + mustExec(t, se, `GRANT UPDATE ON t1 TO tr_update`) + mustExec(t, se, `GRANT DELETE ON t1 TO tr_delete`) // Restrict the permission to INSERT only. - c.Assert(se.Auth(&auth.UserIdentity{Username: "tr_insert", Hostname: "localhost", AuthUsername: "tr_insert", AuthHostname: "%"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "tr_insert", Hostname: "localhost", AuthUsername: "tr_insert", AuthHostname: "%"}, nil, nil)) // REPLACE requires INSERT + DELETE privileges, having INSERT alone is insufficient. _, err := se.ExecuteInternal(context.Background(), `REPLACE INTO t1 VALUES (1, 2)`) - c.Assert(terror.ErrorEqual(err, core.ErrTableaccessDenied), IsTrue) - c.Assert(err.Error(), Equals, "[planner:1142]DELETE command denied to user 'tr_insert'@'%' for table 't1'") + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) + require.EqualError(t, err, "[planner:1142]DELETE command denied to user 'tr_insert'@'%' for table 't1'") // INSERT ON DUPLICATE requires INSERT + UPDATE privileges, having INSERT alone is insufficient. _, err = se.ExecuteInternal(context.Background(), `INSERT INTO t1 VALUES (3, 4) ON DUPLICATE KEY UPDATE b = 5`) - c.Assert(terror.ErrorEqual(err, core.ErrTableaccessDenied), IsTrue) - c.Assert(err.Error(), Equals, "[planner:1142]UPDATE command denied to user 'tr_insert'@'%' for table 't1'") + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) + require.EqualError(t, err, "[planner:1142]UPDATE command denied to user 'tr_insert'@'%' for table 't1'") // Plain INSERT should work. - mustExec(c, se, `INSERT INTO t1 VALUES (6, 7)`) + mustExec(t, se, `INSERT INTO t1 VALUES (6, 7)`) // Also check that having DELETE alone is insufficient for REPLACE. - c.Assert(se.Auth(&auth.UserIdentity{Username: "tr_delete", Hostname: "localhost", AuthUsername: "tr_delete", AuthHostname: "%"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "tr_delete", Hostname: "localhost", AuthUsername: "tr_delete", AuthHostname: "%"}, nil, nil)) _, err = se.ExecuteInternal(context.Background(), `REPLACE INTO t1 VALUES (8, 9)`) - c.Assert(terror.ErrorEqual(err, core.ErrTableaccessDenied), IsTrue) - c.Assert(err.Error(), Equals, "[planner:1142]INSERT command denied to user 'tr_delete'@'%' for table 't1'") + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) + require.EqualError(t, err, "[planner:1142]INSERT command denied to user 'tr_delete'@'%' for table 't1'") // Also check that having UPDATE alone is insufficient for INSERT ON DUPLICATE. - c.Assert(se.Auth(&auth.UserIdentity{Username: "tr_update", Hostname: "localhost", AuthUsername: "tr_update", AuthHostname: "%"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "tr_update", Hostname: "localhost", AuthUsername: "tr_update", AuthHostname: "%"}, nil, nil)) _, err = se.ExecuteInternal(context.Background(), `INSERT INTO t1 VALUES (10, 11) ON DUPLICATE KEY UPDATE b = 12`) - c.Assert(terror.ErrorEqual(err, core.ErrTableaccessDenied), IsTrue) - c.Assert(err.Error(), Equals, "[planner:1142]INSERT command denied to user 'tr_update'@'%' for table 't1'") + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) + require.EqualError(t, err, "[planner:1142]INSERT command denied to user 'tr_update'@'%' for table 't1'") } -func (s *testPrivilegeSuite) TestAnalyzeTable(c *C) { +func TestAnalyzeTable(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() - se := newSession(c, s.store, s.dbName) + se := newSession(t, store, dbName) // high privileged user - mustExec(c, se, "CREATE USER 'asuper'") - mustExec(c, se, "CREATE USER 'anobody'") - mustExec(c, se, "GRANT ALL ON *.* TO 'asuper' WITH GRANT OPTION") - mustExec(c, se, "CREATE DATABASE atest") - mustExec(c, se, "use atest") - mustExec(c, se, "CREATE TABLE t1 (a int)") - - c.Assert(se.Auth(&auth.UserIdentity{Username: "asuper", Hostname: "localhost", AuthUsername: "asuper", AuthHostname: "%"}, nil, nil), IsTrue) - mustExec(c, se, "analyze table mysql.user") + mustExec(t, se, "CREATE USER 'asuper'") + mustExec(t, se, "CREATE USER 'anobody'") + mustExec(t, se, "GRANT ALL ON *.* TO 'asuper' WITH GRANT OPTION") + mustExec(t, se, "CREATE DATABASE atest") + mustExec(t, se, "use atest") + mustExec(t, se, "CREATE TABLE t1 (a int)") + + require.True(t, se.Auth(&auth.UserIdentity{Username: "asuper", Hostname: "localhost", AuthUsername: "asuper", AuthHostname: "%"}, nil, nil)) + mustExec(t, se, "analyze table mysql.user") // low privileged user - c.Assert(se.Auth(&auth.UserIdentity{Username: "anobody", Hostname: "localhost", AuthUsername: "anobody", AuthHostname: "%"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "anobody", Hostname: "localhost", AuthUsername: "anobody", AuthHostname: "%"}, nil, nil)) _, err := se.ExecuteInternal(context.Background(), "analyze table t1") - c.Assert(terror.ErrorEqual(err, core.ErrTableaccessDenied), IsTrue) - c.Assert(err.Error(), Equals, "[planner:1142]INSERT command denied to user 'anobody'@'%' for table 't1'") + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) + require.EqualError(t, err, "[planner:1142]INSERT command denied to user 'anobody'@'%' for table 't1'") _, err = se.ExecuteInternal(context.Background(), "select * from t1") - c.Assert(err.Error(), Equals, "[planner:1142]SELECT command denied to user 'anobody'@'%' for table 't1'") + require.EqualError(t, err, "[planner:1142]SELECT command denied to user 'anobody'@'%' for table 't1'") // try again after SELECT privilege granted - c.Assert(se.Auth(&auth.UserIdentity{Username: "asuper", Hostname: "localhost", AuthUsername: "asuper", AuthHostname: "%"}, nil, nil), IsTrue) - mustExec(c, se, "GRANT SELECT ON atest.* TO 'anobody'") - c.Assert(se.Auth(&auth.UserIdentity{Username: "anobody", Hostname: "localhost", AuthUsername: "anobody", AuthHostname: "%"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "asuper", Hostname: "localhost", AuthUsername: "asuper", AuthHostname: "%"}, nil, nil)) + mustExec(t, se, "GRANT SELECT ON atest.* TO 'anobody'") + require.True(t, se.Auth(&auth.UserIdentity{Username: "anobody", Hostname: "localhost", AuthUsername: "anobody", AuthHostname: "%"}, nil, nil)) _, err = se.ExecuteInternal(context.Background(), "analyze table t1") - c.Assert(terror.ErrorEqual(err, core.ErrTableaccessDenied), IsTrue) - c.Assert(err.Error(), Equals, "[planner:1142]INSERT command denied to user 'anobody'@'%' for table 't1'") + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) + require.EqualError(t, err, "[planner:1142]INSERT command denied to user 'anobody'@'%' for table 't1'") // Add INSERT privilege and it should work. - c.Assert(se.Auth(&auth.UserIdentity{Username: "asuper", Hostname: "localhost", AuthUsername: "asuper", AuthHostname: "%"}, nil, nil), IsTrue) - mustExec(c, se, "GRANT INSERT ON atest.* TO 'anobody'") - c.Assert(se.Auth(&auth.UserIdentity{Username: "anobody", Hostname: "localhost", AuthUsername: "anobody", AuthHostname: "%"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "asuper", Hostname: "localhost", AuthUsername: "asuper", AuthHostname: "%"}, nil, nil)) + mustExec(t, se, "GRANT INSERT ON atest.* TO 'anobody'") + require.True(t, se.Auth(&auth.UserIdentity{Username: "anobody", Hostname: "localhost", AuthUsername: "anobody", AuthHostname: "%"}, nil, nil)) _, err = se.ExecuteInternal(context.Background(), "analyze table t1") - c.Assert(err, IsNil) + require.NoError(t, err) } -func (s *testPrivilegeSuite) TestSystemSchema(c *C) { +func TestSystemSchema(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + // This test tests no privilege check for INFORMATION_SCHEMA database. - se := newSession(c, s.store, s.dbName) - mustExec(c, se, `CREATE USER 'u1'@'localhost';`) - c.Assert(se.Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, `select * from information_schema.tables`) - mustExec(c, se, `select * from information_schema.key_column_usage`) + se := newSession(t, store, dbName) + mustExec(t, se, `CREATE USER 'u1'@'localhost';`) + require.True(t, se.Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, `select * from information_schema.tables`) + mustExec(t, se, `select * from information_schema.key_column_usage`) _, err := se.ExecuteInternal(context.Background(), "create table information_schema.t(a int)") - c.Assert(strings.Contains(err.Error(), "denied to user"), IsTrue) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), "denied to user")) _, err = se.ExecuteInternal(context.Background(), "drop table information_schema.tables") - c.Assert(strings.Contains(err.Error(), "denied to user"), IsTrue) + require.Error(t, err) + require.True(t, strings.Contains(err.Error(), "denied to user")) _, err = se.ExecuteInternal(context.Background(), "update information_schema.tables set table_name = 'tst' where table_name = 'mysql'") - c.Assert(strings.Contains(err.Error(), "privilege check"), IsTrue) + require.Error(t, err) + require.True(t, terror.ErrorEqual(err, core.ErrPrivilegeCheckFail)) // Test performance_schema. - mustExec(c, se, `select * from performance_schema.events_statements_summary_by_digest`) + mustExec(t, se, `select * from performance_schema.events_statements_summary_by_digest`) _, err = se.ExecuteInternal(context.Background(), "drop table performance_schema.events_statements_summary_by_digest") - c.Assert(strings.Contains(err.Error(), "denied to user"), IsTrue) + require.Error(t, err) + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) _, err = se.ExecuteInternal(context.Background(), "update performance_schema.events_statements_summary_by_digest set schema_name = 'tst'") - c.Assert(strings.Contains(err.Error(), "privilege check"), IsTrue) + require.Error(t, err) + require.True(t, terror.ErrorEqual(err, core.ErrPrivilegeCheckFail)) _, err = se.ExecuteInternal(context.Background(), "delete from performance_schema.events_statements_summary_by_digest") - c.Assert(strings.Contains(err.Error(), "DELETE command denied to user"), IsTrue) + require.Error(t, err) + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) _, err = se.ExecuteInternal(context.Background(), "create table performance_schema.t(a int)") - c.Assert(err, NotNil) - c.Assert(strings.Contains(err.Error(), "CREATE command denied"), IsTrue, Commentf(err.Error())) + require.Error(t, err) + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) // Test metric_schema. - mustExec(c, se, `select * from metrics_schema.tidb_query_duration`) + mustExec(t, se, `select * from metrics_schema.tidb_query_duration`) _, err = se.ExecuteInternal(context.Background(), "drop table metrics_schema.tidb_query_duration") - c.Assert(strings.Contains(err.Error(), "denied to user"), IsTrue) + require.Error(t, err) + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) _, err = se.ExecuteInternal(context.Background(), "update metrics_schema.tidb_query_duration set instance = 'tst'") - c.Assert(strings.Contains(err.Error(), "privilege check"), IsTrue) + require.Error(t, err) + require.True(t, terror.ErrorEqual(err, core.ErrPrivilegeCheckFail)) _, err = se.ExecuteInternal(context.Background(), "delete from metrics_schema.tidb_query_duration") - c.Assert(strings.Contains(err.Error(), "DELETE command denied to user"), IsTrue) + require.Error(t, err) + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) _, err = se.ExecuteInternal(context.Background(), "create table metric_schema.t(a int)") - c.Assert(err, NotNil) - c.Assert(strings.Contains(err.Error(), "CREATE command denied"), IsTrue, Commentf(err.Error())) + require.Error(t, err) + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) } -func (s *testPrivilegeSuite) TestAdminCommand(c *C) { - se := newSession(c, s.store, s.dbName) - c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, `CREATE USER 'test_admin'@'localhost';`) - mustExec(c, se, `CREATE TABLE t(a int)`) +func TestAdminCommand(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se := newSession(t, store, dbName) + require.True(t, se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, `CREATE USER 'test_admin'@'localhost';`) + mustExec(t, se, `CREATE TABLE t(a int)`) - c.Assert(se.Auth(&auth.UserIdentity{Username: "test_admin", Hostname: "localhost"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "test_admin", Hostname: "localhost"}, nil, nil)) _, err := se.ExecuteInternal(context.Background(), "ADMIN SHOW DDL JOBS") - c.Assert(strings.Contains(err.Error(), "privilege check"), IsTrue) + require.Error(t, err) + require.True(t, terror.ErrorEqual(err, core.ErrPrivilegeCheckFail)) _, err = se.ExecuteInternal(context.Background(), "ADMIN CHECK TABLE t") - c.Assert(strings.Contains(err.Error(), "privilege check"), IsTrue) + require.Error(t, err) + require.True(t, terror.ErrorEqual(err, core.ErrPrivilegeCheckFail)) - c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil)) _, err = se.ExecuteInternal(context.Background(), "ADMIN SHOW DDL JOBS") - c.Assert(err, IsNil) + require.NoError(t, err) } -func (s *testPrivilegeSuite) TestTableNotExistNoPermissions(c *C) { - se := newSession(c, s.store, s.dbName) - c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, `CREATE USER 'testnotexist'@'localhost';`) - mustExec(c, se, `CREATE DATABASE dbexists`) - mustExec(c, se, `CREATE TABLE dbexists.t1 (a int)`) +func TestTableNotExistNoPermissions(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() - c.Assert(se.Auth(&auth.UserIdentity{Username: "testnotexist", Hostname: "localhost"}, nil, nil), IsTrue) + se := newSession(t, store, dbName) + require.True(t, se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, `CREATE USER 'testnotexist'@'localhost';`) + mustExec(t, se, `CREATE DATABASE dbexists`) + mustExec(t, se, `CREATE TABLE dbexists.t1 (a int)`) + + require.True(t, se.Auth(&auth.UserIdentity{Username: "testnotexist", Hostname: "localhost"}, nil, nil)) tests := []struct { stmt string @@ -1190,115 +1224,140 @@ func (s *testPrivilegeSuite) TestTableNotExistNoPermissions(c *C) { }, } - for _, t := range tests { + for _, tt := range tests { - _, err1 := se.ExecuteInternal(context.Background(), fmt.Sprintf(t.stmt, "dbexists", "t1")) - _, err2 := se.ExecuteInternal(context.Background(), fmt.Sprintf(t.stmt, "dbnotexists", "t1")) + _, err1 := se.ExecuteInternal(context.Background(), fmt.Sprintf(tt.stmt, "dbexists", "t1")) + _, err2 := se.ExecuteInternal(context.Background(), fmt.Sprintf(tt.stmt, "dbnotexists", "t1")) // Check the error is the same whether table exists or not. - c.Assert(terror.ErrorEqual(err1, err2), IsTrue) + require.True(t, terror.ErrorEqual(err1, err2)) // Check it is permission denied, not not found. - c.Assert(err2.Error(), Equals, fmt.Sprintf("[planner:1142]%s command denied to user 'testnotexist'@'localhost' for table 't1'", t.stmtType)) - + require.EqualError(t, err2, fmt.Sprintf("[planner:1142]%s command denied to user 'testnotexist'@'localhost' for table 't1'", tt.stmtType)) } } -func (s *testPrivilegeSuite) TestLoadDataPrivilege(c *C) { +func TestLoadDataPrivilege(t *testing.T) { + t.Parallel() // Create file. path := "/tmp/load_data_priv.csv" fp, err := os.Create(path) - c.Assert(err, IsNil) - c.Assert(fp, NotNil) + require.NoError(t, err) + require.NotNil(t, fp) defer func() { err = fp.Close() - c.Assert(err, IsNil) + require.NoError(t, err) err = os.Remove(path) - c.Assert(err, IsNil) + require.NoError(t, err) }() _, err = fp.WriteString("1\n") - c.Assert(err, IsNil) - - se := newSession(c, s.store, s.dbName) - c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, `CREATE USER 'test_load'@'localhost';`) - mustExec(c, se, `CREATE TABLE t_load(a int)`) - mustExec(c, se, `GRANT SELECT on *.* to 'test_load'@'localhost'`) - c.Assert(se.Auth(&auth.UserIdentity{Username: "test_load", Hostname: "localhost"}, nil, nil), IsTrue) + require.NoError(t, err) + + store, clean := newStore(t) + defer clean() + + se := newSession(t, store, dbName) + require.True(t, se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, `CREATE USER 'test_load'@'localhost';`) + mustExec(t, se, `CREATE TABLE t_load(a int)`) + mustExec(t, se, `GRANT SELECT on *.* to 'test_load'@'localhost'`) + require.True(t, se.Auth(&auth.UserIdentity{Username: "test_load", Hostname: "localhost"}, nil, nil)) _, err = se.ExecuteInternal(context.Background(), "LOAD DATA LOCAL INFILE '/tmp/load_data_priv.csv' INTO TABLE t_load") - c.Assert(strings.Contains(err.Error(), "INSERT command denied to user 'test_load'@'localhost' for table 't_load'"), IsTrue) - c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil), IsTrue) - mustExec(c, se, `GRANT INSERT on *.* to 'test_load'@'localhost'`) - c.Assert(se.Auth(&auth.UserIdentity{Username: "test_load", Hostname: "localhost"}, nil, nil), IsTrue) + require.Error(t, err) + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) + require.True(t, se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil)) + mustExec(t, se, `GRANT INSERT on *.* to 'test_load'@'localhost'`) + require.True(t, se.Auth(&auth.UserIdentity{Username: "test_load", Hostname: "localhost"}, nil, nil)) _, err = se.ExecuteInternal(context.Background(), "LOAD DATA LOCAL INFILE '/tmp/load_data_priv.csv' INTO TABLE t_load") - c.Assert(err, IsNil) + require.NoError(t, err) } -func (s *testPrivilegeSuite) TestSelectIntoNoPremissions(c *C) { - se := newSession(c, s.store, s.dbName) - mustExec(c, se, `CREATE USER 'nofile'@'localhost';`) - c.Assert(se.Auth(&auth.UserIdentity{Username: "nofile", Hostname: "localhost"}, nil, nil), IsTrue) +func TestSelectIntoNoPermissions(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se := newSession(t, store, dbName) + mustExec(t, se, `CREATE USER 'nofile'@'localhost';`) + require.True(t, se.Auth(&auth.UserIdentity{Username: "nofile", Hostname: "localhost"}, nil, nil)) _, err := se.ExecuteInternal(context.Background(), `select 1 into outfile '/tmp/doesntmatter-no-permissions'`) - message := "Access denied; you need (at least one of) the FILE privilege(s) for this operation" - c.Assert(strings.Contains(err.Error(), message), IsTrue) + require.Error(t, err) + require.True(t, terror.ErrorEqual(err, core.ErrSpecificAccessDenied)) } -func (s *testPrivilegeSuite) TestGetEncodedPassword(c *C) { - se := newSession(c, s.store, s.dbName) - mustExec(c, se, `CREATE USER 'test_encode_u'@'localhost' identified by 'root';`) +func TestGetEncodedPassword(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se := newSession(t, store, dbName) + mustExec(t, se, `CREATE USER 'test_encode_u'@'localhost' identified by 'root';`) pc := privilege.GetPrivilegeManager(se) - c.Assert(pc.GetEncodedPassword("test_encode_u", "localhost"), Equals, "*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B") + require.Equal(t, pc.GetEncodedPassword("test_encode_u", "localhost"), "*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B") } -func (s *testPrivilegeSuite) TestAuthHost(c *C) { - rootSe := newSession(c, s.store, s.dbName) - se := newSession(c, s.store, s.dbName) - mustExec(c, rootSe, `CREATE USER 'test_auth_host'@'%';`) - mustExec(c, rootSe, `GRANT ALL ON *.* TO 'test_auth_host'@'%' WITH GRANT OPTION;`) +func TestAuthHost(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + rootSe := newSession(t, store, dbName) + se := newSession(t, store, dbName) + mustExec(t, rootSe, `CREATE USER 'test_auth_host'@'%';`) + mustExec(t, rootSe, `GRANT ALL ON *.* TO 'test_auth_host'@'%' WITH GRANT OPTION;`) - c.Assert(se.Auth(&auth.UserIdentity{Username: "test_auth_host", Hostname: "192.168.0.10"}, nil, nil), IsTrue) - mustExec(c, se, "CREATE USER 'test_auth_host'@'192.168.%';") - mustExec(c, se, "GRANT SELECT ON *.* TO 'test_auth_host'@'192.168.%';") + require.True(t, se.Auth(&auth.UserIdentity{Username: "test_auth_host", Hostname: "192.168.0.10"}, nil, nil)) + mustExec(t, se, "CREATE USER 'test_auth_host'@'192.168.%';") + mustExec(t, se, "GRANT SELECT ON *.* TO 'test_auth_host'@'192.168.%';") - c.Assert(se.Auth(&auth.UserIdentity{Username: "test_auth_host", Hostname: "192.168.0.10"}, nil, nil), IsTrue) + require.True(t, se.Auth(&auth.UserIdentity{Username: "test_auth_host", Hostname: "192.168.0.10"}, nil, nil)) _, err := se.ExecuteInternal(context.Background(), "create user test_auth_host_a") - c.Assert(err, NotNil) + require.Error(t, err) - mustExec(c, rootSe, "DROP USER 'test_auth_host'@'192.168.%';") - mustExec(c, rootSe, "DROP USER 'test_auth_host'@'%';") + mustExec(t, rootSe, "DROP USER 'test_auth_host'@'192.168.%';") + mustExec(t, rootSe, "DROP USER 'test_auth_host'@'%';") } -func (s *testPrivilegeSuite) TestDefaultRoles(c *C) { - rootSe := newSession(c, s.store, s.dbName) - mustExec(c, rootSe, `CREATE USER 'testdefault'@'localhost';`) - mustExec(c, rootSe, `CREATE ROLE 'testdefault_r1'@'localhost', 'testdefault_r2'@'localhost';`) - mustExec(c, rootSe, `GRANT 'testdefault_r1'@'localhost', 'testdefault_r2'@'localhost' TO 'testdefault'@'localhost';`) +func TestDefaultRoles(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() - se := newSession(c, s.store, s.dbName) + rootSe := newSession(t, store, dbName) + mustExec(t, rootSe, `CREATE USER 'testdefault'@'localhost';`) + mustExec(t, rootSe, `CREATE ROLE 'testdefault_r1'@'localhost', 'testdefault_r2'@'localhost';`) + mustExec(t, rootSe, `GRANT 'testdefault_r1'@'localhost', 'testdefault_r2'@'localhost' TO 'testdefault'@'localhost';`) + + se := newSession(t, store, dbName) pc := privilege.GetPrivilegeManager(se) ret := pc.GetDefaultRoles("testdefault", "localhost") - c.Assert(len(ret), Equals, 0) + require.Len(t, ret, 0) - mustExec(c, rootSe, `SET DEFAULT ROLE ALL TO 'testdefault'@'localhost';`) - mustExec(c, rootSe, `flush privileges;`) + mustExec(t, rootSe, `SET DEFAULT ROLE ALL TO 'testdefault'@'localhost';`) + mustExec(t, rootSe, `flush privileges;`) ret = pc.GetDefaultRoles("testdefault", "localhost") - c.Assert(len(ret), Equals, 2) + require.Len(t, ret, 2) - mustExec(c, rootSe, `SET DEFAULT ROLE NONE TO 'testdefault'@'localhost';`) - mustExec(c, rootSe, `flush privileges;`) + mustExec(t, rootSe, `SET DEFAULT ROLE NONE TO 'testdefault'@'localhost';`) + mustExec(t, rootSe, `flush privileges;`) ret = pc.GetDefaultRoles("testdefault", "localhost") - c.Assert(len(ret), Equals, 0) + require.Len(t, ret, 0) } -func (s *testPrivilegeSuite) TestUserTableConsistency(c *C) { - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("create user superadmin") - tk.MustExec("grant all privileges on *.* to 'superadmin'") +func TestUserTableConsistency(t *testing.T) { + t.Parallel() + store, clean := testkit.CreateMockStore(t) + defer clean() + + tk := testkit.NewAsyncTestKit(t, store) + ctx := tk.OpenSession(context.Background(), dbName) + tk.MustExec(ctx, "create user superadmin") + tk.MustExec(ctx, "grant all privileges on *.* to 'superadmin'") // GrantPriv is not in AllGlobalPrivs any more, see pingcap/parser#581 - c.Assert(len(mysql.Priv2UserCol), Equals, len(mysql.AllGlobalPrivs)+1) + require.Equal(t, len(mysql.Priv2UserCol), len(mysql.AllGlobalPrivs)+1) var buf bytes.Buffer var res bytes.Buffer @@ -1314,141 +1373,165 @@ func (s *testPrivilegeSuite) TestUserTableConsistency(c *C) { i++ } buf.WriteString(" from mysql.user where user = 'superadmin'") - tk.MustQuery(buf.String()).Check(testkit.Rows(res.String())) + tk.MustQuery(ctx, buf.String()).Check(testkit.Rows(res.String())) } -func (s *testPrivilegeSuite) TestFieldList(c *C) { // Issue #14237 List fields RPC - se := newSession(c, s.store, s.dbName) - mustExec(c, se, `CREATE USER 'tableaccess'@'localhost'`) - mustExec(c, se, `CREATE TABLE fieldlistt1 (a int)`) - c.Assert(se.Auth(&auth.UserIdentity{Username: "tableaccess", Hostname: "localhost"}, nil, nil), IsTrue) +func TestFieldList(t *testing.T) { // Issue #14237 List fields RPC + t.Parallel() + store, clean := testkit.CreateMockStore(t) + defer clean() + + se := newSession(t, store, dbName) + mustExec(t, se, `CREATE USER 'tableaccess'@'localhost'`) + mustExec(t, se, `CREATE TABLE fieldlistt1 (a int)`) + require.True(t, se.Auth(&auth.UserIdentity{Username: "tableaccess", Hostname: "localhost"}, nil, nil)) _, err := se.FieldList("fieldlistt1") - message := "SELECT command denied to user 'tableaccess'@'localhost' for table 'fieldlistt1'" - c.Assert(strings.Contains(err.Error(), message), IsTrue) + require.Error(t, err) + require.True(t, terror.ErrorEqual(err, core.ErrTableaccessDenied)) } -func mustExec(c *C, se session.Session, sql string) { +func mustExec(t *testing.T, se session.Session, sql string) { _, err := se.ExecuteInternal(context.Background(), sql) - c.Assert(err, IsNil) + require.NoError(t, err) } -func newStore(c *C, dbPath string) (*domain.Domain, kv.Storage) { +func newStore(t *testing.T) (kv.Storage, func()) { store, err := mockstore.NewMockStore() - session.SetSchemaLease(0) - session.DisableStats4Test() - c.Assert(err, IsNil) + require.NoError(t, err) dom, err := session.BootstrapSession(store) - c.Assert(err, IsNil) - return dom, store + require.NoError(t, err) + setUpTest(t, store, dbName) + + clean := func() { + tearDownTest(t, store, dbName) + dom.Close() + err = store.Close() + require.NoError(t, err) + } + return store, clean } -func newSession(c *C, store kv.Storage, dbName string) session.Session { +func newSession(t *testing.T, store kv.Storage, dbName string) session.Session { se, err := session.CreateSession4Test(store) - c.Assert(err, IsNil) - mustExec(c, se, "create database if not exists "+dbName) - mustExec(c, se, "use "+dbName) + require.NoError(t, err) + mustExec(t, se, "create database if not exists "+dbName) + mustExec(t, se, "use "+dbName) return se } -func (s *testPrivilegeSuite) TestDynamicPrivs(c *C) { - rootSe := newSession(c, s.store, s.dbName) - mustExec(c, rootSe, "CREATE USER notsuper") - mustExec(c, rootSe, "CREATE USER otheruser") - mustExec(c, rootSe, "CREATE ROLE anyrolename") +func TestDynamicPrivs(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() - se := newSession(c, s.store, s.dbName) - c.Assert(se.Auth(&auth.UserIdentity{Username: "notsuper", Hostname: "%"}, nil, nil), IsTrue) + rootSe := newSession(t, store, dbName) + mustExec(t, rootSe, "CREATE USER notsuper") + mustExec(t, rootSe, "CREATE USER otheruser") + mustExec(t, rootSe, "CREATE ROLE anyrolename") + + se := newSession(t, store, dbName) + require.True(t, se.Auth(&auth.UserIdentity{Username: "notsuper", Hostname: "%"}, nil, nil)) // test SYSTEM_VARIABLES_ADMIN _, err := se.ExecuteInternal(context.Background(), "SET GLOBAL wait_timeout = 86400") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation") - mustExec(c, rootSe, "GRANT SYSTEM_VARIABLES_admin ON *.* TO notsuper") - mustExec(c, se, "SET GLOBAL wait_timeout = 86400") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation") + mustExec(t, rootSe, "GRANT SYSTEM_VARIABLES_admin ON *.* TO notsuper") + mustExec(t, se, "SET GLOBAL wait_timeout = 86400") // test ROLE_ADMIN _, err = se.ExecuteInternal(context.Background(), "GRANT anyrolename TO otheruser") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the SUPER or ROLE_ADMIN privilege(s) for this operation") - mustExec(c, rootSe, "GRANT ROLE_ADMIN ON *.* TO notsuper") - mustExec(c, se, "GRANT anyrolename TO otheruser") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the SUPER or ROLE_ADMIN privilege(s) for this operation") + mustExec(t, rootSe, "GRANT ROLE_ADMIN ON *.* TO notsuper") + mustExec(t, se, "GRANT anyrolename TO otheruser") // revoke SYSTEM_VARIABLES_ADMIN, confirm it is dropped - mustExec(c, rootSe, "REVOKE SYSTEM_VARIABLES_AdmIn ON *.* FROM notsuper") + mustExec(t, rootSe, "REVOKE SYSTEM_VARIABLES_AdmIn ON *.* FROM notsuper") _, err = se.ExecuteInternal(context.Background(), "SET GLOBAL wait_timeout = 86000") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation") // grant super, confirm that it is also a substitute for SYSTEM_VARIABLES_ADMIN - mustExec(c, rootSe, "GRANT SUPER ON *.* TO notsuper") - mustExec(c, se, "SET GLOBAL wait_timeout = 86400") + mustExec(t, rootSe, "GRANT SUPER ON *.* TO notsuper") + mustExec(t, se, "SET GLOBAL wait_timeout = 86400") // revoke SUPER, assign SYSTEM_VARIABLES_ADMIN to anyrolename. // confirm that a dynamic privilege can be inherited from a role. - mustExec(c, rootSe, "REVOKE SUPER ON *.* FROM notsuper") - mustExec(c, rootSe, "GRANT SYSTEM_VARIABLES_AdmIn ON *.* TO anyrolename") - mustExec(c, rootSe, "GRANT anyrolename TO notsuper") + mustExec(t, rootSe, "REVOKE SUPER ON *.* FROM notsuper") + mustExec(t, rootSe, "GRANT SYSTEM_VARIABLES_AdmIn ON *.* TO anyrolename") + mustExec(t, rootSe, "GRANT anyrolename TO notsuper") // It's not a default role, this should initially fail: _, err = se.ExecuteInternal(context.Background(), "SET GLOBAL wait_timeout = 86400") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation") - mustExec(c, se, "SET ROLE anyrolename") - mustExec(c, se, "SET GLOBAL wait_timeout = 87000") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation") + mustExec(t, se, "SET ROLE anyrolename") + mustExec(t, se, "SET GLOBAL wait_timeout = 87000") } -func (s *testPrivilegeSuite) TestDynamicGrantOption(c *C) { - rootSe := newSession(c, s.store, s.dbName) - mustExec(c, rootSe, "CREATE USER varuser1") - mustExec(c, rootSe, "CREATE USER varuser2") - mustExec(c, rootSe, "CREATE USER varuser3") +func TestDynamicGrantOption(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + rootSe := newSession(t, store, dbName) + mustExec(t, rootSe, "CREATE USER varuser1") + mustExec(t, rootSe, "CREATE USER varuser2") + mustExec(t, rootSe, "CREATE USER varuser3") - mustExec(c, rootSe, "GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO varuser1") - mustExec(c, rootSe, "GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO varuser2 WITH GRANT OPTION") + mustExec(t, rootSe, "GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO varuser1") + mustExec(t, rootSe, "GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO varuser2 WITH GRANT OPTION") - se1 := newSession(c, s.store, s.dbName) + se1 := newSession(t, store, dbName) - c.Assert(se1.Auth(&auth.UserIdentity{Username: "varuser1", Hostname: "%"}, nil, nil), IsTrue) + require.True(t, se1.Auth(&auth.UserIdentity{Username: "varuser1", Hostname: "%"}, nil, nil)) _, err := se1.ExecuteInternal(context.Background(), "GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO varuser3") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the GRANT OPTION privilege(s) for this operation") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the GRANT OPTION privilege(s) for this operation") - se2 := newSession(c, s.store, s.dbName) + se2 := newSession(t, store, dbName) - c.Assert(se2.Auth(&auth.UserIdentity{Username: "varuser2", Hostname: "%"}, nil, nil), IsTrue) - mustExec(c, se2, "GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO varuser3") + require.True(t, se2.Auth(&auth.UserIdentity{Username: "varuser2", Hostname: "%"}, nil, nil)) + mustExec(t, se2, "GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO varuser3") } -func (s *testPrivilegeSuite) TestSecurityEnhancedModeRestrictedTables(c *C) { +func TestSecurityEnhancedModeRestrictedTables(t *testing.T) { + store, clean := newStore(t) + defer clean() + // This provides an integration test of the tests in util/security/security_test.go - cloudAdminSe := newSession(c, s.store, s.dbName) - mustExec(c, cloudAdminSe, "CREATE USER cloudadmin") - mustExec(c, cloudAdminSe, "GRANT RESTRICTED_TABLES_ADMIN, SELECT ON *.* to cloudadmin") - mustExec(c, cloudAdminSe, "GRANT CREATE ON mysql.* to cloudadmin") - mustExec(c, cloudAdminSe, "CREATE USER uroot") - mustExec(c, cloudAdminSe, "GRANT ALL ON *.* to uroot WITH GRANT OPTION") // A "MySQL" all powerful user. - c.Assert(cloudAdminSe.Auth(&auth.UserIdentity{Username: "cloudadmin", Hostname: "%"}, nil, nil), IsTrue) - urootSe := newSession(c, s.store, s.dbName) - c.Assert(urootSe.Auth(&auth.UserIdentity{Username: "uroot", Hostname: "%"}, nil, nil), IsTrue) + cloudAdminSe := newSession(t, store, dbName) + mustExec(t, cloudAdminSe, "CREATE USER cloudadmin") + mustExec(t, cloudAdminSe, "GRANT RESTRICTED_TABLES_ADMIN, SELECT ON *.* to cloudadmin") + mustExec(t, cloudAdminSe, "GRANT CREATE ON mysql.* to cloudadmin") + mustExec(t, cloudAdminSe, "CREATE USER uroot") + mustExec(t, cloudAdminSe, "GRANT ALL ON *.* to uroot WITH GRANT OPTION") // A "MySQL" all powerful user. + require.True(t, cloudAdminSe.Auth(&auth.UserIdentity{Username: "cloudadmin", Hostname: "%"}, nil, nil)) + urootSe := newSession(t, store, dbName) + require.True(t, urootSe.Auth(&auth.UserIdentity{Username: "uroot", Hostname: "%"}, nil, nil)) sem.Enable() defer sem.Disable() _, err := urootSe.ExecuteInternal(context.Background(), "use metrics_schema") - c.Assert(err.Error(), Equals, "[executor:1044]Access denied for user 'uroot'@'%' to database 'metrics_schema'") + require.EqualError(t, err, "[executor:1044]Access denied for user 'uroot'@'%' to database 'metrics_schema'") _, err = urootSe.ExecuteInternal(context.Background(), "SELECT * FROM metrics_schema.uptime") - c.Assert(err.Error(), Equals, "[planner:1142]SELECT command denied to user 'uroot'@'%' for table 'uptime'") + require.EqualError(t, err, "[planner:1142]SELECT command denied to user 'uroot'@'%' for table 'uptime'") _, err = urootSe.ExecuteInternal(context.Background(), "CREATE TABLE mysql.abcd (a int)") - c.Assert(err.Error(), Equals, "[planner:1142]CREATE command denied to user 'uroot'@'%' for table 'abcd'") + require.EqualError(t, err, "[planner:1142]CREATE command denied to user 'uroot'@'%' for table 'abcd'") - mustExec(c, cloudAdminSe, "USE metrics_schema") - mustExec(c, cloudAdminSe, "SELECT * FROM metrics_schema.uptime") - mustExec(c, cloudAdminSe, "CREATE TABLE mysql.abcd (a int)") + mustExec(t, cloudAdminSe, "USE metrics_schema") + mustExec(t, cloudAdminSe, "SELECT * FROM metrics_schema.uptime") + mustExec(t, cloudAdminSe, "CREATE TABLE mysql.abcd (a int)") } -func (s *testPrivilegeSuite) TestSecurityEnhancedModeInfoschema(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestSecurityEnhancedModeInfoschema(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) + tk.MustExec("CREATE USER uroot1, uroot2, uroot3") tk.MustExec("GRANT SUPER ON *.* to uroot1 WITH GRANT OPTION") // super not process tk.MustExec("GRANT SUPER, PROCESS, RESTRICTED_TABLES_ADMIN ON *.* to uroot2 WITH GRANT OPTION") - tk.Se.Auth(&auth.UserIdentity{ + tk.Session().Auth(&auth.UserIdentity{ Username: "uroot1", Hostname: "localhost", }, nil, nil) @@ -1459,11 +1542,11 @@ func (s *testPrivilegeSuite) TestSecurityEnhancedModeInfoschema(c *C) { // Even though we have super, we still can't read protected information from tidb_servers_info, cluster_* tables tk.MustQuery(`SELECT COUNT(*) FROM information_schema.tidb_servers_info WHERE ip IS NOT NULL`).Check(testkit.Rows("0")) err := tk.QueryToErr(`SELECT COUNT(*) FROM information_schema.cluster_info WHERE status_address IS NOT NULL`) - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") + require.Error(t, err) + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") // That is unless we have the RESTRICTED_TABLES_ADMIN privilege - tk.Se.Auth(&auth.UserIdentity{ + tk.Session().Auth(&auth.UserIdentity{ Username: "uroot2", Hostname: "localhost", }, nil, nil) @@ -1473,45 +1556,49 @@ func (s *testPrivilegeSuite) TestSecurityEnhancedModeInfoschema(c *C) { tk.MustQuery(`SELECT COUNT(*) FROM information_schema.cluster_info WHERE status_address IS NULL`).Check(testkit.Rows("0")) } -func (s *testPrivilegeSuite) TestClusterConfigInfoschema(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestClusterConfigInfoschema(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + tk := testkit.NewTestKit(t, store) tk.MustExec("CREATE USER ccnobody, ccconfig, ccprocess") tk.MustExec("GRANT CONFIG ON *.* TO ccconfig") tk.MustExec("GRANT Process ON *.* TO ccprocess") // incorrect/no permissions - tk.Se.Auth(&auth.UserIdentity{ + tk.Session().Auth(&auth.UserIdentity{ Username: "ccnobody", Hostname: "localhost", }, nil, nil) tk.MustQuery("SHOW GRANTS").Check(testkit.Rows("GRANT USAGE ON *.* TO 'ccnobody'@'%'")) err := tk.QueryToErr("SELECT * FROM information_schema.cluster_config") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the CONFIG privilege(s) for this operation") + require.Error(t, err) + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the CONFIG privilege(s) for this operation") err = tk.QueryToErr("SELECT * FROM information_schema.cluster_hardware") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the CONFIG privilege(s) for this operation") + require.Error(t, err) + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the CONFIG privilege(s) for this operation") err = tk.QueryToErr("SELECT * FROM information_schema.cluster_info") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") + require.Error(t, err) + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") err = tk.QueryToErr("SELECT * FROM information_schema.cluster_load") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") + require.Error(t, err) + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") err = tk.QueryToErr("SELECT * FROM information_schema.cluster_systeminfo") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") + require.Error(t, err) + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") err = tk.QueryToErr("SELECT * FROM information_schema.cluster_log WHERE time BETWEEN '2021-07-13 00:00:00' AND '2021-07-13 02:00:00' AND message like '%'") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") + require.Error(t, err) + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") // With correct/CONFIG permissions - tk.Se.Auth(&auth.UserIdentity{ + tk.Session().Auth(&auth.UserIdentity{ Username: "ccconfig", Hostname: "localhost", }, nil, nil) @@ -1521,20 +1608,20 @@ func (s *testPrivilegeSuite) TestClusterConfigInfoschema(c *C) { tk.MustQuery("SELECT * FROM information_schema.cluster_HARDWARE") // Missing Process privilege err = tk.QueryToErr("SELECT * FROM information_schema.cluster_INFO") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") + require.Error(t, err) + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") err = tk.QueryToErr("SELECT * FROM information_schema.cluster_LOAD") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") + require.Error(t, err) + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") err = tk.QueryToErr("SELECT * FROM information_schema.cluster_SYSTEMINFO") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") + require.Error(t, err) + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") err = tk.QueryToErr("SELECT * FROM information_schema.cluster_LOG WHERE time BETWEEN '2021-07-13 00:00:00' AND '2021-07-13 02:00:00' AND message like '%'") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") + require.Error(t, err) + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the PROCESS privilege(s) for this operation") // With correct/Process permissions - tk.Se.Auth(&auth.UserIdentity{ + tk.Session().Auth(&auth.UserIdentity{ Username: "ccprocess", Hostname: "localhost", }, nil, nil) @@ -1546,106 +1633,126 @@ func (s *testPrivilegeSuite) TestClusterConfigInfoschema(c *C) { tk.MustQuery("SELECT * FROM information_schema.CLUSTER_log WHERE time BETWEEN '1970-07-13 00:00:00' AND '1970-07-13 02:00:00' AND message like '%'") // Missing CONFIG privilege err = tk.QueryToErr("SELECT * FROM information_schema.CLUSTER_config") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the CONFIG privilege(s) for this operation") + require.Error(t, err) + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the CONFIG privilege(s) for this operation") err = tk.QueryToErr("SELECT * FROM information_schema.CLUSTER_hardware") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the CONFIG privilege(s) for this operation") + require.Error(t, err) + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the CONFIG privilege(s) for this operation") } -func (s *testPrivilegeSuite) TestSecurityEnhancedModeStatusVars(c *C) { +func TestSecurityEnhancedModeStatusVars(t *testing.T) { // Without TiKV the status var list does not include tidb_gc_leader_desc // So we can only test that the dynamic privilege is grantable. // We will have to use an integration test to run SHOW STATUS LIKE 'tidb_gc_leader_desc' // and verify if it appears. - tk := testkit.NewTestKit(c, s.store) + t.Parallel() + store, clean := newStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("CREATE USER unostatus, ustatus") tk.MustExec("GRANT RESTRICTED_STATUS_ADMIN ON *.* to ustatus") - tk.Se.Auth(&auth.UserIdentity{ + tk.Session().Auth(&auth.UserIdentity{ Username: "unostatus", Hostname: "localhost", }, nil, nil) } -func (s *testPrivilegeSuite) TestSecurityEnhancedLocalBackupRestore(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestSecurityEnhancedLocalBackupRestore(t *testing.T) { + store, clean := newStore(t) + defer clean() + + tk := testkit.NewTestKit(t, store) tk.MustExec("CREATE USER backuprestore") tk.MustExec("GRANT BACKUP_ADMIN,RESTORE_ADMIN ON *.* to backuprestore") - tk.Se.Auth(&auth.UserIdentity{ + tk.Session().Auth(&auth.UserIdentity{ Username: "backuprestore", Hostname: "localhost", }, nil, nil) // Prior to SEM nolocal has permission, the error should be because backup requires tikv - _, err := tk.Se.ExecuteInternal(context.Background(), "BACKUP DATABASE * TO 'Local:///tmp/test';") - c.Assert(err.Error(), Equals, "BACKUP requires tikv store, not unistore") + _, err := tk.Session().ExecuteInternal(context.Background(), "BACKUP DATABASE * TO 'Local:///tmp/test';") + require.EqualError(t, err, "BACKUP requires tikv store, not unistore") - _, err = tk.Se.ExecuteInternal(context.Background(), "RESTORE DATABASE * FROM 'LOCAl:///tmp/test';") - c.Assert(err.Error(), Equals, "RESTORE requires tikv store, not unistore") + _, err = tk.Session().ExecuteInternal(context.Background(), "RESTORE DATABASE * FROM 'LOCAl:///tmp/test';") + require.EqualError(t, err, "RESTORE requires tikv store, not unistore") sem.Enable() defer sem.Disable() // With SEM enabled nolocal does not have permission, but yeslocal does. - _, err = tk.Se.ExecuteInternal(context.Background(), "BACKUP DATABASE * TO 'Local:///tmp/test';") - c.Assert(err.Error(), Equals, "[planner:8132]Feature 'local://' is not supported when security enhanced mode is enabled") + _, err = tk.Session().ExecuteInternal(context.Background(), "BACKUP DATABASE * TO 'Local:///tmp/test';") + require.EqualError(t, err, "[planner:8132]Feature 'local://' is not supported when security enhanced mode is enabled") - _, err = tk.Se.ExecuteInternal(context.Background(), "RESTORE DATABASE * FROM 'LOCAl:///tmp/test';") - c.Assert(err.Error(), Equals, "[planner:8132]Feature 'local://' is not supported when security enhanced mode is enabled") + _, err = tk.Session().ExecuteInternal(context.Background(), "RESTORE DATABASE * FROM 'LOCAl:///tmp/test';") + require.EqualError(t, err, "[planner:8132]Feature 'local://' is not supported when security enhanced mode is enabled") } -func (s *testPrivilegeSuite) TestRenameUser(c *C) { - rootSe := newSession(c, s.store, s.dbName) - mustExec(c, rootSe, "DROP USER IF EXISTS 'ru1'@'localhost'") - mustExec(c, rootSe, "DROP USER IF EXISTS ru3") - mustExec(c, rootSe, "DROP USER IF EXISTS ru6@localhost") - mustExec(c, rootSe, "CREATE USER 'ru1'@'localhost'") - mustExec(c, rootSe, "CREATE USER ru3") - mustExec(c, rootSe, "CREATE USER ru6@localhost") - se1 := newSession(c, s.store, s.dbName) - c.Assert(se1.Auth(&auth.UserIdentity{Username: "ru1", Hostname: "localhost"}, nil, nil), IsTrue) +func TestRenameUser(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + rootSe := newSession(t, store, dbName) + mustExec(t, rootSe, "DROP USER IF EXISTS 'ru1'@'localhost'") + mustExec(t, rootSe, "DROP USER IF EXISTS ru3") + mustExec(t, rootSe, "DROP USER IF EXISTS ru6@localhost") + mustExec(t, rootSe, "CREATE USER 'ru1'@'localhost'") + mustExec(t, rootSe, "CREATE USER ru3") + mustExec(t, rootSe, "CREATE USER ru6@localhost") + se1 := newSession(t, store, dbName) + require.True(t, se1.Auth(&auth.UserIdentity{Username: "ru1", Hostname: "localhost"}, nil, nil)) // Check privileges (need CREATE USER) _, err := se1.ExecuteInternal(context.Background(), "RENAME USER ru3 TO ru4") - c.Assert(err, ErrorMatches, ".*Access denied; you need .at least one of. the CREATE USER privilege.s. for this operation") - mustExec(c, rootSe, "GRANT UPDATE ON mysql.user TO 'ru1'@'localhost'") + require.Error(t, err) + require.Regexp(t, ".*Access denied; you need .at least one of. the CREATE USER privilege.s. for this operation", err.Error()) + mustExec(t, rootSe, "GRANT UPDATE ON mysql.user TO 'ru1'@'localhost'") _, err = se1.ExecuteInternal(context.Background(), "RENAME USER ru3 TO ru4") - c.Assert(err, ErrorMatches, ".*Access denied; you need .at least one of. the CREATE USER privilege.s. for this operation") - mustExec(c, rootSe, "GRANT CREATE USER ON *.* TO 'ru1'@'localhost'") + require.Error(t, err) + require.Regexp(t, ".*Access denied; you need .at least one of. the CREATE USER privilege.s. for this operation", err.Error()) + mustExec(t, rootSe, "GRANT CREATE USER ON *.* TO 'ru1'@'localhost'") _, err = se1.ExecuteInternal(context.Background(), "RENAME USER ru3 TO ru4") - c.Assert(err, IsNil) + require.NoError(t, err) // Test a few single rename (both Username and Hostname) _, err = se1.ExecuteInternal(context.Background(), "RENAME USER 'ru4'@'%' TO 'ru3'@'localhost'") - c.Assert(err, IsNil) + require.NoError(t, err) _, err = se1.ExecuteInternal(context.Background(), "RENAME USER 'ru3'@'localhost' TO 'ru3'@'%'") - c.Assert(err, IsNil) + require.NoError(t, err) // Including negative tests, i.e. non existing from user and existing to user _, err = rootSe.ExecuteInternal(context.Background(), "RENAME USER ru3 TO ru1@localhost") - c.Assert(err, ErrorMatches, ".*Operation RENAME USER failed for ru3@%.*") + require.Error(t, err) + require.Regexp(t, ".*Operation RENAME USER failed for ru3@%.*", err.Error()) _, err = se1.ExecuteInternal(context.Background(), "RENAME USER ru4 TO ru5@localhost") - c.Assert(err, ErrorMatches, ".*Operation RENAME USER failed for ru4@%.*") + require.Error(t, err) + require.Regexp(t, ".*Operation RENAME USER failed for ru4@%.*", err.Error()) _, err = se1.ExecuteInternal(context.Background(), "RENAME USER ru3 TO ru3") - c.Assert(err, ErrorMatches, ".*Operation RENAME USER failed for ru3@%.*") + require.Error(t, err) + require.Regexp(t, ".*Operation RENAME USER failed for ru3@%.*", err.Error()) _, err = se1.ExecuteInternal(context.Background(), "RENAME USER ru3 TO ru5@localhost, ru4 TO ru7") - c.Assert(err, ErrorMatches, ".*Operation RENAME USER failed for ru4@%.*") + require.Error(t, err) + require.Regexp(t, ".*Operation RENAME USER failed for ru4@%.*", err.Error()) _, err = se1.ExecuteInternal(context.Background(), "RENAME USER ru3 TO ru5@localhost, ru6@localhost TO ru1@localhost") - c.Assert(err, ErrorMatches, ".*Operation RENAME USER failed for ru6@localhost.*") + require.Error(t, err) + require.Regexp(t, ".*Operation RENAME USER failed for ru6@localhost.*", err.Error()) // Test multi rename, this is a full swap of ru3 and ru6, i.e. need to read its previous state in the same transaction. _, err = se1.ExecuteInternal(context.Background(), "RENAME USER 'ru3' TO 'ru3_tmp', ru6@localhost TO ru3, 'ru3_tmp' to ru6@localhost") - c.Assert(err, IsNil) + require.NoError(t, err) // Cleanup - mustExec(c, rootSe, "DROP USER ru6@localhost") - mustExec(c, rootSe, "DROP USER ru3") - mustExec(c, rootSe, "DROP USER 'ru1'@'localhost'") + mustExec(t, rootSe, "DROP USER ru6@localhost") + mustExec(t, rootSe, "DROP USER ru3") + mustExec(t, rootSe, "DROP USER 'ru1'@'localhost'") } -func (s *testPrivilegeSuite) TestSecurityEnhancedModeSysVars(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestSecurityEnhancedModeSysVars(t *testing.T) { + store, clean := newStore(t) + defer clean() + + tk := testkit.NewTestKit(t, store) tk.MustExec("CREATE USER svroot1, svroot2") tk.MustExec("GRANT SUPER ON *.* to svroot1 WITH GRANT OPTION") tk.MustExec("GRANT SUPER, RESTRICTED_VARIABLES_ADMIN ON *.* to svroot2") @@ -1654,7 +1761,7 @@ func (s *testPrivilegeSuite) TestSecurityEnhancedModeSysVars(c *C) { defer sem.Disable() // svroot1 has SUPER but in SEM will be restricted - tk.Se.Auth(&auth.UserIdentity{ + tk.Session().Auth(&auth.UserIdentity{ Username: "svroot1", Hostname: "localhost", AuthUsername: "uroot", @@ -1665,16 +1772,16 @@ func (s *testPrivilegeSuite) TestSecurityEnhancedModeSysVars(c *C) { tk.MustQuery(`SHOW GLOBAL VARIABLES LIKE 'tidb_enable_telemetry'`).Check(testkit.Rows()) _, err := tk.Exec("SET tidb_force_priority = 'NO_PRIORITY'") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the RESTRICTED_VARIABLES_ADMIN privilege(s) for this operation") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the RESTRICTED_VARIABLES_ADMIN privilege(s) for this operation") _, err = tk.Exec("SET GLOBAL tidb_enable_telemetry = OFF") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the RESTRICTED_VARIABLES_ADMIN privilege(s) for this operation") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the RESTRICTED_VARIABLES_ADMIN privilege(s) for this operation") _, err = tk.Exec("SELECT @@session.tidb_force_priority") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the RESTRICTED_VARIABLES_ADMIN privilege(s) for this operation") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the RESTRICTED_VARIABLES_ADMIN privilege(s) for this operation") _, err = tk.Exec("SELECT @@global.tidb_enable_telemetry") - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the RESTRICTED_VARIABLES_ADMIN privilege(s) for this operation") + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the RESTRICTED_VARIABLES_ADMIN privilege(s) for this operation") - tk.Se.Auth(&auth.UserIdentity{ + tk.Session().Auth(&auth.UserIdentity{ Username: "svroot2", Hostname: "localhost", AuthUsername: "uroot", @@ -1694,8 +1801,12 @@ func (s *testPrivilegeSuite) TestSecurityEnhancedModeSysVars(c *C) { // TestViewDefiner tests that default roles are correctly applied in the algorithm definer // See: https://github.com/pingcap/tidb/issues/24414 -func (s *testPrivilegeSuite) TestViewDefiner(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestViewDefiner(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + tk := testkit.NewTestKit(t, store) tk.MustExec("CREATE DATABASE issue24414") tk.MustExec("USE issue24414") tk.MustExec(`create table table1( @@ -1720,8 +1831,11 @@ func (s *testPrivilegeSuite) TestViewDefiner(c *C) { tk.MustExec("select * from test_view2") } -func (s *testPrivilegeSuite) TestSecurityEnhancedModeRestrictedUsers(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestSecurityEnhancedModeRestrictedUsers(t *testing.T) { + store, clean := newStore(t) + defer clean() + + tk := testkit.NewTestKit(t, store) tk.MustExec("CREATE USER ruroot1, ruroot2, ruroot3") tk.MustExec("CREATE ROLE notimportant") tk.MustExec("GRANT SUPER, CREATE USER ON *.* to ruroot1 WITH GRANT OPTION") @@ -1740,7 +1854,7 @@ func (s *testPrivilegeSuite) TestSecurityEnhancedModeRestrictedUsers(c *C) { } // ruroot1 has SUPER but in SEM will be restricted - tk.Se.Auth(&auth.UserIdentity{ + tk.Session().Auth(&auth.UserIdentity{ Username: "ruroot1", Hostname: "localhost", AuthUsername: "uroot", @@ -1748,12 +1862,12 @@ func (s *testPrivilegeSuite) TestSecurityEnhancedModeRestrictedUsers(c *C) { }, nil, nil) for _, stmt := range stmts { - err := tk.ExecToErr(stmt) - c.Assert(err.Error(), Equals, "[planner:1227]Access denied; you need (at least one of) the RESTRICTED_USER_ADMIN privilege(s) for this operation") + _, err := tk.Exec(stmt) + require.EqualError(t, err, "[planner:1227]Access denied; you need (at least one of) the RESTRICTED_USER_ADMIN privilege(s) for this operation") } // Switch to ruroot2, it should be permitted - tk.Se.Auth(&auth.UserIdentity{ + tk.Session().Auth(&auth.UserIdentity{ Username: "ruroot2", Hostname: "localhost", AuthUsername: "uroot", @@ -1761,59 +1875,66 @@ func (s *testPrivilegeSuite) TestSecurityEnhancedModeRestrictedUsers(c *C) { }, nil, nil) for _, stmt := range stmts { - err := tk.ExecToErr(stmt) - c.Assert(err, IsNil) + tk.MustExec(stmt) } } -func (s *testPrivilegeSuite) TestDynamicPrivsRegistration(c *C) { - se := newSession(c, s.store, s.dbName) +func TestDynamicPrivsRegistration(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + se := newSession(t, store, dbName) pm := privilege.GetPrivilegeManager(se) count := len(privileges.GetDynamicPrivileges()) - c.Assert(pm.IsDynamicPrivilege("ACDC_ADMIN"), IsFalse) - c.Assert(privileges.RegisterDynamicPrivilege("ACDC_ADMIN"), IsNil) - c.Assert(pm.IsDynamicPrivilege("ACDC_ADMIN"), IsTrue) - c.Assert(len(privileges.GetDynamicPrivileges()), Equals, count+1) + require.False(t, pm.IsDynamicPrivilege("ACDC_ADMIN")) + require.Nil(t, privileges.RegisterDynamicPrivilege("ACDC_ADMIN")) + require.True(t, pm.IsDynamicPrivilege("ACDC_ADMIN")) + require.Len(t, privileges.GetDynamicPrivileges(), count+1) - c.Assert(pm.IsDynamicPrivilege("iAmdynamIC"), IsFalse) - c.Assert(privileges.RegisterDynamicPrivilege("IAMdynamic"), IsNil) - c.Assert(pm.IsDynamicPrivilege("IAMdyNAMIC"), IsTrue) - c.Assert(len(privileges.GetDynamicPrivileges()), Equals, count+2) + require.False(t, pm.IsDynamicPrivilege("iAmdynamIC")) + require.Nil(t, privileges.RegisterDynamicPrivilege("IAMdynamic")) + require.True(t, pm.IsDynamicPrivilege("IAMdyNAMIC")) + require.Len(t, privileges.GetDynamicPrivileges(), count+2) - c.Assert(privileges.RegisterDynamicPrivilege("THIS_PRIVILEGE_NAME_IS_TOO_LONG_THE_MAX_IS_32_CHARS").Error(), Equals, "privilege name is longer than 32 characters") - c.Assert(pm.IsDynamicPrivilege("THIS_PRIVILEGE_NAME_IS_TOO_LONG_THE_MAX_IS_32_CHARS"), IsFalse) + require.Equal(t, "privilege name is longer than 32 characters", privileges.RegisterDynamicPrivilege("THIS_PRIVILEGE_NAME_IS_TOO_LONG_THE_MAX_IS_32_CHARS").Error()) + require.False(t, pm.IsDynamicPrivilege("THIS_PRIVILEGE_NAME_IS_TOO_LONG_THE_MAX_IS_32_CHARS")) - tk := testkit.NewTestKit(c, s.store) + tk := testkit.NewTestKit(t, store) tk.MustExec("CREATE USER privassigntest") // Check that all privileges registered are assignable to users, // including the recently registered ACDC_ADMIN for _, priv := range privileges.GetDynamicPrivileges() { sqlGrant, err := sqlexec.EscapeSQL("GRANT %n ON *.* TO privassigntest", priv) - c.Assert(err, IsNil) + require.NoError(t, err) tk.MustExec(sqlGrant) } // Check that all privileges registered are revokable for _, priv := range privileges.GetDynamicPrivileges() { sqlGrant, err := sqlexec.EscapeSQL("REVOKE %n ON *.* FROM privassigntest", priv) - c.Assert(err, IsNil) + require.NoError(t, err) tk.MustExec(sqlGrant) } } -func (s *testPrivilegeSuite) TestInfoschemaUserPrivileges(c *C) { +func TestInfoSchemaUserPrivileges(t *testing.T) { // Being able to read all privileges from information_schema.user_privileges requires a very specific set of permissions. // SUPER user is not sufficient. It was observed in MySQL to require SELECT on mysql.* - tk := testkit.NewTestKit(c, s.store) + t.Parallel() + store, clean := newStore(t) + defer clean() + + tk := testkit.NewTestKit(t, store) tk.MustExec("CREATE USER isnobody, isroot, isselectonmysqluser, isselectonmysql") tk.MustExec("GRANT SUPER ON *.* TO isroot") tk.MustExec("GRANT SELECT ON mysql.user TO isselectonmysqluser") tk.MustExec("GRANT SELECT ON mysql.* TO isselectonmysql") // First as Nobody - tk.Se.Auth(&auth.UserIdentity{ + tk.Session().Auth(&auth.UserIdentity{ Username: "isnobody", Hostname: "localhost", }, nil, nil) @@ -1824,7 +1945,7 @@ func (s *testPrivilegeSuite) TestInfoschemaUserPrivileges(c *C) { tk.MustQuery(`SELECT * FROM information_schema.user_privileges WHERE grantee = "'isselectonmysqluser'@'%'"`).Check(testkit.Rows()) // Basically the same result as as isselectonmysqluser - tk.Se.Auth(&auth.UserIdentity{ + tk.Session().Auth(&auth.UserIdentity{ Username: "isselectonmysqluser", Hostname: "localhost", }, nil, nil) @@ -1837,7 +1958,7 @@ func (s *testPrivilegeSuite) TestInfoschemaUserPrivileges(c *C) { tk.MustQuery(`SELECT * FROM information_schema.user_privileges WHERE grantee = "'isselectonmysql'@'%'"`).Check(testkit.Rows()) // Now as root - tk.Se.Auth(&auth.UserIdentity{ + tk.Session().Auth(&auth.UserIdentity{ Username: "isroot", Hostname: "localhost", }, nil, nil) @@ -1848,7 +1969,7 @@ func (s *testPrivilegeSuite) TestInfoschemaUserPrivileges(c *C) { tk.MustQuery(`SELECT * FROM information_schema.user_privileges WHERE grantee = "'isselectonmysqluser'@'%'"`).Check(testkit.Rows()) // Now as isselectonmysqluser - tk.Se.Auth(&auth.UserIdentity{ + tk.Session().Auth(&auth.UserIdentity{ Username: "isselectonmysql", Hostname: "localhost", }, nil, nil) @@ -1860,15 +1981,19 @@ func (s *testPrivilegeSuite) TestInfoschemaUserPrivileges(c *C) { } // Issues https://github.com/pingcap/tidb/issues/25972 and https://github.com/pingcap/tidb/issues/26451 -func (s *testPrivilegeSuite) TestGrantOptionAndRevoke(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestGrantOptionAndRevoke(t *testing.T) { + t.Parallel() + store, clean := newStore(t) + defer clean() + + tk := testkit.NewTestKit(t, store) tk.MustExec("DROP USER IF EXISTS u1, u2, u3, ruser") tk.MustExec("CREATE USER u1, u2, u3, ruser") tk.MustExec("GRANT ALL ON *.* TO ruser WITH GRANT OPTION") tk.MustExec("GRANT SELECT ON *.* TO u1 WITH GRANT OPTION") tk.MustExec("GRANT UPDATE, DELETE on db.* TO u1") - tk.Se.Auth(&auth.UserIdentity{ + tk.Session().Auth(&auth.UserIdentity{ Username: "ruser", Hostname: "localhost", }, nil, nil) @@ -1906,3 +2031,30 @@ func (s *testPrivilegeSuite) TestGrantOptionAndRevoke(c *C) { "GRANT USAGE ON test.testgrant TO 'u3'@'%' WITH GRANT OPTION", )) } +func setUpTest(t *testing.T, store kv.Storage, dbName string) { + se := newSession(t, store, dbName) + createDBSQL := fmt.Sprintf("create database if not exists %s;", dbName) + createDB1SQL := fmt.Sprintf("create database if not exists %s1;", dbName) + useDBSQL := fmt.Sprintf("use %s;", dbName) + createTableSQL := `CREATE TABLE test(id INT NOT NULL DEFAULT 1, name varchar(255), PRIMARY KEY(id));` + + mustExec(t, se, createDBSQL) + mustExec(t, se, createDB1SQL) // create database test1 + mustExec(t, se, useDBSQL) + mustExec(t, se, createTableSQL) + + createSystemDBSQL := fmt.Sprintf("create database if not exists %s;", mysql.SystemDB) + + mustExec(t, se, createSystemDBSQL) + mustExec(t, se, session.CreateUserTable) + mustExec(t, se, session.CreateDBPrivTable) + mustExec(t, se, session.CreateTablePrivTable) + mustExec(t, se, session.CreateColumnPrivTable) +} + +func tearDownTest(t *testing.T, store kv.Storage, dbName string) { + // drop db + se := newSession(t, store, dbName) + dropDBSQL := fmt.Sprintf("drop database if exists %s;", dbName) + mustExec(t, se, dropDBSQL) +} diff --git a/testkit/result.go b/testkit/result.go index 4f30b47b1dddf..a88320ebaab28 100644 --- a/testkit/result.go +++ b/testkit/result.go @@ -18,6 +18,7 @@ package testkit import ( "bytes" "fmt" + "sort" "strings" "github.com/stretchr/testify/assert" @@ -52,6 +53,23 @@ func Rows(args ...string) [][]interface{} { return RowsWithSep(" ", args...) } +// Sort sorts and return the result. +func (res *Result) Sort() *Result { + sort.Slice(res.rows, func(i, j int) bool { + a := res.rows[i] + b := res.rows[j] + for i := range a { + if a[i] < b[i] { + return true + } else if a[i] > b[i] { + return false + } + } + return false + }) + return res +} + // RowsWithSep is a convenient function to wrap args to a slice of []interface. // The arg represents a row, split by sep. func RowsWithSep(sep string, args ...string) [][]interface{} { diff --git a/testkit/testkit.go b/testkit/testkit.go index 93414bddcc625..acad311033517 100644 --- a/testkit/testkit.go +++ b/testkit/testkit.go @@ -76,6 +76,17 @@ func (tk *TestKit) MustQuery(sql string, args ...interface{}) *Result { return tk.ResultSetToResult(rs, comment) } +// QueryToErr executes a sql statement and discard results. +func (tk *TestKit) QueryToErr(sql string, args ...interface{}) error { + comment := fmt.Sprintf("sql:%s, args:%v", sql, args) + res, err := tk.Exec(sql, args...) + tk.require.NoError(err, comment) + tk.require.NotNil(res, comment) + _, resErr := session.GetRows4Test(context.Background(), tk.session, res) + tk.require.Nil(res.Close()) + return resErr +} + // ResultSetToResult converts sqlexec.RecordSet to testkit.Result. // It is used to check results of execute statement in binary mode. func (tk *TestKit) ResultSetToResult(rs sqlexec.RecordSet, comment string) *Result {