@@ -19,17 +19,37 @@ public Task<Tuple<string, string>> Load(HostAddress hostAddress)
1919 {
2020 Guard . ArgumentNotNull ( hostAddress , nameof ( hostAddress ) ) ;
2121
22+ var key = GetKey ( hostAddress . CredentialCacheKeyHost ) ;
23+ var keyGit = GetKeyGit ( hostAddress . CredentialCacheKeyHost ) ;
2224 var keyHost = GetKeyHost ( hostAddress . CredentialCacheKeyHost ) ;
23-
24- using ( var credential = new Credential ( ) )
25+ Tuple < string , string > result = null ;
26+
27+ // Visual Studio requires two credentials, keyed as "{hostname}" (e.g. "https://github.com/") and
28+ // "git:{hostname}" (e.g. "git:https://github.com"). We have a problem in that these credentials can
29+ // potentially be overwritten by other applications, so we store an extra "master" key as
30+ // "GitHub for Visual Studio - {hostname}". Whenever we read the credentials we overwrite the other
31+ // two keys with the value from the master key. Older versions of GHfVS did not store this master key
32+ // so if it does not exist, try to get the value from the "{hostname}" key.
33+ using ( var credential = Credential . Load ( key ) )
34+ using ( var credentialGit = Credential . Load ( keyGit ) )
35+ using ( var credentialHost = Credential . Load ( keyHost ) )
2536 {
26- credential . Target = keyHost ;
27- credential . Type = CredentialType . Generic ;
28- if ( credential . Load ( ) )
29- return Task . FromResult ( Tuple . Create ( credential . Username , credential . Password ) ) ;
37+ if ( credential != null )
38+ {
39+ result = Tuple . Create ( credential . Username , credential . Password ) ;
40+ }
41+ else if ( credentialHost != null )
42+ {
43+ result = Tuple . Create ( credentialHost . Username , credentialHost . Password ) ;
44+ }
45+
46+ if ( result != null )
47+ {
48+ Save ( result . Item1 , result . Item2 , hostAddress ) ;
49+ }
3050 }
3151
32- return Task . FromResult < Tuple < string , string > > ( null ) ;
52+ return Task . FromResult ( result ) ;
3353 }
3454
3555 /// <inheritdoc/>
@@ -39,18 +59,13 @@ public Task Save(string userName, string password, HostAddress hostAddress)
3959 Guard . ArgumentNotEmptyString ( password , nameof ( password ) ) ;
4060 Guard . ArgumentNotNull ( hostAddress , nameof ( hostAddress ) ) ;
4161
62+ var key = GetKey ( hostAddress . CredentialCacheKeyHost ) ;
4263 var keyGit = GetKeyGit ( hostAddress . CredentialCacheKeyHost ) ;
4364 var keyHost = GetKeyHost ( hostAddress . CredentialCacheKeyHost ) ;
4465
45- using ( var credential = new Credential ( userName , password , keyGit ) )
46- {
47- credential . Save ( ) ;
48- }
49-
50- using ( var credential = new Credential ( userName , password , keyHost ) )
51- {
52- credential . Save ( ) ;
53- }
66+ Credential . Save ( key , userName , password ) ;
67+ Credential . Save ( keyGit , userName , password ) ;
68+ Credential . Save ( keyHost , userName , password ) ;
5469
5570 return Task . CompletedTask ;
5671 }
@@ -60,26 +75,27 @@ public Task Delete(HostAddress hostAddress)
6075 {
6176 Guard . ArgumentNotNull ( hostAddress , nameof ( hostAddress ) ) ;
6277
78+ var key = GetKey ( hostAddress . CredentialCacheKeyHost ) ;
6379 var keyGit = GetKeyGit ( hostAddress . CredentialCacheKeyHost ) ;
6480 var keyHost = GetKeyHost ( hostAddress . CredentialCacheKeyHost ) ;
6581
66- using ( var credential = new Credential ( ) )
67- {
68- credential . Target = keyGit ;
69- credential . Type = CredentialType . Generic ;
70- credential . Delete ( ) ;
71- }
72-
73- using ( var credential = new Credential ( ) )
74- {
75- credential . Target = keyHost ;
76- credential . Type = CredentialType . Generic ;
77- credential . Delete ( ) ;
78- }
82+ Credential . Delete ( key ) ;
83+ Credential . Delete ( keyGit ) ;
84+ Credential . Delete ( keyHost ) ;
7985
8086 return Task . CompletedTask ;
8187 }
8288
89+ static string GetKey ( string key )
90+ {
91+ key = FormatKey ( key ) ;
92+ if ( key . StartsWith ( "git:" , StringComparison . Ordinal ) )
93+ key = key . Substring ( "git:" . Length ) ;
94+ if ( ! key . EndsWith ( "/" , StringComparison . Ordinal ) )
95+ key += '/' ;
96+ return "GitHub for Visual Studio - " + key ;
97+ }
98+
8399 static string GetKeyGit ( string key )
84100 {
85101 key = FormatKey ( key ) ;
0 commit comments