Merge pull request #14410 from vivekpatani/release-3.4

[release-3.4] server,test: refresh cache on each NewAuthStore
This commit is contained in:
Benjamin Wang 2022-09-09 09:34:32 +08:00 committed by GitHub
commit 6730ed8477
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 166 additions and 3 deletions

View File

@ -1203,6 +1203,8 @@ func NewAuthStore(lg *zap.Logger, be backend.Backend, tp TokenProvider, bcryptCo
as.setupMetricsReporter()
as.refreshRangePermCache(tx)
tx.Unlock()
be.ForceCommit()

View File

@ -394,3 +394,79 @@ func TestV3AuthOldRevConcurrent(t *testing.T) {
}
wg.Wait()
}
func TestV3AuthRestartMember(t *testing.T) {
defer testutil.AfterTest(t)
// create a cluster with 1 member
clus := NewClusterV3(t, &ClusterConfig{Size: 1})
defer clus.Terminate(t)
// create a client
c, cerr := clientv3.New(clientv3.Config{
Endpoints: clus.Client(0).Endpoints(),
DialTimeout: 5 * time.Second,
})
testutil.AssertNil(t, cerr)
defer c.Close()
authData := []struct {
user string
role string
pass string
}{
{
user: "root",
role: "root",
pass: "123",
},
{
user: "user0",
role: "role0",
pass: "123",
},
}
for _, authObj := range authData {
// add a role
_, err := c.RoleAdd(context.TODO(), authObj.role)
testutil.AssertNil(t, err)
// add a user
_, err = c.UserAdd(context.TODO(), authObj.user, authObj.pass)
testutil.AssertNil(t, err)
// grant role to user
_, err = c.UserGrantRole(context.TODO(), authObj.user, authObj.role)
testutil.AssertNil(t, err)
}
// role grant permission to role0
_, err := c.RoleGrantPermission(context.TODO(), authData[1].role, "foo", "", clientv3.PermissionType(clientv3.PermReadWrite))
testutil.AssertNil(t, err)
// enable auth
_, err = c.AuthEnable(context.TODO())
testutil.AssertNil(t, err)
// create another client with ID:Password
c2, cerr := clientv3.New(clientv3.Config{
Endpoints: clus.Client(0).Endpoints(),
DialTimeout: 5 * time.Second,
Username: authData[1].user,
Password: authData[1].pass,
})
testutil.AssertNil(t, cerr)
defer c2.Close()
// create foo since that is within the permission set
// expectation is to succeed
_, err = c2.Put(context.TODO(), "foo", "bar")
testutil.AssertNil(t, err)
clus.Members[0].Stop(t)
err = clus.Members[0].Restart(t)
testutil.AssertNil(t, err)
// nothing has changed, but it fails without refreshing cache after restart
_, err = c2.Put(context.TODO(), "foo", "bar2")
testutil.AssertNil(t, err)
}

View File

@ -15,8 +15,10 @@
package e2e
import (
"context"
"fmt"
"os"
"syscall"
"testing"
"time"
@ -61,9 +63,10 @@ func TestCtlV3AuthDefrag(t *testing.T) { testCtl(t, authTestDefrag) }
func TestCtlV3AuthEndpointHealth(t *testing.T) {
testCtl(t, authTestEndpointHealth, withQuorum())
}
func TestCtlV3AuthSnapshot(t *testing.T) { testCtl(t, authTestSnapshot) }
func TestCtlV3AuthSnapshotJWT(t *testing.T) { testCtl(t, authTestSnapshot, withCfg(configJWT)) }
func TestCtlV3AuthJWTExpire(t *testing.T) { testCtl(t, authTestJWTExpire, withCfg(configJWT)) }
func TestCtlV3AuthSnapshot(t *testing.T) { testCtl(t, authTestSnapshot) }
func TestCtlV3AuthSnapshotJWT(t *testing.T) { testCtl(t, authTestSnapshot, withCfg(configJWT)) }
func TestCtlV3AuthJWTExpire(t *testing.T) { testCtl(t, authTestJWTExpire, withCfg(configJWT)) }
func TestCtlV3AuthTestCacheReload(t *testing.T) { testCtl(t, authTestCacheReload) }
func authEnableTest(cx ctlCtx) {
if err := authEnable(cx); err != nil {
@ -1125,3 +1128,85 @@ func authTestJWTExpire(cx ctlCtx) {
cx.t.Error(err)
}
}
// authTestCacheReload tests the permissions when a member restarts
func authTestCacheReload(cx ctlCtx) {
authData := []struct {
user string
role string
pass string
}{
{
user: "root",
role: "root",
pass: "123",
},
{
user: "user0",
role: "role0",
pass: "123",
},
}
node0 := cx.epc.procs[0]
endpoint := node0.EndpointsV3()[0]
// create a client
c, err := clientv3.New(clientv3.Config{Endpoints: []string{endpoint}, DialTimeout: 3 * time.Second})
if err != nil {
cx.t.Fatal(err)
}
defer c.Close()
for _, authObj := range authData {
// add role
if _, err = c.RoleAdd(context.TODO(), authObj.role); err != nil {
cx.t.Fatal(err)
}
// add user
if _, err = c.UserAdd(context.TODO(), authObj.user, authObj.pass); err != nil {
cx.t.Fatal(err)
}
// grant role to user
if _, err = c.UserGrantRole(context.TODO(), authObj.user, authObj.role); err != nil {
cx.t.Fatal(err)
}
}
// role grant permission to role0
if _, err = c.RoleGrantPermission(context.TODO(), authData[1].role, "foo", "", clientv3.PermissionType(clientv3.PermReadWrite)); err != nil {
cx.t.Fatal(err)
}
// enable auth
if _, err = c.AuthEnable(context.TODO()); err != nil {
cx.t.Fatal(err)
}
// create another client with ID:Password
c2, err := clientv3.New(clientv3.Config{Endpoints: []string{endpoint}, Username: authData[1].user, Password: authData[1].pass, DialTimeout: 3 * time.Second})
if err != nil {
cx.t.Fatal(err)
}
defer c2.Close()
// create foo since that is within the permission set
// expectation is to succeed
if _, err = c2.Put(context.TODO(), "foo", "bar"); err != nil {
cx.t.Fatal(err)
}
// restart the node
node0.WithStopSignal(syscall.SIGINT)
if err := node0.Restart(); err != nil {
cx.t.Fatal(err)
}
// nothing has changed, but it fails without refreshing cache after restart
if _, err = c2.Put(context.TODO(), "foo", "bar2"); err != nil {
cx.t.Fatal(err)
}
}