@cryptotaxi247 / kubo / commits / 396c34b4e

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