Merge pull request #6414 from mitake/prefix-perm

etcdctl: an option for granting permission with key prefix
This commit is contained in:
Xiang Li 2016-09-13 23:29:40 -05:00 committed by GitHub
commit 672472f85e
3 changed files with 53 additions and 4 deletions

View File

@ -17,6 +17,8 @@ package e2e
import (
"fmt"
"testing"
"github.com/coreos/etcd/clientv3"
)
func TestCtlV3AuthEnable(t *testing.T) { testCtl(t, authEnableTest) }
@ -26,6 +28,7 @@ func TestCtlV3AuthRoleUpdate(t *testing.T) { testCtl(t, authRoleUpdateT
func TestCtlV3AuthUserDeleteDuringOps(t *testing.T) { testCtl(t, authUserDeleteDuringOpsTest) }
func TestCtlV3AuthRoleRevokeDuringOps(t *testing.T) { testCtl(t, authRoleRevokeDuringOpsTest) }
func TestCtlV3AuthTxn(t *testing.T) { testCtl(t, authTestTxn) }
func TestCtlV3AuthPerfixPerm(t *testing.T) { testCtl(t, authTestPrefixPerm) }
func authEnableTest(cx ctlCtx) {
if err := authEnable(cx); err != nil {
@ -172,7 +175,7 @@ func authRoleUpdateTest(cx ctlCtx) {
// grant a new key
cx.user, cx.pass = "root", "root"
if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "hoo", ""}); err != nil {
if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, "hoo", "", false}); err != nil {
cx.t.Fatal(err)
}
@ -268,7 +271,7 @@ func authRoleRevokeDuringOpsTest(cx ctlCtx) {
cx.t.Fatal(err)
}
// grant a new key to the new role
if err := ctlV3RoleGrantPermission(cx, "test-role2", grantingPerm{true, true, "hoo", ""}); err != nil {
if err := ctlV3RoleGrantPermission(cx, "test-role2", grantingPerm{true, true, "hoo", "", false}); err != nil {
cx.t.Fatal(err)
}
// grant the new role to the user
@ -370,7 +373,7 @@ func authTestTxn(cx ctlCtx) {
// grant keys to test-user
cx.user, cx.pass = "root", "root"
for _, key := range grantedKeys {
if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, key, ""}); err != nil {
if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, key, "", false}); err != nil {
cx.t.Fatal(err)
}
}
@ -422,3 +425,32 @@ func authTestTxn(cx ctlCtx) {
cx.t.Fatal(err)
}
}
func authTestPrefixPerm(cx ctlCtx) {
if err := authEnable(cx); err != nil {
cx.t.Fatal(err)
}
cx.user, cx.pass = "root", "root"
authSetupTestUser(cx)
prefix := "/prefix/" // directory like prefix
// grant keys to test-user
cx.user, cx.pass = "root", "root"
if err := ctlV3RoleGrantPermission(cx, "test-role", grantingPerm{true, true, prefix, "", true}); err != nil {
cx.t.Fatal(err)
}
// try a prefix granted permission
cx.user, cx.pass = "test-user", "pass"
for i := 0; i < 10; i++ {
key := fmt.Sprintf("%s%d", prefix, i)
if err := ctlV3Put(cx, key, "val", ""); err != nil {
cx.t.Fatal(err)
}
}
if err := ctlV3PutFailPerm(cx, clientv3.GetPrefixRangeEnd(prefix), "baz"); err != nil {
cx.t.Fatal(err)
}
}

View File

@ -101,6 +101,9 @@ func ctlV3Role(cx ctlCtx, args []string, expStr string) error {
func ctlV3RoleGrantPermission(cx ctlCtx, rolename string, perm grantingPerm) error {
cmdArgs := append(cx.PrefixArgs(), "role", "grant-permission")
if perm.prefix {
cmdArgs = append(cmdArgs, "--prefix")
}
cmdArgs = append(cmdArgs, rolename)
cmdArgs = append(cmdArgs, grantingPermToArgs(perm)...)
@ -137,6 +140,7 @@ type grantingPerm struct {
write bool
key string
rangeEnd string
prefix bool
}
func grantingPermToArgs(perm grantingPerm) []string {

View File

@ -22,6 +22,10 @@ import (
"golang.org/x/net/context"
)
var (
grantPermissionPrefix bool
)
// NewRoleCommand returns the cobra command for "role".
func NewRoleCommand() *cobra.Command {
ac := &cobra.Command{
@ -72,11 +76,15 @@ func newRoleListCommand() *cobra.Command {
}
func newRoleGrantPermissionCommand() *cobra.Command {
return &cobra.Command{
cmd := &cobra.Command{
Use: "grant-permission <role name> <permission type> <key> [endkey]",
Short: "Grants a key to a role",
Run: roleGrantPermissionCommandFunc,
}
cmd.Flags().BoolVar(&grantPermissionPrefix, "prefix", false, "grant a prefix permission")
return cmd
}
func newRoleRevokePermissionCommand() *cobra.Command {
@ -183,7 +191,12 @@ func roleGrantPermissionCommandFunc(cmd *cobra.Command, args []string) {
rangeEnd := ""
if 4 <= len(args) {
if grantPermissionPrefix {
ExitWithError(ExitBadArgs, fmt.Errorf("don't pass both of --prefix option and range end to grant permission command"))
}
rangeEnd = args[3]
} else if grantPermissionPrefix {
rangeEnd = clientv3.GetPrefixRangeEnd(args[2])
}
_, err = mustClientFromCmd(cmd).Auth.RoleGrantPermission(context.TODO(), args[0], args[2], rangeEnd, perm)