github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/petri/acyclic/privilege/privileges/privileges_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, 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  	"bytes"
    18  	"context"
    19  	"crypto/tls"
    20  	"crypto/x509"
    21  	"crypto/x509/pkix"
    22  	"fmt"
    23  	"net/url"
    24  	"os"
    25  	"strings"
    26  	"testing"
    27  
    28  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    29  	"github.com/whtcorpsinc/BerolinaSQL/auth"
    30  	"github.com/whtcorpsinc/BerolinaSQL/terror"
    31  	. "github.com/whtcorpsinc/check"
    32  	"github.com/whtcorpsinc/milevadb/causet/embedded"
    33  	"github.com/whtcorpsinc/milevadb/causetstore/mockstore"
    34  	"github.com/whtcorpsinc/milevadb/ekv"
    35  	"github.com/whtcorpsinc/milevadb/petri"
    36  	"github.com/whtcorpsinc/milevadb/privilege"
    37  	"github.com/whtcorpsinc/milevadb/privilege/privileges"
    38  	"github.com/whtcorpsinc/milevadb/soliton"
    39  	"github.com/whtcorpsinc/milevadb/soliton/solitonutil"
    40  	"github.com/whtcorpsinc/milevadb/soliton/testkit"
    41  	"github.com/whtcorpsinc/milevadb/soliton/testleak"
    42  	"github.com/whtcorpsinc/milevadb/stochastik"
    43  	"github.com/whtcorpsinc/milevadb/stochastikctx"
    44  )
    45  
    46  func TestT(t *testing.T) {
    47  	CustomVerboseFlag = true
    48  	TestingT(t)
    49  }
    50  
    51  var _ = Suite(&testPrivilegeSuite{})
    52  
    53  type testPrivilegeSuite struct {
    54  	causetstore ekv.CausetStorage
    55  	dom         *petri.Petri
    56  	dbName      string
    57  
    58  	createDBALLEGROSQL                      string
    59  	createDB1ALLEGROSQL                     string
    60  	droFIDelBALLEGROSQL                     string
    61  	useDBALLEGROSQL                         string
    62  	createBlockALLEGROSQL                   string
    63  	createSystemDBALLEGROSQL                string
    64  	createUserBlockALLEGROSQL               string
    65  	createDBPrivBlockALLEGROSQL             string
    66  	createBlockPrivBlockALLEGROSQL          string
    67  	createDeferredCausetPrivBlockALLEGROSQL string
    68  }
    69  
    70  func (s *testPrivilegeSuite) SetUpSuite(c *C) {
    71  	testleak.BeforeTest()
    72  	s.dbName = "test"
    73  	s.dom, s.causetstore = newStore(c, s.dbName)
    74  }
    75  
    76  func (s *testPrivilegeSuite) TearDownSuite(c *C) {
    77  	s.dom.Close()
    78  	s.causetstore.Close()
    79  	testleak.AfterTest(c)()
    80  }
    81  
    82  func (s *testPrivilegeSuite) SetUpTest(c *C) {
    83  	se := newStochastik(c, s.causetstore, s.dbName)
    84  	s.createDBALLEGROSQL = fmt.Sprintf("create database if not exists %s;", s.dbName)
    85  	s.createDB1ALLEGROSQL = fmt.Sprintf("create database if not exists %s1;", s.dbName)
    86  	s.droFIDelBALLEGROSQL = fmt.Sprintf("drop database if exists %s;", s.dbName)
    87  	s.useDBALLEGROSQL = fmt.Sprintf("use %s;", s.dbName)
    88  	s.createBlockALLEGROSQL = `CREATE TABLE test(id INT NOT NULL DEFAULT 1, name varchar(255), PRIMARY KEY(id));`
    89  
    90  	mustInterDirc(c, se, s.createDBALLEGROSQL)
    91  	mustInterDirc(c, se, s.createDB1ALLEGROSQL) // create database test1
    92  	mustInterDirc(c, se, s.useDBALLEGROSQL)
    93  	mustInterDirc(c, se, s.createBlockALLEGROSQL)
    94  
    95  	s.createSystemDBALLEGROSQL = fmt.Sprintf("create database if not exists %s;", allegrosql.SystemDB)
    96  	s.createUserBlockALLEGROSQL = stochastik.CreateUserBlock
    97  	s.createDBPrivBlockALLEGROSQL = stochastik.CreateDBPrivBlock
    98  	s.createBlockPrivBlockALLEGROSQL = stochastik.CreateBlockPrivBlock
    99  	s.createDeferredCausetPrivBlockALLEGROSQL = stochastik.CreateDeferredCausetPrivBlock
   100  
   101  	mustInterDirc(c, se, s.createSystemDBALLEGROSQL)
   102  	mustInterDirc(c, se, s.createUserBlockALLEGROSQL)
   103  	mustInterDirc(c, se, s.createDBPrivBlockALLEGROSQL)
   104  	mustInterDirc(c, se, s.createBlockPrivBlockALLEGROSQL)
   105  	mustInterDirc(c, se, s.createDeferredCausetPrivBlockALLEGROSQL)
   106  }
   107  
   108  func (s *testPrivilegeSuite) TearDownTest(c *C) {
   109  	// drop EDB
   110  	se := newStochastik(c, s.causetstore, s.dbName)
   111  	mustInterDirc(c, se, s.droFIDelBALLEGROSQL)
   112  }
   113  
   114  func (s *testPrivilegeSuite) TestCheckDBPrivilege(c *C) {
   115  	rootSe := newStochastik(c, s.causetstore, s.dbName)
   116  	mustInterDirc(c, rootSe, `CREATE USER 'testcheck'@'localhost';`)
   117  	mustInterDirc(c, rootSe, `CREATE USER 'testcheck_tmp'@'localhost';`)
   118  
   119  	se := newStochastik(c, s.causetstore, s.dbName)
   120  	activeRoles := make([]*auth.RoleIdentity, 0)
   121  	c.Assert(se.Auth(&auth.UserIdentity{Username: "testcheck", Hostname: "localhost"}, nil, nil), IsTrue)
   122  	pc := privilege.GetPrivilegeManager(se)
   123  	c.Assert(pc.RequestVerification(activeRoles, "test", "", "", allegrosql.SelectPriv), IsFalse)
   124  
   125  	mustInterDirc(c, rootSe, `GRANT SELECT ON *.* TO  'testcheck'@'localhost';`)
   126  	c.Assert(pc.RequestVerification(activeRoles, "test", "", "", allegrosql.SelectPriv), IsTrue)
   127  	c.Assert(pc.RequestVerification(activeRoles, "test", "", "", allegrosql.UFIDelatePriv), IsFalse)
   128  
   129  	mustInterDirc(c, rootSe, `GRANT UFIDelate ON test.* TO  'testcheck'@'localhost';`)
   130  	c.Assert(pc.RequestVerification(activeRoles, "test", "", "", allegrosql.UFIDelatePriv), IsTrue)
   131  
   132  	activeRoles = append(activeRoles, &auth.RoleIdentity{Username: "testcheck", Hostname: "localhost"})
   133  	mustInterDirc(c, rootSe, `GRANT 'testcheck'@'localhost' TO 'testcheck_tmp'@'localhost';`)
   134  	se2 := newStochastik(c, s.causetstore, s.dbName)
   135  	c.Assert(se2.Auth(&auth.UserIdentity{Username: "testcheck_tmp", Hostname: "localhost"}, nil, nil), IsTrue)
   136  	pc = privilege.GetPrivilegeManager(se2)
   137  	c.Assert(pc.RequestVerification(activeRoles, "test", "", "", allegrosql.SelectPriv), IsTrue)
   138  	c.Assert(pc.RequestVerification(activeRoles, "test", "", "", allegrosql.UFIDelatePriv), IsTrue)
   139  }
   140  
   141  func (s *testPrivilegeSuite) TestCheckPointGetDBPrivilege(c *C) {
   142  	rootSe := newStochastik(c, s.causetstore, s.dbName)
   143  	mustInterDirc(c, rootSe, `CREATE USER 'tester'@'localhost';`)
   144  	mustInterDirc(c, rootSe, `GRANT SELECT,UFIDelATE ON test.* TO  'tester'@'localhost';`)
   145  	mustInterDirc(c, rootSe, `flush privileges;`)
   146  	mustInterDirc(c, rootSe, `create database test2`)
   147  	mustInterDirc(c, rootSe, `create causet test2.t(id int, v int, primary key(id))`)
   148  	mustInterDirc(c, rootSe, `insert into test2.t(id, v) values(1, 1)`)
   149  
   150  	se := newStochastik(c, s.causetstore, s.dbName)
   151  	c.Assert(se.Auth(&auth.UserIdentity{Username: "tester", Hostname: "localhost"}, nil, nil), IsTrue)
   152  	mustInterDirc(c, se, `use test;`)
   153  	_, err := se.InterDircute(context.Background(), `select * from test2.t where id = 1`)
   154  	c.Assert(terror.ErrorEqual(err, embedded.ErrBlockaccessDenied), IsTrue)
   155  	_, err = se.InterDircute(context.Background(), "uFIDelate test2.t set v = 2 where id = 1")
   156  	c.Assert(terror.ErrorEqual(err, embedded.ErrBlockaccessDenied), IsTrue)
   157  }
   158  
   159  func (s *testPrivilegeSuite) TestCheckBlockPrivilege(c *C) {
   160  	rootSe := newStochastik(c, s.causetstore, s.dbName)
   161  	mustInterDirc(c, rootSe, `CREATE USER 'test1'@'localhost';`)
   162  	mustInterDirc(c, rootSe, `CREATE USER 'test1_tmp'@'localhost';`)
   163  
   164  	se := newStochastik(c, s.causetstore, s.dbName)
   165  	activeRoles := make([]*auth.RoleIdentity, 0)
   166  	c.Assert(se.Auth(&auth.UserIdentity{Username: "test1", Hostname: "localhost"}, nil, nil), IsTrue)
   167  	pc := privilege.GetPrivilegeManager(se)
   168  	c.Assert(pc.RequestVerification(activeRoles, "test", "test", "", allegrosql.SelectPriv), IsFalse)
   169  
   170  	mustInterDirc(c, rootSe, `GRANT SELECT ON *.* TO  'test1'@'localhost';`)
   171  	c.Assert(pc.RequestVerification(activeRoles, "test", "test", "", allegrosql.SelectPriv), IsTrue)
   172  	c.Assert(pc.RequestVerification(activeRoles, "test", "test", "", allegrosql.UFIDelatePriv), IsFalse)
   173  
   174  	mustInterDirc(c, rootSe, `GRANT UFIDelate ON test.* TO  'test1'@'localhost';`)
   175  	c.Assert(pc.RequestVerification(activeRoles, "test", "test", "", allegrosql.UFIDelatePriv), IsTrue)
   176  	c.Assert(pc.RequestVerification(activeRoles, "test", "test", "", allegrosql.IndexPriv), IsFalse)
   177  
   178  	activeRoles = append(activeRoles, &auth.RoleIdentity{Username: "test1", Hostname: "localhost"})
   179  	se2 := newStochastik(c, s.causetstore, s.dbName)
   180  	mustInterDirc(c, rootSe, `GRANT 'test1'@'localhost' TO 'test1_tmp'@'localhost';`)
   181  	c.Assert(se2.Auth(&auth.UserIdentity{Username: "test1_tmp", Hostname: "localhost"}, nil, nil), IsTrue)
   182  	pc2 := privilege.GetPrivilegeManager(se2)
   183  	c.Assert(pc2.RequestVerification(activeRoles, "test", "test", "", allegrosql.SelectPriv), IsTrue)
   184  	c.Assert(pc2.RequestVerification(activeRoles, "test", "test", "", allegrosql.UFIDelatePriv), IsTrue)
   185  	c.Assert(pc2.RequestVerification(activeRoles, "test", "test", "", allegrosql.IndexPriv), IsFalse)
   186  
   187  	mustInterDirc(c, rootSe, `GRANT Index ON test.test TO  'test1'@'localhost';`)
   188  	c.Assert(pc.RequestVerification(activeRoles, "test", "test", "", allegrosql.IndexPriv), IsTrue)
   189  	c.Assert(pc2.RequestVerification(activeRoles, "test", "test", "", allegrosql.IndexPriv), IsTrue)
   190  }
   191  
   192  func (s *testPrivilegeSuite) TestCheckViewPrivilege(c *C) {
   193  	rootSe := newStochastik(c, s.causetstore, s.dbName)
   194  	mustInterDirc(c, rootSe, `CREATE USER 'vuser'@'localhost';`)
   195  	mustInterDirc(c, rootSe, `CREATE VIEW v AS SELECT * FROM test;`)
   196  
   197  	se := newStochastik(c, s.causetstore, s.dbName)
   198  	activeRoles := make([]*auth.RoleIdentity, 0)
   199  	c.Assert(se.Auth(&auth.UserIdentity{Username: "vuser", Hostname: "localhost"}, nil, nil), IsTrue)
   200  	pc := privilege.GetPrivilegeManager(se)
   201  	c.Assert(pc.RequestVerification(activeRoles, "test", "v", "", allegrosql.SelectPriv), IsFalse)
   202  
   203  	mustInterDirc(c, rootSe, `GRANT SELECT ON test.v TO 'vuser'@'localhost';`)
   204  	c.Assert(pc.RequestVerification(activeRoles, "test", "v", "", allegrosql.SelectPriv), IsTrue)
   205  	c.Assert(pc.RequestVerification(activeRoles, "test", "v", "", allegrosql.ShowViewPriv), IsFalse)
   206  
   207  	mustInterDirc(c, rootSe, `GRANT SHOW VIEW ON test.v TO 'vuser'@'localhost';`)
   208  	c.Assert(pc.RequestVerification(activeRoles, "test", "v", "", allegrosql.SelectPriv), IsTrue)
   209  	c.Assert(pc.RequestVerification(activeRoles, "test", "v", "", allegrosql.ShowViewPriv), IsTrue)
   210  }
   211  
   212  func (s *testPrivilegeSuite) TestCheckPrivilegeWithRoles(c *C) {
   213  	rootSe := newStochastik(c, s.causetstore, s.dbName)
   214  	mustInterDirc(c, rootSe, `CREATE USER 'test_role'@'localhost';`)
   215  	mustInterDirc(c, rootSe, `CREATE ROLE r_1, r_2, r_3;`)
   216  	mustInterDirc(c, rootSe, `GRANT r_1, r_2, r_3 TO 'test_role'@'localhost';`)
   217  
   218  	se := newStochastik(c, s.causetstore, s.dbName)
   219  	c.Assert(se.Auth(&auth.UserIdentity{Username: "test_role", Hostname: "localhost"}, nil, nil), IsTrue)
   220  	mustInterDirc(c, se, `SET ROLE r_1, r_2;`)
   221  	mustInterDirc(c, rootSe, `SET DEFAULT ROLE r_1 TO 'test_role'@'localhost';`)
   222  
   223  	mustInterDirc(c, rootSe, `GRANT SELECT ON test.* TO r_1;`)
   224  	pc := privilege.GetPrivilegeManager(se)
   225  	activeRoles := se.GetStochastikVars().ActiveRoles
   226  	c.Assert(pc.RequestVerification(activeRoles, "test", "", "", allegrosql.SelectPriv), IsTrue)
   227  	c.Assert(pc.RequestVerification(activeRoles, "test", "", "", allegrosql.UFIDelatePriv), IsFalse)
   228  	mustInterDirc(c, rootSe, `GRANT UFIDelATE ON test.* TO r_2;`)
   229  	c.Assert(pc.RequestVerification(activeRoles, "test", "", "", allegrosql.UFIDelatePriv), IsTrue)
   230  
   231  	mustInterDirc(c, se, `SET ROLE NONE;`)
   232  	c.Assert(len(se.GetStochastikVars().ActiveRoles), Equals, 0)
   233  	mustInterDirc(c, se, `SET ROLE DEFAULT;`)
   234  	c.Assert(len(se.GetStochastikVars().ActiveRoles), Equals, 1)
   235  	mustInterDirc(c, se, `SET ROLE ALL;`)
   236  	c.Assert(len(se.GetStochastikVars().ActiveRoles), Equals, 3)
   237  	mustInterDirc(c, se, `SET ROLE ALL EXCEPT r_1, r_2;`)
   238  	c.Assert(len(se.GetStochastikVars().ActiveRoles), Equals, 1)
   239  }
   240  
   241  func (s *testPrivilegeSuite) TestShowGrants(c *C) {
   242  	se := newStochastik(c, s.causetstore, s.dbName)
   243  	ctx, _ := se.(stochastikctx.Context)
   244  	mustInterDirc(c, se, `CREATE USER 'show'@'localhost' identified by '123';`)
   245  	mustInterDirc(c, se, `GRANT Index ON *.* TO  'show'@'localhost';`)
   246  	pc := privilege.GetPrivilegeManager(se)
   247  
   248  	gs, err := pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil)
   249  	c.Assert(err, IsNil)
   250  	c.Assert(gs, HasLen, 1)
   251  	c.Assert(gs[0], Equals, `GRANT Index ON *.* TO 'show'@'localhost'`)
   252  
   253  	mustInterDirc(c, se, `GRANT Select ON *.* TO  'show'@'localhost';`)
   254  	gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil)
   255  	c.Assert(err, IsNil)
   256  	c.Assert(gs, HasLen, 1)
   257  	c.Assert(gs[0], Equals, `GRANT Select,Index ON *.* TO 'show'@'localhost'`)
   258  
   259  	// The order of privs is the same with AllGlobalPrivs
   260  	mustInterDirc(c, se, `GRANT UFIDelate ON *.* TO  'show'@'localhost';`)
   261  	gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil)
   262  	c.Assert(err, IsNil)
   263  	c.Assert(gs, HasLen, 1)
   264  	c.Assert(gs[0], Equals, `GRANT Select,UFIDelate,Index ON *.* TO 'show'@'localhost'`)
   265  
   266  	// All privileges
   267  	mustInterDirc(c, se, `GRANT ALL ON *.* TO  'show'@'localhost';`)
   268  	gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil)
   269  	c.Assert(err, IsNil)
   270  	c.Assert(gs, HasLen, 1)
   271  	c.Assert(gs[0], Equals, `GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`)
   272  
   273  	// All privileges with grant option
   274  	mustInterDirc(c, se, `GRANT ALL ON *.* TO 'show'@'localhost' WITH GRANT OPTION;`)
   275  	gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil)
   276  	c.Assert(err, IsNil)
   277  	c.Assert(gs, HasLen, 1)
   278  	c.Assert(gs[0], Equals, `GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost' WITH GRANT OPTION`)
   279  
   280  	// Revoke grant option
   281  	mustInterDirc(c, se, `REVOKE GRANT OPTION ON *.* FROM 'show'@'localhost';`)
   282  	gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil)
   283  	c.Assert(err, IsNil)
   284  	c.Assert(gs, HasLen, 1)
   285  	c.Assert(gs[0], Equals, `GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`)
   286  
   287  	// Add EDB scope privileges
   288  	mustInterDirc(c, se, `GRANT Select ON test.* TO  'show'@'localhost';`)
   289  	gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil)
   290  	c.Assert(err, IsNil)
   291  	c.Assert(gs, HasLen, 2)
   292  	expected := []string{`GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`,
   293  		`GRANT Select ON test.* TO 'show'@'localhost'`}
   294  	c.Assert(solitonutil.CompareUnorderedStringSlice(gs, expected), IsTrue)
   295  
   296  	mustInterDirc(c, se, `GRANT Index ON test1.* TO  'show'@'localhost';`)
   297  	gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil)
   298  	c.Assert(err, IsNil)
   299  	c.Assert(gs, HasLen, 3)
   300  	expected = []string{`GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`,
   301  		`GRANT Select ON test.* TO 'show'@'localhost'`,
   302  		`GRANT Index ON test1.* TO 'show'@'localhost'`}
   303  	c.Assert(solitonutil.CompareUnorderedStringSlice(gs, expected), IsTrue)
   304  
   305  	mustInterDirc(c, se, `GRANT ALL ON test1.* TO  'show'@'localhost';`)
   306  	gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil)
   307  	c.Assert(err, IsNil)
   308  	c.Assert(gs, HasLen, 3)
   309  	expected = []string{`GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`,
   310  		`GRANT Select ON test.* TO 'show'@'localhost'`,
   311  		`GRANT ALL PRIVILEGES ON test1.* TO 'show'@'localhost'`}
   312  	c.Assert(solitonutil.CompareUnorderedStringSlice(gs, expected), IsTrue)
   313  
   314  	// Add causet scope privileges
   315  	mustInterDirc(c, se, `GRANT UFIDelate ON test.test TO  'show'@'localhost';`)
   316  	gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil)
   317  	c.Assert(err, IsNil)
   318  	c.Assert(gs, HasLen, 4)
   319  	expected = []string{`GRANT ALL PRIVILEGES ON *.* TO 'show'@'localhost'`,
   320  		`GRANT Select ON test.* TO 'show'@'localhost'`,
   321  		`GRANT ALL PRIVILEGES ON test1.* TO 'show'@'localhost'`,
   322  		`GRANT UFIDelate ON test.test TO 'show'@'localhost'`}
   323  	c.Assert(solitonutil.CompareUnorderedStringSlice(gs, expected), IsTrue)
   324  
   325  	// Expected behavior: Usage still exists after revoking all privileges
   326  	mustInterDirc(c, se, `REVOKE ALL PRIVILEGES ON *.* FROM 'show'@'localhost'`)
   327  	mustInterDirc(c, se, `REVOKE Select on test.* FROM 'show'@'localhost'`)
   328  	mustInterDirc(c, se, `REVOKE ALL ON test1.* FROM 'show'@'localhost'`)
   329  	mustInterDirc(c, se, `REVOKE UFIDelATE on test.test FROM 'show'@'localhost'`)
   330  	gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil)
   331  	c.Assert(err, IsNil)
   332  	c.Assert(gs, HasLen, 1)
   333  	c.Assert(gs[0], Equals, `GRANT USAGE ON *.* TO 'show'@'localhost'`)
   334  
   335  	// Usage should not exist after dropping the user
   336  	// Which we need privileges to do so!
   337  	ctx.GetStochastikVars().User = &auth.UserIdentity{Username: "root", Hostname: "localhost"}
   338  	mustInterDirc(c, se, `DROP USER 'show'@'localhost'`)
   339  
   340  	// This should now return an error
   341  	_, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "show", Hostname: "localhost"}, nil)
   342  	c.Assert(err, NotNil)
   343  	// cant show grants for non-existent
   344  	c.Assert(terror.ErrorEqual(err, privileges.ErrNonexistingGrant), IsTrue)
   345  
   346  	// Test SHOW GRANTS with USING roles.
   347  	mustInterDirc(c, se, `CREATE ROLE 'r1', 'r2'`)
   348  	mustInterDirc(c, se, `GRANT SELECT ON test.* TO 'r1'`)
   349  	mustInterDirc(c, se, `GRANT INSERT, UFIDelATE ON test.* TO 'r2'`)
   350  	mustInterDirc(c, se, `CREATE USER 'testrole'@'localhost' IDENTIFIED BY 'u1pass'`)
   351  	mustInterDirc(c, se, `GRANT 'r1', 'r2' TO 'testrole'@'localhost'`)
   352  	gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "testrole", Hostname: "localhost"}, nil)
   353  	c.Assert(err, IsNil)
   354  	c.Assert(gs, HasLen, 2)
   355  	roles := make([]*auth.RoleIdentity, 0)
   356  	roles = append(roles, &auth.RoleIdentity{Username: "r2", Hostname: "%"})
   357  	mustInterDirc(c, se, `GRANT DELETE ON test.* TO 'testrole'@'localhost'`)
   358  	gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "testrole", Hostname: "localhost"}, roles)
   359  	c.Assert(err, IsNil)
   360  	c.Assert(gs, HasLen, 3)
   361  	roles = append(roles, &auth.RoleIdentity{Username: "r1", Hostname: "%"})
   362  	gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "testrole", Hostname: "localhost"}, roles)
   363  	c.Assert(err, IsNil)
   364  	c.Assert(gs, HasLen, 3)
   365  	mustInterDirc(c, se, `GRANT INSERT, DELETE ON test.test TO 'r2'`)
   366  	mustInterDirc(c, se, `create causet test.b (id int)`)
   367  	mustInterDirc(c, se, `GRANT UFIDelATE ON test.b TO 'testrole'@'localhost'`)
   368  	gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "testrole", Hostname: "localhost"}, roles)
   369  	c.Assert(err, IsNil)
   370  	c.Assert(gs, HasLen, 5)
   371  	mustInterDirc(c, se, `DROP ROLE 'r1', 'r2'`)
   372  	mustInterDirc(c, se, `DROP USER 'testrole'@'localhost'`)
   373  	mustInterDirc(c, se, `CREATE ROLE 'r1', 'r2'`)
   374  	mustInterDirc(c, se, `GRANT SELECT ON test.* TO 'r2'`)
   375  	mustInterDirc(c, se, `CREATE USER 'testrole'@'localhost' IDENTIFIED BY 'u1pass'`)
   376  	mustInterDirc(c, se, `GRANT 'r1' TO 'testrole'@'localhost'`)
   377  	mustInterDirc(c, se, `GRANT 'r2' TO 'r1'`)
   378  	gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "testrole", Hostname: "localhost"}, nil)
   379  	c.Assert(err, IsNil)
   380  	c.Assert(gs, HasLen, 2)
   381  	roles = make([]*auth.RoleIdentity, 0)
   382  	roles = append(roles, &auth.RoleIdentity{Username: "r1", Hostname: "%"})
   383  	gs, err = pc.ShowGrants(se, &auth.UserIdentity{Username: "testrole", Hostname: "localhost"}, roles)
   384  	c.Assert(err, IsNil)
   385  	c.Assert(gs, HasLen, 3)
   386  }
   387  
   388  func (s *testPrivilegeSuite) TestShowDeferredCausetGrants(c *C) {
   389  	se := newStochastik(c, s.causetstore, s.dbName)
   390  	mustInterDirc(c, se, `USE test`)
   391  	mustInterDirc(c, se, `CREATE USER 'column'@'%'`)
   392  	mustInterDirc(c, se, `CREATE TABLE column_block (a int, b int, c int)`)
   393  	mustInterDirc(c, se, `GRANT Select(a),UFIDelate(a,b),Insert(c) ON test.column_block TO  'column'@'%'`)
   394  
   395  	pc := privilege.GetPrivilegeManager(se)
   396  	gs, err := pc.ShowGrants(se, &auth.UserIdentity{Username: "column", Hostname: "%"}, nil)
   397  	c.Assert(err, IsNil)
   398  	c.Assert(strings.Join(gs, " "), Equals, "GRANT USAGE ON *.* TO 'column'@'%' GRANT Select(a), Insert(c), UFIDelate(a, b) ON test.column_block TO 'column'@'%'")
   399  }
   400  
   401  func (s *testPrivilegeSuite) TestDropBlockPriv(c *C) {
   402  	se := newStochastik(c, s.causetstore, s.dbName)
   403  	ctx, _ := se.(stochastikctx.Context)
   404  	mustInterDirc(c, se, `CREATE TABLE todrop(c int);`)
   405  	// ctx.GetStochastikVars().User = "root@localhost"
   406  	c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil), IsTrue)
   407  	mustInterDirc(c, se, `CREATE USER 'drop'@'localhost';`)
   408  	mustInterDirc(c, se, `GRANT Select ON test.todrop TO  'drop'@'localhost';`)
   409  
   410  	// ctx.GetStochastikVars().User = "drop@localhost"
   411  	c.Assert(se.Auth(&auth.UserIdentity{Username: "drop", Hostname: "localhost"}, nil, nil), IsTrue)
   412  	mustInterDirc(c, se, `SELECT * FROM todrop;`)
   413  	_, err := se.InterDircute(context.Background(), "DROP TABLE todrop;")
   414  	c.Assert(err, NotNil)
   415  
   416  	se = newStochastik(c, s.causetstore, s.dbName)
   417  	ctx.GetStochastikVars().User = &auth.UserIdentity{Username: "root", Hostname: "localhost"}
   418  	mustInterDirc(c, se, `GRANT Drop ON test.todrop TO  'drop'@'localhost';`)
   419  
   420  	se = newStochastik(c, s.causetstore, s.dbName)
   421  	ctx.GetStochastikVars().User = &auth.UserIdentity{Username: "drop", Hostname: "localhost"}
   422  	mustInterDirc(c, se, `DROP TABLE todrop;`)
   423  }
   424  
   425  func (s *testPrivilegeSuite) TestSetPasswdStmt(c *C) {
   426  
   427  	se := newStochastik(c, s.causetstore, s.dbName)
   428  
   429  	// high privileged user setting password for other user (passes)
   430  	mustInterDirc(c, se, "CREATE USER 'superuser'")
   431  	mustInterDirc(c, se, "CREATE USER 'nobodyuser'")
   432  	mustInterDirc(c, se, "GRANT ALL ON *.* TO 'superuser'")
   433  
   434  	c.Assert(se.Auth(&auth.UserIdentity{Username: "superuser", Hostname: "localhost", AuthUsername: "superuser", AuthHostname: "%"}, nil, nil), IsTrue)
   435  	mustInterDirc(c, se, "SET PASSWORD for 'nobodyuser' = 'newpassword'")
   436  	mustInterDirc(c, se, "SET PASSWORD for 'nobodyuser' = ''")
   437  
   438  	// low privileged user trying to set password for other user (fails)
   439  	c.Assert(se.Auth(&auth.UserIdentity{Username: "nobodyuser", Hostname: "localhost", AuthUsername: "nobodyuser", AuthHostname: "%"}, nil, nil), IsTrue)
   440  	_, err := se.InterDircute(context.Background(), "SET PASSWORD for 'superuser' = 'newpassword'")
   441  	c.Assert(err, NotNil)
   442  }
   443  
   444  func (s *testPrivilegeSuite) TestSelectViewSecurity(c *C) {
   445  	se := newStochastik(c, s.causetstore, s.dbName)
   446  	ctx, _ := se.(stochastikctx.Context)
   447  	mustInterDirc(c, se, `CREATE TABLE viewsecurity(c int);`)
   448  	// ctx.GetStochastikVars().User = "root@localhost"
   449  	c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil), IsTrue)
   450  	mustInterDirc(c, se, `CREATE USER 'selectusr'@'localhost';`)
   451  	mustInterDirc(c, se, `GRANT CREATE VIEW ON test.* TO  'selectusr'@'localhost';`)
   452  	mustInterDirc(c, se, `GRANT SELECT ON test.viewsecurity TO  'selectusr'@'localhost';`)
   453  
   454  	// ctx.GetStochastikVars().User = "selectusr@localhost"
   455  	c.Assert(se.Auth(&auth.UserIdentity{Username: "selectusr", Hostname: "localhost"}, nil, nil), IsTrue)
   456  	mustInterDirc(c, se, `SELECT * FROM test.viewsecurity;`)
   457  	mustInterDirc(c, se, `CREATE ALGORITHM = UNDEFINED ALLEGROALLEGROSQL SECURITY DEFINER VIEW test.selectviewsecurity as select * FROM test.viewsecurity;`)
   458  
   459  	se = newStochastik(c, s.causetstore, s.dbName)
   460  	ctx.GetStochastikVars().User = &auth.UserIdentity{Username: "root", Hostname: "localhost"}
   461  	mustInterDirc(c, se, "SELECT * FROM test.selectviewsecurity")
   462  	mustInterDirc(c, se, `REVOKE Select ON test.viewsecurity FROM  'selectusr'@'localhost';`)
   463  	_, err := se.InterDircute(context.Background(), "select * from test.selectviewsecurity")
   464  	c.Assert(err.Error(), Equals, embedded.ErrViewInvalid.GenWithStackByArgs("test", "selectviewsecurity").Error())
   465  }
   466  
   467  func (s *testPrivilegeSuite) TestRoleAdminSecurity(c *C) {
   468  	se := newStochastik(c, s.causetstore, s.dbName)
   469  	mustInterDirc(c, se, `CREATE USER 'ar1'@'localhost';`)
   470  	mustInterDirc(c, se, `CREATE USER 'ar2'@'localhost';`)
   471  	mustInterDirc(c, se, `GRANT ALL ON *.* to ar1@localhost`)
   472  	defer func() {
   473  		c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil), IsTrue)
   474  		mustInterDirc(c, se, "drop user 'ar1'@'localhost'")
   475  		mustInterDirc(c, se, "drop user 'ar2'@'localhost'")
   476  	}()
   477  
   478  	c.Assert(se.Auth(&auth.UserIdentity{Username: "ar1", Hostname: "localhost"}, nil, nil), IsTrue)
   479  	mustInterDirc(c, se, `create role r_test1@localhost`)
   480  
   481  	c.Assert(se.Auth(&auth.UserIdentity{Username: "ar2", Hostname: "localhost"}, nil, nil), IsTrue)
   482  	_, err := se.InterDircute(context.Background(), `create role r_test2@localhost`)
   483  	c.Assert(terror.ErrorEqual(err, embedded.ErrSpecificAccessDenied), IsTrue)
   484  }
   485  
   486  func (s *testPrivilegeSuite) TestCheckCertBasedAuth(c *C) {
   487  	se := newStochastik(c, s.causetstore, s.dbName)
   488  	mustInterDirc(c, se, `CREATE USER 'r1'@'localhost';`)
   489  	mustInterDirc(c, se, `CREATE USER 'r2'@'localhost' require none;`)
   490  	mustInterDirc(c, se, `CREATE USER 'r3'@'localhost' require ssl;`)
   491  	mustInterDirc(c, se, `CREATE USER 'r4'@'localhost' require x509;`)
   492  	mustInterDirc(c, se, `CREATE USER 'r5'@'localhost' require issuer '/C=US/ST=California/L=San Francisco/O=WHTCORPS INC/OU=MilevaDB/CN=MilevaDB admin'
   493  		subject '/C=ZH/ST=Beijing/L=Haidian/O=WHTCORPS INC.Inc/OU=MilevaDB/CN=tester1' cipher 'TLS_AES_128_GCM_SHA256'`)
   494  	mustInterDirc(c, se, `CREATE USER 'r6'@'localhost' require issuer '/C=US/ST=California/L=San Francisco/O=WHTCORPS INC/OU=MilevaDB/CN=MilevaDB admin'
   495  		subject '/C=ZH/ST=Beijing/L=Haidian/O=WHTCORPS INC.Inc/OU=MilevaDB/CN=tester1'`)
   496  	mustInterDirc(c, se, `CREATE USER 'r7_issuer_only'@'localhost' require issuer '/C=US/ST=California/L=San Francisco/O=WHTCORPS INC/OU=MilevaDB/CN=MilevaDB admin'`)
   497  	mustInterDirc(c, se, `CREATE USER 'r8_subject_only'@'localhost' require subject '/C=ZH/ST=Beijing/L=Haidian/O=WHTCORPS INC.Inc/OU=MilevaDB/CN=tester1'`)
   498  	mustInterDirc(c, se, `CREATE USER 'r9_subject_disorder'@'localhost' require subject '/ST=Beijing/C=ZH/L=Haidian/O=WHTCORPS INC.Inc/OU=MilevaDB/CN=tester1'`)
   499  	mustInterDirc(c, se, `CREATE USER 'r10_issuer_disorder'@'localhost' require issuer '/ST=California/C=US/L=San Francisco/O=WHTCORPS INC/OU=MilevaDB/CN=MilevaDB admin'`)
   500  	mustInterDirc(c, se, `CREATE USER 'r11_cipher_only'@'localhost' require cipher 'TLS_AES_256_GCM_SHA384'`)
   501  	mustInterDirc(c, se, `CREATE USER 'r12_old_milevadb_user'@'localhost'`)
   502  	mustInterDirc(c, se, "DELETE FROM allegrosql.global_priv WHERE `user` = 'r12_old_milevadb_user' and `host` = 'localhost'")
   503  	mustInterDirc(c, se, `CREATE USER 'r13_broken_user'@'localhost'require issuer '/C=US/ST=California/L=San Francisco/O=WHTCORPS INC/OU=MilevaDB/CN=MilevaDB admin'
   504  		subject '/C=ZH/ST=Beijing/L=Haidian/O=WHTCORPS INC.Inc/OU=MilevaDB/CN=tester1'`)
   505  	mustInterDirc(c, se, "UFIDelATE allegrosql.global_priv set priv = 'abc' where `user` = 'r13_broken_user' and `host` = 'localhost'")
   506  	mustInterDirc(c, se, `CREATE USER 'r14_san_only_pass'@'localhost' require san 'URI:spiffe://mesh.whtcorpsinc.com/ns/timesh/sa/me1'`)
   507  	mustInterDirc(c, se, `CREATE USER 'r15_san_only_fail'@'localhost' require san 'URI:spiffe://mesh.whtcorpsinc.com/ns/timesh/sa/me2'`)
   508  	mustInterDirc(c, se, "flush privileges")
   509  
   510  	defer func() {
   511  		c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil), IsTrue)
   512  		mustInterDirc(c, se, "drop user 'r1'@'localhost'")
   513  		mustInterDirc(c, se, "drop user 'r2'@'localhost'")
   514  		mustInterDirc(c, se, "drop user 'r3'@'localhost'")
   515  		mustInterDirc(c, se, "drop user 'r4'@'localhost'")
   516  		mustInterDirc(c, se, "drop user 'r5'@'localhost'")
   517  		mustInterDirc(c, se, "drop user 'r6'@'localhost'")
   518  		mustInterDirc(c, se, "drop user 'r7_issuer_only'@'localhost'")
   519  		mustInterDirc(c, se, "drop user 'r8_subject_only'@'localhost'")
   520  		mustInterDirc(c, se, "drop user 'r9_subject_disorder'@'localhost'")
   521  		mustInterDirc(c, se, "drop user 'r10_issuer_disorder'@'localhost'")
   522  		mustInterDirc(c, se, "drop user 'r11_cipher_only'@'localhost'")
   523  		mustInterDirc(c, se, "drop user 'r12_old_milevadb_user'@'localhost'")
   524  		mustInterDirc(c, se, "drop user 'r13_broken_user'@'localhost'")
   525  		mustInterDirc(c, se, "drop user 'r14_san_only_pass'@'localhost'")
   526  		mustInterDirc(c, se, "drop user 'r15_san_only_fail'@'localhost'")
   527  	}()
   528  
   529  	// test without ssl or ca
   530  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r1", Hostname: "localhost"}, nil, nil), IsTrue)
   531  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r2", Hostname: "localhost"}, nil, nil), IsTrue)
   532  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r3", Hostname: "localhost"}, nil, nil), IsFalse)
   533  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r4", Hostname: "localhost"}, nil, nil), IsFalse)
   534  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil), IsFalse)
   535  
   536  	// test use ssl without ca
   537  	se.GetStochastikVars().TLSConnectionState = &tls.ConnectionState{VerifiedChains: nil}
   538  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r1", Hostname: "localhost"}, nil, nil), IsTrue)
   539  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r2", Hostname: "localhost"}, nil, nil), IsTrue)
   540  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r3", Hostname: "localhost"}, nil, nil), IsTrue)
   541  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r4", Hostname: "localhost"}, nil, nil), IsFalse)
   542  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil), IsFalse)
   543  
   544  	// test use ssl with signed but info wrong ca.
   545  	se.GetStochastikVars().TLSConnectionState = &tls.ConnectionState{VerifiedChains: [][]*x509.Certificate{{{}}}}
   546  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r1", Hostname: "localhost"}, nil, nil), IsTrue)
   547  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r2", Hostname: "localhost"}, nil, nil), IsTrue)
   548  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r3", Hostname: "localhost"}, nil, nil), IsTrue)
   549  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r4", Hostname: "localhost"}, nil, nil), IsTrue)
   550  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil), IsFalse)
   551  
   552  	// test a all pass case
   553  	se.GetStochastikVars().TLSConnectionState = connectionState(
   554  		pkix.Name{
   555  			Names: []pkix.AttributeTypeAndValue{
   556  				soliton.MockPkixAttribute(soliton.Country, "US"),
   557  				soliton.MockPkixAttribute(soliton.Province, "California"),
   558  				soliton.MockPkixAttribute(soliton.Locality, "San Francisco"),
   559  				soliton.MockPkixAttribute(soliton.Organization, "WHTCORPS INC"),
   560  				soliton.MockPkixAttribute(soliton.OrganizationalUnit, "MilevaDB"),
   561  				soliton.MockPkixAttribute(soliton.CommonName, "MilevaDB admin"),
   562  			},
   563  		},
   564  		pkix.Name{
   565  			Names: []pkix.AttributeTypeAndValue{
   566  				soliton.MockPkixAttribute(soliton.Country, "ZH"),
   567  				soliton.MockPkixAttribute(soliton.Province, "Beijing"),
   568  				soliton.MockPkixAttribute(soliton.Locality, "Haidian"),
   569  				soliton.MockPkixAttribute(soliton.Organization, "WHTCORPS INC.Inc"),
   570  				soliton.MockPkixAttribute(soliton.OrganizationalUnit, "MilevaDB"),
   571  				soliton.MockPkixAttribute(soliton.CommonName, "tester1"),
   572  			},
   573  		},
   574  		tls.TLS_AES_128_GCM_SHA256, func(c *x509.Certificate) {
   575  			var url url.URL
   576  			url.UnmarshalBinary([]byte("spiffe://mesh.whtcorpsinc.com/ns/timesh/sa/me1"))
   577  			c.URIs = append(c.URIs, &url)
   578  		})
   579  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r1", Hostname: "localhost"}, nil, nil), IsTrue)
   580  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r2", Hostname: "localhost"}, nil, nil), IsTrue)
   581  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r3", Hostname: "localhost"}, nil, nil), IsTrue)
   582  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r4", Hostname: "localhost"}, nil, nil), IsTrue)
   583  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil), IsTrue)
   584  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r14_san_only_pass", Hostname: "localhost"}, nil, nil), IsTrue)
   585  
   586  	// test require but give nothing
   587  	se.GetStochastikVars().TLSConnectionState = nil
   588  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil), IsFalse)
   589  
   590  	// test mismatch cipher
   591  	se.GetStochastikVars().TLSConnectionState = connectionState(
   592  		pkix.Name{
   593  			Names: []pkix.AttributeTypeAndValue{
   594  				soliton.MockPkixAttribute(soliton.Country, "US"),
   595  				soliton.MockPkixAttribute(soliton.Province, "California"),
   596  				soliton.MockPkixAttribute(soliton.Locality, "San Francisco"),
   597  				soliton.MockPkixAttribute(soliton.Organization, "WHTCORPS INC"),
   598  				soliton.MockPkixAttribute(soliton.OrganizationalUnit, "MilevaDB"),
   599  				soliton.MockPkixAttribute(soliton.CommonName, "MilevaDB admin"),
   600  			},
   601  		},
   602  		pkix.Name{
   603  			Names: []pkix.AttributeTypeAndValue{
   604  				soliton.MockPkixAttribute(soliton.Country, "ZH"),
   605  				soliton.MockPkixAttribute(soliton.Province, "Beijing"),
   606  				soliton.MockPkixAttribute(soliton.Locality, "Haidian"),
   607  				soliton.MockPkixAttribute(soliton.Organization, "WHTCORPS INC.Inc"),
   608  				soliton.MockPkixAttribute(soliton.OrganizationalUnit, "MilevaDB"),
   609  				soliton.MockPkixAttribute(soliton.CommonName, "tester1"),
   610  			},
   611  		},
   612  		tls.TLS_AES_256_GCM_SHA384)
   613  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r5", Hostname: "localhost"}, nil, nil), IsFalse)
   614  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r6", Hostname: "localhost"}, nil, nil), IsTrue) // not require cipher
   615  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r11_cipher_only", Hostname: "localhost"}, nil, nil), IsTrue)
   616  
   617  	// test only subject or only issuer
   618  	se.GetStochastikVars().TLSConnectionState = connectionState(
   619  		pkix.Name{
   620  			Names: []pkix.AttributeTypeAndValue{
   621  				soliton.MockPkixAttribute(soliton.Country, "US"),
   622  				soliton.MockPkixAttribute(soliton.Province, "California"),
   623  				soliton.MockPkixAttribute(soliton.Locality, "San Francisco"),
   624  				soliton.MockPkixAttribute(soliton.Organization, "WHTCORPS INC"),
   625  				soliton.MockPkixAttribute(soliton.OrganizationalUnit, "MilevaDB"),
   626  				soliton.MockPkixAttribute(soliton.CommonName, "MilevaDB admin"),
   627  			},
   628  		},
   629  		pkix.Name{
   630  			Names: []pkix.AttributeTypeAndValue{
   631  				soliton.MockPkixAttribute(soliton.Country, "AZ"),
   632  				soliton.MockPkixAttribute(soliton.Province, "Beijing"),
   633  				soliton.MockPkixAttribute(soliton.Locality, "Shijingshang"),
   634  				soliton.MockPkixAttribute(soliton.Organization, "CAPPing.Inc"),
   635  				soliton.MockPkixAttribute(soliton.OrganizationalUnit, "MilevaDB"),
   636  				soliton.MockPkixAttribute(soliton.CommonName, "tester2"),
   637  			},
   638  		},
   639  		tls.TLS_AES_128_GCM_SHA256)
   640  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r7_issuer_only", Hostname: "localhost"}, nil, nil), IsTrue)
   641  	se.GetStochastikVars().TLSConnectionState = connectionState(
   642  		pkix.Name{
   643  			Names: []pkix.AttributeTypeAndValue{
   644  				soliton.MockPkixAttribute(soliton.Country, "AU"),
   645  				soliton.MockPkixAttribute(soliton.Province, "California"),
   646  				soliton.MockPkixAttribute(soliton.Locality, "San Francisco"),
   647  				soliton.MockPkixAttribute(soliton.Organization, "WHTCORPS INC"),
   648  				soliton.MockPkixAttribute(soliton.OrganizationalUnit, "MilevaDB"),
   649  				soliton.MockPkixAttribute(soliton.CommonName, "MilevaDB admin2"),
   650  			},
   651  		},
   652  		pkix.Name{
   653  			Names: []pkix.AttributeTypeAndValue{
   654  				soliton.MockPkixAttribute(soliton.Country, "ZH"),
   655  				soliton.MockPkixAttribute(soliton.Province, "Beijing"),
   656  				soliton.MockPkixAttribute(soliton.Locality, "Haidian"),
   657  				soliton.MockPkixAttribute(soliton.Organization, "WHTCORPS INC.Inc"),
   658  				soliton.MockPkixAttribute(soliton.OrganizationalUnit, "MilevaDB"),
   659  				soliton.MockPkixAttribute(soliton.CommonName, "tester1"),
   660  			},
   661  		},
   662  		tls.TLS_AES_128_GCM_SHA256)
   663  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r8_subject_only", Hostname: "localhost"}, nil, nil), IsTrue)
   664  
   665  	// test disorder issuer or subject
   666  	se.GetStochastikVars().TLSConnectionState = connectionState(
   667  		pkix.Name{
   668  			Names: []pkix.AttributeTypeAndValue{},
   669  		},
   670  		pkix.Name{
   671  			Names: []pkix.AttributeTypeAndValue{
   672  				soliton.MockPkixAttribute(soliton.Country, "ZH"),
   673  				soliton.MockPkixAttribute(soliton.Province, "Beijing"),
   674  				soliton.MockPkixAttribute(soliton.Locality, "Haidian"),
   675  				soliton.MockPkixAttribute(soliton.Organization, "WHTCORPS INC.Inc"),
   676  				soliton.MockPkixAttribute(soliton.OrganizationalUnit, "MilevaDB"),
   677  				soliton.MockPkixAttribute(soliton.CommonName, "tester1"),
   678  			},
   679  		},
   680  		tls.TLS_AES_128_GCM_SHA256)
   681  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r9_subject_disorder", Hostname: "localhost"}, nil, nil), IsFalse)
   682  	se.GetStochastikVars().TLSConnectionState = connectionState(
   683  		pkix.Name{
   684  			Names: []pkix.AttributeTypeAndValue{
   685  				soliton.MockPkixAttribute(soliton.Country, "US"),
   686  				soliton.MockPkixAttribute(soliton.Province, "California"),
   687  				soliton.MockPkixAttribute(soliton.Locality, "San Francisco"),
   688  				soliton.MockPkixAttribute(soliton.Organization, "WHTCORPS INC"),
   689  				soliton.MockPkixAttribute(soliton.OrganizationalUnit, "MilevaDB"),
   690  				soliton.MockPkixAttribute(soliton.CommonName, "MilevaDB admin"),
   691  			},
   692  		},
   693  		pkix.Name{
   694  			Names: []pkix.AttributeTypeAndValue{},
   695  		},
   696  		tls.TLS_AES_128_GCM_SHA256)
   697  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r10_issuer_disorder", Hostname: "localhost"}, nil, nil), IsFalse)
   698  
   699  	// test mismatch san
   700  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r15_san_only_fail", Hostname: "localhost"}, nil, nil), IsFalse)
   701  
   702  	// test old data and broken data
   703  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r12_old_milevadb_user", Hostname: "localhost"}, nil, nil), IsTrue)
   704  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r13_broken_user", Hostname: "localhost"}, nil, nil), IsFalse)
   705  
   706  }
   707  
   708  func connectionState(issuer, subject pkix.Name, cipher uint16, opt ...func(c *x509.Certificate)) *tls.ConnectionState {
   709  	cert := &x509.Certificate{Issuer: issuer, Subject: subject}
   710  	for _, o := range opt {
   711  		o(cert)
   712  	}
   713  	return &tls.ConnectionState{
   714  		VerifiedChains: [][]*x509.Certificate{{cert}},
   715  		CipherSuite:    cipher,
   716  	}
   717  }
   718  
   719  func (s *testPrivilegeSuite) TestCheckAuthenticate(c *C) {
   720  
   721  	se := newStochastik(c, s.causetstore, s.dbName)
   722  	mustInterDirc(c, se, `CREATE USER 'u1'@'localhost';`)
   723  	mustInterDirc(c, se, `CREATE USER 'u2'@'localhost' identified by 'abc';`)
   724  	mustInterDirc(c, se, `CREATE USER 'u3@example.com'@'localhost';`)
   725  	mustInterDirc(c, se, `CREATE USER u4@localhost;`)
   726  
   727  	c.Assert(se.Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost"}, nil, nil), IsTrue)
   728  	c.Assert(se.Auth(&auth.UserIdentity{Username: "u2", Hostname: "localhost"}, nil, nil), IsFalse)
   729  	salt := []byte{85, 92, 45, 22, 58, 79, 107, 6, 122, 125, 58, 80, 12, 90, 103, 32, 90, 10, 74, 82}
   730  	authentication := []byte{24, 180, 183, 225, 166, 6, 81, 102, 70, 248, 199, 143, 91, 204, 169, 9, 161, 171, 203, 33}
   731  	c.Assert(se.Auth(&auth.UserIdentity{Username: "u2", Hostname: "localhost"}, authentication, salt), IsTrue)
   732  	c.Assert(se.Auth(&auth.UserIdentity{Username: "u3@example.com", Hostname: "localhost"}, nil, nil), IsTrue)
   733  	c.Assert(se.Auth(&auth.UserIdentity{Username: "u4", Hostname: "localhost"}, nil, nil), IsTrue)
   734  
   735  	se1 := newStochastik(c, s.causetstore, s.dbName)
   736  	mustInterDirc(c, se1, "drop user 'u1'@'localhost'")
   737  	mustInterDirc(c, se1, "drop user 'u2'@'localhost'")
   738  	mustInterDirc(c, se1, "drop user 'u3@example.com'@'localhost'")
   739  	mustInterDirc(c, se1, "drop user u4@localhost")
   740  
   741  	c.Assert(se.Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost"}, nil, nil), IsFalse)
   742  	c.Assert(se.Auth(&auth.UserIdentity{Username: "u2", Hostname: "localhost"}, nil, nil), IsFalse)
   743  	c.Assert(se.Auth(&auth.UserIdentity{Username: "u3@example.com", Hostname: "localhost"}, nil, nil), IsFalse)
   744  	c.Assert(se.Auth(&auth.UserIdentity{Username: "u4", Hostname: "localhost"}, nil, nil), IsFalse)
   745  
   746  	se2 := newStochastik(c, s.causetstore, s.dbName)
   747  	mustInterDirc(c, se2, "create role 'r1'@'localhost'")
   748  	mustInterDirc(c, se2, "create role 'r2'@'localhost'")
   749  	mustInterDirc(c, se2, "create role 'r3@example.com'@'localhost'")
   750  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r1", Hostname: "localhost"}, nil, nil), IsFalse)
   751  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r2", Hostname: "localhost"}, nil, nil), IsFalse)
   752  	c.Assert(se.Auth(&auth.UserIdentity{Username: "r3@example.com", Hostname: "localhost"}, nil, nil), IsFalse)
   753  
   754  	mustInterDirc(c, se1, "drop user 'r1'@'localhost'")
   755  	mustInterDirc(c, se1, "drop user 'r2'@'localhost'")
   756  	mustInterDirc(c, se1, "drop user 'r3@example.com'@'localhost'")
   757  }
   758  
   759  func (s *testPrivilegeSuite) TestUseDB(c *C) {
   760  
   761  	se := newStochastik(c, s.causetstore, s.dbName)
   762  	// high privileged user
   763  	mustInterDirc(c, se, "CREATE USER 'usesuper'")
   764  	mustInterDirc(c, se, "CREATE USER 'usenobody'")
   765  	mustInterDirc(c, se, "GRANT ALL ON *.* TO 'usesuper'")
   766  	//without grant option
   767  	c.Assert(se.Auth(&auth.UserIdentity{Username: "usesuper", Hostname: "localhost", AuthUsername: "usesuper", AuthHostname: "%"}, nil, nil), IsTrue)
   768  	_, e := se.InterDircute(context.Background(), "GRANT SELECT ON allegrosql.* TO 'usenobody'")
   769  	c.Assert(e, NotNil)
   770  	//with grant option
   771  	se = newStochastik(c, s.causetstore, s.dbName)
   772  	// high privileged user
   773  	mustInterDirc(c, se, "GRANT ALL ON *.* TO 'usesuper' WITH GRANT OPTION")
   774  	c.Assert(se.Auth(&auth.UserIdentity{Username: "usesuper", Hostname: "localhost", AuthUsername: "usesuper", AuthHostname: "%"}, nil, nil), IsTrue)
   775  	mustInterDirc(c, se, "use allegrosql")
   776  	// low privileged user
   777  	c.Assert(se.Auth(&auth.UserIdentity{Username: "usenobody", Hostname: "localhost", AuthUsername: "usenobody", AuthHostname: "%"}, nil, nil), IsTrue)
   778  	_, err := se.InterDircute(context.Background(), "use allegrosql")
   779  	c.Assert(err, NotNil)
   780  
   781  	// try again after privilege granted
   782  	c.Assert(se.Auth(&auth.UserIdentity{Username: "usesuper", Hostname: "localhost", AuthUsername: "usesuper", AuthHostname: "%"}, nil, nil), IsTrue)
   783  	mustInterDirc(c, se, "GRANT SELECT ON allegrosql.* TO 'usenobody'")
   784  	c.Assert(se.Auth(&auth.UserIdentity{Username: "usenobody", Hostname: "localhost", AuthUsername: "usenobody", AuthHostname: "%"}, nil, nil), IsTrue)
   785  	_, err = se.InterDircute(context.Background(), "use allegrosql")
   786  	c.Assert(err, IsNil)
   787  
   788  	// test `use EDB` for role.
   789  	c.Assert(se.Auth(&auth.UserIdentity{Username: "usesuper", Hostname: "localhost", AuthUsername: "usesuper", AuthHostname: "%"}, nil, nil), IsTrue)
   790  	mustInterDirc(c, se, `CREATE DATABASE app_db`)
   791  	mustInterDirc(c, se, `CREATE ROLE 'app_developer'`)
   792  	mustInterDirc(c, se, `GRANT ALL ON app_db.* TO 'app_developer'`)
   793  	mustInterDirc(c, se, `CREATE USER 'dev'@'localhost'`)
   794  	mustInterDirc(c, se, `GRANT 'app_developer' TO 'dev'@'localhost'`)
   795  	mustInterDirc(c, se, `SET DEFAULT ROLE 'app_developer' TO 'dev'@'localhost'`)
   796  	c.Assert(se.Auth(&auth.UserIdentity{Username: "dev", Hostname: "localhost", AuthUsername: "dev", AuthHostname: "localhost"}, nil, nil), IsTrue)
   797  	_, err = se.InterDircute(context.Background(), "use app_db")
   798  	c.Assert(err, IsNil)
   799  	_, err = se.InterDircute(context.Background(), "use allegrosql")
   800  	c.Assert(err, NotNil)
   801  }
   802  
   803  func (s *testPrivilegeSuite) TestRevokePrivileges(c *C) {
   804  	se := newStochastik(c, s.causetstore, s.dbName)
   805  	mustInterDirc(c, se, "CREATE USER 'hasgrant'")
   806  	mustInterDirc(c, se, "CREATE USER 'withoutgrant'")
   807  	mustInterDirc(c, se, "GRANT ALL ON *.* TO 'hasgrant'")
   808  	mustInterDirc(c, se, "GRANT ALL ON allegrosql.* TO 'withoutgrant'")
   809  	// Without grant option
   810  	c.Assert(se.Auth(&auth.UserIdentity{Username: "hasgrant", Hostname: "localhost", AuthUsername: "hasgrant", AuthHostname: "%"}, nil, nil), IsTrue)
   811  	_, e := se.InterDircute(context.Background(), "REVOKE SELECT ON allegrosql.* FROM 'withoutgrant'")
   812  	c.Assert(e, NotNil)
   813  	// With grant option
   814  	se = newStochastik(c, s.causetstore, s.dbName)
   815  	mustInterDirc(c, se, "GRANT ALL ON *.* TO 'hasgrant' WITH GRANT OPTION")
   816  	c.Assert(se.Auth(&auth.UserIdentity{Username: "hasgrant", Hostname: "localhost", AuthUsername: "hasgrant", AuthHostname: "%"}, nil, nil), IsTrue)
   817  	mustInterDirc(c, se, "REVOKE SELECT ON allegrosql.* FROM 'withoutgrant'")
   818  	mustInterDirc(c, se, "REVOKE ALL ON allegrosql.* FROM withoutgrant")
   819  }
   820  
   821  func (s *testPrivilegeSuite) TestSetGlobal(c *C) {
   822  	se := newStochastik(c, s.causetstore, s.dbName)
   823  	mustInterDirc(c, se, `CREATE USER setglobal_a@localhost`)
   824  	mustInterDirc(c, se, `CREATE USER setglobal_b@localhost`)
   825  	mustInterDirc(c, se, `GRANT SUPER ON *.* to setglobal_a@localhost`)
   826  
   827  	c.Assert(se.Auth(&auth.UserIdentity{Username: "setglobal_a", Hostname: "localhost"}, nil, nil), IsTrue)
   828  	mustInterDirc(c, se, `set global innodb_commit_concurrency=16`)
   829  
   830  	c.Assert(se.Auth(&auth.UserIdentity{Username: "setglobal_b", Hostname: "localhost"}, nil, nil), IsTrue)
   831  	_, err := se.InterDircute(context.Background(), `set global innodb_commit_concurrency=16`)
   832  	c.Assert(terror.ErrorEqual(err, embedded.ErrSpecificAccessDenied), IsTrue)
   833  }
   834  
   835  func (s *testPrivilegeSuite) TestCreateDropUser(c *C) {
   836  	se := newStochastik(c, s.causetstore, s.dbName)
   837  	mustInterDirc(c, se, `CREATE USER tcd1, tcd2`)
   838  	mustInterDirc(c, se, `GRANT ALL ON *.* to tcd2 WITH GRANT OPTION`)
   839  
   840  	// should fail
   841  	c.Assert(se.Auth(&auth.UserIdentity{Username: "tcd1", Hostname: "localhost", AuthUsername: "tcd1", AuthHostname: "%"}, nil, nil), IsTrue)
   842  	_, err := se.InterDircute(context.Background(), `CREATE USER acdc`)
   843  	c.Assert(terror.ErrorEqual(err, embedded.ErrSpecificAccessDenied), IsTrue)
   844  	_, err = se.InterDircute(context.Background(), `DROP USER tcd2`)
   845  	c.Assert(terror.ErrorEqual(err, embedded.ErrSpecificAccessDenied), IsTrue)
   846  
   847  	// should pass
   848  	c.Assert(se.Auth(&auth.UserIdentity{Username: "tcd2", Hostname: "localhost", AuthUsername: "tcd2", AuthHostname: "%"}, nil, nil), IsTrue)
   849  	mustInterDirc(c, se, `DROP USER tcd1`)
   850  	mustInterDirc(c, se, `CREATE USER tcd1`)
   851  
   852  	// should pass
   853  	mustInterDirc(c, se, `GRANT tcd2 TO tcd1`)
   854  	c.Assert(se.Auth(&auth.UserIdentity{Username: "tcd1", Hostname: "localhost", AuthUsername: "tcd1", AuthHostname: "%"}, nil, nil), IsTrue)
   855  	mustInterDirc(c, se, `SET ROLE tcd2;`)
   856  	mustInterDirc(c, se, `CREATE USER tcd3`)
   857  	mustInterDirc(c, se, `DROP USER tcd3`)
   858  }
   859  
   860  func (s *testPrivilegeSuite) TestConfigPrivilege(c *C) {
   861  	se := newStochastik(c, s.causetstore, s.dbName)
   862  	mustInterDirc(c, se, `DROP USER IF EXISTS tcd1`)
   863  	mustInterDirc(c, se, `CREATE USER tcd1`)
   864  	mustInterDirc(c, se, `GRANT ALL ON *.* to tcd1`)
   865  	mustInterDirc(c, se, `DROP USER IF EXISTS tcd2`)
   866  	mustInterDirc(c, se, `CREATE USER tcd2`)
   867  	mustInterDirc(c, se, `GRANT ALL ON *.* to tcd2`)
   868  	mustInterDirc(c, se, `REVOKE CONFIG ON *.* FROM tcd2`)
   869  
   870  	c.Assert(se.Auth(&auth.UserIdentity{Username: "tcd1", Hostname: "localhost", AuthHostname: "tcd1", AuthUsername: "%"}, nil, nil), IsTrue)
   871  	mustInterDirc(c, se, `SET CONFIG EinsteinDB testkey="testval"`)
   872  	c.Assert(se.Auth(&auth.UserIdentity{Username: "tcd2", Hostname: "localhost", AuthHostname: "tcd2", AuthUsername: "%"}, nil, nil), IsTrue)
   873  	_, err := se.InterDircute(context.Background(), `SET CONFIG EinsteinDB testkey="testval"`)
   874  	c.Assert(err, ErrorMatches, ".*you need \\(at least one of\\) the CONFIG privilege\\(s\\) for this operation")
   875  	mustInterDirc(c, se, `DROP USER tcd1, tcd2`)
   876  }
   877  
   878  func (s *testPrivilegeSuite) TestShowCreateBlock(c *C) {
   879  	se := newStochastik(c, s.causetstore, s.dbName)
   880  	mustInterDirc(c, se, `CREATE USER tsct1, tsct2`)
   881  	mustInterDirc(c, se, `GRANT select ON allegrosql.* to tsct2`)
   882  
   883  	// should fail
   884  	c.Assert(se.Auth(&auth.UserIdentity{Username: "tsct1", Hostname: "localhost", AuthUsername: "tsct1", AuthHostname: "%"}, nil, nil), IsTrue)
   885  	_, err := se.InterDircute(context.Background(), `SHOW CREATE TABLE allegrosql.user`)
   886  	c.Assert(terror.ErrorEqual(err, embedded.ErrBlockaccessDenied), IsTrue)
   887  
   888  	// should pass
   889  	c.Assert(se.Auth(&auth.UserIdentity{Username: "tsct2", Hostname: "localhost", AuthUsername: "tsct2", AuthHostname: "%"}, nil, nil), IsTrue)
   890  	mustInterDirc(c, se, `SHOW CREATE TABLE allegrosql.user`)
   891  }
   892  
   893  func (s *testPrivilegeSuite) TestAnalyzeBlock(c *C) {
   894  
   895  	se := newStochastik(c, s.causetstore, s.dbName)
   896  	// high privileged user
   897  	mustInterDirc(c, se, "CREATE USER 'asuper'")
   898  	mustInterDirc(c, se, "CREATE USER 'anobody'")
   899  	mustInterDirc(c, se, "GRANT ALL ON *.* TO 'asuper' WITH GRANT OPTION")
   900  	mustInterDirc(c, se, "CREATE DATABASE atest")
   901  	mustInterDirc(c, se, "use atest")
   902  	mustInterDirc(c, se, "CREATE TABLE t1 (a int)")
   903  
   904  	c.Assert(se.Auth(&auth.UserIdentity{Username: "asuper", Hostname: "localhost", AuthUsername: "asuper", AuthHostname: "%"}, nil, nil), IsTrue)
   905  	mustInterDirc(c, se, "analyze causet allegrosql.user")
   906  	// low privileged user
   907  	c.Assert(se.Auth(&auth.UserIdentity{Username: "anobody", Hostname: "localhost", AuthUsername: "anobody", AuthHostname: "%"}, nil, nil), IsTrue)
   908  	_, err := se.InterDircute(context.Background(), "analyze causet t1")
   909  	c.Assert(terror.ErrorEqual(err, embedded.ErrBlockaccessDenied), IsTrue)
   910  	c.Assert(err.Error(), Equals, "[causet:1142]INSERT command denied to user 'anobody'@'%' for causet 't1'")
   911  
   912  	_, err = se.InterDircute(context.Background(), "select * from t1")
   913  	c.Assert(err.Error(), Equals, "[causet:1142]SELECT command denied to user 'anobody'@'%' for causet 't1'")
   914  
   915  	// try again after SELECT privilege granted
   916  	c.Assert(se.Auth(&auth.UserIdentity{Username: "asuper", Hostname: "localhost", AuthUsername: "asuper", AuthHostname: "%"}, nil, nil), IsTrue)
   917  	mustInterDirc(c, se, "GRANT SELECT ON atest.* TO 'anobody'")
   918  	c.Assert(se.Auth(&auth.UserIdentity{Username: "anobody", Hostname: "localhost", AuthUsername: "anobody", AuthHostname: "%"}, nil, nil), IsTrue)
   919  	_, err = se.InterDircute(context.Background(), "analyze causet t1")
   920  	c.Assert(terror.ErrorEqual(err, embedded.ErrBlockaccessDenied), IsTrue)
   921  	c.Assert(err.Error(), Equals, "[causet:1142]INSERT command denied to user 'anobody'@'%' for causet 't1'")
   922  	// Add INSERT privilege and it should work.
   923  	c.Assert(se.Auth(&auth.UserIdentity{Username: "asuper", Hostname: "localhost", AuthUsername: "asuper", AuthHostname: "%"}, nil, nil), IsTrue)
   924  	mustInterDirc(c, se, "GRANT INSERT ON atest.* TO 'anobody'")
   925  	c.Assert(se.Auth(&auth.UserIdentity{Username: "anobody", Hostname: "localhost", AuthUsername: "anobody", AuthHostname: "%"}, nil, nil), IsTrue)
   926  	_, err = se.InterDircute(context.Background(), "analyze causet t1")
   927  	c.Assert(err, IsNil)
   928  
   929  }
   930  
   931  func (s *testPrivilegeSuite) TestSystemSchema(c *C) {
   932  	// This test tests no privilege check for INFORMATION_SCHEMA database.
   933  	se := newStochastik(c, s.causetstore, s.dbName)
   934  	mustInterDirc(c, se, `CREATE USER 'u1'@'localhost';`)
   935  	c.Assert(se.Auth(&auth.UserIdentity{Username: "u1", Hostname: "localhost"}, nil, nil), IsTrue)
   936  	mustInterDirc(c, se, `select * from information_schema.blocks`)
   937  	mustInterDirc(c, se, `select * from information_schema.key_column_usage`)
   938  	_, err := se.InterDircute(context.Background(), "create causet information_schema.t(a int)")
   939  	c.Assert(strings.Contains(err.Error(), "denied to user"), IsTrue)
   940  	_, err = se.InterDircute(context.Background(), "drop causet information_schema.blocks")
   941  	c.Assert(strings.Contains(err.Error(), "denied to user"), IsTrue)
   942  	_, err = se.InterDircute(context.Background(), "uFIDelate information_schema.blocks set block_name = 'tst' where block_name = 'allegrosql'")
   943  	c.Assert(strings.Contains(err.Error(), "privilege check fail"), IsTrue)
   944  
   945  	// Test performance_schema.
   946  	mustInterDirc(c, se, `select * from performance_schema.events_memexs_summary_by_digest`)
   947  	_, err = se.InterDircute(context.Background(), "drop causet performance_schema.events_memexs_summary_by_digest")
   948  	c.Assert(strings.Contains(err.Error(), "denied to user"), IsTrue)
   949  	_, err = se.InterDircute(context.Background(), "uFIDelate performance_schema.events_memexs_summary_by_digest set schema_name = 'tst'")
   950  	c.Assert(strings.Contains(err.Error(), "privilege check fail"), IsTrue)
   951  	_, err = se.InterDircute(context.Background(), "delete from performance_schema.events_memexs_summary_by_digest")
   952  	c.Assert(strings.Contains(err.Error(), "privilege check fail"), IsTrue)
   953  	_, err = se.InterDircute(context.Background(), "create causet performance_schema.t(a int)")
   954  	c.Assert(err, NotNil)
   955  	c.Assert(strings.Contains(err.Error(), "CREATE command denied"), IsTrue, Commentf(err.Error()))
   956  
   957  	// Test metric_schema.
   958  	mustInterDirc(c, se, `select * from metrics_schema.milevadb_query_duration`)
   959  	_, err = se.InterDircute(context.Background(), "drop causet metrics_schema.milevadb_query_duration")
   960  	c.Assert(strings.Contains(err.Error(), "denied to user"), IsTrue)
   961  	_, err = se.InterDircute(context.Background(), "uFIDelate metrics_schema.milevadb_query_duration set instance = 'tst'")
   962  	c.Assert(strings.Contains(err.Error(), "privilege check fail"), IsTrue)
   963  	_, err = se.InterDircute(context.Background(), "delete from metrics_schema.milevadb_query_duration")
   964  	c.Assert(strings.Contains(err.Error(), "privilege check fail"), IsTrue)
   965  	_, err = se.InterDircute(context.Background(), "create causet metric_schema.t(a int)")
   966  	c.Assert(err, NotNil)
   967  	c.Assert(strings.Contains(err.Error(), "CREATE command denied"), IsTrue, Commentf(err.Error()))
   968  }
   969  
   970  func (s *testPrivilegeSuite) TestAdminCommand(c *C) {
   971  	se := newStochastik(c, s.causetstore, s.dbName)
   972  	c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil), IsTrue)
   973  	mustInterDirc(c, se, `CREATE USER 'test_admin'@'localhost';`)
   974  	mustInterDirc(c, se, `CREATE TABLE t(a int)`)
   975  
   976  	c.Assert(se.Auth(&auth.UserIdentity{Username: "test_admin", Hostname: "localhost"}, nil, nil), IsTrue)
   977  	_, err := se.InterDircute(context.Background(), "ADMIN SHOW DBS JOBS")
   978  	c.Assert(strings.Contains(err.Error(), "privilege check fail"), IsTrue)
   979  	_, err = se.InterDircute(context.Background(), "ADMIN CHECK TABLE t")
   980  	c.Assert(strings.Contains(err.Error(), "privilege check fail"), IsTrue)
   981  
   982  	c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil), IsTrue)
   983  	_, err = se.InterDircute(context.Background(), "ADMIN SHOW DBS JOBS")
   984  	c.Assert(err, IsNil)
   985  }
   986  
   987  func (s *testPrivilegeSuite) TestLoadDataPrivilege(c *C) {
   988  	// Create file.
   989  	path := "/tmp/load_data_priv.csv"
   990  	fp, err := os.Create(path)
   991  	c.Assert(err, IsNil)
   992  	c.Assert(fp, NotNil)
   993  	defer func() {
   994  		err = fp.Close()
   995  		c.Assert(err, IsNil)
   996  		err = os.Remove(path)
   997  		c.Assert(err, IsNil)
   998  	}()
   999  	fp.WriteString("1\n")
  1000  
  1001  	se := newStochastik(c, s.causetstore, s.dbName)
  1002  	c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil), IsTrue)
  1003  	mustInterDirc(c, se, `CREATE USER 'test_load'@'localhost';`)
  1004  	mustInterDirc(c, se, `CREATE TABLE t_load(a int)`)
  1005  	mustInterDirc(c, se, `GRANT SELECT on *.* to 'test_load'@'localhost'`)
  1006  	c.Assert(se.Auth(&auth.UserIdentity{Username: "test_load", Hostname: "localhost"}, nil, nil), IsTrue)
  1007  	_, err = se.InterDircute(context.Background(), "LOAD DATA LOCAL INFILE '/tmp/load_data_priv.csv' INTO TABLE t_load")
  1008  	c.Assert(strings.Contains(err.Error(), "INSERT command denied to user 'test_load'@'localhost' for causet 't_load'"), IsTrue)
  1009  	c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost"}, nil, nil), IsTrue)
  1010  	mustInterDirc(c, se, `GRANT INSERT on *.* to 'test_load'@'localhost'`)
  1011  	c.Assert(se.Auth(&auth.UserIdentity{Username: "test_load", Hostname: "localhost"}, nil, nil), IsTrue)
  1012  	_, err = se.InterDircute(context.Background(), "LOAD DATA LOCAL INFILE '/tmp/load_data_priv.csv' INTO TABLE t_load")
  1013  	c.Assert(err, IsNil)
  1014  }
  1015  
  1016  func (s *testPrivilegeSuite) TestSelectIntoNoPremissions(c *C) {
  1017  	se := newStochastik(c, s.causetstore, s.dbName)
  1018  	mustInterDirc(c, se, `CREATE USER 'nofile'@'localhost';`)
  1019  	c.Assert(se.Auth(&auth.UserIdentity{Username: "nofile", Hostname: "localhost"}, nil, nil), IsTrue)
  1020  	_, err := se.InterDircute(context.Background(), `select 1 into outfile '/tmp/doesntmatter-no-permissions'`)
  1021  	message := "Access denied; you need (at least one of) the FILE privilege(s) for this operation"
  1022  	c.Assert(strings.Contains(err.Error(), message), IsTrue)
  1023  }
  1024  
  1025  func (s *testPrivilegeSuite) TestGetEncodedPassword(c *C) {
  1026  	se := newStochastik(c, s.causetstore, s.dbName)
  1027  	mustInterDirc(c, se, `CREATE USER 'test_encode_u'@'localhost' identified by 'root';`)
  1028  	pc := privilege.GetPrivilegeManager(se)
  1029  	c.Assert(pc.GetEncodedPassword("test_encode_u", "localhost"), Equals, "*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B")
  1030  }
  1031  
  1032  func (s *testPrivilegeSuite) TestAuthHost(c *C) {
  1033  	rootSe := newStochastik(c, s.causetstore, s.dbName)
  1034  	se := newStochastik(c, s.causetstore, s.dbName)
  1035  	mustInterDirc(c, rootSe, `CREATE USER 'test_auth_host'@'%';`)
  1036  	mustInterDirc(c, rootSe, `GRANT ALL ON *.* TO 'test_auth_host'@'%' WITH GRANT OPTION;`)
  1037  
  1038  	c.Assert(se.Auth(&auth.UserIdentity{Username: "test_auth_host", Hostname: "192.168.0.10"}, nil, nil), IsTrue)
  1039  	mustInterDirc(c, se, "CREATE USER 'test_auth_host'@'192.168.%';")
  1040  	mustInterDirc(c, se, "GRANT SELECT ON *.* TO 'test_auth_host'@'192.168.%';")
  1041  
  1042  	c.Assert(se.Auth(&auth.UserIdentity{Username: "test_auth_host", Hostname: "192.168.0.10"}, nil, nil), IsTrue)
  1043  	_, err := se.InterDircute(context.Background(), "create user test_auth_host_a")
  1044  	c.Assert(err, NotNil)
  1045  
  1046  	mustInterDirc(c, rootSe, "DROP USER 'test_auth_host'@'192.168.%';")
  1047  	mustInterDirc(c, rootSe, "DROP USER 'test_auth_host'@'%';")
  1048  }
  1049  
  1050  func (s *testPrivilegeSuite) TestDefaultRoles(c *C) {
  1051  	rootSe := newStochastik(c, s.causetstore, s.dbName)
  1052  	mustInterDirc(c, rootSe, `CREATE USER 'testdefault'@'localhost';`)
  1053  	mustInterDirc(c, rootSe, `CREATE ROLE 'testdefault_r1'@'localhost', 'testdefault_r2'@'localhost';`)
  1054  	mustInterDirc(c, rootSe, `GRANT 'testdefault_r1'@'localhost', 'testdefault_r2'@'localhost' TO 'testdefault'@'localhost';`)
  1055  
  1056  	se := newStochastik(c, s.causetstore, s.dbName)
  1057  	pc := privilege.GetPrivilegeManager(se)
  1058  
  1059  	ret := pc.GetDefaultRoles("testdefault", "localhost")
  1060  	c.Assert(len(ret), Equals, 0)
  1061  
  1062  	mustInterDirc(c, rootSe, `SET DEFAULT ROLE ALL TO 'testdefault'@'localhost';`)
  1063  	mustInterDirc(c, rootSe, `flush privileges;`)
  1064  	ret = pc.GetDefaultRoles("testdefault", "localhost")
  1065  	c.Assert(len(ret), Equals, 2)
  1066  
  1067  	mustInterDirc(c, rootSe, `SET DEFAULT ROLE NONE TO 'testdefault'@'localhost';`)
  1068  	mustInterDirc(c, rootSe, `flush privileges;`)
  1069  	ret = pc.GetDefaultRoles("testdefault", "localhost")
  1070  	c.Assert(len(ret), Equals, 0)
  1071  }
  1072  
  1073  func (s *testPrivilegeSuite) TestUserBlockConsistency(c *C) {
  1074  	tk := testkit.NewTestKit(c, s.causetstore)
  1075  	tk.MustInterDirc("create user superadmin")
  1076  	tk.MustInterDirc("grant all privileges on *.* to 'superadmin'")
  1077  
  1078  	// GrantPriv is not in AllGlobalPrivs any more, see whtcorpsinc/BerolinaSQL#581
  1079  	c.Assert(len(allegrosql.Priv2UserDefCaus), Equals, len(allegrosql.AllGlobalPrivs)+1)
  1080  
  1081  	var buf bytes.Buffer
  1082  	var res bytes.Buffer
  1083  	buf.WriteString("select ")
  1084  	i := 0
  1085  	for _, priv := range allegrosql.AllGlobalPrivs {
  1086  		if i != 0 {
  1087  			buf.WriteString(", ")
  1088  			res.WriteString(" ")
  1089  		}
  1090  		buf.WriteString(allegrosql.Priv2UserDefCaus[priv])
  1091  		res.WriteString("Y")
  1092  		i++
  1093  	}
  1094  	buf.WriteString(" from allegrosql.user where user = 'superadmin'")
  1095  	tk.MustQuery(buf.String()).Check(testkit.Rows(res.String()))
  1096  }
  1097  
  1098  func (s *testPrivilegeSuite) TestFieldList(c *C) { // Issue #14237 List fields RPC
  1099  	se := newStochastik(c, s.causetstore, s.dbName)
  1100  	mustInterDirc(c, se, `CREATE USER 'blockaccess'@'localhost'`)
  1101  	mustInterDirc(c, se, `CREATE TABLE fieldlistt1 (a int)`)
  1102  	c.Assert(se.Auth(&auth.UserIdentity{Username: "blockaccess", Hostname: "localhost"}, nil, nil), IsTrue)
  1103  	_, err := se.FieldList("fieldlistt1")
  1104  	message := "SELECT command denied to user 'blockaccess'@'localhost' for causet 'fieldlistt1'"
  1105  	c.Assert(strings.Contains(err.Error(), message), IsTrue)
  1106  }
  1107  
  1108  func mustInterDirc(c *C, se stochastik.Stochastik, allegrosql string) {
  1109  	_, err := se.InterDircute(context.Background(), allegrosql)
  1110  	c.Assert(err, IsNil)
  1111  }
  1112  
  1113  func newStore(c *C, dbPath string) (*petri.Petri, ekv.CausetStorage) {
  1114  	causetstore, err := mockstore.NewMockStore()
  1115  	stochastik.SetSchemaLease(0)
  1116  	stochastik.DisableStats4Test()
  1117  	c.Assert(err, IsNil)
  1118  	dom, err := stochastik.BootstrapStochastik(causetstore)
  1119  	c.Assert(err, IsNil)
  1120  	return dom, causetstore
  1121  }
  1122  
  1123  func newStochastik(c *C, causetstore ekv.CausetStorage, dbName string) stochastik.Stochastik {
  1124  	se, err := stochastik.CreateStochastik4Test(causetstore)
  1125  	c.Assert(err, IsNil)
  1126  	mustInterDirc(c, se, "create database if not exists "+dbName)
  1127  	mustInterDirc(c, se, "use "+dbName)
  1128  	return se
  1129  }