Слияние кода завершено, страница обновится автоматически
// Copyright 2016 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 (
"github.com/hanchuanchuan/goInception/domain"
"github.com/hanchuanchuan/goInception/kv"
"github.com/hanchuanchuan/goInception/mysql"
"github.com/hanchuanchuan/goInception/privilege/privileges"
"github.com/hanchuanchuan/goInception/session"
"github.com/hanchuanchuan/goInception/store/mockstore"
. "github.com/pingcap/check"
)
var _ = Suite(&testCacheSuite{})
type testCacheSuite struct {
store kv.Storage
dbName string
domain *domain.Domain
}
func (s *testCacheSuite) SetUpSuite(c *C) {
store, err := mockstore.NewMockTikvStore()
session.SetSchemaLease(0)
session.SetStatsLease(0)
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)
defer se.Close()
mustExec(c, se, "use mysql;")
mustExec(c, se, "truncate table user;")
var p privileges.MySQLPrivilege
err = p.LoadUserTable(se)
c.Assert(err, IsNil)
c.Assert(len(p.User), Equals, 0)
// Host | User | Password | 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, Password, Select_priv) VALUES ("%", "root", "", "Y")`)
mustExec(c, se, `INSERT INTO mysql.user (Host, User, Password, Insert_priv) VALUES ("%", "root1", "admin", "Y")`)
mustExec(c, se, `INSERT INTO mysql.user (Host, User, Password, Update_priv, Show_db_priv, References_priv) VALUES ("%", "root11", "", "Y", "Y", "Y")`)
mustExec(c, se, `INSERT INTO mysql.user (Host, User, Password, Create_user_priv, Index_priv, Execute_priv, Show_db_priv, Super_priv, Trigger_priv) VALUES ("%", "root111", "", "Y", "Y", "Y", "Y", "Y", "Y")`)
p = privileges.MySQLPrivilege{}
err = p.LoadUserTable(se)
c.Assert(err, IsNil)
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.ShowDBPriv|mysql.SuperPriv|mysql.TriggerPriv)
}
func (s *testCacheSuite) TestLoadDBTable(c *C) {
se, err := session.CreateSession4Test(s.store)
c.Assert(err, IsNil)
defer se.Close()
mustExec(c, se, "use mysql;")
mustExec(c, 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, Execute_priv) VALUES ("%", "mysql", "root1", "Y", "Y", "Y", "Y", "Y")`)
var p privileges.MySQLPrivilege
err = p.LoadDBTable(se)
c.Assert(err, IsNil)
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.ExecutePriv)
}
func (s *testCacheSuite) TestLoadTablesPrivTable(c *C) {
se, err := session.CreateSession4Test(s.store)
c.Assert(err, IsNil)
defer se.Close()
mustExec(c, se, "use mysql;")
mustExec(c, 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")`)
var p privileges.MySQLPrivilege
err = p.LoadTablesPrivTable(se)
c.Assert(err, IsNil)
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)
}
func (s *testCacheSuite) TestLoadColumnsPrivTable(c *C) {
se, err := session.CreateSession4Test(s.store)
c.Assert(err, IsNil)
defer se.Close()
mustExec(c, se, "use mysql;")
mustExec(c, 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")`)
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)
}
func (s *testCacheSuite) TestPatternMatch(c *C) {
se, err := session.CreateSession4Test(s.store)
c.Assert(err, IsNil)
defer se.Close()
mustExec(c, se, "USE MYSQL;")
mustExec(c, se, "TRUNCATE TABLE mysql.user")
mustExec(c, se, `INSERT INTO mysql.user VALUES ("10.0.%", "root", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y")`)
var p privileges.MySQLPrivilege
err = p.LoadUserTable(se)
c.Assert(err, IsNil)
c.Assert(p.RequestVerification("root", "10.0.1", "test", "", "", mysql.SelectPriv), IsTrue)
c.Assert(p.RequestVerification("root", "10.0.1.118", "test", "", "", mysql.SelectPriv), IsTrue)
c.Assert(p.RequestVerification("root", "localhost", "test", "", "", mysql.SelectPriv), IsFalse)
c.Assert(p.RequestVerification("root", "127.0.0.1", "test", "", "", mysql.SelectPriv), IsFalse)
c.Assert(p.RequestVerification("root", "114.114.114.114", "test", "", "", mysql.SelectPriv), IsFalse)
c.Assert(p.RequestVerification("root", "114.114.114.114", "test", "", "", mysql.PrivilegeType(0)), IsTrue)
mustExec(c, se, "TRUNCATE TABLE mysql.user")
mustExec(c, se, `INSERT INTO mysql.user VALUES ("", "root", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y")`)
p = privileges.MySQLPrivilege{}
err = p.LoadUserTable(se)
c.Assert(err, IsNil)
c.Assert(p.RequestVerification("root", "", "test", "", "", mysql.SelectPriv), IsTrue)
c.Assert(p.RequestVerification("root", "notnull", "test", "", "", mysql.SelectPriv), IsFalse)
// 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')`)
err = p.LoadDBTable(se)
c.Assert(err, IsNil)
c.Assert(p.RequestVerification("genius", "127.0.0.1", "test", "", "", mysql.SelectPriv), IsTrue)
}
func (s *testCacheSuite) TestCaseInsensitive(c *C) {
se, err := session.CreateSession4Test(s.store)
c.Assert(err, IsNil)
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")`)
var p privileges.MySQLPrivilege
err = p.LoadDBTable(se)
c.Assert(err, IsNil)
// DB and Table names are case insensitive in MySQL.
c.Assert(p.RequestVerification("genius", "127.0.0.1", "TCTrain", "TCTrainOrder", "", mysql.SelectPriv), IsTrue)
c.Assert(p.RequestVerification("genius", "127.0.0.1", "TCTRAIN", "TCTRAINORDER", "", mysql.SelectPriv), IsTrue)
c.Assert(p.RequestVerification("genius", "127.0.0.1", "tctrain", "tctrainorder", "", mysql.SelectPriv), IsTrue)
}
func (s *testCacheSuite) TestAbnormalMySQLTable(c *C) {
store, err := mockstore.NewMockTikvStore()
c.Assert(err, IsNil)
defer store.Close()
session.SetSchemaLease(0)
session.SetStatsLease(0)
dom, err := session.BootstrapSession(store)
c.Assert(err, IsNil)
defer dom.Close()
se, err := session.CreateSession4Test(store)
c.Assert(err, IsNil)
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 (
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 '',
Select_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Insert_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Update_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Delete_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Create_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Drop_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Reload_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Shutdown_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Process_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
File_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Grant_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
References_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Index_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Alter_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Show_db_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Super_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Create_tmp_table_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Lock_tables_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Execute_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Repl_slave_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Repl_client_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Create_view_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Show_view_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Create_routine_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Alter_routine_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Create_user_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Event_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Trigger_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
Create_tablespace_priv enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
ssl_type enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 NOT NULL DEFAULT '',
ssl_cipher blob NOT NULL,
x509_issuer blob NOT NULL,
x509_subject blob NOT NULL,
max_questions int(11) unsigned NOT NULL DEFAULT '0',
max_updates int(11) unsigned NOT NULL DEFAULT '0',
max_connections int(11) unsigned NOT NULL DEFAULT '0',
max_user_connections int(11) unsigned NOT NULL DEFAULT '0',
plugin char(64) COLLATE utf8_bin DEFAULT 'mysql_native_password',
authentication_string text COLLATE utf8_bin,
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','','','','',0,0,0,0,'mysql_native_password','','N');
`)
var p privileges.MySQLPrivilege
err = p.LoadUserTable(se)
c.Assert(err, IsNil)
// MySQL mysql.user table schema is not identical to TiDB, check it doesn't break privilege.
c.Assert(p.RequestVerification("root", "localhost", "test", "", "", mysql.SelectPriv), IsTrue)
// 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;")
err = p.LoadAll(se)
c.Assert(err, IsNil)
}
func (s *testCacheSuite) TestSortUserTable(c *C) {
var p privileges.MySQLPrivilege
p.User = []privileges.UserRecord{
{Host: `%`, User: "root"},
{Host: `%`, User: "jeffrey"},
{Host: "localhost", User: "root"},
{Host: "localhost", User: ""},
}
p.SortUserTable()
result := []privileges.UserRecord{
{Host: "localhost", User: "root"},
{Host: "localhost", User: ""},
{Host: `%`, User: "jeffrey"},
{Host: `%`, User: "root"},
}
checkUserRecord(p.User, result, c)
p.User = []privileges.UserRecord{
{Host: `%`, User: "jeffrey"},
{Host: "h1.example.net", User: ""},
}
p.SortUserTable()
result = []privileges.UserRecord{
{Host: "h1.example.net", User: ""},
{Host: `%`, User: "jeffrey"},
}
checkUserRecord(p.User, result, c)
p.User = []privileges.UserRecord{
{Host: `192.168.%`, User: "xxx"},
{Host: `192.168.199.%`, User: "xxx"},
}
p.SortUserTable()
result = []privileges.UserRecord{
{Host: `192.168.199.%`, User: "xxx"},
{Host: `192.168.%`, User: "xxx"},
}
checkUserRecord(p.User, result, c)
}
func checkUserRecord(x, y []privileges.UserRecord, c *C) {
c.Assert(len(x), Equals, 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)
}
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарий ( 0 )