Browse Source

Removed keys/server as it is now in cosmos-sdk

pull/1782/head
Ethan Frey 7 years ago
parent
commit
69a7b389b8
6 changed files with 0 additions and 440 deletions
  1. +0
    -13
      keys/server/README.md
  2. +0
    -59
      keys/server/helpers.go
  3. +0
    -128
      keys/server/keys.go
  4. +0
    -193
      keys/server/keys_test.go
  5. +0
    -35
      keys/server/types/keys.go
  6. +0
    -12
      keys/server/valid.go

+ 0
- 13
keys/server/README.md View File

@ -1,13 +0,0 @@
# Proxy Server
This package provides all the functionality for a local http server, providing access to key management functionality (creating, listing, updating, and deleting keys). This is a nice building block for larger apps, and the HTTP handlers here can be embedded in a larger server that does nice things like signing transactions and posting them to a tendermint chain (which requires domain-knowledge of the transactions types and out of scope of this generic app).
## Key Management
We expose a number of methods for safely managing your keychain. If you are embedding this in a larger server, you will typically want to mount all these paths under `/keys`.
* `POST /` - provide a name and passphrase and create a brand new key
* `GET /` - get a list of all available key names, along with their public key and address
* `GET /{name}` - get public key and address for this named key
* `PUT /{name}` - update the passphrase for the given key. requires you to correctly provide the current passphrase, as well as a new one.
* `DELETE /{name}` - permanently delete this private key. requires you to correctly provide the current passphrase

+ 0
- 59
keys/server/helpers.go View File

@ -1,59 +0,0 @@
/*
package server provides http handlers to construct a server server
for key management, transaction signing, and query validation.
Please read the README and godoc to see how to
configure the server for your application.
*/
package server
import (
"encoding/json"
"io/ioutil"
"net/http"
"github.com/tendermint/go-crypto/keys/server/types"
data "github.com/tendermint/go-wire/data"
"github.com/pkg/errors"
)
func readRequest(r *http.Request, o interface{}) error {
defer r.Body.Close()
data, err := ioutil.ReadAll(r.Body)
if err != nil {
return errors.Wrap(err, "Read Request")
}
err = json.Unmarshal(data, o)
if err != nil {
return errors.Wrap(err, "Parse")
}
return validate(o)
}
// most errors are bad input, so 406... do better....
func writeError(w http.ResponseWriter, err error) {
// fmt.Printf("Error: %+v\n", err)
res := types.ErrorResponse{
Code: 406,
Error: err.Error(),
}
writeCode(w, &res, 406)
}
func writeCode(w http.ResponseWriter, o interface{}, code int) {
// two space indent to make it easier to read
data, err := data.ToJSON(o)
if err != nil {
writeError(w, err)
} else {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(code)
w.Write(data)
}
}
func writeSuccess(w http.ResponseWriter, o interface{}) {
writeCode(w, o, 200)
}

+ 0
- 128
keys/server/keys.go View File

