coreapi: key tests
License: MIT Signed-off-by: Łukasz Magiera <magik6k@gmail.com>
Łukasz Magiera committed
Jan 1, 2018 at 18:59 UTC
396c34b4e11ba773687f746d6bf1086a270721ff
6 files changed
+440
-10
core/coreapi/interface/interface.go
+3
-3
@@ -148,13 +148,13 @@ type KeyAPI interface {
148
// name and returns a base58 encoded multihash of it's public key
149
Generate(ctx context.Context, name string, opts ...options.KeyGenerateOption) (Key, error)
150
151
- // WithAlgorithm is an option for Generate which specifies which algorithm
151
+ // WithType is an option for Generate which specifies which algorithm
152
// should be used for the key. Default is options.RSAKey
153
//
154
- // Supported algorithms:
154
+ // Supported key types:
155
// * options.RSAKey
156
// * options.Ed25519Key
157
- WithAlgorithm(algorithm string) options.KeyGenerateOption
157
+ WithType(algorithm string) options.KeyGenerateOption
158
159
// WithSize is an option for Generate which specifies the size of the key to
160
// generated. Default is 0
core/coreapi/interface/options/key.go
+4
-2
@@ -3,6 +3,8 @@ package options
3
const (
4
RSAKey = "rsa"
5
Ed25519Key = "ed25519"
6
+
7
+ DefaultRSALen = 2048
8
)
9
10
type KeyGenerateSettings struct {
@@ -20,7 +22,7 @@ type KeyRenameOption func(*KeyRenameSettings) error
22
func KeyGenerateOptions(opts ...KeyGenerateOption) (*KeyGenerateSettings, error) {
23
options := &KeyGenerateSettings{
24
Algorithm: RSAKey,
23
- Size: 0,
25
+ Size: -1,
26
}
27
28
for _, opt := range opts {
@@ -48,7 +50,7 @@ func KeyRenameOptions(opts ...KeyRenameOption) (*KeyRenameSettings, error) {
50
51
type KeyOptions struct{}
52
51
-func (api *KeyOptions) WithAlgorithm(algorithm string) KeyGenerateOption {
53
+func (api *KeyOptions) WithType(algorithm string) KeyGenerateOption {
54
return func(settings *KeyGenerateSettings) error {
55
settings.Algorithm = algorithm
56
return nil
core/coreapi/key.go
+13
-4
@@ -29,7 +29,7 @@ func (k *key) Name() string {
29
}
30
31
func (k *key) Path() coreiface.Path {
32
- return &path{path: ipfspath.FromString(ipfspath.Join([]string{"/ipns/", k.peerId}))}
32
+ return &path{path: ipfspath.FromString(ipfspath.Join([]string{"/ipns", k.peerId}))}
33
}
34
35
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
38
return nil, err
39
}
40
41
+ if name == "self" {
42
+ return nil, fmt.Errorf("cannot overwrite key with name 'self'")
43
+ }
44
+
45
+ _, err = api.node.Repo.Keystore().Get(name)
46
+ if err == nil {
47
+ return nil, fmt.Errorf("key with name '%s' already exists", name)
48
+ }
49
+
50
var sk crypto.PrivKey
51
var pk crypto.PubKey
52
53
switch options.Algorithm {
54
case "rsa":
46
- if options.Size == 0 {
47
- return nil, fmt.Errorf("please specify a key size with WithSize option")
55
+ if options.Size == -1 {
56
+ options.Size = caopts.DefaultRSALen
57
}
58
59
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
85
return nil, err
86
}
87
79
- return &key{name, pid.String()}, nil
88
+ return &key{name, pid.Pretty()}, nil
89
}
90
91
func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) {
core/coreapi/key_test.go
new
+416
@@ -0,0 +1,416 @@
1
+package coreapi_test
2
+
3
+import (
4
+ "context"
5
+ "strings"
6
+ "testing"
7
+
8
+ opts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
9
+)
10
+
11
+func TestListSelf(t *testing.T) {
12
+ ctx := context.Background()
13
+ _, api, err := makeAPI(ctx)
14
+ if err != nil {
15
+ t.Fatal(err)
16
+ return
17
+ }
18
+
19
+ keys, err := api.Key().List(ctx)
20
+ if err != nil {
21
+ t.Fatalf("failed to list keys: %s", err)
22
+ return
23
+ }
24
+
25
+ if len(keys) != 1 {
26
+ t.Fatalf("there should be 1 key (self), got %d", len(keys))
27
+ return
28
+ }
29
+
30
+ if keys[0].Name() != "self" {
31
+ t.Errorf("expected the key to be called 'self', got '%s'", keys[0].Name())
32
+ }
33
+
34
+ if keys[0].Path().String() != "/ipns/Qmfoo" {
35
+ t.Errorf("expected the key to have path '/ipns/Qmfoo', got '%s'", keys[0].Path().String())
36
+ }
37
+}
38
+
39
+func TestRenameSelf(t *testing.T) {
40
+ ctx := context.Background()
41
+ _, api, err := makeAPI(ctx)
42
+ if err != nil {
43
+ t.Fatal(err)
44
+ return
45
+ }
46
+
47
+ _, _, err = api.Key().Rename(ctx, "self", "foo")
48
+ if err == nil {
49
+ t.Error("expected error to not be nil")
50
+ } else {
51
+ if err.Error() != "cannot rename key with name 'self'" {
52
+ t.Fatalf("expected error 'cannot rename key with name 'self'', got '%s'", err.Error())
53
+ }
54
+ }
55
+
56
+ _, _, err = api.Key().Rename(ctx, "self", "foo", api.Key().WithForce(true))
57
+ if err == nil {
58
+ t.Error("expected error to not be nil")
59
+ } else {
60
+ if err.Error() != "cannot rename key with name 'self'" {
61
+ t.Fatalf("expected error 'cannot rename key with name 'self'', got '%s'", err.Error())
62
+ }
63
+ }
64
+}
65
+
66
+func TestRemoveSelf(t *testing.T) {
67
+ ctx := context.Background()
68
+ _, api, err := makeAPI(ctx)
69
+ if err != nil {
70
+ t.Fatal(err)
71
+ return
72
+ }
73
+
74
+ _, err = api.Key().Remove(ctx, "self")
75
+ if err == nil {
76
+ t.Error("expected error to not be nil")
77
+ } else {
78
+ if err.Error() != "cannot remove key with name 'self'" {
79
+ t.Fatalf("expected error 'cannot remove key with name 'self'', got '%s'", err.Error())
80
+ }
81
+ }
82
+}
83
+
84
+func TestGenerate(t *testing.T) {
85
+ ctx := context.Background()
86
+ _, api, err := makeAPI(ctx)
87
+ if err != nil {
88
+ t.Error(err)
89
+ }
90
+
91
+ k, err := api.Key().Generate(ctx, "foo")
92
+ if err != nil {
93
+ t.Fatal(err)
94
+ return
95
+ }
96
+
97
+ if k.Name() != "foo" {
98
+ t.Errorf("expected the key to be called 'foo', got '%s'", k.Name())
99
+ }
100
+
101
+ if !strings.HasPrefix(k.Path().String(), "/ipns/Qm") {
102
+ t.Errorf("expected the key to be prefixed with '/ipns/Qm', got '%s'", k.Path().String())
103
+ }
104
+}
105
+
106
+func TestGenerateSize(t *testing.T) {
107
+ ctx := context.Background()
108
+ _, api, err := makeAPI(ctx)
109
+ if err != nil {
110
+ t.Error(err)
111
+ }
112
+
113
+ k, err := api.Key().Generate(ctx, "foo", api.Key().WithSize(1024))
114
+ if err != nil {
115
+ t.Fatal(err)
116
+ return
117
+ }
118
+
119
+ if k.Name() != "foo" {
120
+ t.Errorf("expected the key to be called 'foo', got '%s'", k.Name())
121
+ }
122
+
123
+ if !strings.HasPrefix(k.Path().String(), "/ipns/Qm") {
124
+ t.Errorf("expected the key to be prefixed with '/ipns/Qm', got '%s'", k.Path().String())
125
+ }
126
+}
127
+
128
+func TestGenerateType(t *testing.T) {
129
+ ctx := context.Background()
130
+ _, api, err := makeAPI(ctx)
131
+ if err != nil {
132
+ t.Error(err)
133
+ }
134
+
135
+ k, err := api.Key().Generate(ctx, "bar", api.Key().WithType(opts.Ed25519Key))
136
+ if err != nil {
137
+ t.Fatal(err)
138
+ return
139
+ }
140
+
141
+ if k.Name() != "bar" {
142
+ t.Errorf("expected the key to be called 'foo', got '%s'", k.Name())
143
+ }
144
+
145
+ if !strings.HasPrefix(k.Path().String(), "/ipns/Qm") {
146
+ t.Errorf("expected the key to be prefixed with '/ipns/Qm', got '%s'", k.Path().String())
147
+ }
148
+}
149
+
150
+func TestGenerateExisting(t *testing.T) {
151
+ ctx := context.Background()
152
+ _, api, err := makeAPI(ctx)
153
+ if err != nil {
154
+ t.Error(err)
155
+ }
156
+
157
+ _, err = api.Key().Generate(ctx, "foo")
158
+ if err != nil {
159
+ t.Fatal(err)
160
+ return
161
+ }
162
+
163
+ _, err = api.Key().Generate(ctx, "foo")
164
+ if err == nil {
165
+ t.Error("expected error to not be nil")
166
+ } else {
167
+ if err.Error() != "key with name 'foo' already exists" {
168
+ t.Fatalf("expected error 'key with name 'foo' already exists', got '%s'", err.Error())
169
+ }
170
+ }
171
+
172
+ _, err = api.Key().Generate(ctx, "self")
173
+ if err == nil {
174
+ t.Error("expected error to not be nil")
175
+ } else {
176
+ if err.Error() != "cannot overwrite key with name 'self'" {
177
+ t.Fatalf("expected error 'cannot overwrite key with name 'self'', got '%s'", err.Error())
178
+ }
179
+ }
180
+}
181
+
182
+func TestList(t *testing.T) {
183
+ ctx := context.Background()
184
+ _, api, err := makeAPI(ctx)
185
+ if err != nil {
186
+ t.Error(err)
187
+ }
188
+
189
+ _, err = api.Key().Generate(ctx, "foo")
190
+ if err != nil {
191
+ t.Fatal(err)
192
+ return
193
+ }
194
+
195
+ l, err := api.Key().List(ctx)
196
+ if err != nil {
197
+ t.Fatal(err)
198
+ return
199
+ }
200
+
201
+ if len(l) != 2 {
202
+ t.Fatalf("expected to get 2 keys, got %d", len(l))
203
+ return
204
+ }
205
+
206
+ if l[0].Name() != "self" {
207
+ t.Fatalf("expected key 0 to be called 'self', got '%s'", l[0].Name())
208
+ return
209
+ }
210
+
211
+ if l[1].Name() != "foo" {
212
+ t.Fatalf("expected key 1 to be called 'foo', got '%s'", l[1].Name())
213
+ return
214
+ }
215
+
216
+ if !strings.HasPrefix(l[0].Path().String(), "/ipns/Qm") {
217
+ t.Fatalf("expected key 0 to be prefixed with '/ipns/Qm', got '%s'", l[0].Name())
218
+ return
219
+ }
220
+
221
+ if !strings.HasPrefix(l[1].Path().String(), "/ipns/Qm") {
222
+ t.Fatalf("expected key 1 to be prefixed with '/ipns/Qm', got '%s'", l[1].Name())
223
+ return
224
+ }
225
+}
226
+
227
+func TestRename(t *testing.T) {
228
+ ctx := context.Background()
229
+ _, api, err := makeAPI(ctx)
230
+ if err != nil {
231
+ t.Error(err)
232
+ }
233
+
234
+ _, err = api.Key().Generate(ctx, "foo")
235
+ if err != nil {
236
+ t.Fatal(err)
237
+ return
238
+ }
239
+
240
+ k, overwrote, err := api.Key().Rename(ctx, "foo", "bar")
241
+ if err != nil {
242
+ t.Fatal(err)
243
+ return
244
+ }
245
+
246
+ if overwrote {
247
+ t.Error("overwrote should be false")
248
+ }
249
+
250
+ if k.Name() != "bar" {
251
+ t.Errorf("returned key should be called 'bar', got '%s'", k.Name())
252
+ }
253
+}
254
+
255
+func TestRenameToSelf(t *testing.T) {
256
+ ctx := context.Background()
257
+ _, api, err := makeAPI(ctx)
258
+ if err != nil {
259
+ t.Error(err)
260
+ }
261
+
262
+ _, err = api.Key().Generate(ctx, "foo")
263
+ if err != nil {
264
+ t.Fatal(err)
265
+ return
266
+ }
267
+
268
+ _, _, err = api.Key().Rename(ctx, "foo", "self")
269
+ if err == nil {
270
+ t.Error("expected error to not be nil")
271
+ } else {
272
+ if err.Error() != "cannot overwrite key with name 'self'" {
273
+ t.Fatalf("expected error 'cannot overwrite key with name 'self'', got '%s'", err.Error())
274
+ }
275
+ }
276
+}
277
+
278
+func TestRenameToSelfForce(t *testing.T) {
279
+ ctx := context.Background()
280
+ _, api, err := makeAPI(ctx)
281
+ if err != nil {
282
+ t.Error(err)
283
+ }
284
+
285
+ _, err = api.Key().Generate(ctx, "foo")
286
+ if err != nil {
287
+ t.Fatal(err)
288
+ return
289
+ }
290
+
291
+ _, _, err = api.Key().Rename(ctx, "foo", "self", api.Key().WithForce(true))
292
+ if err == nil {
293
+ t.Error("expected error to not be nil")
294
+ } else {
295
+ if err.Error() != "cannot overwrite key with name 'self'" {
296
+ t.Fatalf("expected error 'cannot overwrite key with name 'self'', got '%s'", err.Error())
297
+ }
298
+ }
299
+}
300
+
301
+func TestRenameOverwriteNoForce(t *testing.T) {
302
+ ctx := context.Background()
303
+ _, api, err := makeAPI(ctx)
304
+ if err != nil {
305
+ t.Error(err)
306
+ }
307
+
308
+ _, err = api.Key().Generate(ctx, "foo")
309
+ if err != nil {
310
+ t.Fatal(err)
311
+ return
312
+ }
313
+
314
+ _, err = api.Key().Generate(ctx, "bar")
315
+ if err != nil {
316
+ t.Fatal(err)
317
+ return
318
+ }
319
+
320
+ _, _, err = api.Key().Rename(ctx, "foo", "bar")
321
+ if err == nil {
322
+ t.Error("expected error to not be nil")
323
+ } else {
324
+ if err.Error() != "key by that name already exists, refusing to overwrite" {
325
+ t.Fatalf("expected error 'key by that name already exists, refusing to overwrite', got '%s'", err.Error())
326
+ }
327
+ }
328
+}
329
+
330
+func TestRenameOverwrite(t *testing.T) {
331
+ ctx := context.Background()
332
+ _, api, err := makeAPI(ctx)
333
+ if err != nil {
334
+ t.Error(err)
335
+ }
336
+
337
+ kfoo, err := api.Key().Generate(ctx, "foo")
338
+ if err != nil {
339
+ t.Fatal(err)
340
+ return
341
+ }
342
+
343
+ _, err = api.Key().Generate(ctx, "bar")
344
+ if err != nil {
345
+ t.Fatal(err)
346
+ return
347
+ }
348
+
349
+ k, overwrote, err := api.Key().Rename(ctx, "foo", "bar", api.Key().WithForce(true))
350
+ if err != nil {
351
+ t.Fatal(err)
352
+ return
353
+ }
354
+
355
+ if !overwrote {
356
+ t.Error("overwrote should be true")
357
+ }
358
+
359
+ if k.Name() != "bar" {
360
+ t.Errorf("returned key should be called 'bar', got '%s'", k.Name())
361
+ }
362
+
363
+ if k.Path().String() != kfoo.Path().String() {
364
+ t.Errorf("k and kfoo should have equal paths, '%s'!='%s'", k.Path().String(), kfoo.Path().String())
365
+ }
366
+}
367
+
368
+func TestRemove(t *testing.T) {
369
+ ctx := context.Background()
370
+ _, api, err := makeAPI(ctx)
371
+ if err != nil {
372
+ t.Error(err)
373
+ }
374
+
375
+ k, err := api.Key().Generate(ctx, "foo")
376
+ if err != nil {
377
+ t.Fatal(err)
378
+ return
379
+ }
380
+
381
+ l, err := api.Key().List(ctx)
382
+ if err != nil {
383
+ t.Fatal(err)
384
+ return
385
+ }
386
+
387
+ if len(l) != 2 {
388
+ t.Fatalf("expected to get 2 keys, got %d", len(l))
389
+ return
390
+ }
391
+
392
+ p, err := api.Key().Remove(ctx, "foo")
393
+ if err != nil {
394
+ t.Fatal(err)
395
+ return
396
+ }
397
+
398
+ if k.Path().String() != p.String() {
399
+ t.Errorf("k and p should have equal paths, '%s'!='%s'", k.Path().String(), p.String())
400
+ }
401
+
402
+ l, err = api.Key().List(ctx)
403
+ if err != nil {
404
+ t.Fatal(err)
405
+ return
406
+ }
407
+
408
+ if len(l) != 1 {
409
+ t.Fatalf("expected to get 1 key, got %d", len(l))
410
+ return
411
+ }
412
+
413
+ if l[0].Name() != "self" {
414
+ t.Errorf("expected the key to be called 'self', got '%s'", l[0].Name())
415
+ }
416
+}
core/coreapi/unixfs_test.go
+3
@@ -19,6 +19,8 @@ import (
19
unixfs "github.com/ipfs/go-ipfs/unixfs"
20
21
cbor "gx/ipfs/QmeZv9VXw2SfVbX55LV6kGTWASKBc9ZxAVqGBeJcDGdoXy/go-ipld-cbor"
22
+
23
+ "github.com/ipfs/go-ipfs/keystore"
24
)
25
26
// `echo -n 'hello, world!' | ipfs add`
@@ -39,6 +41,7 @@ func makeAPI(ctx context.Context) (*core.IpfsNode, coreiface.CoreAPI, error) {
41
},
42
},
43
D: ds2.ThreadSafeCloserMapDatastore(),
44
+ K: keystore.NewMemKeystore(),
45
}
46
node, err := core.NewNode(ctx, &core.BuildCfg{Repo: r})
47
if err != nil {
repo/mock.go
+1
-1
@@ -44,7 +44,7 @@ func (m *Mock) Close() error { return errTODO }
44
45
func (m *Mock) SetAPIAddr(addr ma.Multiaddr) error { return errTODO }
46
47
-func (m *Mock) Keystore() keystore.Keystore { return nil }
47
+func (m *Mock) Keystore() keystore.Keystore { return m.K }
48
49
func (m *Mock) SwarmKey() ([]byte, error) {
50
return nil, nil