mirror of
https://github.com/gopasspw/gopass.git
synced 2025-12-08 19:24:54 +00:00
356 lines
8.0 KiB
Go
356 lines
8.0 KiB
Go
package tpl
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/gopasspw/gopass/internal/config"
|
|
"github.com/gopasspw/gopass/internal/pwschemes/argon2i"
|
|
"github.com/gopasspw/gopass/internal/pwschemes/argon2id"
|
|
"github.com/gopasspw/gopass/pkg/gopass"
|
|
"github.com/gopasspw/gopass/pkg/gopass/secrets/secparse"
|
|
"github.com/jsimonetti/pwscheme/md5crypt"
|
|
"github.com/jsimonetti/pwscheme/ssha"
|
|
"github.com/jsimonetti/pwscheme/ssha256"
|
|
"github.com/jsimonetti/pwscheme/ssha512"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func Example() { //nolint:testableexamples
|
|
ctx := config.NewContextInMemory()
|
|
tpl := `Password-value of existing entry: {{ getpw "foo" }}
|
|
Password-value of the new entry: {{ .Content }}
|
|
Md5sum of the new password: {{ .Content | md5sum }}
|
|
Sha1sum of the new password: {{ .Content | sha1sum }}
|
|
Blake3 of the new password: {{ .Content | blake3 }}
|
|
Md5crypt of the new password: {{ .Content | md5crypt }}
|
|
SSHA of the new password: {{ .Content | ssha }}
|
|
SSHA256 of the new password: {{ .Content | ssha256 }}
|
|
SSHA512 of the new password: {{ .Content | ssha512 }}
|
|
Argon2i of the new password: {{ .Content | argon2i }}
|
|
Argon2id of the new password: {{ .Content | argon2id }}
|
|
Bcrypt of the new password: {{ .Content | bcrypt }}
|
|
`
|
|
kv := kvMock{}
|
|
|
|
// Arguments: context, template string, name of the secret, generated password, kv store
|
|
buf, err := Execute(ctx, tpl, "example", []byte("bar"), kv)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Println(string(buf))
|
|
}
|
|
|
|
type kvMock struct{}
|
|
|
|
func (k kvMock) Get(ctx context.Context, key string) (gopass.Secret, error) {
|
|
return secparse.Parse([]byte("barfoo\n---\nbarkey: barvalue\n")) //nolint:wrapcheck
|
|
}
|
|
|
|
//nolint:gocognit
|
|
func TestVars(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ctx := config.NewContextInMemory()
|
|
kv := kvMock{}
|
|
|
|
for _, tc := range []struct {
|
|
Template string
|
|
Name string
|
|
Content []byte
|
|
Output string
|
|
OutputFunc func(string) error
|
|
ShouldFail bool
|
|
}{
|
|
{
|
|
Template: "{{.Dir}}",
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
Output: ".",
|
|
},
|
|
{
|
|
Template: "{{.Path}}",
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
Output: "testdir",
|
|
},
|
|
{
|
|
Template: "{{.DirName}}",
|
|
Name: "foo/bar/baz",
|
|
Content: []byte("foobar"),
|
|
Output: "bar",
|
|
},
|
|
{
|
|
Template: "{{.Name}}",
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
Output: "testdir",
|
|
},
|
|
{
|
|
Template: "{{.Content}}",
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
Output: "foobar",
|
|
},
|
|
{
|
|
Template: "{{.Content | md5sum}}",
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
Output: "3858f62230ac3c915f300c664312c63f",
|
|
},
|
|
{
|
|
Template: "{{.Content | sha1sum}}",
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
Output: "8843d7f92416211de9ebb963ff4ce28125932878",
|
|
},
|
|
{
|
|
Template: `{{getpw "testdir"}}`,
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
Output: "barfoo",
|
|
},
|
|
{
|
|
Template: `{{get "testdir"}}`,
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
Output: "barfoo\n---\nbarkey: barvalue\n",
|
|
},
|
|
{
|
|
Template: `{{getpw "testdir"}}`,
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
Output: "barfoo",
|
|
},
|
|
{
|
|
Template: `{{getval "testdir" "barkey"}}`,
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
Output: "barvalue",
|
|
},
|
|
{
|
|
Template: `{{getval "testdir" "barkeyINVALID"}}`,
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
Output: "",
|
|
ShouldFail: true,
|
|
},
|
|
{
|
|
Template: `{{getvals "testdir" "barkey"}}`,
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
Output: "[barvalue]",
|
|
},
|
|
{
|
|
Template: `md5{{(print .Content .Name) | md5sum}}`,
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
Output: "md55d952fb5e2b5c6258b044a663518349f",
|
|
},
|
|
{
|
|
Template: `{{|}}`,
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
Output: "",
|
|
ShouldFail: true,
|
|
},
|
|
{
|
|
Template: "{{.Content | ssha \"12\"}}",
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
OutputFunc: func(s string) error {
|
|
if !strings.HasPrefix(s, "{SSHA}") {
|
|
return fmt.Errorf("wrong prefix")
|
|
}
|
|
|
|
ok, err := ssha.Validate("foobar", s)
|
|
if err != nil {
|
|
return fmt.Errorf("can't validate: %w", err)
|
|
}
|
|
|
|
if !ok {
|
|
return fmt.Errorf("hash mismatch")
|
|
}
|
|
|
|
return nil
|
|
},
|
|
},
|
|
{
|
|
Template: "{{.Content | ssha256 \"12\"}}",
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
OutputFunc: func(s string) error {
|
|
if !strings.HasPrefix(s, "{SSHA256}") {
|
|
return fmt.Errorf("wrong prefix: %s", s)
|
|
}
|
|
|
|
ok, err := ssha256.Validate("foobar", s)
|
|
if err != nil {
|
|
return fmt.Errorf("can't validate: %w", err)
|
|
}
|
|
|
|
if !ok {
|
|
return fmt.Errorf("hash mismatch")
|
|
}
|
|
|
|
return nil
|
|
},
|
|
},
|
|
{
|
|
Template: "{{.Content | ssha512 \"12\"}}",
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
OutputFunc: func(s string) error {
|
|
if !strings.HasPrefix(s, "{SSHA512}") {
|
|
return fmt.Errorf("wrong prefix: %s", s)
|
|
}
|
|
|
|
ok, err := ssha512.Validate("foobar", s)
|
|
if err != nil {
|
|
return fmt.Errorf("can't validate: %w", err)
|
|
}
|
|
|
|
if !ok {
|
|
return fmt.Errorf("hash mismatch")
|
|
}
|
|
|
|
return nil
|
|
},
|
|
},
|
|
{
|
|
Template: "{{.Content | ssha512 \"-12\" \"invalid\"}}",
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
OutputFunc: func(s string) error {
|
|
if !strings.HasPrefix(s, "{SSHA512}") {
|
|
return fmt.Errorf("wrong prefix: %s", s)
|
|
}
|
|
|
|
ok, err := ssha512.Validate("foobar", s)
|
|
if err != nil {
|
|
return fmt.Errorf("can't validate: %w", err)
|
|
}
|
|
|
|
if !ok {
|
|
return fmt.Errorf("hash mismatch")
|
|
}
|
|
|
|
return nil
|
|
},
|
|
},
|
|
{
|
|
Template: "{{.Content | md5crypt \"7\"}}",
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
OutputFunc: func(s string) error {
|
|
if !strings.HasPrefix(s, "{MD5-CRYPT}") {
|
|
return fmt.Errorf("wrong prefix: %s", s)
|
|
}
|
|
|
|
ok, err := md5crypt.Validate("foobar", s)
|
|
if err != nil {
|
|
return fmt.Errorf("can't validate: %w", err)
|
|
}
|
|
|
|
if !ok {
|
|
return fmt.Errorf("hash mismatch")
|
|
}
|
|
|
|
return nil
|
|
},
|
|
},
|
|
{
|
|
Template: "{{.Content | md5crypt \"0\"}}",
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
OutputFunc: func(s string) error {
|
|
if !strings.HasPrefix(s, "{MD5-CRYPT}") {
|
|
return fmt.Errorf("wrong prefix: %s", s)
|
|
}
|
|
|
|
ok, err := md5crypt.Validate("foobar", s)
|
|
if err != nil {
|
|
return fmt.Errorf("can't validate: %w", err)
|
|
}
|
|
|
|
if !ok {
|
|
return fmt.Errorf("hash mismatch")
|
|
}
|
|
|
|
return nil
|
|
},
|
|
},
|
|
{
|
|
Template: "{{.Content | argon2i \"64\"}}",
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
OutputFunc: func(s string) error {
|
|
if !strings.HasPrefix(s, "{ARGON2I}") {
|
|
return fmt.Errorf("wrong prefix: %s", s)
|
|
}
|
|
|
|
ok, err := argon2i.Validate("foobar", s)
|
|
if err != nil {
|
|
return fmt.Errorf("can't validate: %w", err)
|
|
}
|
|
|
|
if !ok {
|
|
return fmt.Errorf("hash mismatch")
|
|
}
|
|
|
|
return nil
|
|
},
|
|
},
|
|
{
|
|
Template: "{{.Content | argon2id \"256\"}}",
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
OutputFunc: func(s string) error {
|
|
if !strings.HasPrefix(s, "{ARGON2ID}") {
|
|
return fmt.Errorf("wrong prefix: %s", s)
|
|
}
|
|
|
|
ok, err := argon2id.Validate("foobar", s)
|
|
if err != nil {
|
|
return fmt.Errorf("can't validate: %w", err)
|
|
}
|
|
|
|
if !ok {
|
|
return fmt.Errorf("hash mismatch")
|
|
}
|
|
|
|
return nil
|
|
},
|
|
},
|
|
{
|
|
Template: "{{ argon2id }}",
|
|
Name: "testdir",
|
|
Content: []byte("foobar"),
|
|
ShouldFail: true,
|
|
},
|
|
} {
|
|
t.Run(tc.Template, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
buf, err := Execute(ctx, tc.Template, tc.Name, tc.Content, kv)
|
|
if tc.ShouldFail {
|
|
require.Error(t, err)
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
if tc.OutputFunc != nil && tc.Output != "" {
|
|
t.Error("must not set output and output func")
|
|
}
|
|
if tc.OutputFunc != nil {
|
|
require.NoError(t, tc.OutputFunc(string(buf)), tc.Template)
|
|
} else {
|
|
assert.Equal(t, tc.Output, string(buf), tc.Template)
|
|
}
|
|
})
|
|
}
|
|
}
|