10000 Merge pull request #1277 from github/refactor/connections-master · github/VisualStudio@63ceb38 · 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.

Commit 63ceb38

Browse files
authored
Merge pull request #1277 from github/refactor/connections-master
Master PR for refactoring connections
2 parents 51aedf2 + 4701dd0 commit 63ceb38

File tree

104 files changed

+2210
-2910
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+2210
-2910
lines changed

src/CredentialManagement/Credential.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,28 @@ public Credential(
6060
_lastWriteTime = DateTime.MinValue;
6161
}
6262

63+
public static Credential Load(string key)
64+
{
65+
var result = new Credential();
66+
result.Target = key;
67+
result.Type = CredentialType.Generic;
68+
return result.Load() ? result : null;
69+
}
70+
71+
public static void Save(string key, string username, string password)
72+
{
73+
var result = new Credential(username, password, key);
74+
result.Save();
75+
}
76+
77+
public static void Delete(string key)
78+
{
79+
var result = new Credential();
80+
result.Target = key;
81+
result.Type = CredentialType.Generic;
82+
result.Delete();
83+
}
84+
6385
bool disposed;
6486
void Dispose(bool disposing)
6587
{

src/GitHub.Api/GitHub.Api.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@
6262
<Link>ApiClientConfiguration_User.cs</Link>
6363
</Compile>
6464
<Compile Include="ApiClientConfiguration_User.cs" Condition="$(Buildtype) != 'Internal'" />
65-
<Compile Include="ILoginCache.cs" />
65+
<Compile Include="IKeychain.cs" />
6666
<Compile Include="ILoginManager.cs" />
6767
<Compile Include="ITwoFactorChallengeHandler.cs" />
6868
<Compile Include="LoginManager.cs" />
69-
<Compile Include="SimpleCredentialStore.cs" />
70-
<Compile Include="WindowsLoginCache.cs" />
69+
<Compile Include="KeychainCredentialStore.cs" />
70+
<Compile Include="WindowsKeychain.cs" />
7171
<Compile Include="Properties\AssemblyInfo.cs" />
7272
<Compile Include="..\common\SolutionInfo.cs">
7373
<Link>Properties\SolutionInfo.cs</Link>

src/GitHub.Api/IKeychain.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using GitHub.Primitives;
4+
5+
namespace GitHub.Api
6+
{
7+
/// <summary>
8+
/// Represents a keychain used to store credentials.
9+
/// </summary>
10+
public interface IKeychain
11+
{
12+
/// <summary>
13+
/// Loads the credentials for the specified host address.
14+
/// </summary>
15+
/// <param name="address">The host address.</param>
16+
/// <returns>
17+
/// A task returning a tuple consisting of the retrieved username and password or null
18+
/// if the credentials were not found.
19+
/// </returns>
20+
Task<Tuple<string, string>> Load(HostAddress address);
21+
22+
/// <summary>
23+
/// Saves the credentials for the specified host address.
24+
/// </summary>
25+
/// <param name="userName">The username.</param>
26+
/// <param name="password">The password.</param>
27+
/// <param name="address">The host address.</param>
28+
/// <returns>A task tracking the operation.</returns>
29+
Task Save(string userName, string password, HostAddress address);
30+
31+
/// <summary>
32+
/// Deletes the login details for the specified host address.
33+
/// </summary>
34+
/// <param name="address"></param>
35+
/// <returns>A task tracking the operation.</returns>
36+
Task Delete(HostAddress address);
37+
}
38+
}

src/GitHub.Api/ILoginCache.cs

Lines changed: 0 additions & 37 deletions
This file was deleted.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using GitHub.Extensions;
4+
using GitHub.Primitives;
5+
using Octokit;
6+
7+
namespace GitHub.Api
8+
{
9+
/// <summary>
10+
/// An Octokit credential store that reads from an <see cref="IKeychain"/>.
11+
/// </summary>
12+
public class KeychainCredentialStore : ICredentialStore
13+
{
14+
readonly IKeychain keychain;
15+
readonly HostAddress address;
16+
17+
public KeychainCredentialStore(IKeychain keychain, HostAddress address)
18+
{
19+
Guard.ArgumentNotNull(keychain, nameof(keychain));
20+
Guard.ArgumentNotNull(address, nameof(keychain));
21+
22+
this.keychain = keychain;
23+
this.address = address;
24+
}
25+
26+
public async Task<Credentials> GetCredentials()
27+
{
28+
var userPass = await keychain.Load(address).ConfigureAwait(false);
29+
return userPass != null ? new Credentials(userPass.Item1, userPass.Item2) : Credentials.Anonymous;
30+
}
31+
}
32+
}

src/GitHub.Api/LoginManager.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace GitHub.Api
1313
public class LoginManager : ILoginManager
1414
{
1515
readonly string[] scopes = { "user", "repo", "gist", "write:public_key" };
16-
readonly ILoginCache loginCache;
16+
readonly IKeychain keychain;
1717
readonly ITwoFactorChallengeHandler twoFactorChallengeHandler;
1818
readonly string clientId;
1919
readonly string clientSecret;
@@ -23,26 +23,26 @@ public class LoginManager : ILoginManager
2323
/// <summary>
2424
/// Initializes a new instance of the <see cref="LoginManager"/> class.
2525
/// </summary>
26-
/// <param name="loginCache">The cache in which to store login details.</param>
26+
/// <param name="keychain">The keychain in which to store credentials.</param>
2727
/// <param name="twoFactorChallengeHandler">The handler for 2FA challenges.</param>
2828
/// <param name="clientId">The application's client API ID.</param>
2929
/// <param name="clientSecret">The application's client API secret.</param>
3030
/// <param name="authorizationNote">An note to store with the authorization.</param>
3131
/// <param name="fingerprint">The machine fingerprint.</param>
3232
public LoginManager(
33-
ILoginCache loginCache,
33+
IKeychain keychain,
3434
ITwoFactorChallengeHandler twoFactorChallengeHandler,
3535
string clientId,
3636
string clientSecret,
3737
string authorizationNote = null,
3838
string fingerprint = null)
3939
{
40-
Guard.ArgumentNotNull(loginCache, nameof(loginCache));
40+
Guard.ArgumentNotNull(keychain, nameof(keychain));
4141
Guard.ArgumentNotNull(twoFactorChallengeHandler, nameof(twoFactorChallengeHandler));
4242
Guard.ArgumentNotEmptyString(clientId, nameof(clientId));
4343
Guard.ArgumentNotEmptyString(clientSecret, nameof(clientSecret));
4444

45-
this.loginCache = loginCache;
45+
this.keychain = keychain;
4646
this.twoFactorChallengeHandler = twoFactorChallengeHandler;
4747
this.clientId = clientId;
4848
this.clientSecret = clientSecret;
@@ -64,7 +64,7 @@ public async Task<User> Login(
6464

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

6969
var newAuth = new NewAuthorization
7070
{
@@ -99,13 +99,13 @@ public async Task<User> Login(
9999
}
100100
else
101101
{
102-
await loginCache.EraseLogin(hostAddress).ConfigureAwait(false);
102+
await keychain.Delete(hostAddress).ConfigureAwait(false);
103103
throw;
104104
}
105105
}
106106
} while (auth == null);
107107

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

110110
var retry = 0;
111111

@@ -141,7 +141,7 @@ public async Task Logout(HostAddress hostAddress, IGitHubClient client)
141141
Guard.ArgumentNotNull(hostAddress, nameof(hostAddress));
142142
Guard.ArgumentNotNull(client, nameof(client));
143143

144-
await loginCache.EraseLogin(hostAddress);
144+
await keychain.Delete(hostAddress);
145145
}
146146

147147
async Task<ApplicationAuthorization> CreateAndDeleteExistingApplicationAuthorization(
@@ -219,7 +219,7 @@ async Task<ApplicationAuthorization> HandleTwoFactorAuthorization(
219219
catch (Exception e)
220220
{
221221
await twoFactorChallengeHandler.ChallengeFailed(e);
222-
await loginCache.EraseLogin(hostAddress).ConfigureAwait(false);
222+
await keychain.Delete(hostAddress).ConfigureAwait(false);
223223
throw;
224224
}
225225
}

src/GitHub.Api/SimpleApiClientFactory.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.ComponentModel.Composition;
43
using GitHub.Models;
54
using GitHub.Primitives;
@@ -14,15 +13,21 @@ namespace GitHub.Api
1413
[PartCreationPolicy(CreationPolicy.Shared)]
1514
public class SimpleApiClientFactory : ISimpleApiClientFactory
1615
{
16+
readonly IKeychain keychain;
1717
readonly ProductHeaderValue productHeader;
1818
readonly Lazy<IEnterpriseProbeTask> lazyEnterpriseProbe;
1919
readonly Lazy<IWikiProbe> lazyWikiProbe;
2020

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

2323
[ImportingConstructor]
24-
public SimpleApiClientFactory(IProgram program, Lazy<IEnterpriseProbeTask> enterpriseProbe, Lazy<IWikiProbe> wikiProbe)
24+
public SimpleApiClientFactory(
25+
IProgram program,
26+
IKeychain keychain,
27+
Lazy<IEnterpriseProbeTask> enterpriseProbe,
28+
Lazy<IWikiProbe> wikiProbe)
2529
{
30+
this.keychain = keychain;
2631
productHeader = program.ProductHeader;
2732
lazyEnterpriseProbe = enterpriseProbe;
2833
lazyWikiProbe = wikiProbe;
@@ -31,8 +36,9 @@ public SimpleApiClientFactory(IProgram program, Lazy<IEnterpriseProbeTask> enter
3136
public Task<ISimpleApiClient> Create(UriString repositoryUrl)
3237
{
3338
var hostAddress = HostAddress.Create(repositoryUrl);
39+
var credentialStore = new KeychainCredentialStore(keychain, hostAddress);
3440
var result = cache.GetOrAdd(repositoryUrl, new SimpleApiClient(repositoryUrl,
35-
new GitHubClient(productHeader 6A8F , new SimpleCredentialStore(hostAddress), hostAddress.ApiUri),
41+
new GitHubClient(productHeader, credentialStore, hostAddress.ApiUri),
3642
lazyEnterpriseProbe, lazyWikiProbe));
3743
return Task.FromResult(result);
3844
}

src/GitHub.Api/SimpleCredentialStore.cs

Lines changed: 0 additions & 83 deletions
This file was deleted.

0 commit comments

Comments
 (0)
0