Skip to content

Commit 4e2a898

Browse files
authored
Return only unique accounts from credential stores (#1369)
If may be possible for multiple credentials for the same user account to exist in any credential store. To avoid issues with redundant account selection prompts we should ensure duplicate accounts are removed from the results of `ICredentialStore.GetAccounts`. Call `.Distinct()` or use a `HashSet` where appropriate on all implementation of `ICredentialStore.GetAccounts`. If there are multiple credentials for the same account, we'd only ever be able to retrieve the first enumerated credential regardless because our matching logic is to return to first credential that matches. Fixes #1368
2 parents eda6d3a + e8b02e0 commit 4e2a898

File tree

5 files changed

+6
-6
lines changed

5 files changed

+6
-6
lines changed

src/shared/Core/Interop/Linux/SecretServiceCollection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public SecretServiceCollection(string @namespace)
3939

4040
public IList<string> GetAccounts(string service)
4141
{
42-
return Enumerate(service, null).Select(x => x.Account).ToList();
42+
return Enumerate(service, null).Select(x => x.Account).Distinct().ToList();
4343
}
4444

4545
public ICredential Get(string service, string account)

src/shared/Core/Interop/MacOS/MacOSKeychain.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,15 @@ public IList<string> GetAccounts(string service)
6666
if (typeId == CFArrayGetTypeID())
6767
{
6868
int len = (int)CFArrayGetCount(resultPtr);
69-
var accounts = new List<string>(len);
69+
var accounts = new HashSet<string>(len);
7070
for (int i = 0; i < len; i++)
7171
{
7272
IntPtr dict = CFArrayGetValueAtIndex(resultPtr, i);
7373
string account = GetStringAttribute(dict, kSecAttrAccount);
7474
accounts.Add(account);
7575
}
7676

77-
return accounts;
77+
return accounts.ToList();
7878
}
7979

8080
throw new InteropException($"Unknown keychain search result type CFTypeID: {typeId}.", -1);

src/shared/Core/Interop/Windows/WindowsCredentialManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public WindowsCredentialManager(string @namespace = null)
2626

2727
public IList<string> GetAccounts(string service)
2828
{
29-
return Enumerate(service, null).Select(x => x.UserName).ToList();
29+
return Enumerate(service, null).Select(x => x.UserName).Distinct().ToList();
3030
}
3131

3232
public ICredential Get(string service, string account)

src/shared/Core/PlaintextCredentialStore.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public PlaintextCredentialStore(IFileSystem fileSystem, string storeRoot, string
2525

2626
public IList<string> GetAccounts(string service)
2727
{
28-
return Enumerate(service, null).Select(x => x.Account).ToList();
28+
return Enumerate(service, null).Select(x => x.Account).Distinct().ToList();
2929
}
3030

3131
public ICredential Get(string service, string account)

src/shared/TestInfrastructure/Objects/TestCredentialStore.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public TestCredentialStore()
1616

1717
public IList<string> GetAccounts(string service)
1818
{
19-
return Query(service, null).Select(x => x.Account).ToList();
19+
return Query(service, null).Select(x => x.Account).Distinct().ToList();
2020
}
2121

2222
ICredential ICredentialStore.Get(string service, string account)

0 commit comments

Comments
 (0)