Compare commits
No commits in common. "master" and "v1.1.4" have entirely different histories.
@ -224,8 +224,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
Note that many functions/methods may return a https://pkg.go.dev/r00t2.io/goutils/multierr#MultiError[`(r00t2.io/goutils/)multierr.MultiError`^], which you may attempt to typeswitch to receive the original errors in their native error format. The functions/methods which may return a MultiError are noted as such in their individual documentation.
|
|
||||||
|
|
||||||
== Library Hacking
|
== Library Hacking
|
||||||
|
|
||||||
=== Reference
|
=== Reference
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/godbus/dbus/v5"
|
"github.com/godbus/dbus/v5"
|
||||||
"r00t2.io/goutils/multierr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -81,9 +80,7 @@ func (c *Collection) CreateItem(label string, attrs map[string]string, secret *S
|
|||||||
}
|
}
|
||||||
|
|
||||||
props[DbusItemLabel] = dbus.MakeVariant(label)
|
props[DbusItemLabel] = dbus.MakeVariant(label)
|
||||||
if !c.service.Legacy {
|
|
||||||
props[DbusItemType] = dbus.MakeVariant(typeString)
|
props[DbusItemType] = dbus.MakeVariant(typeString)
|
||||||
}
|
|
||||||
props[DbusItemAttributes] = dbus.MakeVariant(attrs)
|
props[DbusItemAttributes] = dbus.MakeVariant(attrs)
|
||||||
props[DbusItemCreated] = dbus.MakeVariant(uint64(time.Now().Unix()))
|
props[DbusItemCreated] = dbus.MakeVariant(uint64(time.Now().Unix()))
|
||||||
// props[DbusItemModified] = dbus.MakeVariant(uint64(time.Now().Unix()))
|
// props[DbusItemModified] = dbus.MakeVariant(uint64(time.Now().Unix()))
|
||||||
@ -147,16 +144,13 @@ func (c *Collection) Delete() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Items returns a slice of Item pointers in the Collection.
|
||||||
Items returns a slice of Item pointers in the Collection.
|
|
||||||
err MAY be a *multierr.MultiError.
|
|
||||||
*/
|
|
||||||
func (c *Collection) Items() (items []*Item, err error) {
|
func (c *Collection) Items() (items []*Item, err error) {
|
||||||
|
|
||||||
var paths []dbus.ObjectPath
|
var paths []dbus.ObjectPath
|
||||||
var item *Item
|
var item *Item
|
||||||
var variant dbus.Variant
|
var variant dbus.Variant
|
||||||
var errs *multierr.MultiError = multierr.NewMultiError()
|
var errs []error = make([]error, 0)
|
||||||
|
|
||||||
if variant, err = c.Dbus.GetProperty(DbusCollectionItems); err != nil {
|
if variant, err = c.Dbus.GetProperty(DbusCollectionItems); err != nil {
|
||||||
return
|
return
|
||||||
@ -169,16 +163,13 @@ func (c *Collection) Items() (items []*Item, err error) {
|
|||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
item = nil
|
item = nil
|
||||||
if item, err = NewItem(c, path); err != nil {
|
if item, err = NewItem(c, path); err != nil {
|
||||||
errs.AddError(err)
|
errs = append(errs, err)
|
||||||
err = nil
|
err = nil
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
items = append(items, item)
|
items = append(items, item)
|
||||||
}
|
}
|
||||||
|
err = NewErrors(err)
|
||||||
if !errs.IsEmpty() {
|
|
||||||
err = errs
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -255,20 +246,18 @@ func (c *Collection) Relabel(newLabel string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SearchItems searches a Collection for a matching "profile" string.
|
SearchItems searches a Collection for a matching profile string.
|
||||||
It's mostly a carry-over from go-libsecret, and is here for convenience. IT MAY BE REMOVED IN THE FUTURE.
|
It's mostly a carry-over from go-libsecret, and is here for convenience. IT MAY BE REMOVED IN THE FUTURE.
|
||||||
|
|
||||||
I promise it's not useful for any other implementation/storage of SecretService whatsoever.
|
I promise it's not useful for any other implementation/storage of SecretService whatsoever.
|
||||||
|
|
||||||
err MAY be a *multierr.MultiError.
|
|
||||||
|
|
||||||
Deprecated: Use Service.SearchItems instead.
|
Deprecated: Use Service.SearchItems instead.
|
||||||
*/
|
*/
|
||||||
func (c *Collection) SearchItems(profile string) (items []*Item, err error) {
|
func (c *Collection) SearchItems(profile string) (items []*Item, err error) {
|
||||||
|
|
||||||
var call *dbus.Call
|
var call *dbus.Call
|
||||||
var paths []dbus.ObjectPath
|
var paths []dbus.ObjectPath
|
||||||
var errs *multierr.MultiError = multierr.NewMultiError()
|
var errs []error = make([]error, 0)
|
||||||
var attrs map[string]string = make(map[string]string, 0)
|
var attrs map[string]string = make(map[string]string, 0)
|
||||||
var item *Item
|
var item *Item
|
||||||
|
|
||||||
@ -289,16 +278,13 @@ func (c *Collection) SearchItems(profile string) (items []*Item, err error) {
|
|||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
item = nil
|
item = nil
|
||||||
if item, err = NewItem(c, path); err != nil {
|
if item, err = NewItem(c, path); err != nil {
|
||||||
errs.AddError(err)
|
errs = append(errs, err)
|
||||||
err = nil
|
err = nil
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
items = append(items, item)
|
items = append(items, item)
|
||||||
}
|
}
|
||||||
|
err = NewErrors(err)
|
||||||
if !errs.IsEmpty() {
|
|
||||||
err = errs
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
4
doc.go
4
doc.go
@ -84,9 +84,5 @@ Usage
|
|||||||
|
|
||||||
Full documentation can be found via inline documentation.
|
Full documentation can be found via inline documentation.
|
||||||
Additionally, use either https://pkg.go.dev/r00t2.io/gosecret or https://pkg.go.dev/golang.org/x/tools/cmd/godoc (or `go doc`) in the source root.
|
Additionally, use either https://pkg.go.dev/r00t2.io/gosecret or https://pkg.go.dev/golang.org/x/tools/cmd/godoc (or `go doc`) in the source root.
|
||||||
|
|
||||||
Note that many functions/methods may return a (r00t2.io/goutils/)multierr.MultiError (https://pkg.go.dev/r00t2.io/goutils/multierr#MultiError),
|
|
||||||
which you may attempt to typeswitch back to a *multierr.MultiErr to receive the original errors in their native error format (MultiError.Errors).
|
|
||||||
The functions/methods which may return a MultiError are noted as such in their individual documentation.
|
|
||||||
*/
|
*/
|
||||||
package gosecret
|
package gosecret
|
||||||
|
74
funcs.go
74
funcs.go
@ -4,7 +4,6 @@ import (
|
|||||||
`strings`
|
`strings`
|
||||||
|
|
||||||
`github.com/godbus/dbus/v5`
|
`github.com/godbus/dbus/v5`
|
||||||
`r00t2.io/goutils/multierr`
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// isPrompt returns a boolean that is true if path is/requires a prompt(ed path) and false if it is/does not.
|
// isPrompt returns a boolean that is true if path is/requires a prompt(ed path) and false if it is/does not.
|
||||||
@ -64,27 +63,19 @@ func pathIsValid(path interface{}) (ok bool, err error) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
validConnPath condenses the checks for connIsValid and pathIsValid into one func due to how frequently this check is done.
|
validConnPath condenses the checks for connIsValid and pathIsValid into one func due to how frequently this check is done.
|
||||||
|
err is a MultiError, which can be treated as an error.error. (See https://pkg.go.dev/builtin#error)
|
||||||
If err is not nil, it IS a *multierr.MultiError.
|
|
||||||
*/
|
*/
|
||||||
func validConnPath(conn *dbus.Conn, path interface{}) (cr *ConnPathCheckResult, err error) {
|
func validConnPath(conn *dbus.Conn, path interface{}) (cr *ConnPathCheckResult, err error) {
|
||||||
|
|
||||||
var errs *multierr.MultiError = multierr.NewMultiError()
|
var connErr error
|
||||||
|
var pathErr error
|
||||||
|
|
||||||
cr = new(ConnPathCheckResult)
|
cr = new(ConnPathCheckResult)
|
||||||
|
|
||||||
if cr.ConnOK, err = connIsValid(conn); err != nil {
|
cr.ConnOK, connErr = connIsValid(conn)
|
||||||
errs.AddError(err)
|
cr.PathOK, pathErr = pathIsValid(path)
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
if cr.PathOK, err = pathIsValid(path); err != nil {
|
|
||||||
errs.AddError(err)
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if !errs.IsEmpty() {
|
err = NewErrors(connErr, pathErr)
|
||||||
err = errs
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -153,56 +144,3 @@ func NameFromPath(path dbus.ObjectPath) (name string, err error) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
CheckErrIsFromLegacy takes an error.Error from e.g.:
|
|
||||||
|
|
||||||
Service.SearchItems
|
|
||||||
Collection.CreateItem
|
|
||||||
NewItem
|
|
||||||
Item.ChangeItemType
|
|
||||||
Item.Type
|
|
||||||
|
|
||||||
and (in order) attempt to typeswitch to a *multierr.MultiError, then iterate through
|
|
||||||
the *multierr.MultiError.Errors, attempt to typeswitch each of them to a Dbus.Error, and then finally
|
|
||||||
check if it is regarding a missing Type property.
|
|
||||||
|
|
||||||
This is *very explicitly* only useful for the above functions/methods. If used anywhere else,
|
|
||||||
it's liable to return an incorrect isLegacy even if parsed == true.
|
|
||||||
|
|
||||||
It is admittedly convoluted and obtuse, but this saves a lot of boilerplate for users.
|
|
||||||
It wouldn't be necessary if projects didn't insist on using the legacy draft SecretService specification.
|
|
||||||
But here we are.
|
|
||||||
|
|
||||||
isLegacy is true if this Service's API destination is legacy spec. Note that this is checking for
|
|
||||||
very explicit conditions; isLegacy may return false but it is in fact running on a legacy API.
|
|
||||||
Don't rely on this too much.
|
|
||||||
|
|
||||||
parsed is true if we found an error type we were able to perform logic of determination on.
|
|
||||||
*/
|
|
||||||
func CheckErrIsFromLegacy(err error) (isLegacy, parsed bool) {
|
|
||||||
|
|
||||||
switch e := err.(type) {
|
|
||||||
case *multierr.MultiError:
|
|
||||||
parsed = true
|
|
||||||
for _, i := range e.Errors {
|
|
||||||
switch e2 := i.(type) {
|
|
||||||
case dbus.Error:
|
|
||||||
if e2.Name == "org.freedesktop.DBus.Error.UnknownProperty" {
|
|
||||||
isLegacy = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case dbus.Error:
|
|
||||||
parsed = true
|
|
||||||
if e.Name == "org.freedesktop.DBus.Error.UnknownProperty" {
|
|
||||||
isLegacy = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
1
go.mod
1
go.mod
@ -5,5 +5,4 @@ go 1.17
|
|||||||
require (
|
require (
|
||||||
github.com/godbus/dbus/v5 v5.0.6
|
github.com/godbus/dbus/v5 v5.0.6
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
r00t2.io/goutils v1.1.2
|
|
||||||
)
|
)
|
||||||
|
5
go.sum
5
go.sum
@ -1,9 +1,4 @@
|
|||||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
|
||||||
github.com/godbus/dbus/v5 v5.0.6 h1:mkgN1ofwASrYnJ5W6U/BxG15eXXXjirgZc7CLqkcaro=
|
github.com/godbus/dbus/v5 v5.0.6 h1:mkgN1ofwASrYnJ5W6U/BxG15eXXXjirgZc7CLqkcaro=
|
||||||
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
r00t2.io/goutils v1.1.2 h1:zOOqNHQ/HpJVggV5NTXBcd7FQtBP2C/sMLkHw3YvBzU=
|
|
||||||
r00t2.io/goutils v1.1.2/go.mod h1:9ObJI9S71wDLTOahwoOPs19DhZVYrOh4LEHmQ8SW4Lk=
|
|
||||||
r00t2.io/sysutils v1.1.1/go.mod h1:Wlfi1rrJpoKBOjWiYM9rw2FaiZqraD6VpXyiHgoDo/o=
|
|
||||||
|
@ -85,11 +85,6 @@ func (i *Item) ChangeItemType(newItemType string) (err error) {
|
|||||||
|
|
||||||
var variant dbus.Variant
|
var variant dbus.Variant
|
||||||
|
|
||||||
// Legacy spec.
|
|
||||||
if i.collection.service.Legacy {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.TrimSpace(newItemType) == "" {
|
if strings.TrimSpace(newItemType) == "" {
|
||||||
newItemType = DbusDefaultItemType
|
newItemType = DbusDefaultItemType
|
||||||
}
|
}
|
||||||
@ -287,11 +282,6 @@ func (i *Item) Type() (itemType string, err error) {
|
|||||||
|
|
||||||
var variant dbus.Variant
|
var variant dbus.Variant
|
||||||
|
|
||||||
// Legacy spec.
|
|
||||||
if i.collection.service.Legacy {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if variant, err = i.Dbus.GetProperty(DbusItemType); err != nil {
|
if variant, err = i.Dbus.GetProperty(DbusItemType); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
58
multierr_funcs.go
Normal file
58
multierr_funcs.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package gosecret
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
NewErrors returns a new MultiError based on a slice of error.Error (errs).
|
||||||
|
Any nil errors are trimmed. If there are no actual errors after trimming, err will be nil.
|
||||||
|
*/
|
||||||
|
func NewErrors(errs ...error) (err error) {
|
||||||
|
|
||||||
|
if errs == nil || len(errs) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var realErrs []error = make([]error, 0)
|
||||||
|
|
||||||
|
for _, e := range errs {
|
||||||
|
if e == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
realErrs = append(realErrs, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(realErrs) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = &MultiError{
|
||||||
|
Errors: realErrs,
|
||||||
|
ErrorSep: "\n",
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error makes a MultiError conform to the error interface.
|
||||||
|
func (e *MultiError) Error() (errStr string) {
|
||||||
|
|
||||||
|
var numErrs int
|
||||||
|
|
||||||
|
if e == nil || len(e.Errors) == 0 {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
numErrs = len(e.Errors)
|
||||||
|
}
|
||||||
|
|
||||||
|
for idx, err := range e.Errors {
|
||||||
|
if (idx + 1) < numErrs {
|
||||||
|
errStr += fmt.Sprintf("%v%v", err.Error(), e.ErrorSep)
|
||||||
|
} else {
|
||||||
|
errStr += err.Error()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
@ -8,7 +8,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/godbus/dbus/v5"
|
"github.com/godbus/dbus/v5"
|
||||||
`r00t2.io/goutils/multierr`
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewService returns a pointer to a new Service connection.
|
// NewService returns a pointer to a new Service connection.
|
||||||
@ -50,17 +49,13 @@ func (s *Service) Close() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Collections returns a slice of Collection items accessible to this Service.
|
||||||
Collections returns a slice of Collection items accessible to this Service.
|
|
||||||
|
|
||||||
err MAY be a *multierr.MultiError.
|
|
||||||
*/
|
|
||||||
func (s *Service) Collections() (collections []*Collection, err error) {
|
func (s *Service) Collections() (collections []*Collection, err error) {
|
||||||
|
|
||||||
var paths []dbus.ObjectPath
|
var paths []dbus.ObjectPath
|
||||||
var variant dbus.Variant
|
var variant dbus.Variant
|
||||||
var coll *Collection
|
var coll *Collection
|
||||||
var errs *multierr.MultiError = multierr.NewMultiError()
|
var errs []error = make([]error, 0)
|
||||||
|
|
||||||
if variant, err = s.Dbus.GetProperty(DbusServiceCollections); err != nil {
|
if variant, err = s.Dbus.GetProperty(DbusServiceCollections); err != nil {
|
||||||
return
|
return
|
||||||
@ -73,16 +68,14 @@ func (s *Service) Collections() (collections []*Collection, err error) {
|
|||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
coll = nil
|
coll = nil
|
||||||
if coll, err = NewCollection(s, path); err != nil {
|
if coll, err = NewCollection(s, path); err != nil {
|
||||||
errs.AddError(err)
|
// return
|
||||||
|
errs = append(errs, err)
|
||||||
err = nil
|
err = nil
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
collections = append(collections, coll)
|
collections = append(collections, coll)
|
||||||
}
|
}
|
||||||
|
err = NewErrors(err)
|
||||||
if !errs.IsEmpty() {
|
|
||||||
err = errs
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -143,12 +136,10 @@ func (s *Service) CreateCollection(label string) (collection *Collection, err er
|
|||||||
/*
|
/*
|
||||||
GetCollection returns a single Collection based on the name (name can also be an alias).
|
GetCollection returns a single Collection based on the name (name can also be an alias).
|
||||||
It's a helper function that avoids needing to make multiple calls in user code.
|
It's a helper function that avoids needing to make multiple calls in user code.
|
||||||
|
|
||||||
err MAY be a *multierr.MultiError.
|
|
||||||
*/
|
*/
|
||||||
func (s *Service) GetCollection(name string) (c *Collection, err error) {
|
func (s *Service) GetCollection(name string) (c *Collection, err error) {
|
||||||
|
|
||||||
var errs *multierr.MultiError = multierr.NewMultiError()
|
var errs []error = make([]error, 0)
|
||||||
var colls []*Collection
|
var colls []*Collection
|
||||||
var pathName string
|
var pathName string
|
||||||
|
|
||||||
@ -169,7 +160,7 @@ func (s *Service) GetCollection(name string) (c *Collection, err error) {
|
|||||||
}
|
}
|
||||||
for _, i := range colls {
|
for _, i := range colls {
|
||||||
if pathName, err = NameFromPath(i.Dbus.Path()); err != nil {
|
if pathName, err = NameFromPath(i.Dbus.Path()); err != nil {
|
||||||
errs.AddError(err)
|
errs = append(errs, err)
|
||||||
err = nil
|
err = nil
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -188,8 +179,9 @@ func (s *Service) GetCollection(name string) (c *Collection, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Couldn't find it by the given name.
|
// Couldn't find it by the given name.
|
||||||
if !errs.IsEmpty() {
|
if errs != nil || len(errs) > 0 {
|
||||||
err = errs
|
errs = append([]error{ErrDoesNotExist}, errs...)
|
||||||
|
err = NewErrors(errs...)
|
||||||
} else {
|
} else {
|
||||||
err = ErrDoesNotExist
|
err = ErrDoesNotExist
|
||||||
}
|
}
|
||||||
@ -257,27 +249,6 @@ func (s *Service) GetSession() (ssn *Session, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scrapping this idea for now; it would require introspection on a known Item path.
|
|
||||||
/*
|
|
||||||
IsLegacy indicates with a decent likelihood of accuracy if this Service is
|
|
||||||
connected to a legacy spec Secret Service (true) or if the spec is current (false).
|
|
||||||
|
|
||||||
It also returns a confidence indicator as a float, which indicates how accurate
|
|
||||||
the guess (because it is a guess) may/is likely to be (as a percentage). For example,
|
|
||||||
if confidence is expressed as 0.25, the result of legacyAPI has a 25% of being accurate.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
func (s *Service) IsLegacy() (legacyAPI bool, confidence int) {
|
|
||||||
|
|
||||||
var maxCon int
|
|
||||||
|
|
||||||
// Test 1, property introspection on Item. We're looking for a Type property.
|
|
||||||
DbusInterfaceItem
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Lock locks an Unlocked Collection or Item (LockableObject).
|
// Lock locks an Unlocked Collection or Item (LockableObject).
|
||||||
func (s *Service) Lock(objects ...LockableObject) (err error) {
|
func (s *Service) Lock(objects ...LockableObject) (err error) {
|
||||||
|
|
||||||
@ -413,8 +384,6 @@ func (s *Service) RemoveAlias(alias string) (err error) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
SearchItems searches all Collection objects and returns all matches based on the map of attributes.
|
SearchItems searches all Collection objects and returns all matches based on the map of attributes.
|
||||||
|
|
||||||
err MAY be a *multierr.MultiError.
|
|
||||||
*/
|
*/
|
||||||
func (s *Service) SearchItems(attributes map[string]string) (unlockedItems []*Item, lockedItems []*Item, err error) {
|
func (s *Service) SearchItems(attributes map[string]string) (unlockedItems []*Item, lockedItems []*Item, err error) {
|
||||||
|
|
||||||
@ -427,7 +396,7 @@ func (s *Service) SearchItems(attributes map[string]string) (unlockedItems []*It
|
|||||||
var c *Collection
|
var c *Collection
|
||||||
var cPath dbus.ObjectPath
|
var cPath dbus.ObjectPath
|
||||||
var item *Item
|
var item *Item
|
||||||
var errs *multierr.MultiError = multierr.NewMultiError()
|
var errs []error = make([]error, 0)
|
||||||
|
|
||||||
if attributes == nil || len(attributes) == 0 {
|
if attributes == nil || len(attributes) == 0 {
|
||||||
err = ErrMissingAttrs
|
err = ErrMissingAttrs
|
||||||
@ -462,17 +431,16 @@ func (s *Service) SearchItems(attributes map[string]string) (unlockedItems []*It
|
|||||||
cPath = dbus.ObjectPath(filepath.Dir(string(i)))
|
cPath = dbus.ObjectPath(filepath.Dir(string(i)))
|
||||||
|
|
||||||
if c, ok = collections[cPath]; !ok {
|
if c, ok = collections[cPath]; !ok {
|
||||||
errs.AddError(errors.New(fmt.Sprintf(
|
errs = append(errs, errors.New(fmt.Sprintf(
|
||||||
"could not find matching Collection for locked item %v", string(i),
|
"could not find matching Collection for locked item %v", string(i),
|
||||||
)))
|
)))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if item, err = NewItem(c, i); err != nil {
|
if item, err = NewItem(c, i); err != nil {
|
||||||
errs.AddError(errors.New(fmt.Sprintf(
|
errs = append(errs, errors.New(fmt.Sprintf(
|
||||||
"could not create Item for locked item %v; error follows", string(i),
|
"could not create Item for locked item %v", string(i),
|
||||||
)))
|
)))
|
||||||
errs.AddError(err)
|
|
||||||
err = nil
|
err = nil
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -486,25 +454,24 @@ func (s *Service) SearchItems(attributes map[string]string) (unlockedItems []*It
|
|||||||
cPath = dbus.ObjectPath(filepath.Dir(string(i)))
|
cPath = dbus.ObjectPath(filepath.Dir(string(i)))
|
||||||
|
|
||||||
if c, ok = collections[cPath]; !ok {
|
if c, ok = collections[cPath]; !ok {
|
||||||
errs.AddError(errors.New(fmt.Sprintf(
|
errs = append(errs, errors.New(fmt.Sprintf(
|
||||||
"could not find matching Collection for unlocked item %v", string(i),
|
"could not find matching Collection for unlocked item %v", string(i),
|
||||||
)))
|
)))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if item, err = NewItem(c, i); err != nil {
|
if item, err = NewItem(c, i); err != nil {
|
||||||
errs.AddError(errors.New(fmt.Sprintf(
|
errs = append(errs, errors.New(fmt.Sprintf(
|
||||||
"could not create Item for unlocked item %v; error follows", string(i),
|
"could not create Item for unlocked item %v", string(i),
|
||||||
)))
|
)))
|
||||||
errs.AddError(err)
|
|
||||||
err = nil
|
err = nil
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
unlockedItems = append(unlockedItems, item)
|
unlockedItems = append(unlockedItems, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !errs.IsEmpty() {
|
if errs != nil && len(errs) > 0 {
|
||||||
err = errs
|
err = NewErrors(errs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
37
types.go
37
types.go
@ -6,6 +6,16 @@ import (
|
|||||||
"github.com/godbus/dbus/v5"
|
"github.com/godbus/dbus/v5"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
MultiError is a type of error.Error that can contain multiple error.Errors. Confused? Don't worry about it.
|
||||||
|
*/
|
||||||
|
type MultiError struct {
|
||||||
|
// Errors is a slice of errors to combine/concatenate when .Error() is called.
|
||||||
|
Errors []error `json:"errors"`
|
||||||
|
// ErrorSep is a string to use to separate errors for .Error(). The default is "\n".
|
||||||
|
ErrorSep string `json:"separator"`
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SecretServiceError is a translated error from SecretService API.
|
SecretServiceError is a translated error from SecretService API.
|
||||||
See https://developer-old.gnome.org/libsecret/unstable/libsecret-SecretError.html#SecretError and
|
See https://developer-old.gnome.org/libsecret/unstable/libsecret-SecretError.html#SecretError and
|
||||||
@ -64,31 +74,6 @@ type Service struct {
|
|||||||
Session *Session `json:"-"`
|
Session *Session `json:"-"`
|
||||||
// IsLocked indicates if the Service is locked or not. Status updated by Service.Locked.
|
// IsLocked indicates if the Service is locked or not. Status updated by Service.Locked.
|
||||||
IsLocked bool `json:"locked"`
|
IsLocked bool `json:"locked"`
|
||||||
/*
|
|
||||||
Legacy indicates that this SecretService implementation breaks current spec
|
|
||||||
by implementing the legacy/obsolete draft spec rather than current libsecret spec
|
|
||||||
for the Dbus API.
|
|
||||||
|
|
||||||
If you're using SecretService with KeePassXC, for instance, or a much older version
|
|
||||||
of Gnome-Keyring *before* libsecret integration(?), or if you are getting strange errors
|
|
||||||
when performing a Service.SearchItems, you probably need to enable this field on the
|
|
||||||
Service returned by NewService. The coverage of this field may expand in the future, but
|
|
||||||
currently it only prevents/suppresses the (non-existent, in legacy spec) Type property
|
|
||||||
from being read or written on Items during e.g.:
|
|
||||||
|
|
||||||
Service.SearchItems
|
|
||||||
Collection.CreateItem
|
|
||||||
NewItem
|
|
||||||
Item.ChangeItemType
|
|
||||||
Item.Type
|
|
||||||
|
|
||||||
It will perform a no-op if enabled in the above contexts to maintain cross-compatability
|
|
||||||
in codebase between legacy and proper current spec systems, avoiding an error return.
|
|
||||||
|
|
||||||
You can use CheckErrIsFromLegacy if Service.Legacy is false and Service.SearchItems returns
|
|
||||||
a non-nil err to determine if this Service is (probably) interfacing with a legacy spec API.
|
|
||||||
*/
|
|
||||||
Legacy bool `json:"is_legacy"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -98,7 +83,7 @@ type Service struct {
|
|||||||
*/
|
*/
|
||||||
type Session struct {
|
type Session struct {
|
||||||
*DbusObject
|
*DbusObject
|
||||||
// service tracks the Service this Session was created from.
|
// collection tracks the Service this Session was created from.
|
||||||
service *Service
|
service *Service
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user