diff --git a/funcs.go b/funcs.go index 0c86e52..aa6dcb8 100644 --- a/funcs.go +++ b/funcs.go @@ -153,3 +153,56 @@ func NameFromPath(path dbus.ObjectPath) (name string, err error) { 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 +} diff --git a/item_funcs.go b/item_funcs.go index 0702c65..1a083bd 100644 --- a/item_funcs.go +++ b/item_funcs.go @@ -85,6 +85,11 @@ func (i *Item) ChangeItemType(newItemType string) (err error) { var variant dbus.Variant + // Legacy spec. + if i.collection.service.Legacy { + return + } + if strings.TrimSpace(newItemType) == "" { newItemType = DbusDefaultItemType } diff --git a/service_funcs.go b/service_funcs.go index e7cbe6f..d6c4f3a 100644 --- a/service_funcs.go +++ b/service_funcs.go @@ -257,6 +257,27 @@ func (s *Service) GetSession() (ssn *Session, err error) { 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). func (s *Service) Lock(objects ...LockableObject) (err error) { diff --git a/types.go b/types.go index 2560b82..8b5410f 100644 --- a/types.go +++ b/types.go @@ -74,7 +74,19 @@ type Service struct { 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 NewItem and Collection.CreateItem respectively. + 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"` }