github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/privilege/privileges/privileges_test.go (about)

     1  // Copyright 2015 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package privileges_test
    15  
    16  import (
    17  	"fmt"
    18  	"testing"
    19  
    20  	"github.com/insionng/yougam/libraries/ngaut/log"
    21  	. "github.com/insionng/yougam/libraries/pingcap/check"
    22  	"github.com/insionng/yougam/libraries/pingcap/tidb"
    23  	"github.com/insionng/yougam/libraries/pingcap/tidb/context"
    24  	"github.com/insionng/yougam/libraries/pingcap/tidb/kv"
    25  	"github.com/insionng/yougam/libraries/pingcap/tidb/model"
    26  	"github.com/insionng/yougam/libraries/pingcap/tidb/mysql"
    27  	"github.com/insionng/yougam/libraries/pingcap/tidb/privilege/privileges"
    28  	"github.com/insionng/yougam/libraries/pingcap/tidb/sessionctx/variable"
    29  	"github.com/insionng/yougam/libraries/pingcap/tidb/util/testleak"
    30  	"github.com/insionng/yougam/libraries/pingcap/tidb/util/testutil"
    31  )
    32  
    33  func TestT(t *testing.T) {
    34  	TestingT(t)
    35  }
    36  
    37  var _ = Suite(&testPrivilegeSuite{})
    38  
    39  type testPrivilegeSuite struct {
    40  	store  kv.Storage
    41  	dbName string
    42  
    43  	createDBSQL              string
    44  	createDB1SQL             string
    45  	dropDBSQL                string
    46  	useDBSQL                 string
    47  	createTableSQL           string
    48  	createSystemDBSQL        string
    49  	createUserTableSQL       string
    50  	createDBPrivTableSQL     string
    51  	createTablePrivTableSQL  string
    52  	createColumnPrivTableSQL string
    53  }
    54  
    55  func (s *testPrivilegeSuite) SetUpTest(c *C) {
    56  	log.SetLevelByString("error")
    57  	s.dbName = "test"
    58  	s.store = newStore(c, s.dbName)
    59  	se := newSession(c, s.store, s.dbName)
    60  	s.createDBSQL = fmt.Sprintf("create database if not exists %s;", s.dbName)
    61  	s.createDB1SQL = fmt.Sprintf("create database if not exists %s1;", s.dbName)
    62  	s.dropDBSQL = fmt.Sprintf("drop database if exists %s;", s.dbName)
    63  	s.useDBSQL = fmt.Sprintf("use %s;", s.dbName)
    64  	s.createTableSQL = `CREATE TABLE test(id INT NOT NULL DEFAULT 1, name varchar(255), PRIMARY KEY(id));`
    65  
    66  	mustExec(c, se, s.createDBSQL)
    67  	mustExec(c, se, s.createDB1SQL) // create database test1
    68  	mustExec(c, se, s.useDBSQL)
    69  	mustExec(c, se, s.createTableSQL)
    70  
    71  	s.createSystemDBSQL = fmt.Sprintf("create database if not exists %s;", mysql.SystemDB)
    72  	s.createUserTableSQL = tidb.CreateUserTable
    73  	s.createDBPrivTableSQL = tidb.CreateDBPrivTable
    74  	s.createTablePrivTableSQL = tidb.CreateTablePrivTable
    75  	s.createColumnPrivTableSQL = tidb.CreateColumnPrivTable
    76  
    77  	mustExec(c, se, s.createSystemDBSQL)
    78  	mustExec(c, se, s.createUserTableSQL)
    79  	mustExec(c, se, s.createDBPrivTableSQL)
    80  	mustExec(c, se, s.createTablePrivTableSQL)
    81  	mustExec(c, se, s.createColumnPrivTableSQL)
    82  }
    83  
    84  func (s *testPrivilegeSuite) TearDownTest(c *C) {
    85  	// drop db
    86  	se := newSession(c, s.store, s.dbName)
    87  	mustExec(c, se, s.dropDBSQL)
    88  }
    89  
    90  func (s *testPrivilegeSuite) TestCheckDBPrivilege(c *C) {
    91  	defer testleak.AfterTest(c)()
    92  	se := newSession(c, s.store, s.dbName)
    93  	mustExec(c, se, `CREATE USER 'test'@'localhost' identified by '123';`)
    94  	pc := &privileges.UserPrivileges{}
    95  	db := &model.DBInfo{
    96  		Name: model.NewCIStr("test"),
    97  	}
    98  	ctx, _ := se.(context.Context)
    99  	variable.GetSessionVars(ctx).User = "test@localhost"
   100  	r, err := pc.Check(ctx, db, nil, mysql.SelectPriv)
   101  	c.Assert(err, IsNil)
   102  	c.Assert(r, IsFalse)
   103  
   104  	mustExec(c, se, `GRANT SELECT ON *.* TO  'test'@'localhost';`)
   105  	pc = &privileges.UserPrivileges{}
   106  	r, err = pc.Check(ctx, db, nil, mysql.SelectPriv)
   107  	c.Assert(err, IsNil)
   108  	c.Assert(r, IsTrue)
   109  	r, err = pc.Check(ctx, db, nil, mysql.UpdatePriv)
   110  	c.Assert(err, IsNil)
   111  	c.Assert(r, IsFalse)
   112  
   113  	mustExec(c, se, `GRANT Update ON test.* TO  'test'@'localhost';`)
   114  	pc = &privileges.UserPrivileges{}
   115  	r, err = pc.Check(ctx, db, nil, mysql.UpdatePriv)
   116  	c.Assert(err, IsNil)
   117  	c.Assert(r, IsTrue)
   118  }
   119  
   120  func (s *testPrivilegeSuite) TestCheckTablePrivilege(c *C) {
   121  	defer testleak.AfterTest(c)()
   122  	se := newSession(c, s.store, s.dbName)
   123  	mustExec(c, se, `CREATE USER 'test1'@'localhost' identified by '123';`)
   124  	pc := &privileges.UserPrivileges{}
   125  	db := &model.DBInfo{
   126  		Name: model.NewCIStr("test"),
   127  	}
   128  	tbl := &model.TableInfo{
   129  		Name: model.NewCIStr("test"),
   130  	}
   131  	ctx, _ := se.(context.Context)
   132  	variable.GetSessionVars(ctx).User = "test1@localhost"
   133  	r, err := pc.Check(ctx, db, tbl, mysql.SelectPriv)
   134  	c.Assert(err, IsNil)
   135  	c.Assert(r, IsFalse)
   136  
   137  	mustExec(c, se, `GRANT SELECT ON *.* TO  'test1'@'localhost';`)
   138  	pc = &privileges.UserPrivileges{}
   139  	r, err = pc.Check(ctx, db, tbl, mysql.SelectPriv)
   140  	c.Assert(err, IsNil)
   141  	c.Assert(r, IsTrue)
   142  	r, err = pc.Check(ctx, db, tbl, mysql.UpdatePriv)
   143  	c.Assert(err, IsNil)
   144  	c.Assert(r, IsFalse)
   145  
   146  	mustExec(c, se, `GRANT Update ON test.* TO  'test1'@'localhost';`)
   147  	pc = &privileges.UserPrivileges{}
   148  	r, err = pc.Check(ctx, db, tbl, mysql.UpdatePriv)
   149  	c.Assert(err, IsNil)
   150  	c.Assert(r, IsTrue)
   151  	r, err = pc.Check(ctx, db, tbl, mysql.IndexPriv)
   152  	c.Assert(err, IsNil)
   153  	c.Assert(r, IsFalse)
   154  
   155  	mustExec(c, se, `GRANT Index ON test.test TO  'test1'@'localhost';`)
   156  	pc = &privileges.UserPrivileges{}
   157  	r, err = pc.Check(ctx, db, tbl, mysql.IndexPriv)
   158  	c.Assert(err, IsNil)
   159  	c.Assert(r, IsTrue)
   160  }
   161  
   162  func (s *testPrivilegeSuite) TestShowGrants(c *C) {
   163  	defer testleak.AfterTest(c)()
   164  	se := newSession(c, s.store, s.dbName)
   165  	ctx, _ := se.(context.Context)
   166  	mustExec(c, se, `CREATE USER 'show'@'localhost' identified by '123';`)
   167  	mustExec(c, se, `GRANT Index ON *.* TO  'show'@'localhost';`)
   168  	pc := &privileges.UserPrivileges{}
   169  	gs, err := pc.ShowGrants(ctx, `show@localhost`)
   170  	c.Assert(err, IsNil)
   171  	c.Assert(gs, HasLen, 1)
   172  	c.Assert(gs[0], Equals, `GRANT Index ON *.* TO 'show'@'localhost'`)
   173  
   174  	mustExec(c, se, `GRANT Select ON *.* TO  'show'@'localhost';`)
   175  	pc = &privileges.UserPrivileges{}
   176  	gs, err = pc.ShowGrants(ctx, `show@localhost`)
   177  	c.Assert(err, IsNil)
   178  	c.Assert(gs, HasLen, 1)
   179  	c.Assert(gs[0], Equals, `GRANT Select,Index ON *.* TO 'show'@'localhost'`)
   180  
   181  	// The order of privs is the same with AllGlobalPrivs
   182  	mustExec(c, se, `GRANT Update ON *.* TO  'show'@'localhost';`)
   183  	pc = &privileges.UserPrivileges{}
   184  	gs, err = pc.ShowGrants(ctx, `show@localhost`)
   185  	c.Assert(err, IsNil)
   186  	c.Assert(gs, HasLen, 1)
   187  	c.Assert(gs[0], Equals, `GRANT Select,Update,Index ON *.* TO 'show'@'localhost'`)
   188  
   189  	// All privileges
   190  	mustExec(c, se, `GRANT ALL ON *.* TO  'show'@'localhost';`)
   191  	pc = &privileges.UserPrivileges{}
   192  	gs, err = pc.ShowGrants(ctx, `show@localhost`)
   193  	c.Assert(err, IsNil)
   194  	c.Assert(gs, HasLen, 1)
   195  	c.Assert(gs[0], Equals, `GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`)
   196  
   197  	// Add db scope privileges
   198  	mustExec(c, se, `GRANT Select ON test.* TO  'show'@'localhost';`)
   199  	pc = &privileges.UserPrivileges{}
   200  	gs, err = pc.ShowGrants(ctx, `show@localhost`)
   201  	c.Assert(err, IsNil)
   202  	c.Assert(gs, HasLen, 2)
   203  	expected := []string{`GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`,
   204  		`GRANT Select ON test.* TO 'show'@'localhost'`}
   205  	c.Assert(testutil.CompareUnorderedStringSlice(gs, expected), IsTrue)
   206  
   207  	mustExec(c, se, `GRANT Index ON test1.* TO  'show'@'localhost';`)
   208  	pc = &privileges.UserPrivileges{}
   209  	gs, err = pc.ShowGrants(ctx, `show@localhost`)
   210  	c.Assert(err, IsNil)
   211  	c.Assert(gs, HasLen, 3)
   212  	expected = []string{`GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`,
   213  		`GRANT Select ON test.* TO 'show'@'localhost'`,
   214  		`GRANT Index ON test1.* TO 'show'@'localhost'`}
   215  	c.Assert(testutil.CompareUnorderedStringSlice(gs, expected), IsTrue)
   216  
   217  	mustExec(c, se, `GRANT ALL ON test1.* TO  'show'@'localhost';`)
   218  	pc = &privileges.UserPrivileges{}
   219  	gs, err = pc.ShowGrants(ctx, `show@localhost`)
   220  	c.Assert(err, IsNil)
   221  	c.Assert(gs, HasLen, 3)
   222  	expected = []string{`GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`,
   223  		`GRANT Select ON test.* TO 'show'@'localhost'`,
   224  		`GRANT ALL PRIVILEGES ON test1.* TO 'show'@'localhost'`}
   225  	c.Assert(testutil.CompareUnorderedStringSlice(gs, expected), IsTrue)
   226  
   227  	// Add table scope privileges
   228  	mustExec(c, se, `GRANT Update ON test.test TO  'show'@'localhost';`)
   229  	pc = &privileges.UserPrivileges{}
   230  	gs, err = pc.ShowGrants(ctx, `show@localhost`)
   231  	c.Assert(err, IsNil)
   232  	c.Assert(gs, HasLen, 4)
   233  	expected = []string{`GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`,
   234  		`GRANT Select ON test.* TO 'show'@'localhost'`,
   235  		`GRANT ALL PRIVILEGES ON test1.* TO 'show'@'localhost'`,
   236  		`GRANT Update ON test.test TO 'show'@'localhost'`}
   237  	c.Assert(testutil.CompareUnorderedStringSlice(gs, expected), IsTrue)
   238  }
   239  
   240  func (s *testPrivilegeSuite) TestDropTablePriv(c *C) {
   241  	defer testleak.AfterTest(c)()
   242  	se := newSession(c, s.store, s.dbName)
   243  	ctx, _ := se.(context.Context)
   244  	mustExec(c, se, `CREATE TABLE todrop(c int);`)
   245  	variable.GetSessionVars(ctx).User = "root@localhost"
   246  	mustExec(c, se, `CREATE USER 'drop'@'localhost' identified by '123';`)
   247  	mustExec(c, se, `GRANT Select ON test.todrop TO  'drop'@'localhost';`)
   248  
   249  	variable.GetSessionVars(ctx).User = "drop@localhost"
   250  	mustExec(c, se, `SELECT * FROM todrop;`)
   251  
   252  	_, err := se.Execute("DROP TABLE todrop;")
   253  	c.Assert(err, NotNil)
   254  
   255  	variable.GetSessionVars(ctx).User = "root@localhost"
   256  	mustExec(c, se, `GRANT Drop ON test.todrop TO  'drop'@'localhost';`)
   257  
   258  	se1 := newSession(c, s.store, s.dbName)
   259  	ctx1, _ := se1.(context.Context)
   260  	variable.GetSessionVars(ctx1).User = "drop@localhost"
   261  	mustExec(c, se1, `DROP TABLE todrop;`)
   262  }
   263  
   264  func mustExec(c *C, se tidb.Session, sql string) {
   265  	_, err := se.Execute(sql)
   266  	c.Assert(err, IsNil)
   267  }
   268  
   269  func newStore(c *C, dbPath string) kv.Storage {
   270  	store, err := tidb.NewStore("memory" + "://" + dbPath)
   271  	c.Assert(err, IsNil)
   272  	return store
   273  }
   274  
   275  func newSession(c *C, store kv.Storage, dbName string) tidb.Session {
   276  	se, err := tidb.CreateSession(store)
   277  	c.Assert(err, IsNil)
   278  	mustExec(c, se, "create database if not exists "+dbName)
   279  	mustExec(c, se, "use "+dbName)
   280  	return se
   281  }