key cmd: refactor to use coreapi
License: MIT Signed-off-by: Łukasz Magiera <magik6k@gmail.com>
Łukasz Magiera committed
Aug 3, 2018 at 16:46 UTC
3a68d6395a9e524efedee8a4e2697d356fbedb9f
2 files changed
+72
-220
core/commands/keystore.go
+71
-219
@@ -1,20 +1,15 @@
1
package commands
2
3
import (
4
- "bytes"
5
- "crypto/rand"
4
"fmt"
5
"io"
8
- "sort"
9
- "strings"
6
"text/tabwriter"
7
12
- cmds "github.com/ipfs/go-ipfs/commands"
13
- e "github.com/ipfs/go-ipfs/core/commands/e"
8
+ "github.com/ipfs/go-ipfs/core/commands/e"
9
+ "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
10
11
+ "gx/ipfs/QmNueRyPRQiV7PUEpnP4GgGLuK1rKQLaRW7sfPvUetYig1/go-ipfs-cmds"
12
"gx/ipfs/QmdE4gMduCKCGAcczM2F5ioYDfdeKuPix138wrES1YSr7f/go-ipfs-cmdkit"
16
- peer "gx/ipfs/QmdVrMn1LhB4ybb8hMVaMLXnA8XRSewMnK6YqXKXoTcRvN/go-libp2p-peer"
17
- ci "gx/ipfs/Qme1knMqwt1hKZbc1BmQFmnm9f36nyQGwXxPGVpVJ9rMK5/go-libp2p-crypto"
13
)
14
15
var KeyCmd = &cmds.Command{
@@ -70,99 +65,54 @@ var keyGenCmd = &cmds.Command{
65
Arguments: []cmdkit.Argument{
66
cmdkit.StringArg("name", true, false, "name of key to create"),
67
},
73
- Run: func(req cmds.Request, res cmds.Response) {
74
- n, err := req.InvocContext().GetNode()
75
- if err != nil {
76
- res.SetError(err, cmdkit.ErrNormal)
77
- return
78
- }
79
-
80
- typ, f, err := req.Option("type").String()
68
+ Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) {
69
+ api, err := GetApi(env)
70
if err != nil {
71
res.SetError(err, cmdkit.ErrNormal)
72
return
73
}
74
75
+ typ, f := req.Options["type"].(string)
76
if !f {
77
res.SetError(fmt.Errorf("please specify a key type with --type"), cmdkit.ErrNormal)
78
return
79
}
80
91
- size, sizefound, err := req.Option("size").Int()
92
- if err != nil {
93
- res.SetError(err, cmdkit.ErrNormal)
94
- return
95
- }
96
-
97
- name := req.Arguments()[0]
81
+ name := req.Arguments[0]
82
if name == "self" {
83
res.SetError(fmt.Errorf("cannot create key with name 'self'"), cmdkit.ErrNormal)
84
return
85
}
86
103
- var sk ci.PrivKey
104
- var pk ci.PubKey
105
-
106
- switch typ {
107
- case "rsa":
108
- if !sizefound {
109
- res.SetError(fmt.Errorf("please specify a key size with --size"), cmdkit.ErrNormal)
110
- return
111
- }
87
+ opts := []options.KeyGenerateOption{options.Key.Type(typ)}
88
113
- priv, pub, err := ci.GenerateKeyPairWithReader(ci.RSA, size, rand.Reader)
114
- if err != nil {
115
- res.SetError(err, cmdkit.ErrNormal)
116
- return
117
- }
118
-
119
- sk = priv
120
- pk = pub
121
- case "ed25519":
122
- priv, pub, err := ci.GenerateEd25519Key(rand.Reader)
123
- if err != nil {
124
- res.SetError(err, cmdkit.ErrNormal)
125
- return
126
- }
127
-
128
- sk = priv
129
- pk = pub
130
- default:
131
- res.SetError(fmt.Errorf("unrecognized key type: %s", typ), cmdkit.ErrNormal)
132
- return
89
+ size, sizefound := req.Options["size"].(int)
90
+ if sizefound {
91
+ opts = append(opts, options.Key.Size(size))
92
}
93
135
- err = n.Repo.Keystore().Put(name, sk)
136
- if err != nil {
137
- res.SetError(err, cmdkit.ErrNormal)
138
- return
139
- }
94
+ key, err := api.Key().Generate(req.Context, name, opts...)
95
141
- pid, err := peer.IDFromPublicKey(pk)
96
if err != nil {
97
res.SetError(err, cmdkit.ErrNormal)
98
return
99
}
100
147
- res.SetOutput(&KeyOutput{
101
+ cmds.EmitOnce(res, &KeyOutput{
102
Name: name,
149
- Id: pid.Pretty(),
103
+ Id: key.Id().Pretty(),
104
})
105
},
152
- Marshalers: cmds.MarshalerMap{
153
- cmds.Text: func(res cmds.Response) (io.Reader, error) {
154
- v, err := unwrapOutput(res.Output())
155
- if err != nil {
156
- return nil, err
157
- }
158
-
106
+ Encoders: cmds.EncoderMap{
107
+ cmds.Text: cmds.MakeEncoder(func(req *cmds.Request, w io.Writer, v interface{}) error {
108
k, ok := v.(*KeyOutput)
109
if !ok {
161
- return nil, e.TypeErr(k, v)
110
+ return e.TypeErr(k, v)
111
}
112
164
- return strings.NewReader(k.Id + "\n"), nil
165
- },
113
+ _, err := w.Write([]byte(k.Id + "\n"))
114
+ return err
115
+ }),
116
},
117
Type: KeyOutput{},
118
}
@@ -174,47 +124,29 @@ var keyListCmd = &cmds.Command{
124
Options: []cmdkit.Option{
125
cmdkit.BoolOption("l", "Show extra information about keys."),
126
},
177
- Run: func(req cmds.Request, res cmds.Response) {
178
- n, err := req.InvocContext().GetNode()
127
+ Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) {
128
+ api, err := GetApi(env)
129
if err != nil {
130
res.SetError(err, cmdkit.ErrNormal)
131
return
132
}
133
184
- keys, err := n.Repo.Keystore().List()
134
+ keys, err := api.Key().List(req.Context)
135
if err != nil {
136
res.SetError(err, cmdkit.ErrNormal)
137
return
138
}
139
190
- sort.Strings(keys)
191
-
192
- list := make([]KeyOutput, 0, len(keys)+1)
193
-
194
- list = append(list, KeyOutput{Name: "self", Id: n.Identity.Pretty()})
140
+ list := make([]KeyOutput, 0, len(keys))
141
142
for _, key := range keys {
197
- privKey, err := n.Repo.Keystore().Get(key)
198
- if err != nil {
199
- res.SetError(err, cmdkit.ErrNormal)
200
- return
201
- }
202
-
203
- pubKey := privKey.GetPublic()
204
-
205
- pid, err := peer.IDFromPublicKey(pubKey)
206
- if err != nil {
207
- res.SetError(err, cmdkit.ErrNormal)
208
- return
209
- }
210
-
211
- list = append(list, KeyOutput{Name: key, Id: pid.Pretty()})
143
+ list = append(list, KeyOutput{Name: key.Name(), Id: key.Id().Pretty()})
144
}
145
214
- res.SetOutput(&KeyOutputList{list})
146
+ cmds.EmitOnce(res, &KeyOutputList{list})
147
},
216
- Marshalers: cmds.MarshalerMap{
217
- cmds.Text: keyOutputListMarshaler,
148
+ Encoders: cmds.EncoderMap{
149
+ cmds.Text: keyOutputListMarshaler(),
150
},
151
Type: KeyOutputList{},
152
}
@@ -230,100 +162,44 @@ var keyRenameCmd = &cmds.Command{
162
Options: []cmdkit.Option{
163
cmdkit.BoolOption("force", "f", "Allow to overwrite an existing key."),
164
},
233
- Run: func(req cmds.Request, res cmds.Response) {
234
- n, err := req.InvocContext().GetNode()
235
- if err != nil {
236
- res.SetError(err, cmdkit.ErrNormal)
237
- return
238
- }
239
-
240
- ks := n.Repo.Keystore()
241
-
242
- name := req.Arguments()[0]
243
- newName := req.Arguments()[1]
244
-
245
- if name == "self" {
246
- res.SetError(fmt.Errorf("cannot rename key with name 'self'"), cmdkit.ErrNormal)
247
- return
248
- }
249
-
250
- if newName == "self" {
251
- res.SetError(fmt.Errorf("cannot overwrite key with name 'self'"), cmdkit.ErrNormal)
252
- return
253
- }
254
-
255
- oldKey, err := ks.Get(name)
256
- if err != nil {
257
- res.SetError(fmt.Errorf("no key named %s was found", name), cmdkit.ErrNormal)
258
- return
259
- }
260
-
261
- pubKey := oldKey.GetPublic()
262
-
263
- pid, err := peer.IDFromPublicKey(pubKey)
165
+ Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) {
166
+ api, err := GetApi(env)
167
if err != nil {
168
res.SetError(err, cmdkit.ErrNormal)
169
return
170
}
171
269
- overwrite := false
270
- force, _, _ := res.Request().Option("f").Bool()
271
- if force {
272
- exist, err := ks.Has(newName)
273
- if err != nil {
274
- res.SetError(err, cmdkit.ErrNormal)
275
- return
276
- }
277
-
278
- if exist {
279
- overwrite = true
280
- err := ks.Delete(newName)
281
- if err != nil {
282
- res.SetError(err, cmdkit.ErrNormal)
283
- return
284
- }
285
- }
286
- }
172
+ name := req.Arguments[0]
173
+ newName := req.Arguments[1]
174
+ force := req.Options["force"].(bool)
175
288
- err = ks.Put(newName, oldKey)
176
+ key, overwritten, err := api.Key().Rename(req.Context, name, newName, options.Key.Force(force))
177
if err != nil {
178
res.SetError(err, cmdkit.ErrNormal)
179
return
180
}
181
294
- err = ks.Delete(name)
295
- if err != nil {
296
- res.SetError(err, cmdkit.ErrNormal)
297
- return
298
- }
299
-
300
- res.SetOutput(&KeyRenameOutput{
182
+ cmds.EmitOnce(res, &KeyRenameOutput{
183
Was: name,
184
Now: newName,
303
- Id: pid.Pretty(),
304
- Overwrite: overwrite,
185
+ Id: key.Id().Pretty(),
186
+ Overwrite: overwritten,
187
})
188
},
307
- Marshalers: cmds.MarshalerMap{
308
- cmds.Text: func(res cmds.Response) (io.Reader, error) {
309
- v, err := unwrapOutput(res.Output())
310
- if err != nil {
311
- return nil, err
312
- }
189
+ Encoders: cmds.EncoderMap{
190
+ cmds.Text: cmds.MakeEncoder(func(req *cmds.Request, w io.Writer, v interface{}) error {
191
k, ok := v.(*KeyRenameOutput)
192
if !ok {
315
- return nil, fmt.Errorf("expected a KeyRenameOutput as command result")
193
+ return fmt.Errorf("expected a KeyRenameOutput as command result")
194
}
195
318
- buf := new(bytes.Buffer)
319
-
196
if k.Overwrite {
321
- fmt.Fprintf(buf, "Key %s renamed to %s with overwriting\n", k.Id, k.Now)
197
+ fmt.Fprintf(w, "Key %s renamed to %s with overwriting\n", k.Id, k.Now)
198
} else {
323
- fmt.Fprintf(buf, "Key %s renamed to %s\n", k.Id, k.Now)
199
+ fmt.Fprintf(w, "Key %s renamed to %s\n", k.Id, k.Now)
200
}
325
- return buf, nil
326
- },
201
+ return nil
202
+ }),
203
},
204
Type: KeyRenameOutput{},
205
}
@@ -338,76 +214,52 @@ var keyRmCmd = &cmds.Command{
214
Options: []cmdkit.Option{
215
cmdkit.BoolOption("l", "Show extra information about keys."),
216
},
341
- Run: func(req cmds.Request, res cmds.Response) {
342
- n, err := req.InvocContext().GetNode()
217
+ Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) {
218
+ api, err := GetApi(env)
219
if err != nil {
220
res.SetError(err, cmdkit.ErrNormal)
221
return
222
}
223
348
- names := req.Arguments()
224
+ names := req.Arguments
225
226
list := make([]KeyOutput, 0, len(names))
227
for _, name := range names {
352
- if name == "self" {
353
- res.SetError(fmt.Errorf("cannot remove key with name 'self'"), cmdkit.ErrNormal)
354
- return
355
- }
356
-
357
- removed, err := n.Repo.Keystore().Get(name)
358
- if err != nil {
359
- res.SetError(fmt.Errorf("no key named %s was found", name), cmdkit.ErrNormal)
360
- return
361
- }
362
-
363
- pubKey := removed.GetPublic()
364
-
365
- pid, err := peer.IDFromPublicKey(pubKey)
228
+ key, err := api.Key().Remove(req.Context, name)
229
if err != nil {
230
res.SetError(err, cmdkit.ErrNormal)
231
return
232
}
233
371
- list = append(list, KeyOutput{Name: name, Id: pid.Pretty()})
234
+ list = append(list, KeyOutput{Name: name, Id: key.Id().Pretty()})
235
}
236
374
- for _, name := range names {
375
- err = n.Repo.Keystore().Delete(name)
376
- if err != nil {
377
- res.SetError(err, cmdkit.ErrNormal)
378
- return
379
- }
380
- }
381
-
382
- res.SetOutput(&KeyOutputList{list})
237
+ cmds.EmitOnce(res, &KeyOutputList{list})
238
},
384
- Marshalers: cmds.MarshalerMap{
385
- cmds.Text: keyOutputListMarshaler,
239
+ Encoders: cmds.EncoderMap{
240
+ cmds.Text: keyOutputListMarshaler(),
241
},
242
Type: KeyOutputList{},
243
}
244
390
-func keyOutputListMarshaler(res cmds.Response) (io.Reader, error) {
391
- withId, _, _ := res.Request().Option("l").Bool()
392
-
393
- v, err := unwrapOutput(res.Output())
394
- if err != nil {
395
- return nil, err
396
- }
397
- list, ok := v.(*KeyOutputList)
398
- if !ok {
399
- return nil, e.TypeErr(list, v)
400
- }
401
-
402
- buf := new(bytes.Buffer)
403
- w := tabwriter.NewWriter(buf, 1, 2, 1, ' ', 0)
404
- for _, s := range list.Keys {
405
- if withId {
406
- fmt.Fprintf(w, "%s\t%s\t\n", s.Id, s.Name)
407
- } else {
408
- fmt.Fprintf(w, "%s\n", s.Name)
245
+func keyOutputListMarshaler() cmds.EncoderFunc {
246
+ return cmds.MakeEncoder(func(req *cmds.Request, w io.Writer, v interface{}) error {
247
+ withId, _ := req.Options["l"].(bool)
248
+
249
+ list, ok := v.(*KeyOutputList)
250
+ if !ok {
251
+ return e.TypeErr(list, v)
252
+ }
253
+
254
+ tw := tabwriter.NewWriter(w, 1, 2, 1, ' ', 0)
255
+ for _, s := range list.Keys {
256
+ if withId {
257
+ fmt.Fprintf(tw, "%s\t%s\t\n", s.Id, s.Name)
258
+ } else {
259
+ fmt.Fprintf(tw, "%s\n", s.Name)
260
+ }
261
}
410
- }
411
- w.Flush()
412
- return buf, nil
262
+ tw.Flush()
263
+ return nil
264
+ })
265
}
core/commands/root.go
+1
-1
@@ -121,7 +121,7 @@ var rootSubcommands = map[string]*cmds.Command{
121
"diag": lgc.NewCommand(DiagCmd),
122
"dns": lgc.NewCommand(DNSCmd),
123
"id": lgc.NewCommand(IDCmd),
124
- "key": lgc.NewCommand(KeyCmd),
124
+ "key": KeyCmd,
125
"log": lgc.NewCommand(LogCmd),
126
"ls": lgc.NewCommand(LsCmd),
127
"mount": lgc.NewCommand(MountCmd),