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

Introduce store interface #722

Merged
merged 1 commit into from
Mar 24, 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
4 changes: 2 additions & 2 deletions pkg/action/sync.go
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
}