mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 10:27:46 +08:00
coreapi: key tests
License: MIT Signed-off-by: Łukasz Magiera <magik6k@gmail.com>
This commit is contained in:
parent
8df2d1a92e
commit
396c34b4e1
@ -148,13 +148,13 @@ type KeyAPI interface {
|
||||
// name and returns a base58 encoded multihash of it's public key
|
||||
Generate(ctx context.Context, name string, opts ...options.KeyGenerateOption) (Key, error)
|
||||
|
||||
// WithAlgorithm is an option for Generate which specifies which algorithm
|
||||
// WithType is an option for Generate which specifies which algorithm
|
||||
// should be used for the key. Default is options.RSAKey
|
||||
//
|
||||
// Supported algorithms:
|
||||
// Supported key types:
|
||||
// * options.RSAKey
|
||||
// * options.Ed25519Key
|
||||
WithAlgorithm(algorithm string) options.KeyGenerateOption
|
||||
WithType(algorithm string) options.KeyGenerateOption
|
||||
|
||||
// WithSize is an option for Generate which specifies the size of the key to
|
||||
// generated. Default is 0
|
||||
|
||||
@ -3,6 +3,8 @@ package options
|
||||
const (
|
||||
RSAKey = "rsa"
|
||||
Ed25519Key = "ed25519"
|
||||
|
||||
DefaultRSALen = 2048
|
||||
)
|
||||
|
||||
type KeyGenerateSettings struct {
|
||||
@ -20,7 +22,7 @@ type KeyRenameOption func(*KeyRenameSettings) error
|
||||
func KeyGenerateOptions(opts ...KeyGenerateOption) (*KeyGenerateSettings, error) {
|
||||
options := &KeyGenerateSettings{
|
||||
Algorithm: RSAKey,
|
||||
Size: 0,
|
||||
Size: -1,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
@ -48,7 +50,7 @@ func KeyRenameOptions(opts ...KeyRenameOption) (*KeyRenameSettings, error) {
|
||||
|
||||
type KeyOptions struct{}
|
||||
|
||||
func (api *KeyOptions) WithAlgorithm(algorithm string) KeyGenerateOption {
|
||||
func (api *KeyOptions) WithType(algorithm string) KeyGenerateOption {
|
||||
return func(settings *KeyGenerateSettings) error {
|
||||
settings.Algorithm = algorithm
|
||||
return nil
|
||||
|
||||
@ -29,7 +29,7 @@ func (k *key) Name() string {
|
||||
}
|
||||
|
||||
func (k *key) Path() coreiface.Path {
|
||||
return &path{path: ipfspath.FromString(ipfspath.Join([]string{"/ipns/", k.peerId}))}
|
||||
return &path{path: ipfspath.FromString(ipfspath.Join([]string{"/ipns", k.peerId}))}
|
||||
}
|
||||
|
||||
func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.KeyGenerateOption) (coreiface.Key, error) {
|
||||
@ -38,13 +38,22 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if name == "self" {
|
||||
return nil, fmt.Errorf("cannot overwrite key with name 'self'")
|
||||
}
|
||||
|
||||
_, err = api.node.Repo.Keystore().Get(name)
|
||||
if err == nil {
|
||||
return nil, fmt.Errorf("key with name '%s' already exists", name)
|
||||
}
|
||||
|
||||
var sk crypto.PrivKey
|
||||
var pk crypto.PubKey
|
||||
|
||||
switch options.Algorithm {
|
||||
case "rsa":
|
||||
if options.Size == 0 {
|
||||
return nil, fmt.Errorf("please specify a key size with WithSize option")
|
||||
if options.Size == -1 {
|
||||
options.Size = caopts.DefaultRSALen
|
||||
}
|
||||
|
||||
priv, pub, err := crypto.GenerateKeyPairWithReader(crypto.RSA, options.Size, rand.Reader)
|
||||
@ -76,7 +85,7 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &key{name, pid.String()}, nil
|
||||
return &key{name, pid.Pretty()}, nil
|
||||
}
|
||||
|
||||
func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) {
|
||||
|
||||
416
core/coreapi/key_test.go
Normal file
416
core/coreapi/key_test.go
Normal file
@ -0,0 +1,416 @@
|
||||
package coreapi_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
opts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
|
||||
)
|
||||
|
||||
func TestListSelf(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, api, err := makeAPI(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
keys, err := api.Key().List(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to list keys: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(keys) != 1 {
|
||||
t.Fatalf("there should be 1 key (self), got %d", len(keys))
|
||||
return
|
||||
}
|
||||
|
||||
if keys[0].Name() != "self" {
|
||||
t.Errorf("expected the key to be called 'self', got '%s'", keys[0].Name())
|
||||
}
|
||||
|
||||
if keys[0].Path().String() != "/ipns/Qmfoo" {
|
||||
t.Errorf("expected the key to have path '/ipns/Qmfoo', got '%s'", keys[0].Path().String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenameSelf(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, api, err := makeAPI(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, _, err = api.Key().Rename(ctx, "self", "foo")
|
||||
if err == nil {
|
||||
t.Error("expected error to not be nil")
|
||||
} else {
|
||||
if err.Error() != "cannot rename key with name 'self'" {
|
||||
t.Fatalf("expected error 'cannot rename key with name 'self'', got '%s'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
_, _, err = api.Key().Rename(ctx, "self", "foo", api.Key().WithForce(true))
|
||||
if err == nil {
|
||||
t.Error("expected error to not be nil")
|
||||
} else {
|
||||
if err.Error() != "cannot rename key with name 'self'" {
|
||||
t.Fatalf("expected error 'cannot rename key with name 'self'', got '%s'", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveSelf(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, api, err := makeAPI(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = api.Key().Remove(ctx, "self")
|
||||
if err == nil {
|
||||
t.Error("expected error to not be nil")
|
||||
} else {
|
||||
if err.Error() != "cannot remove key with name 'self'" {
|
||||
t.Fatalf("expected error 'cannot remove key with name 'self'', got '%s'", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerate(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, api, err := makeAPI(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
k, err := api.Key().Generate(ctx, "foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
if k.Name() != "foo" {
|
||||
t.Errorf("expected the key to be called 'foo', got '%s'", k.Name())
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(k.Path().String(), "/ipns/Qm") {
|
||||
t.Errorf("expected the key to be prefixed with '/ipns/Qm', got '%s'", k.Path().String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateSize(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, api, err := makeAPI(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
k, err := api.Key().Generate(ctx, "foo", api.Key().WithSize(1024))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
if k.Name() != "foo" {
|
||||
t.Errorf("expected the key to be called 'foo', got '%s'", k.Name())
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(k.Path().String(), "/ipns/Qm") {
|
||||
t.Errorf("expected the key to be prefixed with '/ipns/Qm', got '%s'", k.Path().String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateType(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, api, err := makeAPI(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
k, err := api.Key().Generate(ctx, "bar", api.Key().WithType(opts.Ed25519Key))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
if k.Name() != "bar" {
|
||||
t.Errorf("expected the key to be called 'foo', got '%s'", k.Name())
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(k.Path().String(), "/ipns/Qm") {
|
||||
t.Errorf("expected the key to be prefixed with '/ipns/Qm', got '%s'", k.Path().String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateExisting(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, api, err := makeAPI(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = api.Key().Generate(ctx, "foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = api.Key().Generate(ctx, "foo")
|
||||
if err == nil {
|
||||
t.Error("expected error to not be nil")
|
||||
} else {
|
||||
if err.Error() != "key with name 'foo' already exists" {
|
||||
t.Fatalf("expected error 'key with name 'foo' already exists', got '%s'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
_, err = api.Key().Generate(ctx, "self")
|
||||
if err == nil {
|
||||
t.Error("expected error to not be nil")
|
||||
} else {
|
||||
if err.Error() != "cannot overwrite key with name 'self'" {
|
||||
t.Fatalf("expected error 'cannot overwrite key with name 'self'', got '%s'", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, api, err := makeAPI(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = api.Key().Generate(ctx, "foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
l, err := api.Key().List(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(l) != 2 {
|
||||
t.Fatalf("expected to get 2 keys, got %d", len(l))
|
||||
return
|
||||
}
|
||||
|
||||
if l[0].Name() != "self" {
|
||||
t.Fatalf("expected key 0 to be called 'self', got '%s'", l[0].Name())
|
||||
return
|
||||
}
|
||||
|
||||
if l[1].Name() != "foo" {
|
||||
t.Fatalf("expected key 1 to be called 'foo', got '%s'", l[1].Name())
|
||||
return
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(l[0].Path().String(), "/ipns/Qm") {
|
||||
t.Fatalf("expected key 0 to be prefixed with '/ipns/Qm', got '%s'", l[0].Name())
|
||||
return
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(l[1].Path().String(), "/ipns/Qm") {
|
||||
t.Fatalf("expected key 1 to be prefixed with '/ipns/Qm', got '%s'", l[1].Name())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestRename(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, api, err := makeAPI(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = api.Key().Generate(ctx, "foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
k, overwrote, err := api.Key().Rename(ctx, "foo", "bar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
if overwrote {
|
||||
t.Error("overwrote should be false")
|
||||
}
|
||||
|
||||
if k.Name() != "bar" {
|
||||
t.Errorf("returned key should be called 'bar', got '%s'", k.Name())
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenameToSelf(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, api, err := makeAPI(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = api.Key().Generate(ctx, "foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, _, err = api.Key().Rename(ctx, "foo", "self")
|
||||
if err == nil {
|
||||
t.Error("expected error to not be nil")
|
||||
} else {
|
||||
if err.Error() != "cannot overwrite key with name 'self'" {
|
||||
t.Fatalf("expected error 'cannot overwrite key with name 'self'', got '%s'", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenameToSelfForce(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, api, err := makeAPI(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = api.Key().Generate(ctx, "foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, _, err = api.Key().Rename(ctx, "foo", "self", api.Key().WithForce(true))
|
||||
if err == nil {
|
||||
t.Error("expected error to not be nil")
|
||||
} else {
|
||||
if err.Error() != "cannot overwrite key with name 'self'" {
|
||||
t.Fatalf("expected error 'cannot overwrite key with name 'self'', got '%s'", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenameOverwriteNoForce(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, api, err := makeAPI(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = api.Key().Generate(ctx, "foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = api.Key().Generate(ctx, "bar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, _, err = api.Key().Rename(ctx, "foo", "bar")
|
||||
if err == nil {
|
||||
t.Error("expected error to not be nil")
|
||||
} else {
|
||||
if err.Error() != "key by that name already exists, refusing to overwrite" {
|
||||
t.Fatalf("expected error 'key by that name already exists, refusing to overwrite', got '%s'", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenameOverwrite(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, api, err := makeAPI(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
kfoo, err := api.Key().Generate(ctx, "foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = api.Key().Generate(ctx, "bar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
k, overwrote, err := api.Key().Rename(ctx, "foo", "bar", api.Key().WithForce(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
if !overwrote {
|
||||
t.Error("overwrote should be true")
|
||||
}
|
||||
|
||||
if k.Name() != "bar" {
|
||||
t.Errorf("returned key should be called 'bar', got '%s'", k.Name())
|
||||
}
|
||||
|
||||
if k.Path().String() != kfoo.Path().String() {
|
||||
t.Errorf("k and kfoo should have equal paths, '%s'!='%s'", k.Path().String(), kfoo.Path().String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemove(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, api, err := makeAPI(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
k, err := api.Key().Generate(ctx, "foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
l, err := api.Key().List(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(l) != 2 {
|
||||
t.Fatalf("expected to get 2 keys, got %d", len(l))
|
||||
return
|
||||
}
|
||||
|
||||
p, err := api.Key().Remove(ctx, "foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
if k.Path().String() != p.String() {
|
||||
t.Errorf("k and p should have equal paths, '%s'!='%s'", k.Path().String(), p.String())
|
||||
}
|
||||
|
||||
l, err = api.Key().List(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(l) != 1 {
|
||||
t.Fatalf("expected to get 1 key, got %d", len(l))
|
||||
return
|
||||
}
|
||||
|
||||
if l[0].Name() != "self" {
|
||||
t.Errorf("expected the key to be called 'self', got '%s'", l[0].Name())
|
||||
}
|
||||
}
|
||||
@ -19,6 +19,8 @@ import (
|
||||
unixfs "github.com/ipfs/go-ipfs/unixfs"
|
||||
|
||||
cbor "gx/ipfs/QmeZv9VXw2SfVbX55LV6kGTWASKBc9ZxAVqGBeJcDGdoXy/go-ipld-cbor"
|
||||
|
||||
"github.com/ipfs/go-ipfs/keystore"
|
||||
)
|
||||
|
||||
// `echo -n 'hello, world!' | ipfs add`
|
||||
@ -39,6 +41,7 @@ func makeAPI(ctx context.Context) (*core.IpfsNode, coreiface.CoreAPI, error) {
|
||||
},
|
||||
},
|
||||
D: ds2.ThreadSafeCloserMapDatastore(),
|
||||
K: keystore.NewMemKeystore(),
|
||||
}
|
||||
node, err := core.NewNode(ctx, &core.BuildCfg{Repo: r})
|
||||
if err != nil {
|
||||
|
||||
@ -44,7 +44,7 @@ func (m *Mock) Close() error { return errTODO }
|
||||
|
||||
func (m *Mock) SetAPIAddr(addr ma.Multiaddr) error { return errTODO }
|
||||
|
||||
func (m *Mock) Keystore() keystore.Keystore { return nil }
|
||||
func (m *Mock) Keystore() keystore.Keystore { return m.K }
|
||||
|
||||
func (m *Mock) SwarmKey() ([]byte, error) {
|
||||
return nil, nil
|
||||
|
||||
Loading…
Reference in New Issue
Block a user