Skip to content

Commit

Permalink
Introduce store interface
Browse files Browse the repository at this point in the history
  • Loading branch information
dominikschulz committed Mar 24, 2018
1 parent b72a332 commit 6199a5f
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 50 deletions.
4 changes: 2 additions & 2 deletions pkg/action/sync.go
Expand Up @@ -86,7 +86,7 @@ func (s *Action) syncMount(ctx context.Context, mp string) error {
}

out.Print(ctxno, "\n "+color.GreenString("git pull and push ... "))
if err := sub.GitPush(ctx, "", ""); err != nil {
if err := sub.RCS().Push(ctx, "", ""); err != nil {
if errors.Cause(err) == store.ErrGitNoRemote {
out.Yellow(ctx, "Skipped (no remote)")
out.Debug(ctx, "Failed to push '%s' to it's remote: %s", name, err)
Expand Down Expand Up @@ -132,7 +132,7 @@ func (s *Action) syncMount(ctx context.Context, mp string) error {

// only run second push if we did export any keys
if exported {
if err := sub.GitPush(ctx, "", ""); err != nil {
if err := sub.RCS().Push(ctx, "", ""); err != nil {
out.Red(ctx, "Failed to push '%s' to it's remote: %s", name, err)
return err
}
Expand Down
3 changes: 3 additions & 0 deletions pkg/cui/recipients.go
Expand Up @@ -184,6 +184,9 @@ func AskForPrivateKey(ctx context.Context, crypto backend.Crypto, name, prompt s
if !ctxutil.IsInteractive(ctx) {
return "", errors.New("no interaction without terminal")
}
if crypto == nil {
return "", errors.New("no key selection without valid crypto")
}

kl, err := crypto.ListPrivateKeyIDs(gpg.WithAlwaysTrust(ctx, false))
if err != nil {
Expand Down
10 changes: 5 additions & 5 deletions pkg/store/root/git.go
Expand Up @@ -26,30 +26,30 @@ func (r *Store) GitInit(ctx context.Context, name, userName, userEmail string) e
// GitInitConfig initializes the git repos local config
func (r *Store) GitInitConfig(ctx context.Context, name, userName, userEmail string) error {
ctx, store, _ := r.getStore(ctx, name)
return store.GitInitConfig(ctx, userName, userEmail)
return store.RCS().InitConfig(ctx, userName, userEmail)
}

// GitVersion returns git version information
func (r *Store) GitVersion(ctx context.Context) semver.Version {
return r.store.GitVersion(ctx)
return r.store.RCS().Version(ctx)
}

// GitAddRemote adds a git remote
func (r *Store) GitAddRemote(ctx context.Context, name, remote, url string) error {
ctx, store, _ := r.getStore(ctx, name)
return store.GitAddRemote(ctx, remote, url)
return store.RCS().AddRemote(ctx, remote, url)
}

// GitPull performs a git pull
func (r *Store) GitPull(ctx context.Context, name, origin, remote string) error {
ctx, store, _ := r.getStore(ctx, name)
return store.GitPush(ctx, origin, remote)
return store.RCS().Push(ctx, origin, remote)
}

// GitPush performs a git push
func (r *Store) GitPush(ctx context.Context, name, origin, remote string) error {
ctx, store, _ := r.getStore(ctx, name)
return store.GitPush(ctx, origin, remote)
return store.RCS().Push(ctx, origin, remote)
}

// ListRevisions will list all revisions for the named entity
Expand Down
2 changes: 1 addition & 1 deletion pkg/store/root/gpg.go
Expand Up @@ -9,7 +9,7 @@ import (
// Crypto returns the crypto backend
func (r *Store) Crypto(ctx context.Context, name string) backend.Crypto {
_, sub, _ := r.getStore(ctx, name)
if sub == nil {
if !sub.Valid() {
return nil
}
return sub.Crypto()
Expand Down
6 changes: 3 additions & 3 deletions pkg/store/root/mount.go
Expand Up @@ -29,7 +29,7 @@ func (r *Store) addMount(ctx context.Context, alias, path string, sc *config.Sto
return errors.Errorf("alias must not be empty")
}
if r.mounts == nil {
r.mounts = make(map[string]*sub.Store, 1)
r.mounts = make(map[string]store.Store, 1)
}
if _, found := r.mounts[alias]; found {
return errors.Errorf("%s is already mounted", alias)
Expand Down Expand Up @@ -141,7 +141,7 @@ func (r *Store) MountPoint(name string) string {
// getStore returns the Store object at the most-specific mount point for the
// given key
// context with sub store options set, sub store reference, truncated path to secret
func (r *Store) getStore(ctx context.Context, name string) (context.Context, *sub.Store, string) {
func (r *Store) getStore(ctx context.Context, name string) (context.Context, store.Store, string) {
name = strings.TrimSuffix(name, "/")
mp := r.MountPoint(name)
if sub, found := r.mounts[mp]; found {
Expand All @@ -152,7 +152,7 @@ func (r *Store) getStore(ctx context.Context, name string) (context.Context, *su

// GetSubStore returns an exact match for a mount point or an error if this
// mount point does not exist
func (r *Store) GetSubStore(name string) (*sub.Store, error) {
func (r *Store) GetSubStore(name string) (store.Store, error) {
if name == "" {
return r.store, nil
}
Expand Down
8 changes: 5 additions & 3 deletions pkg/store/root/store.go
Expand Up @@ -8,14 +8,16 @@ import (
"github.com/justwatchcom/gopass/pkg/agent/client"
"github.com/justwatchcom/gopass/pkg/backend"
"github.com/justwatchcom/gopass/pkg/config"
"github.com/justwatchcom/gopass/pkg/store"
"github.com/justwatchcom/gopass/pkg/store/sub"
"github.com/pkg/errors"
)

// Store is the public facing password store
type Store struct {
cfg *config.Config
mounts map[string]*sub.Store
cfg *config.Config
//mounts map[string]*sub.Store
mounts map[string]store.Store
url *backend.URL // url of the root store
store *sub.Store
version string
Expand All @@ -32,7 +34,7 @@ func New(ctx context.Context, cfg *config.Config) (*Store, error) {
}
r := &Store{
cfg: cfg,
mounts: make(map[string]*sub.Store, len(cfg.Mounts)),
mounts: make(map[string]store.Store, len(cfg.Mounts)),
url: cfg.Root.Path,
version: cfg.Version,
}
Expand Down
62 changes: 60 additions & 2 deletions pkg/store/store.go
@@ -1,6 +1,12 @@
package store

import "context"
import (
"context"
"fmt"

"github.com/justwatchcom/gopass/pkg/backend"
"github.com/justwatchcom/gopass/pkg/tree"
)

// RecipientCallback is a callback to verify the list of recipients
type RecipientCallback func(context.Context, string, []string) ([]string, error)
Expand All @@ -13,4 +19,56 @@ type ImportCallback func(context.Context, string, []string) bool
// corrective actions
type FsckCallback func(context.Context, string) bool

// TODO add store interface
// TemplateStore is a store supporting templating operations
type TemplateStore interface {
GetTemplate(context.Context, string) ([]byte, error)
HasTemplate(context.Context, string) bool
ListTemplates(context.Context, string) []string
LookupTemplate(context.Context, string) ([]byte, bool)
RemoveTemplate(context.Context, string) error
SetTemplate(context.Context, string, []byte) error
TemplateTree(context.Context) (tree.Tree, error)
}

// RecipientStore is a store supporting recipient operations
type RecipientStore interface {
AddRecipient(context.Context, string) error
GetRecipients(context.Context, string) ([]string, error)
RemoveRecipient(context.Context, string) error
SaveRecipients(context.Context) error
Recipients(context.Context) []string
ImportMissingPublicKeys(context.Context) error
ExportMissingPublicKeys(context.Context, []string) (bool, error)
}

// Store is secrets store
type Store interface {
fmt.Stringer

TemplateStore
RecipientStore

Fsck(context.Context, string) error
Path() string
URL() string
RCS() backend.RCS
Crypto() backend.Crypto
Storage() backend.Storage
GitInit(context.Context, string, string) error
Alias() string
Copy(context.Context, string, string) error
Delete(context.Context, string) error
Equals(Store) bool
Exists(context.Context, string) bool
Get(context.Context, string) (Secret, error)
GetRevision(context.Context, string, string) (Secret, error)
Init(context.Context, string, ...string) error
Initialized(context.Context) bool
IsDir(context.Context, string) bool
List(context.Context, string) ([]string, error)
ListRevisions(context.Context, string) ([]backend.Revision, error)
Move(context.Context, string, string) error
Set(context.Context, string, Secret) error
Prune(context.Context, string) error
Valid() bool
}
26 changes: 0 additions & 26 deletions pkg/store/sub/git.go
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"fmt"

"github.com/blang/semver"
"github.com/justwatchcom/gopass/pkg/backend"
gitcli "github.com/justwatchcom/gopass/pkg/backend/rcs/git/cli"
"github.com/justwatchcom/gopass/pkg/backend/rcs/git/gogit"
Expand Down Expand Up @@ -45,31 +44,6 @@ func (s *Store) GitInit(ctx context.Context, un, ue string) error {
}
}

// GitInitConfig (re-)intializes the git config in an existing repo
func (s *Store) GitInitConfig(ctx context.Context, un, ue string) error {
return s.rcs.InitConfig(ctx, un, ue)
}

// GitVersion returns the git version
func (s *Store) GitVersion(ctx context.Context) semver.Version {
return s.rcs.Version(ctx)
}

// GitAddRemote adds a new remote
func (s *Store) GitAddRemote(ctx context.Context, remote, url string) error {
return s.rcs.AddRemote(ctx, remote, url)
}

// GitPull performs a git pull
func (s *Store) GitPull(ctx context.Context, origin, branch string) error {
return s.rcs.Pull(ctx, origin, branch)
}

// GitPush performs a git push
func (s *Store) GitPush(ctx context.Context, origin, branch string) error {
return s.rcs.Push(ctx, origin, branch)
}

// ListRevisions will list all revisions for a secret
func (s *Store) ListRevisions(ctx context.Context, name string) ([]backend.Revision, error) {
p := s.passfile(name)
Expand Down
12 changes: 6 additions & 6 deletions pkg/store/sub/git_test.go
Expand Up @@ -26,11 +26,11 @@ func TestGit(t *testing.T) {

assert.NotNil(t, s.RCS())
assert.Equal(t, "noop", s.RCS().Name())
assert.NoError(t, s.GitInitConfig(ctx, "foo", "bar@baz.com"))
assert.Equal(t, semver.Version{}, s.GitVersion(ctx))
assert.NoError(t, s.GitAddRemote(ctx, "foo", "bar"))
assert.NoError(t, s.GitPull(ctx, "origin", "master"))
assert.NoError(t, s.GitPush(ctx, "origin", "master"))
assert.NoError(t, s.RCS().InitConfig(ctx, "foo", "bar@baz.com"))
assert.Equal(t, semver.Version{}, s.RCS().Version(ctx))
assert.NoError(t, s.RCS().AddRemote(ctx, "foo", "bar"))
assert.NoError(t, s.RCS().Pull(ctx, "origin", "master"))
assert.NoError(t, s.RCS().Push(ctx, "origin", "master"))

assert.NoError(t, s.GitInit(ctx, "", ""))
assert.NoError(t, s.GitInit(backend.WithRCSBackend(ctx, backend.Noop), "", ""))
Expand All @@ -55,7 +55,7 @@ func TestGitRevisions(t *testing.T) {

assert.NotNil(t, s.RCS())
assert.Equal(t, "noop", s.RCS().Name())
assert.NoError(t, s.GitInitConfig(ctx, "foo", "bar@baz.com"))
assert.NoError(t, s.RCS().InitConfig(ctx, "foo", "bar@baz.com"))

_, err = s.ListRevisions(ctx, "foo")
assert.Error(t, err)
Expand Down
14 changes: 12 additions & 2 deletions pkg/store/sub/store.go
Expand Up @@ -99,11 +99,11 @@ func (s *Store) idFile(ctx context.Context, name string) string {
}

// Equals returns true if this.storage has the same on-disk path as the other
func (s *Store) Equals(other *Store) bool {
func (s *Store) Equals(other store.Store) bool {
if other == nil {
return false
}
return s.url.String() == other.url.String()
return s.URL() == other.URL()
}

// IsDir returns true if the entry is folder inside the store
Expand Down Expand Up @@ -235,7 +235,17 @@ func (s *Store) Alias() string {
return s.alias
}

// URL returns the store URL
func (s *Store) URL() string {
return s.url.String()
}

// Storage returns the storage backend used by this.storage
func (s *Store) Storage() backend.Storage {
return s.storage
}

// Valid returns true if this store is not nil
func (s *Store) Valid() bool {
return s != nil
}

0 comments on commit 6199a5f

Please sign in to comment.