Skip to content

Commit

Permalink
Implement secrets interface (gopasspw#714)
Browse files Browse the repository at this point in the history
  • Loading branch information
dominikschulz authored Mar 15, 2018
1 parent fe1de47 commit 997e830
Show file tree
Hide file tree
Showing 16 changed files with 53 additions and 27 deletions.
9 changes: 7 additions & 2 deletions action/insert.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"os"

"github.com/justwatchcom/gopass/store"
"github.com/justwatchcom/gopass/store/secret"
"github.com/justwatchcom/gopass/store/sub"
"github.com/justwatchcom/gopass/utils/ctxutil"
Expand Down Expand Up @@ -97,13 +98,15 @@ func (s *Action) insertStdin(ctx context.Context, name string, content []byte) e
}

func (s *Action) insertSingle(ctx context.Context, name, pw string) error {
sec := &secret.Secret{}
var sec store.Secret
if s.Store.Exists(ctx, name) {
var err error
sec, err = s.Store.Get(ctx, name)
if err != nil {
return exitError(ctx, ExitDecrypt, err, "failed to decrypt existing secret: %s", err)
}
} else {
sec = &secret.Secret{}
}
sec.SetPassword(pw)
printAuditResult(ctx, sec.Password())
Expand All @@ -123,13 +126,15 @@ func (s *Action) insertYAML(ctx context.Context, name, key string, content []byt
content = []byte(pw)
}

sec := secret.New("", "")
var sec store.Secret
if s.Store.Exists(ctx, name) {
var err error
sec, err = s.Store.Get(ctx, name)
if err != nil {
return exitError(ctx, ExitEncrypt, err, "failed to set key '%s' of '%s': %s", key, name, err)
}
} else {
sec = &secret.Secret{}
}
if err := sec.SetValue(key, string(content)); err != nil {
return exitError(ctx, ExitEncrypt, err, "failed to set key '%s' of '%s': %s", key, name, err)
Expand Down
4 changes: 2 additions & 2 deletions action/otp.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"time"

"github.com/gokyle/twofactor"
"github.com/justwatchcom/gopass/store/secret"
"github.com/justwatchcom/gopass/store"
"github.com/justwatchcom/gopass/utils/out"
"github.com/urfave/cli"
)
Expand Down Expand Up @@ -69,7 +69,7 @@ func (s *Action) otp(ctx context.Context, name, qrf string, clip bool) error {
return nil
}

func otpData(ctx context.Context, name string, sec *secret.Secret) (twofactor.OTP, string, error) {
func otpData(ctx context.Context, name string, sec store.Secret) (twofactor.OTP, string, error) {
otpURL := ""
// check body
for _, line := range strings.Split(sec.Body(), "\n") {
Expand Down
3 changes: 1 addition & 2 deletions action/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"strings"

"github.com/justwatchcom/gopass/store"
"github.com/justwatchcom/gopass/store/secret"
"github.com/justwatchcom/gopass/utils/ctxutil"
"github.com/justwatchcom/gopass/utils/out"
"github.com/justwatchcom/gopass/utils/qrcon"
Expand Down Expand Up @@ -76,7 +75,7 @@ func (s *Action) showHandleRevision(ctx context.Context, c *cli.Context, name, k
return s.showHandleOutput(ctx, name, key, sec)
}

func (s *Action) showHandleOutput(ctx context.Context, name, key string, sec *secret.Secret) error {
func (s *Action) showHandleOutput(ctx context.Context, name, key string, sec store.Secret) error {
var content string

switch {
Expand Down
4 changes: 2 additions & 2 deletions store/root/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (

"github.com/blang/semver"
"github.com/justwatchcom/gopass/backend"
"github.com/justwatchcom/gopass/store/secret"
"github.com/justwatchcom/gopass/store"
)

// Sync returns the sync backend
Expand Down Expand Up @@ -59,7 +59,7 @@ func (r *Store) ListRevisions(ctx context.Context, name string) ([]backend.Revis
}

// GetRevision will try to retrieve the given revision from the sync backend
func (r *Store) GetRevision(ctx context.Context, name, revision string) (*secret.Secret, error) {
func (r *Store) GetRevision(ctx context.Context, name, revision string) (store.Secret, error) {
ctx, store, name := r.getStore(ctx, name)
return store.GetRevision(ctx, name, revision)
}
6 changes: 3 additions & 3 deletions store/root/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ package root
import (
"context"

"github.com/justwatchcom/gopass/store/secret"
"github.com/justwatchcom/gopass/store"
)

// Get returns the plaintext of a single key
func (r *Store) Get(ctx context.Context, name string) (*secret.Secret, error) {
func (r *Store) Get(ctx context.Context, name string) (store.Secret, error) {
// forward to substore
ctx, store, name := r.getStore(ctx, name)
return store.Get(ctx, name)
}

// GetContext returns the plaintext and the context of a single key
func (r *Store) GetContext(ctx context.Context, name string) (*secret.Secret, context.Context, error) {
func (r *Store) GetContext(ctx context.Context, name string) (store.Secret, context.Context, error) {
// forward to substore
ctx, store, name := r.getStore(ctx, name)
sec, err := store.Get(ctx, name)
Expand Down
6 changes: 3 additions & 3 deletions store/root/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ package root
import (
"context"

"github.com/justwatchcom/gopass/store/secret"
"github.com/justwatchcom/gopass/store"
)

// Set encodes and write the ciphertext of one entry to disk
func (r *Store) Set(ctx context.Context, name string, sec *secret.Secret) error {
func (r *Store) Set(ctx context.Context, name string, sec store.Secret) error {
ctx, store, name := r.getStore(ctx, name)
return store.Set(ctx, name, sec)
}

// SetContext encodes and write the ciphertext of one entry to disk and propagate the context
func (r *Store) SetContext(ctx context.Context, name string, sec *secret.Secret) (context.Context, error) {
func (r *Store) SetContext(ctx context.Context, name string, sec store.Secret) (context.Context, error) {
ctx, store, name := r.getStore(ctx, name)
return ctx, store.Set(ctx, name, sec)
}
16 changes: 16 additions & 0 deletions store/secret.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package store

// Secret is an in-memory secret with a key/value part
type Secret interface {
Body() string
Bytes() ([]byte, error)
Data() map[string]interface{}
DeleteKey(string) error
Equal(Secret) bool
Password() string
SetBody(string) error
SetPassword(string)
SetValue(string, string) error
String() string
Value(string) (string, error)
}
9 changes: 6 additions & 3 deletions store/secret/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package secret
import (
"bytes"
"os"
"reflect"
"strings"
"sync"

"github.com/justwatchcom/gopass/store"
)

var debug bool
Expand Down Expand Up @@ -115,11 +118,11 @@ func (s *Secret) SetBody(b string) error {
}

// Equal returns true if two secrets are equal
func (s *Secret) Equal(other *Secret) bool {
if s == nil && other == nil {
func (s *Secret) Equal(other store.Secret) bool {
if s == nil && (other == nil || reflect.ValueOf(other).IsNil()) {
return true
}
if s == nil || other == nil {
if s == nil || other == nil || reflect.ValueOf(other).IsNil() {
return false
}

Expand Down
2 changes: 1 addition & 1 deletion store/sub/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func (s *Store) ListRevisions(ctx context.Context, name string) ([]backend.Revis
}

// GetRevision will retrieve a single revision from the backend
func (s *Store) GetRevision(ctx context.Context, name, revision string) (*secret.Secret, error) {
func (s *Store) GetRevision(ctx context.Context, name, revision string) (store.Secret, error) {
p := s.passfile(name)
ciphertext, err := s.rcs.GetRevision(ctx, p, revision)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion store/sub/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

// Get returns the plaintext of a single key
func (s *Store) Get(ctx context.Context, name string) (*secret.Secret, error) {
func (s *Store) Get(ctx context.Context, name string) (store.Secret, error) {
p := s.passfile(name)

ciphertext, err := s.storage.Get(ctx, p)
Expand Down
3 changes: 1 addition & 2 deletions store/sub/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import (
"strings"

"github.com/justwatchcom/gopass/store"
"github.com/justwatchcom/gopass/store/secret"
"github.com/justwatchcom/gopass/utils/ctxutil"
"github.com/justwatchcom/gopass/utils/out"
"github.com/pkg/errors"
)

// Set encodes and writes the cipertext of one entry to disk
func (s *Store) Set(ctx context.Context, name string, sec *secret.Secret) error {
func (s *Store) Set(ctx context.Context, name string, sec store.Secret) error {
if strings.Contains(name, "//") {
return errors.Errorf("invalid secret name: %s", name)
}
Expand Down
3 changes: 2 additions & 1 deletion utils/jsonapi/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ import (

"github.com/justwatchcom/gopass/backend"
"github.com/justwatchcom/gopass/config"
"github.com/justwatchcom/gopass/store"
"github.com/justwatchcom/gopass/store/root"
"github.com/justwatchcom/gopass/store/secret"
"github.com/stretchr/testify/assert"
)

type storedSecret struct {
Name []string
Secret *secret.Secret
Secret store.Secret
}

func TestRespondMessageBrokenInput(t *testing.T) {
Expand Down
3 changes: 2 additions & 1 deletion utils/jsonapi/responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"path"

"github.com/justwatchcom/gopass/store"
"github.com/justwatchcom/gopass/store/secret"
"github.com/justwatchcom/gopass/utils/pwgen"
"github.com/pkg/errors"
Expand Down Expand Up @@ -118,7 +119,7 @@ func (api *API) respondGetLogin(ctx context.Context, msgBytes []byte) error {
}, api.Writer)
}

func (api *API) getUsername(name string, sec *secret.Secret) string {
func (api *API) getUsername(name string, sec store.Secret) string {
// look for a meta-data entry containing the username first
for _, key := range []string{"login", "username", "user"} {
value, err := sec.Value(key)
Expand Down
3 changes: 2 additions & 1 deletion utils/jsonapi/responses_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ package jsonapi
import (
"testing"

"github.com/justwatchcom/gopass/store"
"github.com/justwatchcom/gopass/store/secret"
)

func TestGetUsername(t *testing.T) {
a := &API{}
for _, tc := range []struct {
Name string
Sec *secret.Secret
Sec store.Secret
Out string
}{
{
Expand Down
4 changes: 2 additions & 2 deletions utils/tpl/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import (
"path/filepath"
"text/template"

"github.com/justwatchcom/gopass/store/secret"
"github.com/justwatchcom/gopass/store"
)

type kvstore interface {
Get(context.Context, string) (*secret.Secret, error)
Get(context.Context, string) (store.Secret, error)
}

type payload struct {
Expand Down
3 changes: 2 additions & 1 deletion utils/tpl/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import (
"context"
"testing"

"github.com/justwatchcom/gopass/store"
"github.com/justwatchcom/gopass/store/secret"
)

type kvMock struct{}

func (k kvMock) Get(ctx context.Context, key string) (*secret.Secret, error) {
func (k kvMock) Get(ctx context.Context, key string) (store.Secret, error) {
return secret.New("barfoo", "---\nbarkey: barvalue\n"), nil
}

Expand Down

0 comments on commit 997e830

Please sign in to comment.