Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: coreapi.Name,Key #4477

Merged
merged 7 commits into from
Jan 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions core/coreapi/coreapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ func (api *CoreAPI) Dag() coreiface.DagAPI {
return &DagAPI{api, nil}
}

func (api *CoreAPI) Name() coreiface.NameAPI {
return &NameAPI{api, nil}
}

func (api *CoreAPI) Key() coreiface.KeyAPI {
return &KeyAPI{api, nil}
}

func (api *CoreAPI) ResolveNode(ctx context.Context, p coreiface.Path) (coreiface.Node, error) {
p, err := api.ResolvePath(ctx, p)
if err != nil {
Expand Down
88 changes: 88 additions & 0 deletions core/coreapi/interface/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"context"
"errors"
"io"
"time"

options "github.com/ipfs/go-ipfs/core/coreapi/interface/options"

Expand All @@ -32,11 +33,23 @@ type Reader interface {
io.Closer
}

type IpnsEntry interface {
Name() string
Value() Path
}

type Key interface {
Name() string
Path() Path
}

// CoreAPI defines an unified interface to IPFS for Go programs.
type CoreAPI interface {
// Unixfs returns an implementation of Unixfs API
Unixfs() UnixfsAPI
Dag() DagAPI
Name() NameAPI
Key() KeyAPI

// ResolvePath resolves the path using Unixfs resolver
ResolvePath(context.Context, Path) (Path, error)
Expand Down Expand Up @@ -90,6 +103,81 @@ type DagAPI interface {
WithDepth(depth int) options.DagTreeOption
}

// NameAPI specifies the interface to IPNS.
//
// IPNS is a PKI namespace, where names are the hashes of public keys, and the
// private key enables publishing new (signed) values. In both publish and
// resolve, the default name used is the node's own PeerID, which is the hash of
// its public key.
//
// You can use .Key API to list and generate more names and their respective keys.
type NameAPI interface {
// Publish announces new IPNS name
Publish(ctx context.Context, path Path, opts ...options.NamePublishOption) (IpnsEntry, error)

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

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

// Resolve attempts to resolve the newest version of the specified name
Resolve(ctx context.Context, name string, opts ...options.NameResolveOption) (Path, error)

// WithRecursive is an option for Resolve which specifies whether to perform a
// recursive lookup. Default value is false
WithRecursive(recursive bool) options.NameResolveOption

// WithLocal is an option for Resolve which specifies if the lookup should be
// offline. Default value is false
WithLocal(local bool) options.NameResolveOption

// WithCache is an option for Resolve which specifies if cache should be used.
// Default value is true
WithCache(cache bool) options.NameResolveOption
}

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

// WithType is an option for Generate which specifies which algorithm
// should be used for the key. Default is options.RSAKey
//
// Supported key types:
// * options.RSAKey
// * options.Ed25519Key
WithType(algorithm string) options.KeyGenerateOption

// WithSize is an option for Generate which specifies the size of the key to
// generated. Default is -1
//
// value of -1 means 'use default size for key type':
// * 2048 for RSA
WithSize(size int) options.KeyGenerateOption

// Rename renames oldName key to newName. Returns the key and whether another
// key was overwritten, or an error
Rename(ctx context.Context, oldName string, newName string, opts ...options.KeyRenameOption) (Key, bool, error)

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

// List lists keys stored in keystore
List(ctx context.Context) ([]Key, error)

// Remove removes keys from keystore. Returns ipns path of the removed key
Remove(ctx context.Context, name string) (Path, error)
}

// type ObjectAPI interface {
// New() (cid.Cid, Object)
// Get(string) (Object, error)
Expand Down
72 changes: 72 additions & 0 deletions core/coreapi/interface/options/key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package options

const (
RSAKey = "rsa"
Ed25519Key = "ed25519"

DefaultRSALen = 2048
)

type KeyGenerateSettings struct {
Algorithm string
Size int
}

type KeyRenameSettings struct {
Force bool
}

type KeyGenerateOption func(*KeyGenerateSettings) error
type KeyRenameOption func(*KeyRenameSettings) error

func KeyGenerateOptions(opts ...KeyGenerateOption) (*KeyGenerateSettings, error) {
options := &KeyGenerateSettings{
Algorithm: RSAKey,
Size: -1,
}

for _, opt := range opts {
err := opt(options)
if err != nil {
return nil, err
}
}
return options, nil
}

func KeyRenameOptions(opts ...KeyRenameOption) (*KeyRenameSettings, error) {
options := &KeyRenameSettings{
Force: false,
}

for _, opt := range opts {
err := opt(options)
if err != nil {
return nil, err
}
}
return options, nil
}

type KeyOptions struct{}

func (api *KeyOptions) WithType(algorithm string) KeyGenerateOption {
return func(settings *KeyGenerateSettings) error {
settings.Algorithm = algorithm
return nil
}
}

func (api *KeyOptions) WithSize(size int) KeyGenerateOption {
return func(settings *KeyGenerateSettings) error {
settings.Size = size
return nil
}
}

func (api *KeyOptions) WithForce(force bool) KeyRenameOption {
return func(settings *KeyRenameSettings) error {
settings.Force = force
return nil
}
}
93 changes: 93 additions & 0 deletions core/coreapi/interface/options/name.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package options

import (
"time"
)

const (
DefaultNameValidTime = 24 * time.Hour
)

type NamePublishSettings struct {
ValidTime time.Duration
Key string
}

type NameResolveSettings struct {
Recursive bool
Local bool
Cache bool
}

type NamePublishOption func(*NamePublishSettings) error
type NameResolveOption func(*NameResolveSettings) error

func NamePublishOptions(opts ...NamePublishOption) (*NamePublishSettings, error) {
options := &NamePublishSettings{
ValidTime: DefaultNameValidTime,
Key: "self",
}

for _, opt := range opts {
err := opt(options)
if err != nil {
return nil, err
}
}

return options, nil
}

func NameResolveOptions(opts ...NameResolveOption) (*NameResolveSettings, error) {
options := &NameResolveSettings{
Recursive: false,
Local: false,
Cache: true,
}

for _, opt := range opts {
err := opt(options)
if err != nil {
return nil, err
}
}

return options, nil
}

type NameOptions struct{}

func (api *NameOptions) WithValidTime(validTime time.Duration) NamePublishOption {
return func(settings *NamePublishSettings) error {
settings.ValidTime = validTime
return nil
}
}

func (api *NameOptions) WithKey(key string) NamePublishOption {
return func(settings *NamePublishSettings) error {
settings.Key = key
return nil
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed key can be both a key name and peerID (see keylookup()) -- cool! Let's make sure to document that :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


func (api *NameOptions) WithRecursive(recursive bool) NameResolveOption {
return func(settings *NameResolveSettings) error {
settings.Recursive = recursive
return nil
}
}

func (api *NameOptions) WithLocal(local bool) NameResolveOption {
return func(settings *NameResolveSettings) error {
settings.Local = local
return nil
}
}

func (api *NameOptions) WithCache(cache bool) NameResolveOption {
return func(settings *NameResolveSettings) error {
settings.Cache = cache
return nil
}
}
Loading