@ -1,128 +0,0 @@
package server
import (
"errors"
"net/http"
"github.com/gorilla/mux"
keys "github.com/tendermint/go-crypto/keys"
"github.com/tendermint/go-crypto/keys/server/types"
)
type Keys struct {
manager keys.Manager
algo string
}
func New(manager keys.Manager, algo string) Keys {
return Keys{
manager: manager,
algo: algo,
}
}
func (k Keys) GenerateKey(w http.ResponseWriter, r *http.Request) {
req := types.CreateKeyRequest{
Algo: k.algo, // default key type from cli
}
err := readRequest(r, &req)
if err != nil {
writeError(w, err)
return
}
key, seed, err := k.manager.Create(req.Name, req.Passphrase, req.Algo)
if err != nil {
writeError(w, err)
return
}
res := types.CreateKeyResponse{key, seed}
writeSuccess(w, &res)
}
func (k Keys) GetKey(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
name := vars["name"]
key, err := k.manager.Get(name)
if err != nil {
writeError(w, err)
return
}
writeSuccess(w, &key)
}
func (k Keys) ListKeys(w http.ResponseWriter, r *http.Request) {
keys, err := k.manager.List()
if err != nil {
writeError(w, err)
return
}
writeSuccess(w, keys)
}
func (k Keys) UpdateKey(w http.ResponseWriter, r *http.Request) {
req := types.UpdateKeyRequest{}
err := readRequest(r, &req)
if err != nil {
writeError(w, err)
return
}
vars := mux.Vars(r)
name := vars["name"]
if name != req.Name {
writeError(w, errors.New("path and json key names don't match"))
return
}
err = k.manager.Update(req.Name, req.OldPass, req.NewPass)
if err != nil {
writeError(w, err)
return
}
key, err := k.manager.Get(req.Name)
if err != nil {
writeError(w, err)
return
}
writeSuccess(w, &key)
}
func (k Keys) DeleteKey(w http.ResponseWriter, r *http.Request) {
req := types.DeleteKeyRequest{}
err := readRequest(r, &req)
if err != nil {
writeError(w, err)
return
}
vars := mux.Vars(r)
name := vars["name"]
if name != req.Name {
writeError(w, errors.New("path and json key names don't match"))
return
}
err = k.manager.Delete(req.Name, req.Passphrase)
if err != nil {
writeError(w, err)
return
}
// not really an error, but something generic
resp := types.ErrorResponse{
Success: true,
}
writeSuccess(w, &resp)
}
func (k Keys) Register(r *mux.Router) {
r.HandleFunc("/", k.GenerateKey).Methods("POST")
r.HandleFunc("/", k.ListKeys).Methods("GET")
r.HandleFunc("/{name}", k.GetKey).Methods("GET")
r.HandleFunc("/{name}", k.UpdateKey).Methods("POST", "PUT")
r.HandleFunc("/{name}", k.DeleteKey).Methods("DELETE")
}

+ 0
- 193
keys/server/keys_test.go View File

@ -1,193 +0,0 @@
package server_test
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/gorilla/mux"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
keys "github.com/tendermint/go-crypto/keys"
"github.com/tendermint/go-crypto/keys/cryptostore"
"github.com/tendermint/go-crypto/keys/server"
"github.com/tendermint/go-crypto/keys/server/types"
"github.com/tendermint/go-crypto/keys/storage/memstorage"
)
func TestKeyServer(t *testing.T) {
assert, require := assert.New(t), require.New(t)
r := setupServer()
// let's abstract this out a bit....
keys, code, err := listKeys(r)
require.Nil(err)
require.Equal(http.StatusOK, code)
assert.Equal(0, len(keys))
algo := "ed25519"
n1, n2 := "personal", "business"
p0, p1, p2 := "1234", "over10chars...", "really-secure!@#$"
// this fails for validation
_, code, err = createKey(r, n1, p0, algo)
require.Nil(err, "%+v", err)
require.NotEqual(http.StatusOK, code)
// new password better
key, code, err := createKey(r, n1, p1, algo)
require.Nil(err, "%+v", err)
require.Equal(http.StatusOK, code)
require.Equal(n1, key.Key.Name)
require.NotEmpty(n1, key.Seed)
// the other one works
key2, code, err := createKey(r, n2, p2, algo)
require.Nil(err, "%+v", err)
require.Equal(http.StatusOK, code)
require.Equal(key2.Key.Name, n2)
require.NotEmpty(n2, key.Seed)
// let's abstract this out a bit....
keys, code, err = listKeys(r)
require.Nil(err)
require.Equal(http.StatusOK, code)
if assert.Equal(2, len(keys)) {
// in alphabetical order
assert.Equal(keys[0].Name, n2)
assert.Equal(keys[1].Name, n1)
}
// get works
k, code, err := getKey(r, n1)
require.Nil(err, "%+v", err)
require.Equal(http.StatusOK, code)
assert.Equal(n1, k.Name)
assert.NotNil(k.Address)
assert.Equal(key.Key.Address, k.Address)
// delete with proper key
_, code, err = deleteKey(r, n1, p1)
require.Nil(err, "%+v", err)
require.Equal(http.StatusOK, code)
// after delete, get and list different
_, code, err = getKey(r, n1)
require.Nil(err, "%+v", err)
require.NotEqual(http.StatusOK, code)
keys, code, err = listKeys(r)
require.Nil(err, "%+v", err)
require.Equal(http.StatusOK, code)
if assert.Equal(1, len(keys)) {
assert.Equal(keys[0].Name, n2)
}
}
func setupServer() http.Handler {
// make the storage with reasonable defaults
cstore := cryptostore.New(
cryptostore.SecretBox,
memstorage.New(),
keys.MustLoadCodec("english"),
)
// build your http server
ks := server.New(cstore, "ed25519")
r := mux.NewRouter()
sk := r.PathPrefix("/keys").Subrouter()
ks.Register(sk)
return r
}
// return data, status code, and error
func listKeys(h http.Handler) (keys.Infos, int, error) {
rr := httptest.NewRecorder()
req, err := http.NewRequest("GET", "/keys/", nil)
if err != nil {
return nil, 0, err
}
h.ServeHTTP(rr, req)
if http.StatusOK != rr.Code {
return nil, rr.Code, nil
}
data := keys.Infos{}
err = json.Unmarshal(rr.Body.Bytes(), &data)
return data, rr.Code, err
}
func getKey(h http.Handler, name string) (*keys.Info, int, error) {
rr := httptest.NewRecorder()
req, err := http.NewRequest("GET", "/keys/"+name, nil)
if err != nil {
return nil, 0, err
}
h.ServeHTTP(rr, req)
if http.StatusOK != rr.Code {
return nil, rr.Code, nil
}
data := keys.Info{}
err = json.Unmarshal(rr.Body.Bytes(), &data)
return &data, rr.Code, err
}
func createKey(h http.Handler, name, passphrase, algo string) (*types.CreateKeyResponse, int, error) {
rr := httptest.NewRecorder()
post := types.CreateKeyRequest{
Name: name,
Passphrase: passphrase,
Algo: algo,
}
var b bytes.Buffer
err := json.NewEncoder(&b).Encode(&post)
if err != nil {
return nil, 0, err
}
req, err := http.NewRequest("POST", "/keys/", &b)
if err != nil {
return nil, 0, err
}
h.ServeHTTP(rr, req)
if http.StatusOK != rr.Code {
return nil, rr.Code, nil
}
data := new(types.CreateKeyResponse)
err = json.Unmarshal(rr.Body.Bytes(), data)
return data, rr.Code, err
}
func deleteKey(h http.Handler, name, passphrase string) (*types.ErrorResponse, int, error) {
rr := httptest.NewRecorder()
post := types.DeleteKeyRequest{
Name: name,
Passphrase: passphrase,
}
var b bytes.Buffer
err := json.NewEncoder(&b).Encode(&post)
if err != nil {
return nil, 0, err
}
req, err := http.NewRequest("DELETE", "/keys/"+name, &b)
if err != nil {
return nil, 0, err
}
h.ServeHTTP(rr, req)
if http.StatusOK != rr.Code {
return nil, rr.Code, nil
}
data := types.ErrorResponse{}
err = json.Unmarshal(rr.Body.Bytes(), &data)
return &data, rr.Code, err
}

