@@ -39,28 +39,42 @@ class Keychain : IKeychain
3939 private Dictionary < UriString , Connection > connectionCache = new Dictionary < UriString , Connection > ( ) ;
4040
4141 // cached credentials loaded from git to pass to GitHub/ApiClient
42- private Dictionary < UriString , KeychainAdapter > keychainAdapters =
43- new Dictionary < UriString , KeychainAdapter > ( ) ;
42+ private readonly Dictionary < UriString , KeychainAdapter > keychainAdapters
43+ = new Dictionary < UriString , KeychainAdapter > ( ) ;
4444
4545 public Keychain ( IEnvironment environment , ICredentialManager credentialManager )
4646 {
47+ Guard . ArgumentNotNull ( environment , nameof ( environment ) ) ;
48+ Guard . ArgumentNotNull ( credentialManager , nameof ( credentialManager ) ) ;
49+
50+ Guard . NotNull ( environment , environment . UserCachePath , nameof ( environment . UserCachePath ) ) ;
51+
4752 cachePath = environment . UserCachePath . Combine ( ConnectionFile ) ;
4853 this . credentialManager = credentialManager ;
4954 }
5055
51- public KeychainAdapter Connect ( UriString host )
56+ public IKeychainAdapter Connect ( UriString host )
5257 {
5358 return FindOrCreateAdapter ( host ) ;
5459 }
5560
56- public async Task < KeychainAdapter > Load ( UriString host )
61+ public async Task < IKeychainAdapter > Load ( UriString host )
5762 {
58- logger . Trace ( "Load Host:{0}" , host ) ;
59-
6063 var keychainAdapter = FindOrCreateAdapter ( host ) ;
6164
65+ logger . Trace ( "Load KeychainAdapter Host:\" {0}\" " , host ) ;
6266 var keychainItem = await credentialManager . Load ( host ) ;
63- keychainAdapter . Set ( keychainItem ) ;
67+
68+ if ( keychainItem == null )
69+ {
70+ logger . Warning ( "Cannot load host from credential manager; removing from cache" ) ;
71+ await Clear ( host , false ) ;
72+ }
73+ else
74+ {
75+ logger . Trace ( "Loading KeychainItem:{0}" , keychainItem . ToString ( ) ) ;
76+ keychainAdapter . Set ( keychainItem ) ;
77+ }
6478
6579 return keychainAdapter ;
6680 }
@@ -89,6 +103,7 @@ private void ReadCacheFromDisk()
89103 logger . Trace ( "ReadCacheFromDisk Path:{0}" , cachePath . ToString ( ) ) ;
90104
91105 ConnectionCacheItem [ ] connections = null ;
106+
92107 if ( cachePath . FileExists ( ) )
93108 {
94109 var json = cachePath . ReadAllText ( ) ;
@@ -122,7 +137,7 @@ private void WriteCacheToDisk()
122137 var connectionCacheItems =
123138 connectionCache . Select (
124139 pair =>
125- new ConnectionCacheItem ( ) {
140+ new ConnectionCacheItem {
126141 Host = pair . Value . Host . ToString ( ) ,
127142 Username = pair . Value . Username
128143 } ) . ToArray ( ) ;
@@ -131,35 +146,27 @@ private void WriteCacheToDisk()
131146 cachePath . WriteAllText ( json ) ;
132147 }
133148
134- /// <summary>
135- /// Call Flush() to apply these changes
136- /// </summary>
137- public void Clear ( UriString host )
149+ public async Task Clear ( UriString host , bool deleteFromCredentialManager )
138150 {
139151 logger . Trace ( "Clear Host:{0}" , host ) ;
140-
152+
141153 // delete connection in the connection list
142154 connectionCache . Remove ( host ) ;
143155
144- // delete credential in octokit store
156+ //clear octokit credentials
145157 FindOrCreateAdapter ( host ) . Clear ( ) ;
146- }
147158
148- /// <summary>
149- /// Call Flush() to apply these changes
150- /// </summary>
151- public void Clear ( )
152- {
153- foreach ( var k in keychainAdapters . Values . ToArray ( ) )
159+ WriteCacheToDisk ( ) ;
160+
161+ if ( deleteFromCredentialManager )
154162 {
155- k . Clear ( ) ;
163+ await credentialManager . Delete ( host ) ;
156164 }
157- connectionCache . Clear ( ) ;
158165 }
159166
160- public async Task Flush ( UriString host )
167+ public async Task Save ( UriString host )
161168 {
162- logger . Trace ( "Flush : {0}" , host ) ;
169+ logger . Trace ( "Save : {0}" , host ) ;
163170
164171 KeychainAdapter credentialAdapter ;
165172 if ( ! keychainAdapters . TryGetValue ( host , out credentialAdapter ) )
@@ -175,6 +182,7 @@ public async Task Flush(UriString host)
175182 // create new connection in the connection cache for this host
176183 if ( connectionCache . ContainsKey ( host ) )
177184 connectionCache . Remove ( host ) ;
185+
178186 connectionCache . Add ( host , new Connection { Host = host , Username = credentialAdapter . OctokitCredentials . Login } ) ;
179187
180188 // flushes credential cache to disk (host and username only)
@@ -185,12 +193,20 @@ public async Task Flush(UriString host)
185193 await credentialManager . Save ( credentialAdapter . Credential ) ;
186194 }
187195
188- public void Save ( ICredential credential )
196+ public void SetCredentials ( ICredential credential )
189197 {
190- logger . Trace ( "Save Host:{0}" , credential . Host ) ;
198+ logger . Trace ( "SetCredentials Host:{0}" , credential . Host ) ;
191199
192- var credentialAdapter = FindOrCreateAdapter ( credential . Host ) ;
193- credentialAdapter . Set ( credential ) ;
200+ var keychainAdapter = keychainAdapters [ credential . Host ] ;
201+ keychainAdapter . Set ( credential ) ;
202+ }
203+
204+ public void SetToken ( UriString host , string token )
205+ {
206+ logger . Trace ( "SetToken Host:{0}" , host ) ;
207+
208+ var keychainAdapter = keychainAdapters [ host ] ;
209+ keychainAdapter . UpdateToken ( token ) ;
194210 }
195211
196212 public void UpdateToken ( UriString host , string token )
@@ -207,6 +223,8 @@ public void UpdateToken(UriString host, string token)
207223 keychainItem . UpdateToken ( token ) ;
208224 }
209225
226+ public IList < UriString > Connections => connectionCache . Keys . ToArray ( ) ;
227+
210228 public bool HasKeys => connectionCache . Any ( ) ;
211229 }
212230}
0 commit comments