coreapi: name/key functional options
License: MIT Signed-off-by: Łukasz Magiera <magik6k@gmail.com>
Łukasz Magiera committed
Dec 13, 2017 at 19:05 UTC
1c73d48e5b7a480dd1b7cf025e92f8e30948f705
6 files changed
+224
-26
core/coreapi/coreapi.go
+8
-2
@@ -30,11 +30,17 @@ func (api *CoreAPI) Dag() coreiface.DagAPI {
30
}
31
32
func (api *CoreAPI) Name() coreiface.NameAPI {
33
- return (*NameAPI)(api)
33
+ return &NameAPI{
34
+ api,
35
+ nil,
36
+ }
37
}
38
39
func (api *CoreAPI) Key() coreiface.KeyAPI {
37
- return (*KeyAPI)(api)
40
+ return &KeyAPI{
41
+ api,
42
+ nil,
43
+ }
44
}
45
46
func (api *CoreAPI) ResolveNode(ctx context.Context, p coreiface.Path) (coreiface.Node, error) {
core/coreapi/interface/interface.go
+15
-4
@@ -99,14 +99,25 @@ type DagAPI interface {
99
}
100
101
type NameAPI interface {
102
- Publish(ctx context.Context, path Path, validTime time.Duration, key string) (*IpnsEntry, error)
103
- Resolve(ctx context.Context, name string, recursive bool, local bool, nocache bool) (Path, error)
102
+ Publish(ctx context.Context, path Path, opts ...options.NamePublishOption) (*IpnsEntry, error)
103
+ WithValidTime(validTime time.Duration) options.NamePublishOption
104
+ WithKey(key string) options.NamePublishOption
105
+
106
+ Resolve(ctx context.Context, name string, opts ...options.NameResolveOption) (Path, error)
107
+ WithRecursive(recursive bool) options.NameResolveOption
108
+ WithLocal(local bool) options.NameResolveOption
109
+ WithNoCache(nocache bool) options.NameResolveOption
110
}
111
112
type KeyAPI interface {
107
- Generate(ctx context.Context, name string, algorithm string, size int) (string, error)
113
+ Generate(ctx context.Context, name string, opts ...options.KeyGenerateOption) (string, error)
114
+ WithAlgorithm(algorithm string) options.KeyGenerateOption
115
+ WithSize(size int) options.KeyGenerateOption
116
+
117
+ Rename(ctx context.Context, oldName string, newName string, opts ...options.KeyRenameOption) (string, bool, error)
118
+ WithForce(force bool) options.KeyRenameOption
119
+
120
List(ctx context.Context) (map[string]string, error) //TODO: better key type?
109
- Rename(ctx context.Context, oldName string, newName string, force bool) (string, bool, error)
121
Remove(ctx context.Context, name string) (string, error)
122
}
123
core/coreapi/interface/options/key.go
new
+65
@@ -0,0 +1,65 @@
1
+package options
2
+
3
+type KeyGenerateSettings struct {
4
+ Algorithm string
5
+ Size int
6
+}
7
+
8
+type KeyRenameSettings struct {
9
+ Force bool
10
+}
11
+
12
+type KeyGenerateOption func(*KeyGenerateSettings) error
13
+type KeyRenameOption func(*KeyRenameSettings) error
14
+
15
+func KeyGenerateOptions(opts ...KeyGenerateOption) (*KeyGenerateSettings, error) {
16
+ options := &KeyGenerateSettings{
17
+ Algorithm: "rsa",
18
+ Size: 0,
19
+ }
20
+
21
+ for _, opt := range opts {
22
+ err := opt(options)
23
+ if err != nil {
24
+ return nil, err
25
+ }
26
+ }
27
+ return options, nil
28
+}
29
+
30
+func KeyRenameOptions(opts ...KeyRenameOption) (*KeyRenameSettings, error) {
31
+ options := &KeyRenameSettings{
32
+ Force: false,
33
+ }
34
+
35
+ for _, opt := range opts {
36
+ err := opt(options)
37
+ if err != nil {
38
+ return nil, err
39
+ }
40
+ }
41
+ return options, nil
42
+}
43
+
44
+type KeyOptions struct{}
45
+
46
+func (api *KeyOptions) WithAlgorithm(algorithm string) KeyGenerateOption {
47
+ return func(settings *KeyGenerateSettings) error {
48
+ settings.Algorithm = algorithm
49
+ return nil
50
+ }
51
+}
52
+
53
+func (api *KeyOptions) WithSize(size int) KeyGenerateOption {
54
+ return func(settings *KeyGenerateSettings) error {
55
+ settings.Size = size
56
+ return nil
57
+ }
58
+}
59
+
60
+func (api *KeyOptions) WithForce(force bool) KeyRenameOption {
61
+ return func(settings *KeyRenameSettings) error {
62
+ settings.Force = force
63
+ return nil
64
+ }
65
+}
core/coreapi/interface/options/name.go
new
+89
@@ -0,0 +1,89 @@
1
+package options
2
+
3
+import (
4
+ "time"
5
+)
6
+
7
+type NamePublishSettings struct {
8
+ ValidTime time.Duration
9
+ Key string
10
+}
11
+
12
+type NameResolveSettings struct {
13
+ Recursive bool
14
+ Local bool
15
+ Nocache bool
16
+}
17
+
18
+type NamePublishOption func(*NamePublishSettings) error
19
+type NameResolveOption func(*NameResolveSettings) error
20
+
21
+func NamePublishOptions(opts ...NamePublishOption) (*NamePublishSettings, error) {
22
+ options := &NamePublishSettings{
23
+ ValidTime: 24 * time.Hour,
24
+ Key: "self",
25
+ }
26
+
27
+ for _, opt := range opts {
28
+ err := opt(options)
29
+ if err != nil {
30
+ return nil, err
31
+ }
32
+ }
33
+
34
+ return options, nil
35
+}
36
+
37
+func NameResolveOptions(opts ...NameResolveOption) (*NameResolveSettings, error) {
38
+ options := &NameResolveSettings{
39
+ Recursive: false,
40
+ Local: false,
41
+ Nocache: false,
42
+ }
43
+
44
+ for _, opt := range opts {
45
+ err := opt(options)
46
+ if err != nil {
47
+ return nil, err
48
+ }
49
+ }
50
+
51
+ return options, nil
52
+}
53
+
54
+type NameOptions struct{}
55
+
56
+func (api *NameOptions) WithValidTime(validTime time.Duration) NamePublishOption {
57
+ return func(settings *NamePublishSettings) error {
58
+ settings.ValidTime = validTime
59
+ return nil
60
+ }
61
+}
62
+
63
+func (api *NameOptions) WithKey(key string) NamePublishOption {
64
+ return func(settings *NamePublishSettings) error {
65
+ settings.Key = key
66
+ return nil
67
+ }
68
+}
69
+
70
+func (api *NameOptions) WithRecursive(recursive bool) NameResolveOption {
71
+ return func(settings *NameResolveSettings) error {
72
+ settings.Recursive = recursive
73
+ return nil
74
+ }
75
+}
76
+
77
+func (api *NameOptions) WithLocal(local bool) NameResolveOption {
78
+ return func(settings *NameResolveSettings) error {
79
+ settings.Local = local
80
+ return nil
81
+ }
82
+}
83
+
84
+func (api *NameOptions) WithNoCache(nocache bool) NameResolveOption {
85
+ return func(settings *NameResolveSettings) error {
86
+ settings.Nocache = nocache
87
+ return nil
88
+ }
89
+}
core/coreapi/key.go
+24
-10
@@ -7,24 +7,33 @@ import (
7
"sort"
8
9
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
10
+ caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
11
12
peer "gx/ipfs/QmXYjuNuxVzXKJCfWasQk1RqkhVLDM9jtUKhqc2WPQmFSB/go-libp2p-peer"
13
crypto "gx/ipfs/QmaPbCnUMBohSGo3KnxEa2bHqyJVVeEEcwtqJAYxerieBo/go-libp2p-crypto"
14
)
15
15
-type KeyAPI CoreAPI
16
+type KeyAPI struct {
17
+ *CoreAPI
18
+ *caopts.KeyOptions
19
+}
20
+
21
+func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.KeyGenerateOption) (string, error) {
22
+ options, err := caopts.KeyGenerateOptions(opts...)
23
+ if err != nil {
24
+ return "", err
25
+ }
26
17
-func (api *KeyAPI) Generate(ctx context.Context, name string, algorithm string, size int) (string, error) {
27
var sk crypto.PrivKey
28
var pk crypto.PubKey
29
21
- switch algorithm {
30
+ switch options.Algorithm {
31
case "rsa":
23
- if size == 0 {
32
+ if options.Size == 0 {
33
return "", fmt.Errorf("please specify a key size with --size")
34
}
35
27
- priv, pub, err := crypto.GenerateKeyPairWithReader(crypto.RSA, size, rand.Reader)
36
+ priv, pub, err := crypto.GenerateKeyPairWithReader(crypto.RSA, options.Size, rand.Reader)
37
if err != nil {
38
return "", err
39
}
@@ -40,10 +49,10 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, algorithm string,
49
sk = priv
50
pk = pub
51
default:
43
- return "", fmt.Errorf("unrecognized key type: %s", algorithm)
52
+ return "", fmt.Errorf("unrecognized key type: %s", options.Algorithm)
53
}
54
46
- err := api.node.Repo.Keystore().Put(name, sk)
55
+ err = api.node.Repo.Keystore().Put(name, sk)
56
if err != nil {
57
return "", err
58
}
@@ -85,7 +94,12 @@ func (api *KeyAPI) List(ctx context.Context) (map[string]string, error) {
94
return out, nil
95
}
96
88
-func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, force bool) (string, bool, error) {
97
+func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, opts ...caopts.KeyRenameOption) (string, bool, error) {
98
+ options, err := caopts.KeyRenameOptions(opts...)
99
+ if newName == "self" {
100
+ return "", false, err
101
+ }
102
+
103
ks := api.node.Repo.Keystore()
104
105
if oldName == "self" {
@@ -109,7 +123,7 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, f
123
}
124
125
overwrite := false
112
- if force {
126
+ if options.Force {
127
exist, err := ks.Has(newName)
128
if err != nil {
129
return "", false, err
@@ -160,5 +174,5 @@ func (api *KeyAPI) Remove(ctx context.Context, name string) (string, error) {
174
}
175
176
func (api *KeyAPI) core() coreiface.CoreAPI {
163
- return (*CoreAPI)(api)
177
+ return api.CoreAPI
178
}
core/coreapi/name.go
+23
-10
@@ -9,6 +9,7 @@ import (
9
10
core "github.com/ipfs/go-ipfs/core"
11
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
12
+ caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
13
keystore "github.com/ipfs/go-ipfs/keystore"
14
namesys "github.com/ipfs/go-ipfs/namesys"
15
ipath "github.com/ipfs/go-ipfs/path"
@@ -18,9 +19,16 @@ import (
19
crypto "gx/ipfs/QmaPbCnUMBohSGo3KnxEa2bHqyJVVeEEcwtqJAYxerieBo/go-libp2p-crypto"
20
)
21
21
-type NameAPI CoreAPI
22
+type NameAPI struct {
23
+ *CoreAPI
24
+ *caopts.NameOptions
25
+}
26
23
-func (api *NameAPI) Publish(ctx context.Context, p coreiface.Path, validTime time.Duration, key string) (*coreiface.IpnsEntry, error) {
27
+func (api *NameAPI) Publish(ctx context.Context, p coreiface.Path, opts ...caopts.NamePublishOption) (*coreiface.IpnsEntry, error) {
28
+ options, err := caopts.NamePublishOptions(opts...)
29
+ if err != nil {
30
+ return nil, err
31
+ }
32
n := api.node
33
34
if !n.OnlineMode() {
@@ -43,12 +51,12 @@ func (api *NameAPI) Publish(ctx context.Context, p coreiface.Path, validTime tim
51
return nil, err
52
}
53
46
- k, err := keylookup(n, key)
54
+ k, err := keylookup(n, options.Key)
55
if err != nil {
56
return nil, err
57
}
58
51
- eol := time.Now().Add(validTime)
59
+ eol := time.Now().Add(options.ValidTime)
60
err = n.Namesys.PublishWithEOL(ctx, k, pth, eol)
61
if err != nil {
62
return nil, err
@@ -65,7 +73,12 @@ func (api *NameAPI) Publish(ctx context.Context, p coreiface.Path, validTime tim
73
}, nil
74
}
75
68
-func (api *NameAPI) Resolve(ctx context.Context, name string, recursive bool, local bool, nocache bool) (coreiface.Path, error) {
76
+func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.NameResolveOption) (coreiface.Path, error) {
77
+ options, err := caopts.NameResolveOptions(opts...)
78
+ if err != nil {
79
+ return nil, err
80
+ }
81
+
82
n := api.node
83
84
if !n.OnlineMode() {
@@ -77,21 +90,21 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, recursive bool, lo
90
91
var resolver namesys.Resolver = n.Namesys
92
80
- if local && nocache {
93
+ if options.Local && options.Nocache {
94
return nil, errors.New("cannot specify both local and nocache")
95
}
96
84
- if local {
97
+ if options.Local {
98
offroute := offline.NewOfflineRouter(n.Repo.Datastore(), n.PrivateKey)
99
resolver = namesys.NewRoutingResolver(offroute, 0)
100
}
101
89
- if nocache {
102
+ if options.Nocache {
103
resolver = namesys.NewNameSystem(n.Routing, n.Repo.Datastore(), 0)
104
}
105
106
depth := 1
94
- if recursive {
107
+ if options.Recursive {
108
depth = namesys.DefaultDepthLimit
109
}
110
@@ -108,7 +121,7 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, recursive bool, lo
121
}
122
123
func (api *NameAPI) core() coreiface.CoreAPI {
111
- return (*CoreAPI)(api)
124
+ return api.CoreAPI
125
}
126
127
func keylookup(n *core.IpfsNode, k string) (crypto.PrivKey, error) {