minor fixes/improvements...
This commit is contained in:
parent
142c0ba74f
commit
56ba974dec
@ -3,6 +3,7 @@ https://developer-old.gnome.org/libsecret/unstable/
|
|||||||
https://developer-old.gnome.org/libsecret/0.18/
|
https://developer-old.gnome.org/libsecret/0.18/
|
||||||
https://people.gnome.org/~stefw/libsecret-docs/index.html
|
https://people.gnome.org/~stefw/libsecret-docs/index.html
|
||||||
|
|
||||||
|
https://freedesktop.org/wiki/Specifications/secret-storage-spec/secrets-api-0.1.html#eggdbus-interface-org.freedesktop.Secrets.Collection
|
||||||
|
|
||||||
Quick reference URLs:
|
Quick reference URLs:
|
||||||
|
|
||||||
|
@ -41,6 +41,66 @@ func NewCollection(service *Service, path dbus.ObjectPath) (coll *Collection, er
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateItem returns a pointer to an Item based on a label, some attributes, a Secret, and whether any existing secret with the same label should be replaced or not.
|
||||||
|
func (c *Collection) CreateItem(label string, attrs map[string]string, secret *Secret, replace bool) (item *Item, err error) {
|
||||||
|
|
||||||
|
var prompt *Prompt
|
||||||
|
var path dbus.ObjectPath
|
||||||
|
var promptPath dbus.ObjectPath
|
||||||
|
var variant *dbus.Variant
|
||||||
|
var props map[string]dbus.Variant = make(map[string]dbus.Variant)
|
||||||
|
|
||||||
|
props[DbusItemLabel] = dbus.MakeVariant(label)
|
||||||
|
props[DbusItemAttributes] = dbus.MakeVariant(attrs)
|
||||||
|
|
||||||
|
if err = c.Dbus.Call(
|
||||||
|
DbusCollectionCreateItem, 0, props, secret, replace,
|
||||||
|
).Store(&path, &promptPath); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if isPrompt(promptPath) {
|
||||||
|
prompt = NewPrompt(c.Conn, promptPath)
|
||||||
|
|
||||||
|
if variant, err = prompt.Prompt(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
path = variant.Value().(dbus.ObjectPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
item, err = NewItem(c, path)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Delete removes a Collection.
|
||||||
|
While *technically* not necessary, it is recommended that you iterate through
|
||||||
|
Collection.Items and do an Item.Delete for each item *before* calling Collection.Delete;
|
||||||
|
the item paths are cached as "orphaned paths" in Dbus otherwise if not deleted before deleting
|
||||||
|
their Collection. They should clear on a reboot or restart of Dbus (but rebooting Dbus on a system in use is... troublesome).
|
||||||
|
*/
|
||||||
|
func (c *Collection) Delete() (err error) {
|
||||||
|
|
||||||
|
var promptPath dbus.ObjectPath
|
||||||
|
var prompt *Prompt
|
||||||
|
|
||||||
|
if err = c.Dbus.Call(DbusCollectionDelete, 0).Store(&promptPath); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if isPrompt(promptPath) {
|
||||||
|
|
||||||
|
prompt = NewPrompt(c.Conn, promptPath)
|
||||||
|
if _, err = prompt.Prompt(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Items returns a slice of Item pointers in the Collection.
|
// Items returns a slice of Item pointers in the Collection.
|
||||||
func (c *Collection) Items() (items []*Item, err error) {
|
func (c *Collection) Items() (items []*Item, err error) {
|
||||||
|
|
||||||
@ -70,22 +130,46 @@ func (c *Collection) Items() (items []*Item, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete removes a Collection.
|
// Label returns the Collection label (name).
|
||||||
func (c *Collection) Delete() (err error) {
|
func (c *Collection) Label() (label string, err error) {
|
||||||
|
|
||||||
var promptPath dbus.ObjectPath
|
var variant dbus.Variant
|
||||||
var prompt *Prompt
|
|
||||||
|
|
||||||
if err = c.Dbus.Call(DbusCollectionDelete, 0).Store(&promptPath); err != nil {
|
if variant, err = c.Dbus.GetProperty(DbusCollectionLabel); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if isPrompt(promptPath) {
|
label = variant.Value().(string)
|
||||||
|
|
||||||
prompt = NewPrompt(c.Conn, promptPath)
|
if label != c.name {
|
||||||
if _, err = prompt.Prompt(); err != nil {
|
c.name = label
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Locked indicates if a Collection is locked (true) or unlocked (false).
|
||||||
|
func (c *Collection) Locked() (isLocked bool, err error) {
|
||||||
|
|
||||||
|
var variant dbus.Variant
|
||||||
|
|
||||||
|
if variant, err = c.Dbus.GetProperty(DbusCollectionLocked); err != nil {
|
||||||
|
isLocked = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isLocked = variant.Value().(bool)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Relabel modifies the Collection's label in Dbus.
|
||||||
|
func (c *Collection) Relabel(newLabel string) (err error) {
|
||||||
|
|
||||||
|
var variant dbus.Variant = dbus.MakeVariant(newLabel)
|
||||||
|
|
||||||
|
if err = c.Dbus.SetProperty(DbusCollectionLabel, variant); err != nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
@ -124,84 +208,6 @@ func (c *Collection) SearchItems(profile string) (items []*Item, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateItem returns a pointer to an Item based on a label, some attributes, a Secret, and whether any existing secret with the same label should be replaced or not.
|
|
||||||
func (c *Collection) CreateItem(label string, attrs map[string]string, secret *Secret, replace bool) (item *Item, err error) {
|
|
||||||
|
|
||||||
var prompt *Prompt
|
|
||||||
var path dbus.ObjectPath
|
|
||||||
var promptPath dbus.ObjectPath
|
|
||||||
var variant *dbus.Variant
|
|
||||||
var props map[string]dbus.Variant = make(map[string]dbus.Variant)
|
|
||||||
|
|
||||||
props[DbusItemLabel] = dbus.MakeVariant(label)
|
|
||||||
props[DbusItemAttributes] = dbus.MakeVariant(attrs)
|
|
||||||
|
|
||||||
if err = c.Dbus.Call(
|
|
||||||
DbusCollectionCreateItem, 0, props, secret, replace,
|
|
||||||
).Store(&path, &promptPath); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if isPrompt(promptPath) {
|
|
||||||
prompt = NewPrompt(c.Conn, promptPath)
|
|
||||||
|
|
||||||
if variant, err = prompt.Prompt(); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
path = variant.Value().(dbus.ObjectPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
item, err = NewItem(c, path)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Locked indicates if a Collection is locked (true) or unlocked (false).
|
|
||||||
func (c *Collection) Locked() (isLocked bool, err error) {
|
|
||||||
|
|
||||||
var variant dbus.Variant
|
|
||||||
|
|
||||||
if variant, err = c.Dbus.GetProperty(DbusCollectionLocked); err != nil {
|
|
||||||
isLocked = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
isLocked = variant.Value().(bool)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Label returns the Collection label (name).
|
|
||||||
func (c *Collection) Label() (label string, err error) {
|
|
||||||
|
|
||||||
var variant dbus.Variant
|
|
||||||
|
|
||||||
if variant, err = c.Dbus.GetProperty(DbusCollectionLabel); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
label = variant.Value().(string)
|
|
||||||
|
|
||||||
if label != c.name {
|
|
||||||
c.name = label
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Relabel modifies the Collection's label in Dbus.
|
|
||||||
func (c *Collection) Relabel(newLabel string) (err error) {
|
|
||||||
|
|
||||||
var variant dbus.Variant = dbus.MakeVariant(newLabel)
|
|
||||||
|
|
||||||
if err = c.Dbus.SetProperty(DbusItemLabel, variant); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Created returns the time.Time of when a Collection was created.
|
// Created returns the time.Time of when a Collection was created.
|
||||||
func (c *Collection) Created() (created time.Time, err error) {
|
func (c *Collection) Created() (created time.Time, err error) {
|
||||||
|
|
||||||
@ -251,3 +257,14 @@ func (c *Collection) Modified() (modified time.Time, isChanged bool, err error)
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
setModify updates the Collection's modification time (as specified by Collection.Modified).
|
||||||
|
It seems that this does not update automatically.
|
||||||
|
*/
|
||||||
|
func (c *Collection) setModify() (err error) {
|
||||||
|
|
||||||
|
err = c.Dbus.SetProperty(DbusCollectionModified, uint64(time.Now().Unix()))
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
158
collection_funcs_test.go
Normal file
158
collection_funcs_test.go
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
package gosecret
|
||||||
|
|
||||||
|
import (
|
||||||
|
`testing`
|
||||||
|
|
||||||
|
`github.com/godbus/dbus/v5`
|
||||||
|
)
|
||||||
|
|
||||||
|
// Some functions are covered in the Service tests.
|
||||||
|
|
||||||
|
/*
|
||||||
|
TestNewCollection tests the following internal functions/methods via nested calls:
|
||||||
|
|
||||||
|
(all calls in TestNewService)
|
||||||
|
NewService
|
||||||
|
NewCollection
|
||||||
|
|
||||||
|
*/
|
||||||
|
func TestNewCollection(t *testing.T) {
|
||||||
|
|
||||||
|
var svc *Service
|
||||||
|
var collection *Collection
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if svc, err = NewService(); err != nil {
|
||||||
|
t.Fatalf("NewService failed: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if collection, err = NewCollection(svc, dbus.ObjectPath(dbusDefaultCollectionPath)); err != nil {
|
||||||
|
t.Errorf(
|
||||||
|
"TestNewCollection failed when fetching collection at '%v': %v",
|
||||||
|
dbusDefaultCollectionPath, err.Error(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
_ = collection
|
||||||
|
|
||||||
|
if err = svc.Close(); err != nil {
|
||||||
|
t.Errorf("could not close Service.Session: %v", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TestCollection_Label tests the following internal functions/methods via nested calls:
|
||||||
|
(all calls in TestNewCollection)
|
||||||
|
Service.GetCollection
|
||||||
|
Collection.Label
|
||||||
|
|
||||||
|
*/
|
||||||
|
func TestCollection_Label(t *testing.T) {
|
||||||
|
|
||||||
|
var svc *Service
|
||||||
|
var collection *Collection
|
||||||
|
var collLabel string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if svc, err = NewService(); err != nil {
|
||||||
|
t.Fatalf("NewService failed: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if collection, err = svc.GetCollection(defaultCollectionLabel); err != nil {
|
||||||
|
t.Errorf(
|
||||||
|
"failed when fetching collection '%v': %v",
|
||||||
|
defaultCollectionLabel, err.Error(),
|
||||||
|
)
|
||||||
|
err = nil
|
||||||
|
if err = svc.Close(); err != nil {
|
||||||
|
t.Errorf("could not close Service.Session: %v", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if collLabel, err = collection.Label(); err != nil {
|
||||||
|
t.Errorf("cannot fetch label for '%v': %v", string(collection.Dbus.Path()), err.Error())
|
||||||
|
if err = svc.Close(); err != nil {
|
||||||
|
t.Fatalf("could not close Service.Session: %v", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if defaultCollection != collLabel {
|
||||||
|
t.Errorf("fetched collection ('%v') does not match fetched collection label ('%v')", collLabel, defaultCollection)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = svc.Close(); err != nil {
|
||||||
|
t.Errorf("could not close Service.Session: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TestCollection_Items tests the following internal functions/methods via nested calls:
|
||||||
|
|
||||||
|
(all calls in TestNewCollection)
|
||||||
|
Service.GetCollection
|
||||||
|
Collection.Items
|
||||||
|
NewSecret
|
||||||
|
Collection.CreateItem
|
||||||
|
Collection.SearchItems
|
||||||
|
Item.Delete
|
||||||
|
|
||||||
|
*/
|
||||||
|
func TestCollection_Items(t *testing.T) {
|
||||||
|
|
||||||
|
var svc *Service
|
||||||
|
var collection *Collection
|
||||||
|
var items []*Item
|
||||||
|
var item *Item
|
||||||
|
var searchItemResults []*Item
|
||||||
|
var secret *Secret
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if svc, err = NewService(); err != nil {
|
||||||
|
t.Fatalf("NewService failed: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if collection, err = svc.GetCollection(defaultCollection); err != nil {
|
||||||
|
if err = svc.Close(); err != nil {
|
||||||
|
t.Errorf("could not close Service.Session: %v", err.Error())
|
||||||
|
}
|
||||||
|
t.Fatalf("failed when fetching collection '%v': %v",
|
||||||
|
defaultCollection, err.Error(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if items, err = collection.Items(); err != nil {
|
||||||
|
t.Errorf(
|
||||||
|
"failed fetching items for '%v' at '%v': %v",
|
||||||
|
defaultCollection, string(collection.Dbus.Path()), err.Error(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
t.Logf("found %v items in collection '%v' at '%v'", len(items), defaultCollection, string(collection.Dbus.Path()))
|
||||||
|
}
|
||||||
|
|
||||||
|
secret = NewSecret(svc.Session, []byte{}, []byte(testSecretContent), "text/plain")
|
||||||
|
|
||||||
|
if item, err = collection.CreateItem(testItemLabel, itemAttrs, secret, false); err != nil {
|
||||||
|
t.Errorf(
|
||||||
|
"could not create item '%v' in collection '%v': %v",
|
||||||
|
testItemLabel, defaultCollection, err.Error(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if searchItemResults, err = collection.SearchItems(testItemLabel); err != nil {
|
||||||
|
t.Errorf("failed to find item '%v' via Collection.SearchItems: %v", string(item.Dbus.Path()), err.Error())
|
||||||
|
} else if len(searchItemResults) == 0 {
|
||||||
|
t.Errorf("failed to find item '%v' via Collection.SearchItems, returned 0 results (should be at least 1)", testItemLabel)
|
||||||
|
} else {
|
||||||
|
t.Logf("found %v results for Collection.SearchItems", len(searchItemResults))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = item.Delete(); err != nil {
|
||||||
|
t.Errorf("failed to delete created item '%v': %v", string(item.Dbus.Path()), err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = svc.Close(); err != nil {
|
||||||
|
t.Errorf("could not close Service.Session: %v", err.Error())
|
||||||
|
}
|
||||||
|
}
|
@ -6,19 +6,27 @@ import (
|
|||||||
|
|
||||||
// Paths.
|
// Paths.
|
||||||
const (
|
const (
|
||||||
DbusDefaultCollectionPath string = DbusPath + "/collections/login"
|
dbusCollectionPath string = DbusPath + "/collection"
|
||||||
|
dbusDefaultCollectionPath string = dbusCollectionPath + "/login"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Strings.
|
// Strings.
|
||||||
const (
|
const (
|
||||||
defaultCollection string = "default" // SHOULD point to a collection named "login"; "default" is the alias.
|
defaultCollectionAlias string = "default" // SHOULD point to a collection named "login" (below); "default" is the alias.
|
||||||
|
defaultCollection string = "login"
|
||||||
|
defaultCollectionLabel string = "Login" // a display name; the label is lowercased and normalized for the path (per above).
|
||||||
testAlias string = "GOSECRET_TESTING_ALIAS"
|
testAlias string = "GOSECRET_TESTING_ALIAS"
|
||||||
testSecretContent string = "This is a test secret for gosecret."
|
testSecretContent string = "This is a test secret for gosecret."
|
||||||
testItemLabel string = "gosecret_test_item"
|
testItemLabel string = "Gosecret Test Item"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Objects.
|
// Objects.
|
||||||
var (
|
var (
|
||||||
collectionName uuid.UUID = uuid.New()
|
collectionName uuid.UUID = uuid.New()
|
||||||
collectionAlias uuid.UUID = uuid.New()
|
collectionAlias uuid.UUID = uuid.New()
|
||||||
|
itemAttrs map[string]string = map[string]string{
|
||||||
|
"GOSECRET": "yes",
|
||||||
|
"foo": "bar",
|
||||||
|
"profile": testItemLabel,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
@ -124,7 +124,9 @@ func (s *Service) CreateCollection(label string) (collection *Collection, err er
|
|||||||
*/
|
*/
|
||||||
func (s *Service) GetCollection(name string) (c *Collection, err error) {
|
func (s *Service) GetCollection(name string) (c *Collection, err error) {
|
||||||
|
|
||||||
|
var errs []error
|
||||||
var colls []*Collection
|
var colls []*Collection
|
||||||
|
var collLabel string
|
||||||
|
|
||||||
// First check for an alias.
|
// First check for an alias.
|
||||||
if c, err = s.ReadAlias(name); err != nil && err != ErrDoesNotExist {
|
if c, err = s.ReadAlias(name); err != nil && err != ErrDoesNotExist {
|
||||||
@ -147,8 +149,26 @@ func (s *Service) GetCollection(name string) (c *Collection, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Still nothing? Try by label.
|
||||||
|
for _, i := range colls {
|
||||||
|
if collLabel, err = i.Label(); err != nil {
|
||||||
|
errs = append(errs, err)
|
||||||
|
err = nil
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if collLabel == name {
|
||||||
|
c = i
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Couldn't find it by the given name.
|
// Couldn't find it by the given name.
|
||||||
|
if errs != nil || len(errs) > 0 {
|
||||||
|
errs = append([]error{ErrDoesNotExist}, errs...)
|
||||||
|
err = NewErrors(errs...)
|
||||||
|
} else {
|
||||||
err = ErrDoesNotExist
|
err = ErrDoesNotExist
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package gosecret
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
`time`
|
||||||
|
|
||||||
`github.com/godbus/dbus/v5`
|
`github.com/godbus/dbus/v5`
|
||||||
)
|
)
|
||||||
@ -43,12 +44,16 @@ func TestNewService(t *testing.T) {
|
|||||||
NewCollection
|
NewCollection
|
||||||
Collection.Modified
|
Collection.Modified
|
||||||
NewErrors
|
NewErrors
|
||||||
|
Collection.Created
|
||||||
*/
|
*/
|
||||||
func TestService_Collections(t *testing.T) {
|
func TestService_Collections(t *testing.T) {
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var svc *Service
|
var svc *Service
|
||||||
var colls []*Collection
|
var colls []*Collection
|
||||||
|
var collLabel string
|
||||||
|
var created time.Time
|
||||||
|
var modified time.Time
|
||||||
|
|
||||||
if svc, err = NewService(); err != nil {
|
if svc, err = NewService(); err != nil {
|
||||||
t.Fatalf("could not get new Service via NewService: %v", err.Error())
|
t.Fatalf("could not get new Service via NewService: %v", err.Error())
|
||||||
@ -59,6 +64,30 @@ func TestService_Collections(t *testing.T) {
|
|||||||
} else {
|
} else {
|
||||||
t.Logf("found %v collections via Service.Collections", len(colls))
|
t.Logf("found %v collections via Service.Collections", len(colls))
|
||||||
}
|
}
|
||||||
|
for idx, c := range colls {
|
||||||
|
if collLabel, err = c.Label(); err != nil {
|
||||||
|
t.Errorf(
|
||||||
|
"failed to get label for collection '%v': %v",
|
||||||
|
string(c.Dbus.Path()), err.Error(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if created, err = c.Created(); err != nil {
|
||||||
|
t.Errorf(
|
||||||
|
"failed to get created time for collection '%v': %v",
|
||||||
|
string(c.Dbus.Path()), err.Error(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if modified, _, err = c.Modified(); err != nil {
|
||||||
|
t.Errorf(
|
||||||
|
"failed to get modified time for collection '%v': %v",
|
||||||
|
string(c.Dbus.Path()), err.Error(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
t.Logf(
|
||||||
|
"collection #%v (name '%v', label '%v'): created %v, last modified %v",
|
||||||
|
idx, c.name, collLabel, created, modified,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if err = svc.Close(); err != nil {
|
if err = svc.Close(); err != nil {
|
||||||
t.Errorf("could not close Service.Session: %v", err.Error())
|
t.Errorf("could not close Service.Session: %v", err.Error())
|
||||||
@ -79,7 +108,7 @@ func TestService_Collections(t *testing.T) {
|
|||||||
(By extension, Service.CreateCollection is also tested as it's a very thin wrapper
|
(By extension, Service.CreateCollection is also tested as it's a very thin wrapper
|
||||||
around Service.CreateAliasedCollection).
|
around Service.CreateAliasedCollection).
|
||||||
*/
|
*/
|
||||||
/* DISABLED. Currently, *only* the alias "default" is allowed. TODO: revisit in future?
|
/* DISABLED. Currently (as of 0.20.4), *only* the alias "default" is allowed. TODO: revisit in future?
|
||||||
func TestService_CreateAliasedCollection(t *testing.T) {
|
func TestService_CreateAliasedCollection(t *testing.T) {
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
@ -121,12 +150,18 @@ func TestService_CreateAliasedCollection(t *testing.T) {
|
|||||||
TestService_GetCollection tests the following internal functions/methods via nested calls:
|
TestService_GetCollection tests the following internal functions/methods via nested calls:
|
||||||
|
|
||||||
(all calls in TestService_CreateAliasedCollection)
|
(all calls in TestService_CreateAliasedCollection)
|
||||||
Service.GetCollection
|
|
||||||
(all calls in TestService_Collections)
|
(all calls in TestService_Collections)
|
||||||
|
|
||||||
|
|
||||||
|
NewErrors
|
||||||
|
Collection.Created
|
||||||
|
Service.GetCollection
|
||||||
|
NewCollection
|
||||||
|
Collection.Modified
|
||||||
Service.ReadAlias
|
Service.ReadAlias
|
||||||
|
|
||||||
The default collection (login) is fetched instead of creating one as this collection should exist,
|
The default collection (login) is fetched instead of creating one as this collection should exist,
|
||||||
and tests fetching existing collections instead of newly-created ones.
|
and thus this function tests fetching existing collections instead of newly-created ones.
|
||||||
*/
|
*/
|
||||||
func TestService_GetCollection(t *testing.T) {
|
func TestService_GetCollection(t *testing.T) {
|
||||||
|
|
||||||
@ -162,6 +197,7 @@ func TestService_GetCollection(t *testing.T) {
|
|||||||
NewSecret
|
NewSecret
|
||||||
Collection.CreateItem
|
Collection.CreateItem
|
||||||
Item.Label
|
Item.Label
|
||||||
|
Item.Delete
|
||||||
|
|
||||||
*/
|
*/
|
||||||
func TestService_Secrets(t *testing.T) {
|
func TestService_Secrets(t *testing.T) {
|
||||||
@ -177,30 +213,49 @@ func TestService_Secrets(t *testing.T) {
|
|||||||
var testSecret *Secret
|
var testSecret *Secret
|
||||||
var secretsResult map[dbus.ObjectPath]*Secret
|
var secretsResult map[dbus.ObjectPath]*Secret
|
||||||
var itemPaths []dbus.ObjectPath
|
var itemPaths []dbus.ObjectPath
|
||||||
var itemAttrs map[string]string = map[string]string{
|
var created time.Time
|
||||||
"GOSECRET": "yes",
|
var modified time.Time
|
||||||
}
|
var newModified time.Time
|
||||||
|
var wasModified bool
|
||||||
|
var isModified bool
|
||||||
|
|
||||||
if svc, err = NewService(); err != nil {
|
if svc, err = NewService(); err != nil {
|
||||||
t.Fatalf("could not get new Service via NewService: %v", err.Error())
|
t.Fatalf("could not get new Service via NewService: %v", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if collection, err = svc.CreateCollection(collectionName.String()); err != nil {
|
if collection, err = svc.CreateCollection(collectionName.String()); err != nil {
|
||||||
|
t.Errorf("could not create collection '%v': %v", collectionName.String(), err.Error())
|
||||||
if err = svc.Close(); err != nil {
|
if err = svc.Close(); err != nil {
|
||||||
t.Errorf("could not close Service.Session: %v", err.Error())
|
t.Fatalf("could not close Service.Session: %v", err.Error())
|
||||||
}
|
}
|
||||||
t.Fatalf("could not create collection '%v': %v", collectionName.String(), err.Error())
|
|
||||||
} else {
|
} else {
|
||||||
t.Logf("created collection '%v' at path '%v' successfully", collectionName.String(), string(collection.Dbus.Path()))
|
t.Logf("created collection '%v' at path '%v' successfully", collectionName.String(), string(collection.Dbus.Path()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if created, err = collection.Created(); err != nil {
|
||||||
|
t.Errorf(
|
||||||
|
"failed to get created time for '%v': %v",
|
||||||
|
collectionName.String(), err.Error(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if modified, wasModified, err = collection.Modified(); err != nil {
|
||||||
|
t.Errorf(
|
||||||
|
"failed to get modified time for '%v': %v",
|
||||||
|
collectionName.String(), err.Error(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
t.Logf(
|
||||||
|
"%v: collection '%v': created at %v, last modified at %v; was changed: %v",
|
||||||
|
time.Now(), collectionName.String(), created, modified, wasModified,
|
||||||
|
)
|
||||||
|
|
||||||
// Create a secret
|
// Create a secret
|
||||||
testSecret = NewSecret(svc.Session, nil, []byte(testSecretContent), "text/plain")
|
testSecret = NewSecret(svc.Session, nil, []byte(testSecretContent), "text/plain")
|
||||||
if testItem, err = collection.CreateItem(testItemLabel, itemAttrs, testSecret, true); err != nil {
|
if testItem, err = collection.CreateItem(testItemLabel, itemAttrs, testSecret, true); err != nil {
|
||||||
|
t.Errorf("could not create Item in collection '%v': %v", collectionName.String(), err.Error())
|
||||||
if err = svc.Close(); err != nil {
|
if err = svc.Close(); err != nil {
|
||||||
t.Errorf("could not close Service.Session: %v", err.Error())
|
t.Fatalf("could not close Service.Session: %v", err.Error())
|
||||||
}
|
}
|
||||||
t.Fatalf("could not create Item in collection '%v': %v", collectionName.String(), err.Error())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if itemName, err = testItem.Label(); err != nil {
|
if itemName, err = testItem.Label(); err != nil {
|
||||||
@ -241,7 +296,46 @@ func TestService_Secrets(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the collection to clean up.
|
// Confirm the modification information changed.
|
||||||
|
_ = newModified
|
||||||
|
_ = isModified
|
||||||
|
/* TODO: Disabled for now; it *seems* the collection modification time doesn't auto-update? See collection.setModify if not.
|
||||||
|
if newModified, isModified, err = collection.Modified(); err != nil {
|
||||||
|
t.Errorf(
|
||||||
|
"failed to get modified time for '%v': %v",
|
||||||
|
collectionName.String(), err.Error(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
t.Logf(
|
||||||
|
"%v: (post-change) collection '%v': last modified at %v; was changed: %v",
|
||||||
|
time.Now(), collectionName.String(), newModified, isModified,
|
||||||
|
)
|
||||||
|
if !isModified {
|
||||||
|
t.Errorf(
|
||||||
|
"modification tracking for collection '%v' failed; expected true but got false",
|
||||||
|
collectionName.String(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
t.Logf("(modification check passed)")
|
||||||
|
}
|
||||||
|
if !newModified.After(modified) {
|
||||||
|
t.Errorf(
|
||||||
|
"modification timestamp update for '%v' failed: old %v, new %v",
|
||||||
|
collectionName.String(), modified, newModified,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Delete the item and collection to clean up.
|
||||||
|
*Technically* the item is deleted if the collection is, but its path is held in memory if not
|
||||||
|
manually removed, leading to a "ghost" item.
|
||||||
|
*/
|
||||||
|
if err = testItem.Delete(); err != nil {
|
||||||
|
t.Errorf("could not delete test item '%v' in collection '%v': %v",
|
||||||
|
string(testItem.Dbus.Path()), collectionName.String(), err.Error(),
|
||||||
|
)
|
||||||
|
}
|
||||||
if err = collection.Delete(); err != nil {
|
if err = collection.Delete(); err != nil {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"error when deleting collection '%v' when testing Service: %v",
|
"error when deleting collection '%v' when testing Service: %v",
|
||||||
@ -254,8 +348,6 @@ func TestService_Secrets(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// service.Lock & service.Unlock
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TestService_Locking tests the following internal functions/methods via nested calls:
|
TestService_Locking tests the following internal functions/methods via nested calls:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user