Skip to content

Commit 8df2d1a

Browse files
committed
coreapi: name/key review suggestions
License: MIT Signed-off-by: Łukasz Magiera <[email protected]>
1 parent 587dc18 commit 8df2d1a

File tree

5 files changed

+108
-69
lines changed

5 files changed

+108
-69
lines changed

core/coreapi/interface/interface.go

+26-19
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,21 @@ type Path interface {
2828
type Node ipld.Node
2929
type Link ipld.Link
3030

31-
type IpnsEntry struct {
32-
Name string
33-
Value Path
34-
}
35-
3631
type Reader interface {
3732
io.ReadSeeker
3833
io.Closer
3934
}
4035

36+
type IpnsEntry interface {
37+
Name() string
38+
Value() Path
39+
}
40+
41+
type Key interface {
42+
Name() string
43+
Path() Path
44+
}
45+
4146
// CoreAPI defines an unified interface to IPFS for Go programs.
4247
type CoreAPI interface {
4348
// Unixfs returns an implementation of Unixfs API
@@ -108,16 +113,17 @@ type DagAPI interface {
108113
// You can use .Key API to list and generate more names and their respective keys.
109114
type NameAPI interface {
110115
// Publish announces new IPNS name
111-
Publish(ctx context.Context, path Path, opts ...options.NamePublishOption) (*IpnsEntry, error)
116+
Publish(ctx context.Context, path Path, opts ...options.NamePublishOption) (IpnsEntry, error)
112117

113118
// WithValidTime is an option for Publish which specifies for how long the
114119
// entry will remain valid. Default value is 24h
115120
WithValidTime(validTime time.Duration) options.NamePublishOption
116121

117122
// WithKey is an option for Publish which specifies the key to use for
118123
// publishing. Default value is "self" which is the node's own PeerID.
124+
// The key parameter must be either PeerID or keystore key alias.
119125
//
120-
// You can use .Key API to list and generate more names and their respective keys.
126+
// You can use KeyAPI to list and generate more names and their respective keys.
121127
WithKey(key string) options.NamePublishOption
122128

123129
// Resolve attempts to resolve the newest version of the specified name
@@ -131,41 +137,42 @@ type NameAPI interface {
131137
// offline. Default value is false
132138
WithLocal(local bool) options.NameResolveOption
133139

134-
// WithNoCache is an option for Resolve which specifies when set to true
135-
// disables the use of local name cache. Default value is false
136-
WithNoCache(nocache bool) options.NameResolveOption
140+
// WithCache is an option for Resolve which specifies if cache should be used.
141+
// Default value is true
142+
WithCache(cache bool) options.NameResolveOption
137143
}
138144

139145
// KeyAPI specifies the interface to Keystore
140146
type KeyAPI interface {
141147
// Generate generates new key, stores it in the keystore under the specified
142148
// name and returns a base58 encoded multihash of it's public key
143-
Generate(ctx context.Context, name string, opts ...options.KeyGenerateOption) (string, error)
149+
Generate(ctx context.Context, name string, opts ...options.KeyGenerateOption) (Key, error)
144150

145151
// WithAlgorithm is an option for Generate which specifies which algorithm
146-
// should be used for the key. Default is "rsa"
152+
// should be used for the key. Default is options.RSAKey
147153
//
148154
// Supported algorithms:
149-
// * rsa
150-
// * ed25519
155+
// * options.RSAKey
156+
// * options.Ed25519Key
151157
WithAlgorithm(algorithm string) options.KeyGenerateOption
152158

153159
// WithSize is an option for Generate which specifies the size of the key to
154160
// generated. Default is 0
155161
WithSize(size int) options.KeyGenerateOption
156162

157-
// Rename renames oldName key to newName.
158-
Rename(ctx context.Context, oldName string, newName string, opts ...options.KeyRenameOption) (string, bool, error)
163+
// Rename renames oldName key to newName. Returns the key and whether another
164+
// key was overwritten, or an error
165+
Rename(ctx context.Context, oldName string, newName string, opts ...options.KeyRenameOption) (Key, bool, error)
159166

160167
// WithForce is an option for Rename which specifies whether to allow to
161168
// replace existing keys.
162169
WithForce(force bool) options.KeyRenameOption
163170

164171
// List lists keys stored in keystore
165-
List(ctx context.Context) (map[string]string, error) //TODO: better key type?
172+
List(ctx context.Context) ([]Key, error)
166173

167-
// Remove removes keys from keystore
168-
Remove(ctx context.Context, name string) (string, error)
174+
// Remove removes keys from keystore. Returns ipns path of the removed key
175+
Remove(ctx context.Context, name string) (Path, error)
169176
}
170177

171178
// type ObjectAPI interface {

core/coreapi/interface/options/key.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
package options
22

3+
const (
4+
RSAKey = "rsa"
5+
Ed25519Key = "ed25519"
6+
)
7+
38
type KeyGenerateSettings struct {
49
Algorithm string
510
Size int
@@ -14,7 +19,7 @@ type KeyRenameOption func(*KeyRenameSettings) error
1419

1520
func KeyGenerateOptions(opts ...KeyGenerateOption) (*KeyGenerateSettings, error) {
1621
options := &KeyGenerateSettings{
17-
Algorithm: "rsa",
22+
Algorithm: RSAKey,
1823
Size: 0,
1924
}
2025

core/coreapi/interface/options/name.go

+9-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import (
44
"time"
55
)
66

7+
const (
8+
DefaultNameValidTime = 24 * time.Hour
9+
)
10+
711
type NamePublishSettings struct {
812
ValidTime time.Duration
913
Key string
@@ -12,15 +16,15 @@ type NamePublishSettings struct {
1216
type NameResolveSettings struct {
1317
Recursive bool
1418
Local bool
15-
Nocache bool
19+
Cache bool
1620
}
1721

1822
type NamePublishOption func(*NamePublishSettings) error
1923
type NameResolveOption func(*NameResolveSettings) error
2024

2125
func NamePublishOptions(opts ...NamePublishOption) (*NamePublishSettings, error) {
2226
options := &NamePublishSettings{
23-
ValidTime: 24 * time.Hour,
27+
ValidTime: DefaultNameValidTime,
2428
Key: "self",
2529
}
2630

@@ -38,7 +42,7 @@ func NameResolveOptions(opts ...NameResolveOption) (*NameResolveSettings, error)
3842
options := &NameResolveSettings{
3943
Recursive: false,
4044
Local: false,
41-
Nocache: false,
45+
Cache: true,
4246
}
4347

4448
for _, opt := range opts {
@@ -81,9 +85,9 @@ func (api *NameOptions) WithLocal(local bool) NameResolveOption {
8185
}
8286
}
8387

84-
func (api *NameOptions) WithNoCache(nocache bool) NameResolveOption {
88+
func (api *NameOptions) WithCache(cache bool) NameResolveOption {
8589
return func(settings *NameResolveSettings) error {
86-
settings.Nocache = nocache
90+
settings.Cache = cache
8791
return nil
8892
}
8993
}

core/coreapi/key.go

+47-33
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import (
88

99
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
1010
caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
11+
ipfspath "github.com/ipfs/go-ipfs/path"
1112

12-
peer "gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer"
13+
peer "gx/ipfs/QmWNY7dV54ZDYmTA1ykVdwNCqC11mpU4zSUp6XDpLTH9eG/go-libp2p-peer"
1314
crypto "gx/ipfs/QmaPbCnUMBohSGo3KnxEa2bHqyJVVeEEcwtqJAYxerieBo/go-libp2p-crypto"
1415
)
1516

@@ -18,10 +19,23 @@ type KeyAPI struct {
1819
*caopts.KeyOptions
1920
}
2021

21-
func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.KeyGenerateOption) (string, error) {
22+
type key struct {
23+
name string
24+
peerId string
25+
}
26+
27+
func (k *key) Name() string {
28+
return k.name
29+
}
30+
31+
func (k *key) Path() coreiface.Path {
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) {
2236
options, err := caopts.KeyGenerateOptions(opts...)
2337
if err != nil {
24-
return "", err
38+
return nil, err
2539
}
2640

2741
var sk crypto.PrivKey
@@ -30,54 +44,54 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key
3044
switch options.Algorithm {
3145
case "rsa":
3246
if options.Size == 0 {
33-
return "", fmt.Errorf("please specify a key size with WithSize option")
47+
return nil, fmt.Errorf("please specify a key size with WithSize option")
3448
}
3549

3650
priv, pub, err := crypto.GenerateKeyPairWithReader(crypto.RSA, options.Size, rand.Reader)
3751
if err != nil {
38-
return "", err
52+
return nil, err
3953
}
4054

4155
sk = priv
4256
pk = pub
4357
case "ed25519":
4458
priv, pub, err := crypto.GenerateEd25519Key(rand.Reader)
4559
if err != nil {
46-
return "", err
60+
return nil, err
4761
}
4862

4963
sk = priv
5064
pk = pub
5165
default:
52-
return "", fmt.Errorf("unrecognized key type: %s", options.Algorithm)
66+
return nil, fmt.Errorf("unrecognized key type: %s", options.Algorithm)
5367
}
5468

5569
err = api.node.Repo.Keystore().Put(name, sk)
5670
if err != nil {
57-
return "", err
71+
return nil, err
5872
}
5973

6074
pid, err := peer.IDFromPublicKey(pk)
6175
if err != nil {
62-
return "", err
76+
return nil, err
6377
}
6478

65-
return pid.String(), nil
79+
return &key{name, pid.String()}, nil
6680
}
6781

68-
func (api *KeyAPI) List(ctx context.Context) (map[string]string, error) {
82+
func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) {
6983
keys, err := api.node.Repo.Keystore().List()
7084
if err != nil {
7185
return nil, err
7286
}
7387

7488
sort.Strings(keys)
7589

76-
out := make(map[string]string, len(keys)+1)
77-
out["self"] = api.node.Identity.Pretty()
90+
out := make([]coreiface.Key, len(keys)+1)
91+
out[0] = &key{"self", api.node.Identity.Pretty()}
7892

79-
for _, key := range keys {
80-
privKey, err := api.node.Repo.Keystore().Get(key)
93+
for n, k := range keys {
94+
privKey, err := api.node.Repo.Keystore().Get(k)
8195
if err != nil {
8296
return nil, err
8397
}
@@ -89,88 +103,88 @@ func (api *KeyAPI) List(ctx context.Context) (map[string]string, error) {
89103
return nil, err
90104
}
91105

92-
out[key] = pid.Pretty()
106+
out[n+1] = &key{k, pid.Pretty()}
93107
}
94108
return out, nil
95109
}
96110

97-
func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, opts ...caopts.KeyRenameOption) (string, bool, error) {
111+
func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, opts ...caopts.KeyRenameOption) (coreiface.Key, bool, error) {
98112
options, err := caopts.KeyRenameOptions(opts...)
99-
if newName == "self" {
100-
return "", false, err
113+
if err != nil {
114+
return nil, false, err
101115
}
102116

103117
ks := api.node.Repo.Keystore()
104118

105119
if oldName == "self" {
106-
return "", false, fmt.Errorf("cannot rename key with name 'self'")
120+
return nil, false, fmt.Errorf("cannot rename key with name 'self'")
107121
}
108122

109123
if newName == "self" {
110-
return "", false, fmt.Errorf("cannot overwrite key with name 'self'")
124+
return nil, false, fmt.Errorf("cannot overwrite key with name 'self'")
111125
}
112126

113127
oldKey, err := ks.Get(oldName)
114128
if err != nil {
115-
return "", false, fmt.Errorf("no key named %s was found", oldName)
129+
return nil, false, fmt.Errorf("no key named %s was found", oldName)
116130
}
117131

118132
pubKey := oldKey.GetPublic()
119133

120134
pid, err := peer.IDFromPublicKey(pubKey)
121135
if err != nil {
122-
return "", false, err
136+
return nil, false, err
123137
}
124138

125139
overwrite := false
126140
if options.Force {
127141
exist, err := ks.Has(newName)
128142
if err != nil {
129-
return "", false, err
143+
return nil, false, err
130144
}
131145

132146
if exist {
133147
overwrite = true
134148
err := ks.Delete(newName)
135149
if err != nil {
136-
return "", false, err
150+
return nil, false, err
137151
}
138152
}
139153
}
140154

141155
err = ks.Put(newName, oldKey)
142156
if err != nil {
143-
return "", false, err
157+
return nil, false, err
144158
}
145159

146-
return pid.Pretty(), overwrite, ks.Delete(oldName)
160+
return &key{newName, pid.Pretty()}, overwrite, ks.Delete(oldName)
147161
}
148162

149-
func (api *KeyAPI) Remove(ctx context.Context, name string) (string, error) {
163+
func (api *KeyAPI) Remove(ctx context.Context, name string) (coreiface.Path, error) {
150164
ks := api.node.Repo.Keystore()
151165

152166
if name == "self" {
153-
return "", fmt.Errorf("cannot remove key with name 'self'")
167+
return nil, fmt.Errorf("cannot remove key with name 'self'")
154168
}
155169

156170
removed, err := ks.Get(name)
157171
if err != nil {
158-
return "", fmt.Errorf("no key named %s was found", name)
172+
return nil, fmt.Errorf("no key named %s was found", name)
159173
}
160174

161175
pubKey := removed.GetPublic()
162176

163177
pid, err := peer.IDFromPublicKey(pubKey)
164178
if err != nil {
165-
return "", err
179+
return nil, err
166180
}
167181

168182
err = ks.Delete(name)
169183
if err != nil {
170-
return "", err
184+
return nil, err
171185
}
172186

173-
return pid.Pretty(), nil
187+
return (&key{"", pid.Pretty()}).Path(), nil
174188
}
175189

176190
func (api *KeyAPI) core() coreiface.CoreAPI {

0 commit comments

Comments
 (0)