Skip to content

Commit e49fef0

Browse files
committed
fixup! introduce PasswordExpiryUTC and OAuthRefreshToken
Limit iterations in GetCredentialAsync
1 parent af784ad commit e49fef0

File tree

2 files changed

+21
-22
lines changed

2 files changed

+21
-22
lines changed

src/shared/Core.Tests/HostProviderTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public async Task HostProvider_GetCredentialAsync_CredentialDoesNotExist_Returns
7676
}
7777

7878
[Fact]
79-
public async Task HostProvider_GetCredentialAsync_InvalidCredentialStored_ReturnsNewGeneratedCredential()
79+
public async Task HostProvider_GetCredentialAsync_InvalidCredentialsStored_ReturnsNewGeneratedCredential()
8080
{
8181
const string userName = "john.doe";
8282
const string password = "letmein123"; // [SuppressMessage("Microsoft.Security", "CS001:SecretInline", Justification="Fake credential")]
@@ -93,6 +93,7 @@ public async Task HostProvider_GetCredentialAsync_InvalidCredentialStored_Return
9393
string refreshTokenSeenByGenerate = null;
9494
var context = new TestCommandContext();
9595
context.CredentialStore.Add(service, new TestCredential(service, "stored-user", "stored-password") { OAuthRefreshToken = storedRefreshToken});
96+
context.CredentialStore.Add(service, new TestCredential(service, "another-stored-user", "another-stored-password"));
9697
var provider = new TestHostProvider(context)
9798
{
9899
ValidateCredentialFunc = (_, _) => false,
@@ -114,7 +115,7 @@ public async Task HostProvider_GetCredentialAsync_InvalidCredentialStored_Return
114115
Assert.Equal(userName, actualCredential.Account);
115116
Assert.Equal(password, actualCredential.Password);
116117
Assert.Equal(refreshToken, actualCredential.OAuthRefreshToken);
117-
// Invalid credential should be erased
118+
// Invalid credentials should be erased
118119
Assert.Equal(0, context.CredentialStore.Count);
119120
}
120121

src/shared/Core/HostProvider.cs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,9 @@ public virtual async Task<ICredential> GetCredentialAsync(InputArguments input)
131131
Context.Trace.WriteLine($"Looking for existing credential in store with service={service} account={input.UserName}...");
132132

133133
// Query for matching credentials
134-
ICredential credential = null;
135-
while (true)
134+
ICredential credential;
135+
// Limit iterations to avoid infinite loop if CredentialStore.Remove misbehaves
136+
for (int i = 0; i < 3; i++)
136137
{
137138
Context.Trace.WriteLine("Querying for existing credentials...");
138139
credential = Context.CredentialStore.Get(service, input.UserName);
@@ -141,28 +142,25 @@ public virtual async Task<ICredential> GetCredentialAsync(InputArguments input)
141142
Context.Trace.WriteLine("No existing credentials found.");
142143
break;
143144
}
145+
Context.Trace.WriteLine("Existing credential found.");
146+
if (await ValidateCredentialAsync(input.GetRemoteUri(), credential))
147+
{
148+
Context.Trace.WriteLine("Existing credential satisfies validation.");
149+
return credential;
150+
}
144151
else
145152
{
146-
Context.Trace.WriteLine("Existing credential found.");
147-
if (await ValidateCredentialAsync(input.GetRemoteUri(), credential))
148-
{
149-
Context.Trace.WriteLine("Existing credential satisfies validation.");
150-
return credential;
151-
}
152-
else
153+
Context.Trace.WriteLine("Existing credential fails validation.");
154+
if (credential.OAuthRefreshToken != null)
153155
{
154-
Context.Trace.WriteLine("Existing credential fails validation.");
155-
if (credential.OAuthRefreshToken != null)
156-
{
157-
Context.Trace.WriteLine("Found OAuth refresh token.");
158-
input = new InputArguments(input, credential.OAuthRefreshToken);
159-
}
160-
Context.Trace.WriteLine("Erasing invalid credential...");
161-
// Why necessary to erase? We can't be sure that storing a fresh
162-
// credential will overwrite the invalid credential, particularly
163-
// if the usernames differ.
164-
Context.CredentialStore.Remove(service, credential);
156+
Context.Trace.WriteLine("Found OAuth refresh token.");
157+
input = new InputArguments(input, credential.OAuthRefreshToken);
165158
}
159+
Context.Trace.WriteLine("Erasing invalid credential...");
160+
// Why necessary to erase? We can't be sure that storing a fresh
161+
// credential will overwrite the invalid credential, particularly
162+
// if the usernames differ.
163+
Context.CredentialStore.Remove(service, credential);
166164
}
167165
}
168166
Context.Trace.WriteLine("Creating new credential...");

0 commit comments

Comments
 (0)