etcdctl: handle empty key permission correctly

Current `etcdctl role grant-permission` doesn't handle an empty key
("") correctly. Because the range permissions are treated as
BytesAffineInterval internally, just specifying the empty key as a
beginning of range introduces an invalid permission which doesn't work
and betray users' intuition. This commit fix the way of handling empty
key as a prefix or from key in permission granting.

Fix https://github.com/coreos/etcd/issues/8494
release-3.3
Hitoshi Mitake 2017-09-07 15:33:17 +09:00
parent 510d884e62
commit 1ae6f1614d
1 changed files with 31 additions and 10 deletions

View File

@ -170,11 +170,8 @@ func roleGrantPermissionCommandFunc(cmd *cobra.Command, args []string) {
ExitWithError(ExitBadArgs, err)
}
rangeEnd, rerr := rangeEndFromPermFlags(args[2:])
if rerr != nil {
ExitWithError(ExitBadArgs, rerr)
}
resp, err := mustClientFromCmd(cmd).Auth.RoleGrantPermission(context.TODO(), args[0], args[2], rangeEnd, perm)
key, rangeEnd := permRange(args[2:])
resp, err := mustClientFromCmd(cmd).Auth.RoleGrantPermission(context.TODO(), args[0], key, rangeEnd, perm)
if err != nil {
ExitWithError(ExitError, err)
}
@ -188,17 +185,41 @@ func roleRevokePermissionCommandFunc(cmd *cobra.Command, args []string) {
ExitWithError(ExitBadArgs, fmt.Errorf("role revoke-permission command requires role name and key [endkey] as its argument."))
}
rangeEnd, rerr := rangeEndFromPermFlags(args[1:])
if rerr != nil {
ExitWithError(ExitBadArgs, rerr)
}
resp, err := mustClientFromCmd(cmd).Auth.RoleRevokePermission(context.TODO(), args[0], args[1], rangeEnd)
key, rangeEnd := permRange(args[1:])
resp, err := mustClientFromCmd(cmd).Auth.RoleRevokePermission(context.TODO(), args[0], key, rangeEnd)
if err != nil {
ExitWithError(ExitError, err)
}
display.RoleRevokePermission(args[0], args[1], rangeEnd, *resp)
}
func permRange(args []string) (string, string) {
key := args[0]
var rangeEnd string
if len(key) == 0 {
if rolePermPrefix && rolePermFromKey {
ExitWithError(ExitBadArgs, fmt.Errorf("--from-key and --prefix flags are mutually exclusive"))
}
// Range permission is expressed as adt.BytesAffineInterval,
// so the empty prefix which should be matched with every key must be like this ["\x00", <end>).
key = "\x00"
if rolePermPrefix || rolePermFromKey {
// For the both cases of prefix and from-key, a permission with an empty key
// should allow access to the entire key space.
// 0x00 will be treated as open ended in server side.
rangeEnd = "\x00"
}
} else {
var err error
rangeEnd, err = rangeEndFromPermFlags(args[0:])
if err != nil {
ExitWithError(ExitBadArgs, err)
}
}
return key, rangeEnd
}
func rangeEndFromPermFlags(args []string) (string, error) {
if len(args) == 1 {
if rolePermPrefix {