@@ -104,11 +104,20 @@ func isServiceCredential[T store.Secret](k *keychainStore[T], attrs []wincred.Cr
104104 return strings .EqualFold (serviceGroup , k .serviceGroup ) && strings .EqualFold (serviceName , k .serviceName )
105105}
106106
107+ // hasAttribute iterates over the credential attributes (attrs) and checks if
108+ // each key exists in the attributes map. If they exist, it compares their values
109+ // each attribute inside attributes must match what is stored in the credential
110+ // attributes (attrs) to return true.
107111func hasAttribute (attributes map [string ]string , attrs []wincred.CredentialAttribute ) bool {
112+ if attributes == nil {
113+ return true
114+ }
108115 allMatch := make ([]bool , len (attributes ))
116+ var i int
109117 for _ , attr := range attrs {
110- if v , ok := attributes [attr .Keyword ]; ok && v == string (attr .Value ) {
111- allMatch = append (allMatch , true )
118+ if v , ok := attributes [attr .Keyword ]; ok && strings .EqualFold (v , string (attr .Value )) {
119+ allMatch [i ] = true
120+ i ++
112121 }
113122 }
114123 return ! slices .Contains (allMatch , false )
@@ -159,36 +168,44 @@ func (k *keychainStore[T]) Save(ctx context.Context, id store.ID, secret store.S
159168 return err
160169 }
161170
162- g := wincred .NewGenericCredential (k .itemLabel (id ))
163- g .UserName = id .String ()
164- g .CredentialBlob = blob
165- g .Persist = wincred .PersistLocalMachine
166- g .Attributes = []wincred.CredentialAttribute {
167- {
168- Keyword : "id" ,
169- Value : []byte (id .String ()),
170- },
171- {
172- Keyword : "service:group" ,
173- Value : []byte (k .serviceGroup ),
174- },
175- {
176- Keyword : "service:name" ,
177- Value : []byte (k .serviceName ),
178- },
179- }
180-
171+ attributes := []wincred.CredentialAttribute {}
181172 parts := strings .SplitSeq (id .String (), "/" )
182173 for p := range parts {
183174 if p == "" {
184175 continue
185176 }
186- g . Attributes = append (g . Attributes , wincred.CredentialAttribute {
177+ attributes = append (attributes , wincred.CredentialAttribute {
187178 Keyword : p ,
188179 Value : []byte (p ),
189180 })
190181 }
182+ for k , v := range secret .Metadata () {
183+ attributes = append (attributes , wincred.CredentialAttribute {
184+ Keyword : k ,
185+ Value : []byte (v ),
186+ })
187+ }
188+
189+ attributes = append (attributes ,
190+ wincred.CredentialAttribute {
191+ Keyword : "id" ,
192+ Value : []byte (id .String ()),
193+ },
194+ wincred.CredentialAttribute {
195+ Keyword : "service:group" ,
196+ Value : []byte (k .serviceGroup ),
197+ },
198+ wincred.CredentialAttribute {
199+ Keyword : "service:name" ,
200+ Value : []byte (k .serviceName ),
201+ },
202+ )
191203
204+ g := wincred .NewGenericCredential (k .itemLabel (id ))
205+ g .UserName = id .String ()
206+ g .CredentialBlob = blob
207+ g .Persist = wincred .PersistLocalMachine
208+ g .Attributes = attributes
192209 return mapWindowsCredentialError (g .Write ())
193210}
194211
0 commit comments