8000 Remove duplicate credential classes. by grokys · Pull Request #1200 · github/VisualStudio · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Remove duplicate credential classes. #1200

Merged
merged 10 commits into from
Nov 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/GitHub.Api/GitHub.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,17 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ApiClientConfiguration.cs"/>
<Compile Include="ApiClientConfiguration.cs" />
<Compile Include="..\..\script\src\ApiClientConfiguration_User.cs" Condition="$(Buildtype) == 'Internal'">
<Link>ApiClientConfiguration_User.cs</Link>
</Compile>
<Compile Include="ApiClientConfiguration_User.cs" Condition="$(Buildtype) != 'Internal'"/>
<Compile Include="ILoginCache.cs" />
<Compile Include="ApiClientConfiguration_User.cs" Condition="$(Buildtype) != 'Internal'" />
<Compile Include="IKeychain.cs" />
<Compile Include="ILoginManager.cs" />
<Compile Include="ITwoFactorChallengeHandler.cs" />
<Compile Include="LoginManager.cs" />
<Compile Include="SimpleCredentialStore.cs" />
<Compile Include="WindowsLoginCache.cs" />
<Compile Include="KeychainCredentialStore.cs" />
<Compile Include="WindowsKeychain.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="..\common\SolutionInfo.cs">
<Link>Properties\SolutionInfo.cs</Link>
Expand Down
38 changes: 38 additions & 0 deletions src/GitHub.Api/IKeychain.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using System.Threading.Tasks;
using GitHub.Primitives;

namespace GitHub.Api
{
/// <summary>
/// Represents a keychain used to store credentials.
/// </summary>
public interface IKeychain
{
/// <summary>
/// Loads the credentials for the specified host address.
/// </summary>
/// <param name="address">The host address.</param>
/// <returns>
/// A task returning a tuple consisting of the retrieved username and password or null
/// if the credentials were not found.
/// </returns>
Task<Tuple<string, string>> Load(HostAddress address);

/// <summary>
/// Saves the credentials for the specified host address.
/// </summary>
/// <param name="userName">The username.</param>
/// <param name="password">The password.</param>
/// <param name="address">The host address.</param>
/// <returns>A task tracking the operation.</returns>
Task Save(string userName, string password, HostAddress address);

/// <summary>
/// Deletes the login details for the specified host address.
/// </summary>
/// <param name="address"></param>
/// <returns>A task tracking the operation.</returns>
Task Delete(HostAddress address);
}
}
37 changes: 0 additions & 37 deletions src/GitHub.Api/ILoginCache.cs

This file was deleted.

32 changes: 32 additions & 0 deletions src/GitHub.Api/KeychainCredentialStore.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Threading.Tasks;
using GitHub.Extensions;
using GitHub.Primitives;
using Octokit;

