Expose address in keyinfo, add get command

This commit is contained in:
Ethan Frey 2017-02-28 20:07:44 +01:00
parent d5931c9ee3
commit c59e2d7d13
11 changed files with 89 additions and 17 deletions

View File

@ -10,6 +10,7 @@ the commands, and give feedback and changes.
```
# keys help
Keys allows you to manage your local keystore for tendermint.
These keys may be in any format supported by go-crypto and can be
@ -20,6 +21,7 @@ Usage:
keys [command]
Available Commands:
get Get details of one key
list List all keys
new Create a new public/private key pair
serve Run the key manager as an http server
@ -30,7 +32,8 @@ Flags:
-o, --output string Output format (text|json) (default "text")
-r, --root string root directory for config and data (default "/Users/ethan/.tlc")
Use "keys [command] --help" for more information about a command.```
Use "keys [command] --help" for more information about a command.
```
## Getting the config file
@ -42,6 +45,8 @@ The first step is to load in root, by checking the following in order:
Once the `rootDir` is established, the script looks for a config file named `keys.{json,toml,yaml,hcl}` in that directory and parses it. These values will provide defaults for flags of the same name.
There is an example config file for testing out locally, which writes keys to `./.mykeys`. You can
## Getting/Setting variables
When we want to get the value of a user-defined variable (eg. `output`), we can call `viper.GetString("output")`, which will do the following checks, until it finds a match:

47
cmd/get.go Normal file
View File

@ -0,0 +1,47 @@
// Copyright © 2017 Ethan Frey
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
// getCmd represents the get command
var getCmd = &cobra.Command{
Use: "get <name>",
Short: "Get details of one key",
Long: `Return public details of one local key.`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 1 || len(args[0]) == 0 {
fmt.Println("You must provide a name for the key")
return
}
name := args[0]
info, err := manager.Get(name)
if err != nil {
fmt.Println(err.Error())
return
}
printInfo(info)
},
}
func init() {
RootCmd.AddCommand(getCmd)
}

View File

@ -84,7 +84,8 @@ func bindFlags(cmd *cobra.Command, args []string) error {
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
fmt.Println("Using config file:", viper.ConfigFileUsed())
// stderr, so if we redirect output to json file, this doesn't appear
fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
}
return validateFlags(cmd)

View File

@ -22,7 +22,7 @@ import (
// updateCmd represents the update command
var updateCmd = &cobra.Command{
Use: "update",
Use: "update <name>",
Short: "Change the password for a private key",
Long: `Change the password for a private key.`,
Run: updatePassword,

View File

@ -41,11 +41,15 @@ func getCheckPassword(prompt, prompt2 string) (string, error) {
func printInfo(info keys.Info) {
switch output {
case "text":
key, err := data.ToText(info.PubKey)
addr, err := data.ToText(info.Address)
if err != nil {
panic(err) // really shouldn't happen...
}
fmt.Printf("%s\t%s\n", info.Name, key)
sep := "\t\t"
if len(info.Name) > 7 {
sep = "\t"
}
fmt.Printf("%s%s%s\n", info.Name, sep, addr)
case "json":
json, err := data.ToJSON(info)
if err != nil {

View File

@ -40,8 +40,10 @@ func (es encryptedStorage) Delete(name string) error {
// info hardcodes the encoding of keys
func info(name string, key crypto.PrivKey) keys.Info {
pub := key.PubKey()
return keys.Info{
Name: name,
PubKey: crypto.PubKeyS{key.PubKey()},
Name: name,
Address: pub.Address(),
PubKey: crypto.PubKeyS{pub},
}
}

View File

@ -74,7 +74,7 @@ func (s FileStore) Get(name string) ([]byte, keys.Info, error) {
}
key, _, err := read(priv)
return key, info, err
return key, info.Format(), err
}
// List parses the key directory for public info and returns a list of
@ -99,7 +99,7 @@ func (s FileStore) List() (keys.Infos, error) {
if err != nil {
return nil, err
}
infos = append(infos, info)
infos = append(infos, info.Format())
}
}

View File

@ -49,11 +49,13 @@ func TestBasicCRUD(t *testing.T) {
k, i, err := store.Get(name)
require.Nil(err, "%+v", err)
assert.Equal(key, k)
assert.Equal(info, i)
assert.Equal(info.Name, i.Name)
assert.Equal(info.PubKey, i.PubKey)
assert.NotEmpty(i.Address)
l, err = store.List()
require.Nil(err, "%+v", err)
assert.Equal(1, len(l))
assert.Equal(info, l[0])
assert.Equal(i, l[0])
// querying a non-existent key fails
_, _, err = store.Get("badname")

View File

@ -44,7 +44,7 @@ func (s MemStore) Get(name string) ([]byte, keys.Info, error) {
if !ok {
err = errors.Errorf("Key named '%s' doesn't exist", name)
}
return d.key, d.info, err
return d.key, d.info.Format(), err
}
// List returns the public info of all keys in the MemStore in unsorted order
@ -52,7 +52,7 @@ func (s MemStore) List() (keys.Infos, error) {
res := make([]keys.Info, len(s))
i := 0
for _, d := range s {
res[i] = d.info
res[i] = d.info.Format()
i++
}
return res, nil

View File

@ -41,11 +41,13 @@ func TestBasicCRUD(t *testing.T) {
k, i, err := store.Get(name)
assert.Nil(err)
assert.Equal(key, k)
assert.Equal(info, i)
assert.Equal(info.Name, i.Name)
assert.Equal(info.PubKey, i.PubKey)
assert.NotEmpty(i.Address)
l, err = store.List()
assert.Nil(err)
assert.Equal(1, len(l))
assert.Equal(info, l[0])
assert.Equal(i, l[0])
// querying a non-existent key fails
_, _, err = store.Get("badname")

View File

@ -4,12 +4,21 @@ import (
"sort"
crypto "github.com/tendermint/go-crypto"
data "github.com/tendermint/go-data"
)
// Info is the public information about a key
type Info struct {
Name string
PubKey crypto.PubKeyS
Name string `json:"name"`
Address data.Bytes `json:"address"`
PubKey crypto.PubKeyS `json:"pubkey"`
}
func (i *Info) Format() Info {
if !i.PubKey.Empty() {
i.Address = i.PubKey.Address()
}
return *i
}
// Infos is a wrapper to allows alphabetical sorting of the keys