@cryptotaxi247 / kubo / commits / 1c73d48e5

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) {