44 "context"
55 "errors"
66 "fmt"
7- "maps"
8- "os"
9- "reflect"
107 "slices"
118 "strings"
129
@@ -70,6 +67,19 @@ func getItemWithData[T store.Secret](id string, k *keychainStore[T]) (*kc.QueryR
7067 return & results [0 ], nil
7168}
7269
70+ func convertAttributes (attributes map [string ]any ) (map [string ]string , error ) {
71+ attr := make (map [string ]string , len (attributes ))
72+ for k , v := range attributes {
73+ switch t := any (v ).(type ) {
74+ case string :
75+ attr [k ] = t
76+ default :
77+ return nil , fmt .Errorf ("attributes of key %s has unsupported type %T" , k , t )
78+ }
79+ }
80+ return attr , nil
81+ }
82+
7383func (k * keychainStore [T ]) Delete (_ context.Context , id store.ID ) error {
7484 if err := id .Valid (); err != nil {
7585 return err
@@ -93,14 +103,22 @@ func (k *keychainStore[T]) Get(_ context.Context, id store.ID) (store.Secret, er
93103 return nil , err
94104 }
95105
96- secret := k .factory (result .Attributes )
106+ attr , err := convertAttributes (result .Attributes )
107+ if err != nil {
108+ return nil , err
109+ }
110+
111+ secret := k .factory ()
112+ if err := secret .SetMetadata (attr ); err != nil {
113+ return nil , err
114+ }
97115 if err := secret .Unmarshal (result .Data ); err != nil {
98116 return nil , err
99117 }
100118 return secret , nil
101119}
102120
103- func (k * keychainStore [T ]) GetAll (context.Context ) ([ ]store.SecretMetadata , error ) {
121+ func (k * keychainStore [T ]) GetAll (context.Context ) (map [store. ID ]store.Secret , error ) {
104122 item := newKeychainItem ("" , k )
105123
106124 // We use the MatchLimitAll attribute to query for multiple items from the
@@ -113,16 +131,21 @@ func (k *keychainStore[T]) GetAll(context.Context) ([]store.SecretMetadata, erro
113131 return nil , mapKeychainError (err )
114132 }
115133
116- creds := make ([ ]store.SecretMetadata , len (results ))
117- for i , result := range results {
134+ creds := make (map [store. ID ]store.Secret , len (results ))
135+ for _ , result := range results {
118136 id , err := store .ParseID (result .Account )
119137 if err != nil {
120138 continue
121139 }
122- creds [i ] = store.SecretMetadata {
123- ID : id ,
124- Metadata : result .Attributes ,
140+ attr , err := convertAttributes (result .Attributes )
141+ if err != nil {
142+ return nil , err
143+ }
144+ secret := k .factory ()
145+ if err := secret .SetMetadata (attr ); err != nil {
146+ return nil , err
125147 }
148+ creds [id ] = secret
126149 }
127150 return creds , nil
128151}
@@ -144,7 +167,9 @@ func (k *keychainStore[T]) Save(_ context.Context, id store.ID, secret store.Sec
144167 item .SetLabel (k .itemLabel (id ))
145168
146169 metadata := make (map [string ]any )
147- maps .Copy (metadata , secret .Metadata ())
170+ for k , v := range secret .Metadata () {
171+ metadata [k ] = v
172+ }
148173 parts := strings .SplitSeq (id .String (), "/" )
149174 for p := range parts {
150175 if p == "" {
@@ -158,23 +183,22 @@ func (k *keychainStore[T]) Save(_ context.Context, id store.ID, secret store.Sec
158183 return mapKeychainError (kc .AddItem (item ))
159184}
160185
161- func hasAttribute (attributes map [string ]any , result kc. QueryResult ) bool {
162- if attributes == nil {
186+ func hasAttribute (searchAttributes , queryAttributes map [string ]string ) bool {
187+ if searchAttributes == nil {
163188 return true
164189 }
165- fmt .Fprintf (os .Stdout , "Attributes: %v\n " , result .Attributes )
166- allMatches := make ([]bool , len (attributes ))
190+ allMatches := make ([]bool , len (searchAttributes ))
167191 var i int
168- for k , v := range result . Attributes {
169- if needle , ok := attributes [k ]; ok && reflect . DeepEqual (needle , v ) {
192+ for k , v := range queryAttributes {
193+ if needle , ok := searchAttributes [k ]; ok && strings . EqualFold (needle , v ) {
170194 allMatches [i ] = true
171195 i ++
172196 }
173197 }
174198 return ! slices .Contains (allMatches , false )
175199}
176200
177- func (k * keychainStore [T ]) Filter (ctx context.Context , id store.ID , attributes map [string ]any ) (map [store.ID ]store.Secret , error ) {
201+ func (k * keychainStore [T ]) Filter (ctx context.Context , id store.ID , attributes map [string ]string ) (map [store.ID ]store.Secret , error ) {
178202 item := newKeychainItem ("" , k )
179203
180204 // We use the MatchLimitAll attribute to query for multiple items from the
@@ -183,7 +207,9 @@ func (k *keychainStore[T]) Filter(ctx context.Context, id store.ID, attributes m
183207 item .SetMatchLimit (kc .MatchLimitAll )
184208
185209 metadata := make (map [string ]any )
186- maps .Copy (metadata , attributes )
210+ for k , v := range attributes {
211+ metadata [k ] = v
212+ }
187213 parts := strings .SplitSeq (id .String (), "/" )
188214 for p := range parts {
189215 if p == "" {
@@ -206,7 +232,12 @@ func (k *keychainStore[T]) Filter(ctx context.Context, id store.ID, attributes m
206232 continue
207233 }
208234
209- if ! hasAttribute (attributes , result ) {
235+ attr , err := convertAttributes (result .Attributes )
236+ if err != nil {
237+ return nil , err
238+ }
239+
240+ if ! hasAttribute (attributes , attr ) {
210241 continue
211242 }
212243
@@ -215,7 +246,10 @@ func (k *keychainStore[T]) Filter(ctx context.Context, id store.ID, attributes m
215246 return nil , err
216247 }
217248
218- secret := k .factory (i .Attributes )
249+ secret := k .factory ()
250+ if err := secret .SetMetadata (attr ); err != nil {
251+ return nil , err
252+ }
219253 if err := secret .Unmarshal (i .Data ); err != nil {
220254 return nil , err
221255 }
0 commit comments