mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Merge pull request #15867 from chaochn47/auth_test_split_8
migrate e2e auth tests to common #8
This commit is contained in:
commit
52dfd4bbed
@ -28,8 +28,9 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var defaultAuthToken = fmt.Sprintf("jwt,pub-key=%s,priv-key=%s,sign-method=RS256,ttl=1s",
|
||||
mustAbsPath("../fixtures/server.crt"), mustAbsPath("../fixtures/server.key.insecure"))
|
||||
var tokenTTL = time.Second
|
||||
var defaultAuthToken = fmt.Sprintf("jwt,pub-key=%s,priv-key=%s,sign-method=RS256,ttl=%s",
|
||||
mustAbsPath("../fixtures/server.crt"), mustAbsPath("../fixtures/server.key.insecure"), tokenTTL)
|
||||
|
||||
const (
|
||||
PermissionDenied = "etcdserver: permission denied"
|
||||
@ -736,6 +737,121 @@ func TestAuthRoleList(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestAuthJWTExpire(t *testing.T) {
|
||||
testRunner.BeforeTest(t)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
clus := testRunner.NewCluster(ctx, t, config.WithClusterConfig(config.ClusterConfig{ClusterSize: 1, AuthToken: defaultAuthToken}))
|
||||
defer clus.Close()
|
||||
cc := testutils.MustClient(clus.Client())
|
||||
testutils.ExecuteUntil(ctx, t, func() {
|
||||
require.NoErrorf(t, setupAuth(cc, []authRole{testRole}, []authUser{rootUser, testUser}), "failed to enable auth")
|
||||
testUserAuthClient := testutils.MustClient(clus.Client(WithAuth(testUserName, testPassword)))
|
||||
|
||||
require.NoError(t, testUserAuthClient.Put(ctx, "foo", "bar", config.PutOptions{}))
|
||||
// wait an expiration of my JWT token
|
||||
<-time.After(3 * tokenTTL)
|
||||
|
||||
// e2e test will generate a new token while
|
||||
// integration test that re-uses the same etcd client will refresh the token on server failure.
|
||||
require.NoError(t, testUserAuthClient.Put(ctx, "foo", "bar", config.PutOptions{}))
|
||||
})
|
||||
}
|
||||
|
||||
// TestAuthRevisionConsistency ensures auth revision is the same after member restarts
|
||||
func TestAuthRevisionConsistency(t *testing.T) {
|
||||
testRunner.BeforeTest(t)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
clus := testRunner.NewCluster(ctx, t, config.WithClusterConfig(config.ClusterConfig{ClusterSize: 1, AuthToken: defaultAuthToken}))
|
||||
defer clus.Close()
|
||||
cc := testutils.MustClient(clus.Client())
|
||||
testutils.ExecuteUntil(ctx, t, func() {
|
||||
require.NoErrorf(t, setupAuth(cc, []authRole{}, []authUser{rootUser}), "failed to enable auth")
|
||||
rootAuthClient := testutils.MustClient(clus.Client(WithAuth(rootUserName, rootPassword)))
|
||||
|
||||
// add user
|
||||
_, err := rootAuthClient.UserAdd(ctx, testUserName, testPassword, config.UserAddOptions{})
|
||||
require.NoError(t, err)
|
||||
// delete the same user
|
||||
_, err = rootAuthClient.UserDelete(ctx, testUserName)
|
||||
require.NoError(t, err)
|
||||
|
||||
// get node0 auth revision
|
||||
aresp, err := rootAuthClient.AuthStatus(ctx)
|
||||
require.NoError(t, err)
|
||||
oldAuthRevision := aresp.AuthRevision
|
||||
|
||||
// restart the node
|
||||
clus.Members()[0].Stop()
|
||||
require.NoError(t, clus.Members()[0].Start(ctx))
|
||||
|
||||
aresp2, err := rootAuthClient.AuthStatus(ctx)
|
||||
require.NoError(t, err)
|
||||
newAuthRevision := aresp2.AuthRevision
|
||||
|
||||
require.Equal(t, oldAuthRevision, newAuthRevision)
|
||||
})
|
||||
}
|
||||
|
||||
// TestAuthTestCacheReload ensures permissions are persisted and will be reloaded after member restarts
|
||||
func TestAuthTestCacheReload(t *testing.T) {
|
||||
testRunner.BeforeTest(t)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
clus := testRunner.NewCluster(ctx, t, config.WithClusterConfig(config.ClusterConfig{ClusterSize: 1, AuthToken: defaultAuthToken}))
|
||||
defer clus.Close()
|
||||
cc := testutils.MustClient(clus.Client())
|
||||
testutils.ExecuteUntil(ctx, t, func() {
|
||||
require.NoErrorf(t, setupAuth(cc, []authRole{testRole}, []authUser{rootUser, testUser}), "failed to enable auth")
|
||||
testUserAuthClient := testutils.MustClient(clus.Client(WithAuth(testUserName, testPassword)))
|
||||
|
||||
// create foo since that is within the permission set
|
||||
// expectation is to succeed
|
||||
require.NoError(t, testUserAuthClient.Put(ctx, "foo", "bar", config.PutOptions{}))
|
||||
|
||||
// restart the node
|
||||
clus.Members()[0].Stop()
|
||||
require.NoError(t, clus.Members()[0].Start(ctx))
|
||||
|
||||
// nothing has changed, but it fails without refreshing cache after restart
|
||||
require.NoError(t, testUserAuthClient.Put(ctx, "foo", "bar2", config.PutOptions{}))
|
||||
})
|
||||
}
|
||||
|
||||
// TestAuthLeaseTimeToLive gated lease time to live with RBAC control
|
||||
func TestAuthLeaseTimeToLive(t *testing.T) {
|
||||
testRunner.BeforeTest(t)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
clus := testRunner.NewCluster(ctx, t, config.WithClusterConfig(config.ClusterConfig{ClusterSize: 1, AuthToken: defaultAuthToken}))
|
||||
defer clus.Close()
|
||||
cc := testutils.MustClient(clus.Client())
|
||||
testutils.ExecuteUntil(ctx, t, func() {
|
||||
require.NoErrorf(t, setupAuth(cc, []authRole{testRole}, []authUser{rootUser, testUser}), "failed to enable auth")
|
||||
testUserAuthClient := testutils.MustClient(clus.Client(WithAuth(testUserName, testPassword)))
|
||||
|
||||
gresp, err := testUserAuthClient.Grant(ctx, 10)
|
||||
require.NoError(t, err)
|
||||
leaseID := gresp.ID
|
||||
|
||||
require.NoError(t, testUserAuthClient.Put(ctx, "foo", "bar", config.PutOptions{LeaseID: leaseID}))
|
||||
_, err = testUserAuthClient.TimeToLive(ctx, leaseID, config.LeaseOption{WithAttachedKeys: true})
|
||||
require.NoError(t, err)
|
||||
|
||||
rootAuthClient := testutils.MustClient(clus.Client(WithAuth(rootUserName, rootPassword)))
|
||||
require.NoError(t, rootAuthClient.Put(ctx, "bar", "foo", config.PutOptions{LeaseID: leaseID}))
|
||||
|
||||
// the lease is attached to bar, which test-user cannot access
|
||||
_, err = testUserAuthClient.TimeToLive(ctx, leaseID, config.LeaseOption{WithAttachedKeys: true})
|
||||
require.Errorf(t, err, "test-user must not be able to access to the lease, because it's attached to the key bar")
|
||||
|
||||
// without --keys, access should be allowed
|
||||
_, err = testUserAuthClient.TimeToLive(ctx, leaseID, config.LeaseOption{WithAttachedKeys: false})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func mustAbsPath(path string) string {
|
||||
abs, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
|
@ -15,15 +15,12 @@
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/tests/v3/framework/e2e"
|
||||
)
|
||||
|
||||
@ -34,20 +31,16 @@ func TestCtlV3AuthFromKeyPerm(t *testing.T) { testCtl(t, authTestFromKeyPerm) }
|
||||
func TestCtlV3AuthAndWatch(t *testing.T) { testCtl(t, authTestWatch) }
|
||||
func TestCtlV3AuthAndWatchJWT(t *testing.T) { testCtl(t, authTestWatch, withCfg(*e2e.NewConfigJWT())) }
|
||||
|
||||
func TestCtlV3AuthDefrag(t *testing.T) { testCtl(t, authTestDefrag) }
|
||||
// TestCtlV3AuthEndpointHealth https://github.com/etcd-io/etcd/pull/13774#discussion_r1189118815 is the blocker of migration to common/auth_test.go
|
||||
func TestCtlV3AuthEndpointHealth(t *testing.T) {
|
||||
testCtl(t, authTestEndpointHealth, withQuorum())
|
||||
}
|
||||
|
||||
// TestCtlV3AuthSnapshot TODO fill up common/maintenance_auth_test.go when Snapshot API is added in interfaces.Client
|
||||
func TestCtlV3AuthSnapshot(t *testing.T) { testCtl(t, authTestSnapshot) }
|
||||
func TestCtlV3AuthSnapshotJWT(t *testing.T) {
|
||||
testCtl(t, authTestSnapshot, withCfg(*e2e.NewConfigJWT()))
|
||||
}
|
||||
func TestCtlV3AuthJWTExpire(t *testing.T) {
|
||||
testCtl(t, authTestJWTExpire, withCfg(*e2e.NewConfigJWT()))
|
||||
}
|
||||
func TestCtlV3AuthRevisionConsistency(t *testing.T) { testCtl(t, authTestRevisionConsistency) }
|
||||
func TestCtlV3AuthTestCacheReload(t *testing.T) { testCtl(t, authTestCacheReload) }
|
||||
func TestCtlV3AuthLeaseTimeToLive(t *testing.T) { testCtl(t, authTestLeaseTimeToLive) }
|
||||
|
||||
func authEnable(cx ctlCtx) error {
|
||||
// create root user with root role
|
||||
@ -303,29 +296,6 @@ func authTestWatch(cx ctlCtx) {
|
||||
|
||||
}
|
||||
|
||||
func authTestDefrag(cx ctlCtx) {
|
||||
maintenanceInitKeys(cx)
|
||||
|
||||
if err := authEnable(cx); err != nil {
|
||||
cx.t.Fatal(err)
|
||||
}
|
||||
|
||||
cx.user, cx.pass = "root", "root"
|
||||
authSetupTestUser(cx)
|
||||
|
||||
// ordinary user cannot defrag
|
||||
cx.user, cx.pass = "test-user", "pass"
|
||||
if err := ctlV3OnlineDefrag(cx); err == nil {
|
||||
cx.t.Fatal("ordinary user should not be able to issue a defrag request")
|
||||
}
|
||||
|
||||
// root can defrag
|
||||
cx.user, cx.pass = "root", "root"
|
||||
if err := ctlV3OnlineDefrag(cx); err != nil {
|
||||
cx.t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func authTestSnapshot(cx ctlCtx) {
|
||||
maintenanceInitKeys(cx)
|
||||
|
||||
@ -456,75 +426,6 @@ func authTestCertCNAndUsernameNoPassword(cx ctlCtx) {
|
||||
certCNAndUsername(cx, true)
|
||||
}
|
||||
|
||||
func authTestJWTExpire(cx ctlCtx) {
|
||||
if err := authEnable(cx); err != nil {
|
||||
cx.t.Fatal(err)
|
||||
}
|
||||
|
||||
cx.user, cx.pass = "root", "root"
|
||||
authSetupTestUser(cx)
|
||||
|
||||
// try a granted key
|
||||
if err := ctlV3Put(cx, "hoo", "bar", ""); err != nil {
|
||||
cx.t.Error(err)
|
||||
}
|
||||
|
||||
// wait an expiration of my JWT token
|
||||
<-time.After(3 * time.Second)
|
||||
|
||||
if err := ctlV3Put(cx, "hoo", "bar", ""); err != nil {
|
||||
cx.t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func authTestRevisionConsistency(cx ctlCtx) {
|
||||
if err := authEnable(cx); err != nil {
|
||||
cx.t.Fatal(err)
|
||||
}
|
||||
cx.user, cx.pass = "root", "root"
|
||||
|
||||
// add user
|
||||
if err := ctlV3User(cx, []string{"add", "test-user", "--interactive=false"}, "User test-user created", []string{"pass"}); err != nil {
|
||||
cx.t.Fatal(err)
|
||||
}
|
||||
// delete the same user
|
||||
if err := ctlV3User(cx, []string{"delete", "test-user"}, "User test-user deleted", []string{}); err != nil {
|
||||
cx.t.Fatal(err)
|
||||
}
|
||||
|
||||
// get node0 auth revision
|
||||
node0 := cx.epc.Procs[0]
|
||||
endpoint := node0.EndpointsGRPC()[0]
|
||||
cli, err := clientv3.New(clientv3.Config{Endpoints: []string{endpoint}, Username: cx.user, Password: cx.pass, DialTimeout: 3 * time.Second})
|
||||
if err != nil {
|
||||
cx.t.Fatal(err)
|
||||
}
|
||||
defer cli.Close()
|
||||
|
||||
sresp, err := cli.AuthStatus(context.TODO())
|
||||
if err != nil {
|
||||
cx.t.Fatal(err)
|
||||
}
|
||||
oldAuthRevision := sresp.AuthRevision
|
||||
|
||||
// restart the node
|
||||
if err := node0.Restart(context.TODO()); err != nil {
|
||||
cx.t.Fatal(err)
|
||||
}
|
||||
|
||||
// get node0 auth revision again
|
||||
sresp, err = cli.AuthStatus(context.TODO())
|
||||
if err != nil {
|
||||
cx.t.Fatal(err)
|
||||
}
|
||||
newAuthRevision := sresp.AuthRevision
|
||||
|
||||
// assert AuthRevision equal
|
||||
if newAuthRevision != oldAuthRevision {
|
||||
cx.t.Fatalf("auth revison shouldn't change when restarting etcd, expected: %d, got: %d", oldAuthRevision, newAuthRevision)
|
||||
}
|
||||
}
|
||||
|
||||
func ctlV3EndpointHealth(cx ctlCtx) error {
|
||||
cmdArgs := append(cx.PrefixArgs(), "endpoint", "health")
|
||||
lines := make([]string, cx.epc.Cfg.ClusterSize)
|
||||
@ -554,132 +455,3 @@ func ctlV3User(cx ctlCtx, args []string, expStr string, stdIn []string) error {
|
||||
_, err = proc.Expect(expStr)
|
||||
return 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.EndpointsGRPC()[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
|
||||
if err := node0.Restart(context.TODO()); 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)
|
||||
}
|
||||
}
|
||||
|
||||
func authTestLeaseTimeToLive(cx ctlCtx) {
|
||||
if err := authEnable(cx); err != nil {
|
||||
cx.t.Fatal(err)
|
||||
}
|
||||
cx.user, cx.pass = "root", "root"
|
||||
|
||||
authSetupTestUser(cx)
|
||||
|
||||
cx.user = "test-user"
|
||||
cx.pass = "pass"
|
||||
|
||||
leaseID, err := ctlV3LeaseGrant(cx, 10)
|
||||
if err != nil {
|
||||
cx.t.Fatal(err)
|
||||
}
|
||||
|
||||
err = ctlV3Put(cx, "foo", "val", leaseID)
|
||||
if err != nil {
|
||||
cx.t.Fatal(err)
|
||||
}
|
||||
|
||||
err = ctlV3LeaseTimeToLive(cx, leaseID, true)
|
||||
if err != nil {
|
||||
cx.t.Fatal(err)
|
||||
}
|
||||
|
||||
cx.user = "root"
|
||||
cx.pass = "root"
|
||||
err = ctlV3Put(cx, "bar", "val", leaseID)
|
||||
if err != nil {
|
||||
cx.t.Fatal(err)
|
||||
}
|
||||
|
||||
cx.user = "test-user"
|
||||
cx.pass = "pass"
|
||||
// the lease is attached to bar, which test-user cannot access
|
||||
err = ctlV3LeaseTimeToLive(cx, leaseID, true)
|
||||
if err == nil {
|
||||
cx.t.Fatal("test-user must not be able to access to the lease, because it's attached to the key bar")
|
||||
}
|
||||
|
||||
// without --keys, access should be allowed
|
||||
err = ctlV3LeaseTimeToLive(cx, leaseID, false)
|
||||
if err != nil {
|
||||
cx.t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
@ -420,83 +420,6 @@ func TestV3AuthOldRevConcurrent(t *testing.T) {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestV3AuthRestartMember(t *testing.T) {
|
||||
integration.BeforeTest(t)
|
||||
|
||||
// create a cluster with 1 member
|
||||
clus := integration.NewCluster(t, &integration.ClusterConfig{Size: 1})
|
||||
defer clus.Terminate(t)
|
||||
|
||||
// create a client
|
||||
c, cerr := integration.NewClient(t, 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 := integration.NewClient(t, 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)
|
||||
integration.WaitClientV3WithKey(t, c2.KV, "foo")
|
||||
|
||||
// nothing has changed, but it fails without refreshing cache after restart
|
||||
_, err = c2.Put(context.TODO(), "foo", "bar2")
|
||||
testutil.AssertNil(t, err)
|
||||
}
|
||||
|
||||
func TestV3AuthWatchAndTokenExpire(t *testing.T) {
|
||||
integration.BeforeTest(t)
|
||||
clus := integration.NewCluster(t, &integration.ClusterConfig{Size: 1, AuthTokenTTL: 3})
|
||||
@ -583,86 +506,3 @@ func TestV3AuthWatchErrorAndWatchId0(t *testing.T) {
|
||||
|
||||
<-watchEndCh
|
||||
}
|
||||
|
||||
func TestV3AuthWithLeaseTimeToLive(t *testing.T) {
|
||||
integration.BeforeTest(t)
|
||||
clus := integration.NewCluster(t, &integration.ClusterConfig{Size: 1})
|
||||
defer clus.Terminate(t)
|
||||
|
||||
users := []user{
|
||||
{
|
||||
name: "user1",
|
||||
password: "user1-123",
|
||||
role: "role1",
|
||||
key: "k1",
|
||||
end: "k3",
|
||||
},
|
||||
{
|
||||
name: "user2",
|
||||
password: "user2-123",
|
||||
role: "role2",
|
||||
key: "k2",
|
||||
end: "k4",
|
||||
},
|
||||
}
|
||||
authSetupUsers(t, integration.ToGRPC(clus.Client(0)).Auth, users)
|
||||
|
||||
authSetupRoot(t, integration.ToGRPC(clus.Client(0)).Auth)
|
||||
|
||||
user1c, cerr := integration.NewClient(t, clientv3.Config{Endpoints: clus.Client(0).Endpoints(), Username: "user1", Password: "user1-123"})
|
||||
if cerr != nil {
|
||||
t.Fatal(cerr)
|
||||
}
|
||||
defer user1c.Close()
|
||||
|
||||
user2c, cerr := integration.NewClient(t, clientv3.Config{Endpoints: clus.Client(0).Endpoints(), Username: "user2", Password: "user2-123"})
|
||||
if cerr != nil {
|
||||
t.Fatal(cerr)
|
||||
}
|
||||
defer user2c.Close()
|
||||
|
||||
leaseResp, err := user1c.Grant(context.TODO(), 90)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
leaseID := leaseResp.ID
|
||||
_, err = user1c.Put(context.TODO(), "k1", "val", clientv3.WithLease(leaseID))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// k2 can be accessed from both user1 and user2
|
||||
_, err = user1c.Put(context.TODO(), "k2", "val", clientv3.WithLease(leaseID))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = user1c.TimeToLive(context.TODO(), leaseID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = user2c.TimeToLive(context.TODO(), leaseID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = user2c.TimeToLive(context.TODO(), leaseID, clientv3.WithAttachedKeys())
|
||||
if err == nil {
|
||||
t.Fatal("timetolive from user2 should be failed with permission denied")
|
||||
}
|
||||
|
||||
rootc, cerr := integration.NewClient(t, clientv3.Config{Endpoints: clus.Client(0).Endpoints(), Username: "root", Password: "123"})
|
||||
if cerr != nil {
|
||||
t.Fatal(cerr)
|
||||
}
|
||||
defer rootc.Close()
|
||||
|
||||
if _, err := rootc.RoleRevokePermission(context.TODO(), "role1", "k1", "k3"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = user1c.TimeToLive(context.TODO(), leaseID, clientv3.WithAttachedKeys())
|
||||
if err == nil {
|
||||
t.Fatal("timetolive from user2 should be failed with permission denied")
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user