+ 0
- 35
keys/server/types/keys.go View File

@ -1,35 +0,0 @@
package types
import "github.com/tendermint/go-crypto/keys"
// CreateKeyRequest is sent to create a new key
type CreateKeyRequest struct {
Name string `json:"name" validate:"required,min=4,printascii"`
Passphrase string `json:"passphrase" validate:"required,min=10"`
Algo string `json:"algo"`
}
// DeleteKeyRequest to destroy a key permanently (careful!)
type DeleteKeyRequest struct {
Name string `json:"name" validate:"required,min=4,printascii"`
Passphrase string `json:"passphrase" validate:"required,min=10"`
}
// UpdateKeyRequest is sent to update the passphrase for an existing key
type UpdateKeyRequest struct {
Name string `json:"name" validate:"required,min=4,printascii"`
OldPass string `json:"passphrase" validate:"required,min=10"`
NewPass string `json:"new_passphrase" validate:"required,min=10"`
}
// ErrorResponse is returned for 4xx and 5xx errors
type ErrorResponse struct {
Success bool `json:"success"`
Error string `json:"error"` // error message if Success is false
Code int `json:"code"` // error code if Success is false
}
type CreateKeyResponse struct {
Key keys.Info `json:"key"`
Seed string `json:"seed_phrase"`
}

+ 0
- 12
keys/server/valid.go View File

@ -1,12 +0,0 @@
package server
import (
"github.com/pkg/errors"
"gopkg.in/go-playground/validator.v9"
)
var v = validator.New()
func validate(req interface{}) error {
return errors.Wrap(v.Struct(req), "Validate")
}

Loading…
Cancel
Save