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
|
|
}
|
|
|
|
// nolint: unparam
|
|
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
|
|
}
|
|
|
|
// nolint: unparam
|
|
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
|
|
}
|
|
|
|
// nolint: unparam
|
|
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
|
|
}
|