@@ -120,6 +120,56 @@ public void GnuPassCredentialStore_ReadWriteDelete_GpgIdInSubdirectory()
120120 }
121121 }
122122
123+ [ PosixFact ]
124+ public void GnuPassCredentialStore_WriteCredential_MultipleGpgIds_UsesNearestGpgId ( )
125+ {
126+ // Verify that when two subdirectories each have their own .gpg-id, encrypting a credential
127+ // under one subdirectory uses that subdirectory's GPG identity, not the other one.
128+ var fs = new TestFileSystem ( ) ;
129+ var gpg = new TestGpg ( fs ) ;
130+
131+ string homePath = Environment . GetFolderPath ( Environment . SpecialFolder . UserProfile ) ;
132+ string storePath = Path . Combine ( homePath , ".password-store" ) ;
133+
134+ const string personalUserId = "personal@example.com" ;
135+ const string workUserId = "work@example.com" ;
136+
137+ // Only register the personal key; if the wrong (work) key is picked, EncryptFile will throw.
138+ gpg . GenerateKeys ( personalUserId ) ;
139+
140+ string personalSubDir = Path . Combine ( storePath , "personal" ) ;
141+ string workSubDir = Path . Combine ( storePath , "work" ) ;
142+
143+ fs . Directories . Add ( storePath ) ;
144+ fs . Directories . Add ( personalSubDir ) ;
145+ fs . Directories . Add ( workSubDir ) ;
146+ fs . Files [ Path . Combine ( personalSubDir , ".gpg-id" ) ] = Encoding . UTF8 . GetBytes ( personalUserId ) ;
147+ fs . Files [ Path . Combine ( workSubDir , ".gpg-id" ) ] = Encoding . UTF8 . GetBytes ( workUserId ) ;
148+
149+ // Use "personal" namespace so credentials are stored under storePath/personal/...
150+ var collection = new GpgPassCredentialStore ( fs , gpg , storePath , "personal" ) ;
151+
152+ string service = $ "https://example.com/{ Guid . NewGuid ( ) : N} ";
153+ const string userName = "john.doe" ;
154+ const string password = "letmein123" ; // [SuppressMessage("Microsoft.Security", "CS001:SecretInline", Justification="Fake credential")]
155+
156+ try
157+ {
158+ // Write - should pick personal/.gpg-id (personalUserId), not work/.gpg-id (workUserId)
159+ collection . AddOrUpdate ( service , userName , password ) ;
160+
161+ ICredential outCredential = collection . Get ( service , userName ) ;
162+
163+ Assert . NotNull ( outCredential ) ;
164+ Assert . Equal ( userName , outCredential . Account ) ;
165+ Assert . Equal ( password , outCredential . Password ) ;
166+ }
167+ finally
168+ {
169+ collection . Remove ( service , userName ) ;
170+ }
171+ }
172+
123173 private static string InitializePasswordStore ( TestFileSystem fs , TestGpg gpg )
124174 {
125175 string homePath = Environment . GetFolderPath ( Environment . SpecialFolder . UserProfile ) ;
0 commit comments