vitess.io/vitess@v0.16.2/go/vt/tableacl/testlib/testlib.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package testlib 18 19 import ( 20 "errors" 21 "fmt" 22 "math/rand" 23 "testing" 24 "time" 25 26 querypb "vitess.io/vitess/go/vt/proto/query" 27 tableaclpb "vitess.io/vitess/go/vt/proto/tableacl" 28 "vitess.io/vitess/go/vt/tableacl" 29 "vitess.io/vitess/go/vt/tableacl/acl" 30 ) 31 32 // TestSuite tests a concrete acl.Factory implementation. 33 func TestSuite(t *testing.T, factory acl.Factory) { 34 name := fmt.Sprintf("tableacl-test-%d", rand.Int63()) 35 tableacl.Register(name, factory) 36 tableacl.SetDefaultACL(name) 37 38 testValidConfigs(t) 39 testDenyReaderInsert(t) 40 testAllowReaderSelect(t) 41 testDenyReaderDDL(t) 42 testAllowUnmatchedTable(t) 43 } 44 45 var currentUser = "DummyUser" 46 47 func testValidConfigs(t *testing.T) { 48 config := newConfigProto("group01", []string{"table1"}, []string{"u1"}, []string{"vt"}, []string{}) 49 if err := checkLoad(config, true); err != nil { 50 t.Fatal(err) 51 } 52 config = newConfigProto( 53 "group01", []string{"table1"}, []string{"u1", "u2"}, []string{"u3"}, []string{}) 54 if err := checkLoad(config, true); err != nil { 55 t.Fatal(err) 56 } 57 config = newConfigProto( 58 "group01", []string{"table%"}, []string{"u1", "u2"}, []string{"u3"}, []string{}) 59 if err := checkLoad(config, true); err != nil { 60 t.Fatal(err) 61 } 62 } 63 64 func testDenyReaderInsert(t *testing.T) { 65 config := newConfigProto( 66 "group01", []string{"table%"}, []string{currentUser}, []string{"u3"}, []string{}) 67 if err := checkAccess(config, "table1", tableacl.WRITER, false); err != nil { 68 t.Fatal(err) 69 } 70 } 71 72 func testAllowReaderSelect(t *testing.T) { 73 config := newConfigProto( 74 "group01", []string{"table%"}, []string{currentUser}, []string{"u3"}, []string{}) 75 if err := checkAccess(config, "table1", tableacl.READER, true); err != nil { 76 t.Fatal(err) 77 } 78 } 79 80 func testDenyReaderDDL(t *testing.T) { 81 config := newConfigProto( 82 "group01", []string{"table%"}, []string{currentUser}, []string{"u3"}, []string{}) 83 if err := checkAccess(config, "table1", tableacl.ADMIN, false); err != nil { 84 t.Fatal(err) 85 } 86 } 87 88 func testAllowUnmatchedTable(t *testing.T) { 89 config := newConfigProto( 90 "group01", []string{"table%"}, []string{currentUser}, []string{"u3"}, []string{}) 91 if err := checkAccess(config, "UNMATCHED_TABLE", tableacl.ADMIN, false); err != nil { 92 t.Fatal(err) 93 } 94 } 95 96 func newConfigProto(groupName string, tableNamesOrPrefixes, readers, writers, admins []string) *tableaclpb.Config { 97 return &tableaclpb.Config{ 98 TableGroups: []*tableaclpb.TableGroupSpec{{ 99 Name: groupName, 100 TableNamesOrPrefixes: tableNamesOrPrefixes, 101 Readers: readers, 102 Writers: writers, 103 Admins: admins, 104 }}, 105 } 106 } 107 108 func checkLoad(config *tableaclpb.Config, valid bool) error { 109 err := tableacl.InitFromProto(config) 110 if !valid && err == nil { 111 return errors.New("expecting parse error none returned") 112 } 113 114 if valid && err != nil { 115 return fmt.Errorf("unexpected load error: %v", err) 116 } 117 return nil 118 } 119 120 func checkAccess(config *tableaclpb.Config, tableName string, role tableacl.Role, want bool) error { 121 if err := checkLoad(config, true); err != nil { 122 return err 123 } 124 got := tableacl.Authorized(tableName, role).IsMember(&querypb.VTGateCallerID{Username: currentUser}) 125 if want != got { 126 return fmt.Errorf("got %v, want %v", got, want) 127 } 128 return nil 129 } 130 131 func init() { 132 rand.Seed(time.Now().UnixNano()) 133 }