Add default scoper and sanity check test

Signed-off-by: jolheiser <john.olheiser@gmail.com>
main
jolheiser 2021-11-09 17:03:32 -06:00
parent 7661556e93
commit bbcba946f1
Signed by: jolheiser
GPG Key ID: B853ADA5DA7BBF7A
5 changed files with 52 additions and 12 deletions

2
go.mod
View File

@ -2,4 +2,4 @@ module go.jolheiser.com/spectre
go 1.17 go 1.17
require golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa // indirect require golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa

11
go.sum
View File

@ -1,2 +1,13 @@
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa h1:idItI2DDfCokpg0N51B2VtiLdJ4vAuXC9fnCb2gACo4= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa h1:idItI2DDfCokpg0N51B2VtiLdJ4vAuXC9fnCb2gACo4=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View File

@ -14,13 +14,13 @@ type Scoper interface {
Scope(Scope) string Scope(Scope) string
} }
// SimpleScope is a simple Scoper // SimpleScoper is a simple Scoper
type SimpleScope struct { type SimpleScoper struct {
Key string Key string
} }
// Scope fulfills Scoper // Scope fulfills Scoper
func (s SimpleScope) Scope(scope Scope) string { func (s SimpleScoper) Scope(scope Scope) string {
switch scope { switch scope {
case Identification: case Identification:
return s.Key + ".login" return s.Key + ".login"
@ -32,3 +32,8 @@ func (s SimpleScope) Scope(scope Scope) string {
return s.Key return s.Key
} }
} }
// DefaultScoper is the default Scoper
var DefaultScoper = SimpleScoper{
Key: "com.lyndir.masterpassword",
}

View File

@ -17,16 +17,29 @@ type Spectre struct {
} }
// New returns a Spectre client // New returns a Spectre client
func New(name, secret string, scoper Scoper) (s *Spectre, err error) { func New(name, secret string, opts ...SpectreOption) (s *Spectre, err error) {
s = &Spectre{ s = &Spectre{
name: name, name: name,
secret: secret, secret: secret,
scoper: scoper, scoper: DefaultScoper,
}
for _, opt := range opts {
opt(s)
} }
s.key, err = s.userKey() s.key, err = s.userKey()
return return
} }
// SpectreOption is a Spectre option
type SpectreOption func(*Spectre)
// WithScoper assigns a scoper to Spectre
func WithScoper(scoper Scoper) SpectreOption {
return func(s *Spectre) {
s.scoper = scoper
}
}
func (s *Spectre) userKey() ([]byte, error) { func (s *Spectre) userKey() ([]byte, error) {
nameBytes := []byte(s.name) nameBytes := []byte(s.name)
secretBytes := []byte(s.secret) secretBytes := []byte(s.secret)

View File

@ -4,7 +4,6 @@ import (
_ "embed" _ "embed"
"encoding/xml" "encoding/xml"
"strconv" "strconv"
"strings"
"testing" "testing"
) )
@ -15,16 +14,13 @@ func TestSpectre(t *testing.T) {
t.FailNow() t.FailNow()
} }
scoper := SimpleScope{
Key: "com.lyndir.masterpassword",
}
dc := tests.Cases[0] dc := tests.Cases[0]
for _, tc := range tests.Cases[1:] { for _, tc := range tests.Cases[1:] {
t.Run(tc.ID, func(t *testing.T) { t.Run(tc.ID, func(t *testing.T) {
user := def(dc.UserName, tc.UserName) user := def(dc.UserName, tc.UserName)
secret := def(dc.UserSecret, tc.UserSecret) secret := def(dc.UserSecret, tc.UserSecret)
s, err := New(user, secret, scoper) s, err := New(user, secret)
if err != nil { if err != nil {
t.Logf("could not initialize spectre: %v", err) t.Logf("could not initialize spectre: %v", err)
t.Fail() t.Fail()
@ -46,7 +42,7 @@ func TestSpectre(t *testing.T) {
WithScope(Scope(scope)), WithScope(Scope(scope)),
) )
if !strings.EqualFold(pass, tc.Result) { if pass != tc.Result {
t.Log("passwords did not match") t.Log("passwords did not match")
t.Fail() t.Fail()
} }
@ -54,6 +50,21 @@ func TestSpectre(t *testing.T) {
} }
} }
// From the website sanity check
func TestSanity(t *testing.T) {
s, err := New("Robert Lee Mitchell", "banana colored duckling")
if err != nil {
t.Logf("failed sanity check: %v", err)
t.FailNow()
}
pw := s.Site("masterpasswordapp.com")
if pw != "Jejr5[RepuSosp" {
t.Log("failed sanity check")
t.FailNow()
}
}
//go:embed spectre_tests.xml //go:embed spectre_tests.xml
var testsXML []byte var testsXML []byte