From 36b59e106bf1edaa76c83ae9231d52473b826acf Mon Sep 17 00:00:00 2001 From: Michael Kincaid Date: Mon, 15 Jun 2020 17:21:16 -0700 Subject: [PATCH 1/2] Clear basic entries in non-user URI format where present --- .../Src/BasicAuthentication.cs | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Microsoft.Alm.Authentication/Src/BasicAuthentication.cs b/Microsoft.Alm.Authentication/Src/BasicAuthentication.cs index e1267a013..081fecea0 100644 --- a/Microsoft.Alm.Authentication/Src/BasicAuthentication.cs +++ b/Microsoft.Alm.Authentication/Src/BasicAuthentication.cs @@ -154,7 +154,32 @@ public override async Task DeleteCredentials(TargetUri targetUri) if (targetUri is null) throw new ArgumentNullException(nameof(targetUri)); - return await _credentialStore.DeleteCredentials(targetUri); + // Delete the credentials for the explicit target uri first. + + var initResult = await _credentialStore.DeleteCredentials(targetUri); + + // If we deleted per user then we should try and delete the host level credentials too if + // they match the username. + var hostTargetUri = new TargetUri(targetUri.ToString(false, true, true)); + var hostCredentials = await GetCredentials(hostTargetUri); + + if (hostCredentials is null) + { + Trace.WriteLine($"No entry found for {hostTargetUri}, nothing more to delete"); + return initResult; + } + + var hostUsername = hostCredentials.Username; + var encodedUsername = Uri.EscapeDataString(targetUri.UserInfo); + if (encodedUsername != hostUsername) + { + Trace.WriteLine($"{hostTargetUri} entry has username {hostUsername} != {encodedUsername}, not deleting"); + return initResult; + } + + Trace.WriteLine($"Also deleting generic entry for {hostTargetUri} with username {hostUsername}"); + return await _credentialStore.DeleteCredentials(hostTargetUri); + } public override async Task GetCredentials(TargetUri targetUri) From 6c867b2c8fcab4c68d2ab6b84df66c754596b39e Mon Sep 17 00:00:00 2001 From: Michael Kincaid Date: Mon, 15 Jun 2020 18:09:12 -0700 Subject: [PATCH 2/2] Basic tests of resolution between both URL formats --- .../Test/BasicAuthTests.cs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/Microsoft.Alm.Authentication/Test/BasicAuthTests.cs b/Microsoft.Alm.Authentication/Test/BasicAuthTests.cs index ea20adb29..2c7ab66f9 100644 --- a/Microsoft.Alm.Authentication/Test/BasicAuthTests.cs +++ b/Microsoft.Alm.Authentication/Test/BasicAuthTests.cs @@ -24,6 +24,23 @@ public async Task BasicAuthDeleteCredentialsTest() Assert.Null(await basicAuth.CredentialStore.ReadCredentials(targetUri)); } + [Fact] + public async Task BasicAuthUserUriDeleteCredentialsTest() + { + TargetUri targetUserUri = new TargetUri("http://username@localhost"); + TargetUri targetGenericUri = new TargetUri("http://localhost"); + BasicAuthentication basicAuth = GetBasicAuthentication(RuntimeContext.Default, "basic-delete-user"); + + await basicAuth.CredentialStore.WriteCredentials(targetUserUri, new Credential("username", "password")); + await basicAuth.CredentialStore.WriteCredentials(targetGenericUri, new Credential("username", "password")); + + /* User-included format is what comes out of "erase" action, so that's what we want to test */ + await basicAuth.DeleteCredentials(targetUserUri); + + Assert.Null(await basicAuth.CredentialStore.ReadCredentials(targetUserUri)); + Assert.Null(await basicAuth.CredentialStore.ReadCredentials(targetGenericUri)); + } + [Fact] public async Task BasicAuthGetCredentialsTest() { @@ -41,6 +58,26 @@ public async Task BasicAuthGetCredentialsTest() Assert.NotNull(credentials = await basicAuth.GetCredentials(targetUri)); } + [Fact] + public async Task BasicAuthUserUriGetCredentialsTest() + { + TargetUri targetUserUri = new TargetUri("http://username@localhost"); + TargetUri targetGenericUri = new TargetUri("http://localhost"); + + BasicAuthentication basicAuth = GetBasicAuthentication(RuntimeContext.Default, "basic-get-user"); + + Credential credentials = null; + + Assert.Null(credentials = await basicAuth.GetCredentials(targetGenericUri)); + Assert.Null(credentials = await basicAuth.GetCredentials(targetUserUri)); + + credentials = new Credential("username", "password"); + + await basicAuth.CredentialStore.WriteCredentials(targetGenericUri, credentials); + + Assert.NotNull(credentials = await basicAuth.GetCredentials(targetUserUri)); + } + [Fact] public async Task BasicAuthSetCredentialsTest() {