2021-12-07 02:56:15 -05:00
|
|
|
package gosecret
|
|
|
|
|
|
|
|
import (
|
2021-12-08 02:34:27 -05:00
|
|
|
"testing"
|
2021-12-12 02:29:29 -05:00
|
|
|
`time`
|
2021-12-08 02:34:27 -05:00
|
|
|
|
2021-12-10 02:50:30 -05:00
|
|
|
`github.com/godbus/dbus/v5`
|
2021-12-07 02:56:15 -05:00
|
|
|
)
|
|
|
|
|
2021-12-08 02:34:27 -05:00
|
|
|
/*
|
|
|
|
TestNewService tests the following internal functions/methods via nested calls:
|
|
|
|
|
|
|
|
NewService
|
|
|
|
Service.GetSession
|
|
|
|
Service.OpenSession
|
|
|
|
NewSession
|
|
|
|
validConnPath
|
|
|
|
connIsValid
|
|
|
|
pathIsValid
|
|
|
|
Service.Close
|
|
|
|
Session.Close
|
|
|
|
|
|
|
|
*/
|
2021-12-07 02:56:15 -05:00
|
|
|
func TestNewService(t *testing.T) {
|
|
|
|
|
|
|
|
var err error
|
2021-12-08 02:34:27 -05:00
|
|
|
var svc *Service
|
|
|
|
|
|
|
|
if svc, err = NewService(); err != nil {
|
|
|
|
t.Fatalf("could not get new Service via NewService: %v", err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = svc.Close(); err != nil {
|
|
|
|
t.Errorf("could not close Service.Session: %v", err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
TestService_Collections tests the following internal functions/methods via nested calls:
|
|
|
|
|
|
|
|
(all calls in TestNewService)
|
|
|
|
Service.Collections
|
|
|
|
NewCollection
|
|
|
|
Collection.Modified
|
|
|
|
NewErrors
|
2021-12-12 02:29:29 -05:00
|
|
|
Collection.Created
|
2021-12-08 02:34:27 -05:00
|
|
|
*/
|
|
|
|
func TestService_Collections(t *testing.T) {
|
|
|
|
|
|
|
|
var err error
|
|
|
|
var svc *Service
|
|
|
|
var colls []*Collection
|
2021-12-12 02:29:29 -05:00
|
|
|
var collLabel string
|
|
|
|
var created time.Time
|
|
|
|
var modified time.Time
|
2021-12-08 02:34:27 -05:00
|
|
|
|
|
|
|
if svc, err = NewService(); err != nil {
|
|
|
|
t.Fatalf("could not get new Service via NewService: %v", err.Error())
|
|
|
|
}
|
|
|
|
|
2021-12-10 02:50:30 -05:00
|
|
|
if colls, err = svc.Collections(); err != nil {
|
2021-12-08 02:34:27 -05:00
|
|
|
t.Errorf("could not get Service.Collections: %v", err.Error())
|
|
|
|
} else {
|
|
|
|
t.Logf("found %v collections via Service.Collections", len(colls))
|
|
|
|
}
|
2021-12-12 02:29:29 -05:00
|
|
|
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",
|
2021-12-12 03:23:51 -05:00
|
|
|
idx, c.PathName(), collLabel, created, modified,
|
2021-12-12 02:29:29 -05:00
|
|
|
)
|
|
|
|
}
|
2021-12-08 02:34:27 -05:00
|
|
|
|
|
|
|
if err = svc.Close(); err != nil {
|
|
|
|
t.Errorf("could not close Service.Session: %v", err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
TestService_CreateAliasedCollection tests the following internal functions/methods via nested calls:
|
|
|
|
|
|
|
|
(all calls in TestNewService)
|
|
|
|
Service.CreateAliasedCollection
|
|
|
|
NewCollection
|
|
|
|
Collection.Modified
|
|
|
|
Collection.Delete
|
|
|
|
Service.SetAlias
|
|
|
|
|
|
|
|
(By extension, Service.CreateCollection is also tested as it's a very thin wrapper
|
|
|
|
around Service.CreateAliasedCollection).
|
|
|
|
*/
|
2021-12-12 02:29:29 -05:00
|
|
|
/* DISABLED. Currently (as of 0.20.4), *only* the alias "default" is allowed. TODO: revisit in future?
|
2021-12-08 02:34:27 -05:00
|
|
|
func TestService_CreateAliasedCollection(t *testing.T) {
|
|
|
|
|
|
|
|
var err error
|
|
|
|
var svc *Service
|
|
|
|
var collection *Collection
|
2021-12-07 02:56:15 -05:00
|
|
|
|
2021-12-08 02:34:27 -05:00
|
|
|
if svc, err = NewService(); err != nil {
|
2021-12-07 02:56:15 -05:00
|
|
|
t.Fatalf("could not get new Service via NewService: %v", err.Error())
|
|
|
|
}
|
|
|
|
|
2021-12-08 02:34:27 -05:00
|
|
|
if collection, err = svc.CreateAliasedCollection(collectionName.String(), collectionAlias.String()); err != nil {
|
|
|
|
t.Errorf(
|
|
|
|
"error when creating aliased collection '%v' with alias '%v': %v",
|
|
|
|
collectionName.String(), collectionAlias.String(), err.Error(),
|
|
|
|
)
|
|
|
|
} else {
|
2021-12-10 02:50:30 -05:00
|
|
|
if err = svc.SetAlias(testAlias, collection.Dbus.Path()); err != nil {
|
|
|
|
t.Errorf(
|
|
|
|
"error when setting an alias '%v' for aliased collection '%v' (original alias '%v')",
|
|
|
|
testAlias, collectionName.String(), collectionAlias.String(),
|
|
|
|
)
|
|
|
|
}
|
2021-12-08 02:34:27 -05:00
|
|
|
if err = collection.Delete(); err != nil {
|
|
|
|
t.Errorf(
|
|
|
|
"error when deleting aliased collection '%v' with alias '%v': %v",
|
|
|
|
collectionName.String(), collectionAlias.String(), err.Error(),
|
|
|
|
)
|
|
|
|
}
|
2021-12-10 03:47:10 -05:00
|
|
|
t.Logf("created collection '%v' at path '%v' successfully", collectionName.String(), string(collection.Dbus.Path()))
|
2021-12-08 02:34:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if err = svc.Close(); err != nil {
|
|
|
|
t.Errorf("could not close Service.Session: %v", err.Error())
|
|
|
|
}
|
|
|
|
}
|
2021-12-10 02:50:30 -05:00
|
|
|
*/
|
2021-12-08 02:34:27 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
TestService_GetCollection tests the following internal functions/methods via nested calls:
|
|
|
|
|
|
|
|
(all calls in TestService_CreateAliasedCollection)
|
2021-12-12 02:29:29 -05:00
|
|
|
(all calls in TestService_Collections)
|
|
|
|
|
|
|
|
|
|
|
|
NewErrors
|
|
|
|
Collection.Created
|
2021-12-08 02:34:27 -05:00
|
|
|
Service.GetCollection
|
2021-12-12 02:29:29 -05:00
|
|
|
NewCollection
|
|
|
|
Collection.Modified
|
2021-12-08 02:34:27 -05:00
|
|
|
Service.ReadAlias
|
|
|
|
|
2021-12-10 02:50:30 -05:00
|
|
|
The default collection (login) is fetched instead of creating one as this collection should exist,
|
2021-12-12 02:29:29 -05:00
|
|
|
and thus this function tests fetching existing collections instead of newly-created ones.
|
2021-12-08 02:34:27 -05:00
|
|
|
*/
|
|
|
|
func TestService_GetCollection(t *testing.T) {
|
|
|
|
|
|
|
|
var err error
|
|
|
|
var svc *Service
|
|
|
|
var coll *Collection
|
|
|
|
|
|
|
|
if svc, err = NewService(); err != nil {
|
|
|
|
t.Fatalf("could not get new Service via NewService: %v", err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
if coll, err = svc.GetCollection(defaultCollection); err != nil {
|
|
|
|
t.Errorf("failed to get collection '%v' via Service.GetCollection: %v", defaultCollection, err.Error())
|
|
|
|
} else {
|
|
|
|
t.Logf("got collection '%v' via reference '%v'", coll.name, defaultCollection)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = svc.Close(); err != nil {
|
|
|
|
t.Errorf("could not close Service.Session: %v", err.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
TestService_Secrets tests the following internal functions/methods via nested calls:
|
|
|
|
|
|
|
|
(all calls in TestNewService)
|
|
|
|
(all calls in TestService_CreateAliasedCollection)
|
|
|
|
Service.CreateCollection
|
|
|
|
Service.SearchItems
|
2021-12-10 02:50:30 -05:00
|
|
|
NewItem
|
|
|
|
NewErrors
|
2021-12-08 02:34:27 -05:00
|
|
|
Service.GetSecrets
|
2021-12-10 02:50:30 -05:00
|
|
|
NewSecret
|
|
|
|
Collection.CreateItem
|
|
|
|
Item.Label
|
2021-12-12 02:29:29 -05:00
|
|
|
Item.Delete
|
2021-12-08 02:34:27 -05:00
|
|
|
|
|
|
|
*/
|
|
|
|
func TestService_Secrets(t *testing.T) {
|
|
|
|
|
|
|
|
var err error
|
|
|
|
var svc *Service
|
|
|
|
var collection *Collection
|
2021-12-10 02:50:30 -05:00
|
|
|
var itemResultsUnlocked []*Item
|
|
|
|
var itemResultsLocked []*Item
|
|
|
|
var itemName string
|
|
|
|
var resultItemName string
|
|
|
|
var testItem *Item
|
|
|
|
var testSecret *Secret
|
|
|
|
var secretsResult map[dbus.ObjectPath]*Secret
|
2021-12-08 02:34:27 -05:00
|
|
|
var itemPaths []dbus.ObjectPath
|
2021-12-12 02:29:29 -05:00
|
|
|
var created time.Time
|
|
|
|
var modified time.Time
|
|
|
|
var newModified time.Time
|
|
|
|
var wasModified bool
|
|
|
|
var isModified bool
|
2021-12-08 02:34:27 -05:00
|
|
|
|
|
|
|
if svc, err = NewService(); err != nil {
|
|
|
|
t.Fatalf("could not get new Service via NewService: %v", err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
if collection, err = svc.CreateCollection(collectionName.String()); err != nil {
|
2021-12-12 02:29:29 -05:00
|
|
|
t.Errorf("could not create collection '%v': %v", collectionName.String(), err.Error())
|
2021-12-10 02:50:30 -05:00
|
|
|
if err = svc.Close(); err != nil {
|
2021-12-12 02:29:29 -05:00
|
|
|
t.Fatalf("could not close Service.Session: %v", err.Error())
|
2021-12-10 02:50:30 -05:00
|
|
|
}
|
2021-12-10 03:47:10 -05:00
|
|
|
} else {
|
|
|
|
t.Logf("created collection '%v' at path '%v' successfully", collectionName.String(), string(collection.Dbus.Path()))
|
2021-12-10 02:50:30 -05:00
|
|
|
}
|
|
|
|
|
2021-12-12 02:29:29 -05:00
|
|
|
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,
|
|
|
|
)
|
|
|
|
|
2021-12-10 02:50:30 -05:00
|
|
|
// Create a secret
|
|
|
|
testSecret = NewSecret(svc.Session, nil, []byte(testSecretContent), "text/plain")
|
|
|
|
if testItem, err = collection.CreateItem(testItemLabel, itemAttrs, testSecret, true); err != nil {
|
2021-12-12 02:29:29 -05:00
|
|
|
t.Errorf("could not create Item in collection '%v': %v", collectionName.String(), err.Error())
|
2021-12-10 02:50:30 -05:00
|
|
|
if err = svc.Close(); err != nil {
|
2021-12-12 02:29:29 -05:00
|
|
|
t.Fatalf("could not close Service.Session: %v", err.Error())
|
2021-12-10 02:50:30 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if itemName, err = testItem.Label(); err != nil {
|
|
|
|
t.Errorf(
|
|
|
|
"could not get label for newly-created item '%v' in collection '%v': %v",
|
|
|
|
string(testItem.Dbus.Path()), collectionName.String(), err.Error(),
|
|
|
|
)
|
|
|
|
itemName = testItemLabel
|
|
|
|
}
|
|
|
|
|
|
|
|
// Search items
|
|
|
|
if itemResultsUnlocked, itemResultsLocked, err = svc.SearchItems(itemAttrs); err != nil {
|
|
|
|
t.Errorf("did not find Item '%v' in collection '%v' SearchItems: %v", itemName, collectionName.String(), err.Error())
|
|
|
|
} else {
|
|
|
|
if len(itemResultsLocked) != 0 && itemResultsUnlocked != nil {
|
|
|
|
t.Errorf("at least one locked item in collection '%v'", collectionName.String())
|
|
|
|
}
|
|
|
|
if len(itemResultsUnlocked) != 1 {
|
|
|
|
t.Errorf("number of unlocked items in collection '%v' is not equal to 1", collectionName.String())
|
|
|
|
}
|
|
|
|
if resultItemName, err = itemResultsUnlocked[0].Label(); err != nil {
|
|
|
|
t.Errorf("cannot fetch test Item name from collection '%v' in SearchItems: %v", collectionName.String(), err.Error())
|
|
|
|
} else {
|
|
|
|
if resultItemName != itemName {
|
|
|
|
t.Errorf("seem to have fetched an improper Item from collection '%v' in SearchItems", collectionName.String())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fetch secrets
|
|
|
|
itemPaths = make([]dbus.ObjectPath, len(itemResultsUnlocked))
|
|
|
|
if len(itemResultsUnlocked) >= 1 {
|
|
|
|
itemPaths[0] = itemResultsUnlocked[0].Dbus.Path()
|
|
|
|
if secretsResult, err = svc.GetSecrets(itemPaths...); err != nil {
|
|
|
|
t.Errorf("failed to fetch Item path '%v' via Service.GetSecrets: %v", string(itemPaths[0]), err.Error())
|
|
|
|
} else if len(secretsResult) != 1 {
|
|
|
|
t.Errorf("received %v secrets from Service.GetSecrets instead of 1", len(secretsResult))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-12 02:29:29 -05:00
|
|
|
// 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(),
|
|
|
|
)
|
|
|
|
}
|
2021-12-10 02:50:30 -05:00
|
|
|
if err = collection.Delete(); err != nil {
|
|
|
|
t.Errorf(
|
|
|
|
"error when deleting collection '%v' when testing Service: %v",
|
|
|
|
collectionName.String(), err.Error(),
|
|
|
|
)
|
2021-12-08 02:34:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if err = svc.Close(); err != nil {
|
|
|
|
t.Errorf("could not close Service.Session: %v", err.Error())
|
|
|
|
}
|
2021-12-07 02:56:15 -05:00
|
|
|
}
|
2021-12-08 02:34:27 -05:00
|
|
|
|
2021-12-10 02:50:30 -05:00
|
|
|
/*
|
|
|
|
TestService_Locking tests the following internal functions/methods via nested calls:
|
|
|
|
|
|
|
|
(all calls in TestNewService)
|
|
|
|
(all calls in TestService_CreateAliasedCollection)
|
|
|
|
Service.Lock
|
|
|
|
Service.Unlock
|
|
|
|
Collection.Locked
|
|
|
|
|
|
|
|
*/
|
|
|
|
func TestService_Locking(t *testing.T) {
|
|
|
|
|
|
|
|
var err error
|
|
|
|
var isLocked bool
|
|
|
|
var stateChangeLock bool
|
|
|
|
var svc *Service
|
|
|
|
var collection *Collection
|
|
|
|
|
|
|
|
if svc, err = NewService(); err != nil {
|
|
|
|
t.Fatalf("could not get new Service via NewService: %v", err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
if collection, err = svc.CreateCollection(collectionName.String()); err != nil {
|
|
|
|
if err = svc.Close(); err != nil {
|
|
|
|
t.Errorf("could not close Service.Session: %v", err.Error())
|
|
|
|
}
|
|
|
|
t.Errorf("could not create collection '%v': %v", collectionName.String(), err.Error())
|
2021-12-10 03:47:10 -05:00
|
|
|
} else {
|
|
|
|
t.Logf("created collection '%v' at path '%v' successfully", collectionName.String(), string(collection.Dbus.Path()))
|
2021-12-10 02:50:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if isLocked, err = collection.Locked(); err != nil {
|
|
|
|
t.Errorf("received error when checking collection '%v' lock status: %v", collectionName.String(), err.Error())
|
|
|
|
if err = collection.Delete(); err != nil {
|
|
|
|
t.Errorf(
|
|
|
|
"error when deleting collection '%v' when testing Service: %v",
|
|
|
|
collectionName.String(), err.Error(),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
if err = svc.Close(); err != nil {
|
|
|
|
t.Errorf("could not close Service.Session: %v", err.Error())
|
|
|
|
}
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
t.Logf("collection '%v' original lock status: %v", collectionName.String(), isLocked)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change the state.
|
|
|
|
if isLocked {
|
|
|
|
if err = svc.Unlock(collection.Dbus.Path()); err != nil {
|
|
|
|
t.Errorf("could not unlock collection '%v': %v", collectionName.String(), err.Error())
|
|
|
|
}
|
|
|
|
if stateChangeLock, err = collection.Locked(); err != nil {
|
|
|
|
t.Errorf("received error when checking collection '%v' lock status: %v", collectionName.String(), err.Error())
|
|
|
|
}
|
|
|
|
if err = svc.Lock(collection.Dbus.Path()); err != nil {
|
|
|
|
t.Errorf("could not lock collection '%v': %v", collectionName.String(), err.Error())
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if err = svc.Lock(collection.Dbus.Path()); err != nil {
|
|
|
|
t.Errorf("could not lock collection '%v': %v", collectionName.String(), err.Error())
|
|
|
|
}
|
|
|
|
if stateChangeLock, err = collection.Locked(); err != nil {
|
|
|
|
t.Errorf("received error when checking collection '%v' lock status: %v", collectionName.String(), err.Error())
|
|
|
|
}
|
|
|
|
if err = svc.Unlock(collection.Dbus.Path()); err != nil {
|
|
|
|
t.Errorf("could not unlock collection '%v': %v", collectionName.String(), err.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if stateChangeLock != !isLocked {
|
|
|
|
t.Errorf(
|
|
|
|
"flipped lock state for collection '%v' (locked: %v) is not opposite of original lock state (locked: %v)",
|
|
|
|
collectionName.String(), stateChangeLock, isLocked,
|
|
|
|
)
|
|
|
|
}
|
2021-12-10 03:47:10 -05:00
|
|
|
|
|
|
|
// Delete the collection to clean up.
|
|
|
|
if err = collection.Delete(); err != nil {
|
|
|
|
t.Errorf(
|
|
|
|
"error when deleting collection '%v' when testing Service: %v",
|
|
|
|
collectionName.String(), err.Error(),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = svc.Close(); err != nil {
|
|
|
|
t.Errorf("could not close Service.Session: %v", err.Error())
|
|
|
|
}
|
2021-12-10 02:50:30 -05:00
|
|
|
}
|