Skip to content

Commit

Permalink
Merge pull request #3 from ipfs/feat/pluggable-keystore
Browse files Browse the repository at this point in the history
pluggable keystores
  • Loading branch information
postables authored Mar 10, 2019
2 parents ab5e543 + b72a340 commit 535b467
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 4 deletions.
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/cenkalti/backoff v2.1.1+incompatible
github.com/dustin/go-humanize v1.0.0
github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302
github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect
github.com/fatih/color v1.7.0 // indirect
github.com/fsnotify/fsnotify v1.4.7
github.com/gogo/protobuf v1.2.1
Expand All @@ -33,7 +34,7 @@ require (
github.com/ipfs/go-ipfs-chunker v0.0.1
github.com/ipfs/go-ipfs-cmdkit v0.0.1
github.com/ipfs/go-ipfs-cmds v0.0.1
github.com/ipfs/go-ipfs-config v0.0.1
github.com/ipfs/go-ipfs-config v0.0.0-20190309024316-a0bdc3f74854
github.com/ipfs/go-ipfs-ds-help v0.0.1
github.com/ipfs/go-ipfs-exchange-interface v0.0.1
github.com/ipfs/go-ipfs-exchange-offline v0.0.1
Expand All @@ -51,12 +52,12 @@ require (
github.com/ipfs/go-metrics-prometheus v0.0.1
github.com/ipfs/go-mfs v0.0.1
github.com/ipfs/go-path v0.0.1
github.com/ipfs/go-prompt v0.0.1
github.com/ipfs/go-unixfs v0.0.1
github.com/ipfs/go-verifcid v0.0.1
github.com/ipfs/hang-fds v0.0.1
github.com/ipfs/interface-go-ipfs-core v0.0.2
github.com/ipfs/iptb v1.4.0
github.com/ipfs/iptb-plugins v0.0.1
github.com/jbenet/go-is-domain v0.0.0-20160119110217-ba9815c809e0
github.com/jbenet/go-random v0.0.0-20190219211222-123a90aedc0c
github.com/jbenet/go-random-files v0.0.0-20190219210431-31b3f20ebded
Expand All @@ -67,6 +68,7 @@ require (
github.com/libp2p/go-libp2p-circuit v0.0.1
github.com/libp2p/go-libp2p-connmgr v0.0.1
github.com/libp2p/go-libp2p-crypto v0.0.1
github.com/libp2p/go-libp2p-daemon v0.0.1 // indirect
github.com/libp2p/go-libp2p-host v0.0.1
github.com/libp2p/go-libp2p-interface-connmgr v0.0.1
github.com/libp2p/go-libp2p-kad-dht v0.0.3
Expand Down Expand Up @@ -102,6 +104,7 @@ require (
github.com/prometheus/client_golang v0.9.2
github.com/syndtr/goleveldb v1.0.0
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc
github.com/whyrusleeping/go-ctrlnet v0.0.0-20180313164037-f564fbbdaa95 // indirect
github.com/whyrusleeping/go-smux-multiplex v3.0.16+incompatible
github.com/whyrusleeping/go-smux-yamux v2.0.8+incompatible
github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1
Expand Down
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ github.com/Kubuxu/go-os-helper v0.0.1 h1:EJiD2VUQyh5A9hWJLmc6iWg6yIcJ7jpBcwC8GMG
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd h1:HNhzThEtZW714v8Eda8sWWRcu9WSzJC+oCyjRjvZgRA=
github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd/go.mod h1:bqoB8kInrTeEtYAwaIXoSRqdwnjQmFhsfusnzyui6yY=
github.com/Songmu/prompter v0.0.0-20181014095714-d227c68538bd h1:WPP3dYxBYZBo0q3t14UIvD0Myr848agWCVSlScH17E0=
github.com/Songmu/prompter v0.0.0-20181014095714-d227c68538bd/go.mod h1:fNhSFBGC+sg+dZ7AqDHgq+xYiom23TeTESzUbO7PIrE=
github.com/Stebalien/go-bitfield v0.0.0-20180330043415-076a62f9ce6e h1:2Z+EBRrOJsA3psnUPcEWMIH2EIga1xHflQcr/EZslx8=
github.com/Stebalien/go-bitfield v0.0.0-20180330043415-076a62f9ce6e/go.mod h1:3oM7gXIttpYDAJXpVNnSCiUMYBLIZ6cb1t+Ip982MRo=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
Expand Down Expand Up @@ -139,6 +141,8 @@ github.com/ipfs/go-ipfs-cmdkit v0.0.1 h1:X6YXEAjUljTzevE6DPUKXSqcgf+4FXzcn5B957F
github.com/ipfs/go-ipfs-cmdkit v0.0.1/go.mod h1:9FtbMdUabcSqv/G4/8WCxSLxkZxn/aZEFrxxqnVcRbg=
github.com/ipfs/go-ipfs-cmds v0.0.1 h1:wPTynLMa+JImcTsPaVmrUDP8mJ3S8HQVUWixnKi7+k4=
github.com/ipfs/go-ipfs-cmds v0.0.1/go.mod h1:k7I8PptE2kCJchR3ta546LRyxl4/uBYbLQHOJM0sUQ8=
github.com/ipfs/go-ipfs-config v0.0.0-20190309024316-a0bdc3f74854 h1:/egI93XR8dai8cn+W2epdY0rCppfFsGjt8UQ741Qhy8=
github.com/ipfs/go-ipfs-config v0.0.0-20190309024316-a0bdc3f74854/go.mod h1:yqJG+KMcBiqX2v2EhxeTi30T0lLGZx6uY3f5B3gD4HI=
github.com/ipfs/go-ipfs-config v0.0.1 h1:6ED08emzI1imdsAjixFi2pEyZxTVD5ECKtCOxLBx+Uc=
github.com/ipfs/go-ipfs-config v0.0.1/go.mod h1:KDbHjNyg4e6LLQSQpkgQMBz6Jf4LXiWAcmnkcwmH0DU=
github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
Expand Down Expand Up @@ -182,6 +186,10 @@ github.com/ipfs/go-mfs v0.0.1 h1:EcQeaxW2DO3LmRXEtbWCGxhZ7YmMR+X7nzjYChBzG8s=
github.com/ipfs/go-mfs v0.0.1/go.mod h1:rUT0dKNWkKa1T+MobpBL2zANn7p8Y6unXANC0PV2FLk=
github.com/ipfs/go-path v0.0.1 h1:6UskTq8xYVs3zVnHjXDvoCqw22dKWK1BwD1cy1cuHyc=
github.com/ipfs/go-path v0.0.1/go.mod h1:ztzG4iSBN2/CJa93rtHAv/I+mpK+BGALeUoJzhclhw0=
github.com/ipfs/go-prompt v0.0.0-20190309021543-60746b51630e h1:rClV9cZC54BQr25YltQRNc3a1GSxiCZSF7jwEWltFVU=
github.com/ipfs/go-prompt v0.0.0-20190309021543-60746b51630e/go.mod h1:9sBllkC9Vc4oYBP/S8iR8IRPbyVSwottiVgKsKA1atE=
github.com/ipfs/go-prompt v0.0.1 h1:yWWyaH5YKSkU9Gejgg8d41wzh5onvckStxK6CuLGSEo=
github.com/ipfs/go-prompt v0.0.1/go.mod h1:9sBllkC9Vc4oYBP/S8iR8IRPbyVSwottiVgKsKA1atE=
github.com/ipfs/go-todocounter v0.0.1 h1:kITWA5ZcQZfrUnDNkRn04Xzh0YFaDFXsoO2A81Eb6Lw=
github.com/ipfs/go-todocounter v0.0.1/go.mod h1:l5aErvQc8qKE2r7NDMjmq5UNAvuZy0rC8BHOplkWvZ4=
github.com/ipfs/go-unixfs v0.0.1 h1:CTTGqLxU5+PRkkeA+w1peStqRWFD1Kya+yZgIT4Xy1w=
Expand Down Expand Up @@ -342,6 +350,8 @@ github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcncea
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.6 h1:SrwhHcpV4nWrMGdNcC2kXpMfcBVYGDuTArqyhocJgvA=
github.com/mattn/go-isatty v0.0.6/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
Expand Down Expand Up @@ -461,6 +471,8 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28DveNzzgmbXR+ENoPjUeIU=
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down
24 changes: 24 additions & 0 deletions plugin/keystore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package plugin

import (
keystore "github.com/ipfs/go-ipfs/keystore"
prompt "github.com/ipfs/go-prompt"
)

// PluginKeystore is an interface that can be implemented to new keystore
// backends.
type PluginKeystore interface {
Plugin

// KeystoreTypeName returns the the keystore's type. In addition to
// loading the keystore plugin, the user must configure their go-ipfs
// node to use the specified keystore backend.
KeystoreTypeName() string

// Open opens the keystore. Prompter may be nil if non-interactive.
Open(
repoPath string,
config map[string]interface{},
prompter prompt.Prompter,
) (keystore.Keystore, error)
}
10 changes: 10 additions & 0 deletions plugin/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ func (loader *PluginLoader) Inject() error {
return err
}
}
if pl, ok := pl.(plugin.PluginKeystore); ok {
err := injectKeystorePlugin(pl)
if err != nil {
return err
}
}
}
return nil
}
Expand Down Expand Up @@ -160,6 +166,10 @@ func injectIPLDPlugin(pl plugin.PluginIPLD) error {
return pl.RegisterInputEncParsers(coredag.DefaultInputEncParsers)
}

func injectKeystorePlugin(pl plugin.PluginKeystore) error {
return fsrepo.AddKeystore(pl.KeystoreTypeName(), pl.Open)
}

func injectTracerPlugin(pl plugin.PluginTracer) error {
tracer, err := pl.InitTracer()
if err != nil {
Expand Down
19 changes: 17 additions & 2 deletions repo/fsrepo/fsrepo.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,23 @@ func (r *FSRepo) openConfig() error {
}

func (r *FSRepo) openKeystore() error {
ksp := filepath.Join(r.path, "keystore")
ks, err := keystore.NewFSKeystore(ksp)
spec := r.config.Keystore
if spec == nil {
spec = map[string]interface{}{"type": "files", "path": "keystore"}
}

ksType, ok := spec["type"]
if !ok {
return fmt.Errorf("keystore config lacks a type")
}

ksCtor, ok := keystores[ksType]
if !ok {
return fmt.Errorf("couldn't find keystore of type %q", ksType)
}

// TODO: feed through a prompter.
ks, err := ksCtor(r.path, spec, nil)
if err != nil {
return err
}
Expand Down
52 changes: 52 additions & 0 deletions repo/fsrepo/keystores.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package fsrepo

import (
"fmt"
"path/filepath"

keystore "github.com/ipfs/go-ipfs/keystore"

prompt "github.com/ipfs/go-prompt"
)

type KeystoreConstructor func(
repoPath string,
cfg map[string]interface{},
prompter prompt.Prompter,
) (keystore.Keystore, error)

var keystores = map[string]KeystoreConstructor{
"memory": MemKeystoreFromConfig,
"files": FSKeystoreFromConfig,
}

func AddKeystore(name string, ctor KeystoreConstructor) error {
_, ok := keystores[name]
if ok {
return fmt.Errorf("keystore %q registered more than once", name)
}
keystores[name] = ctor
return nil
}

func FSKeystoreFromConfig(
repo string,
cfg map[string]interface{},
_ prompt.Prompter,
) (keystore.Keystore, error) {
path, ok := cfg["path"].(string)
if !ok {
return nil, fmt.Errorf("'path' field is missing or not a string")
}
return keystore.NewFSKeystore(filepath.Join(repo, path))
}

// MemKeystoreFromConfig opens an in-memory keystore based on the current
// config.
func MemKeystoreFromConfig(
_ string,
_ map[string]interface{},
_ prompt.Prompter,
) (keystore.Keystore, error) {
return keystore.NewMemKeystore(), nil
}

0 comments on commit 535b467

Please sign in to comment.