Browse Source

Expose address in keyinfo, add get command

pull/1782/head
Ethan Frey 8 years ago
parent
commit
c59e2d7d13
11 changed files with 89 additions and 17 deletions
  1. +6
    -1
      cmd/README.md
  2. +47
    -0
      cmd/get.go
  3. +2
    -1
      cmd/root.go
  4. +1
    -1
      cmd/update.go
  5. +6
    -2
      cmd/utils.go
  6. +4
    -2
      cryptostore/enc_storage.go
  7. +2
    -2
      storage/filestorage/main.go
  8. +4
    -2
      storage/filestorage/main_test.go
  9. +2
    -2
      storage/memstorage/main.go
  10. +4
    -2
      storage/memstorage/main_test.go
  11. +11
    -2
      transactions.go

+ 6
- 1
cmd/README.md View File

@ -10,6 +10,7 @@ the commands, and give feedback and changes.
``` ```
# keys help # keys help
Keys allows you to manage your local keystore for tendermint. Keys allows you to manage your local keystore for tendermint.
These keys may be in any format supported by go-crypto and can be These keys may be in any format supported by go-crypto and can be
@ -20,6 +21,7 @@ Usage:
keys [command] keys [command]
Available Commands: Available Commands:
get Get details of one key
list List all keys list List all keys
new Create a new public/private key pair new Create a new public/private key pair
serve Run the key manager as an http server serve Run the key manager as an http server
@ -30,7 +32,8 @@ Flags:
-o, --output string Output format (text|json) (default "text") -o, --output string Output format (text|json) (default "text")
-r, --root string root directory for config and data (default "/Users/ethan/.tlc") -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 ## 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. 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 ## 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: 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
- 0
cmd/get.go 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)
}

+ 2
- 1
cmd/root.go View File

@ -84,7 +84,8 @@ func bindFlags(cmd *cobra.Command, args []string) error {
// If a config file is found, read it in. // If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil { 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) return validateFlags(cmd)


+ 1
- 1
cmd/update.go View File

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


+ 6
- 2
cmd/utils.go View File

@ -41,11 +41,15 @@ func getCheckPassword(prompt, prompt2 string) (string, error) {
func printInfo(info keys.Info) { func printInfo(info keys.Info) {
switch output { switch output {
case "text": case "text":
key, err := data.ToText(info.PubKey)
addr, err := data.ToText(info.Address)
if err != nil { if err != nil {
panic(err) // really shouldn't happen... 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": case "json":
json, err := data.ToJSON(info) json, err := data.ToJSON(info)
if err != nil { if err != nil {


+ 4
- 2
cryptostore/enc_storage.go View File

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

+ 2
- 2
storage/filestorage/main.go View File

@ -74,7 +74,7 @@ func (s FileStore) Get(name string) ([]byte, keys.Info, error) {
} }
key, _, err := read(priv) 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 // 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 { if err != nil {
return nil, err return nil, err
} }
infos = append(infos, info)
infos = append(infos, info.Format())
} }
} }


+ 4
- 2
storage/filestorage/main_test.go View File

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


+ 2
- 2
storage/memstorage/main.go View File

@ -44,7 +44,7 @@ func (s MemStore) Get(name string) ([]byte, keys.Info, error) {
if !ok { if !ok {
err = errors.Errorf("Key named '%s' doesn't exist", name) 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 // 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)) res := make([]keys.Info, len(s))
i := 0 i := 0
for _, d := range s { for _, d := range s {
res[i] = d.info
res[i] = d.info.Format()
i++ i++
} }
return res, nil return res, nil


+ 4
- 2
storage/memstorage/main_test.go View File

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


+ 11
- 2
transactions.go View File

@ -4,12 +4,21 @@ import (
"sort" "sort"
crypto "github.com/tendermint/go-crypto" crypto "github.com/tendermint/go-crypto"
data "github.com/tendermint/go-data"
) )
// Info is the public information about a key // Info is the public information about a key
type Info struct { 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 // Infos is a wrapper to allows alphabetical sorting of the keys


Loading…
Cancel
Save