namespace GitHub.Api
{
/// <summary>
/// An Octokit credential store that reads from an <see cref="IKeychain"/>.
/// </summary>
public class KeychainCredentialStore : ICredentialStore
{
readonly IKeychain keychain;
readonly HostAddress address;

public KeychainCredentialStore(IKeychain keychain, HostAddress address)
{
Guard.ArgumentNotNull(keychain, nameof(keychain));
Guard.ArgumentNotNull(address, nameof(keychain));

this.keychain = keychain;
this.address = address;
}

public async Task<Credentials> GetCredentials()
{
var userPass = await keychain.Load(address).ConfigureAwait(false);
return userPass != null ? new Credentials(userPass.Item1, userPass.Item2) : Credentials.Anonymous;
}
}
}
20 changes: 10 additions & 10 deletions src/GitHub.Api/LoginManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace GitHub.Api
public class LoginManager : ILoginManager
{
readonly string[] scopes = { "user", "repo", "gist", "write:public_key" };
readonly ILoginCache loginCache;
readonly IKeychain keychain;
readonly ITwoFactorChallengeHandler twoFactorChallengeHandler;
readonly string clientId;
readonly string clientSecret;
Expand All @@ -23,26 +23,26 @@ public class LoginManager : ILoginManager
/// <summary>
/// Initializes a new instance of the <see cref="LoginManager"/> class.
/// </summary>
/// <param name="loginCache">The cache in which to store login details.</param>
/// <param name="keychain">The keychain in which to store credentials.</param>
/// <param name="twoFactorChallengeHandler">The handler for 2FA challenges.</param>
/// <param name="clientId">The application's client API ID.</param>
/// <param name="clientSecret">The application's client API secret.</param>
/// <param name="authorizationNote">An note to store with the authorization.</param>
/// <param name="fingerprint">The machine fingerprint.</param>
public LoginManager(
ILoginCache loginCache,
IKeychain keychain,
ITwoFactorChallengeHandler twoFactorChallengeHandler,
string clientId,
string clientSecret,
string authorizationNote = null,
string fingerprint = null)
{
Guard.ArgumentNotNull(loginCache, nameof(loginCache));
Guard.ArgumentNotNull(keychain, nameof(keychain));
Guard.ArgumentNotNull(twoFactorChallengeHandler, nameof(twoFactorChallengeHandler));
Guard.ArgumentNotEmptyString(clientId, nameof(clientId));
Guard.ArgumentNotEmptyString(clientSecret, nameof(clientSecret));

this.loginCache = loginCache;
this.keychain = keychain;
this.twoFactorChallengeHandler = twoFactorChallengeHandler;
this.clientId = clientId;
this.clientSecret = clientSecret;
Expand All @@ -64,7 +64,7 @@ public async Task<User> Login(

// Start by saving the username and password, these will be used by the `IGitHubClient`
// until an authorization token has been created and acquired:
await loginCache.SaveLogin(userName, password, hostAddress).ConfigureAwait(false);
await keychain.Save(userName, password, hostAddress).ConfigureAwait(false);

var newAuth = new NewAuthorization
{
Expand Down Expand Up @@ -99,13 +99,13 @@ public async Task<User> Login(
}
else
{
await loginCache.EraseLogin(hostAddress).ConfigureAwait(false);
await keychain.Delete(hostAddress).ConfigureAwait(false);
throw;
}
}
} while (auth == null);

await loginCache.SaveLogin(userName, auth.Token, hostAddress).ConfigureAwait(false);
await keychain.Save(userName, auth.Token, hostAddress).ConfigureAwait(false);

var retry = 0;

Expand Down Expand Up @@ -141,7 +141,7 @@ public async Task Logout(HostAddress hostAddress, IGitHubClient client)
Guard.ArgumentNotNull(hostAddress, nameof(hostAddress));
Guard.ArgumentNotNull(client, nameof(client));

await loginCache.EraseLogin(hostAddress);
await keychain.Delete(hostAddress);
}

async Task<ApplicationAuthorization> CreateAndDeleteExistingApplicationAuthorization(
Expand Down Expand Up @@ -219,7 +219,7 @@ async Task<ApplicationAuthorization> HandleTwoFactorAuthorization(
catch (Exception e)
{
await twoFactorChallengeHandler.ChallengeFailed(e);
await loginCache.EraseLogin(hostAddress).ConfigureAwait(false);
await keychain.Delete(hostAddress).ConfigureAwait(false);
throw;
}
}
Expand Down
12 changes: 9 additions & 3 deletions src/GitHub.Api/SimpleApiClientFactory.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using GitHub.Models;
using GitHub.Primitives;
Expand All @@ -14,15 +13,21 @@ namespace GitHub.Api
[PartCreationPolicy(CreationPolicy.Shared)]
public class SimpleApiClientFactory : ISimpleApiClientFactory
{
readonly IKeychain keychain;
readonly ProductHeaderValue productHeader;
readonly Lazy<IEnterpriseProbeTask> lazyEnterpriseProbe;
readonly Lazy<IWikiProbe> lazyWikiProbe;

static readonly ConcurrentDictionary<UriString, ISimpleApiClient> cache = new ConcurrentDictionary<UriString, ISimpleApiClient>();

[ImportingConstructor]
public SimpleApiClientFactory(IProgram program, Lazy<IEnterpriseProbeTask> enterpriseProbe, Lazy<IWikiProbe> wikiProbe)
public SimpleApiClientFactory(
IProgram program,
IKeychain keychain,
Lazy<IEnterpriseProbeTask> enterpriseProbe,
Lazy<IWikiProbe> wikiProbe)
{
this.keychain = keychain;
productHeader = program.ProductHeader;
lazyEnterpriseProbe = enterpriseProbe;
lazyWikiProbe = wikiProbe;
Expand All @@ -31,8 +36,9 @@ public SimpleApiClientFactory(IProgram program, Lazy<IEnterpriseProbeTask> enter
public Task<ISimpleApiClient> Create(UriString repositoryUrl)
{
var hostAddress = HostAddress.Create(repositoryUrl);
var credentialStore = new KeychainCredentialStore(keychain, hostAddress);
var result = cache.GetOrAdd(repositoryUrl, new SimpleApiClient(repositoryUrl,
new GitHubClient(productHeader, new SimpleCredentialStore(hostAddress), hostAddress.ApiUri),
new GitHubClient(productHeader, credentialStore, hostAddress.ApiUri),
lazyEnterpriseProbe, lazyWikiProbe));
return Task.FromResult(result);
}
Expand Down
83 changes: 0 additions & 83 deletions src/GitHub.Api/SimpleCredentialStore.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
namespace GitHub.Api
{
/// <summary>
/// A login cache that stores logins in the windows credential cache.
/// A keychain that stores logins in the windows credential store.
/// </summary>
[Export(typeof(ILoginCache))]
[Export(typeof(IKeychain))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class WindowsLoginCache : ILoginCache
public class WindowsKeychain : IKeychain
{
/// <inheritdoc/>
public Task<Tuple<string, string>> GetLogin(HostAddress hostAddress)
public Task<Tuple<string, string>> Load(HostAddress hostAddress)
{
Guard.ArgumentNotNull(hostAddress, nameof(hostAddress));

Expand All @@ -29,11 +29,11 @@ public Task<Tuple<string, string>> GetLogin(HostAddress hostAddress)
return Task.FromResult(Tuple.Create(credential.Username, credential.Password));
}

return Task.FromResult(Tuple.Create<string, string>(null, null));
return Task.FromResult<Tuple<string, string>>(null);
}

/// <inheritdoc/>
public Task SaveLogin(string userName, string password, HostAddress hostAddress)
public Task Save(string userName, string password, HostAddress hostAddress)
{
Guard.ArgumentNotEmptyString(userName, nameof(userName));
Guard.ArgumentNotEmptyString(password, nameof(password));
Expand All @@ -56,7 +56,7 @@ public Task SaveLogin(string userName, string password, HostAddress hostAddress)
}

/// <inheritdoc/>
public Task EraseLogin(HostAddress hostAddress)
public Task Delete(HostAddress hostAddress)
{
Guard.ArgumentNotNull(hostAddress, nameof(hostAddress));

Expand Down
Loading
0