@@ -22,6 +22,8 @@ class ApiClient : IApiClient
2222 private readonly ITaskManager taskManager ;
2323 private readonly ILoginManager loginManager ;
2424 private readonly IEnvironment environment ;
25+ private IKeychainAdapter keychainAdapter ;
26+ private Connection connection ;
2527
2628 public ApiClient ( IKeychain keychain , IProcessManager processManager , ITaskManager taskManager , IEnvironment environment ) :
2729 this ( UriString . ToUriString ( HostAddress . GitHubDotComHostAddress . WebUri ) , keychain , processManager , taskManager , environment )
@@ -36,8 +38,6 @@ public ApiClient(UriString host, IKeychain keychain, IProcessManager processMana
3638 host = new UriString ( host . ToRepositoryUri ( ) . GetComponents ( UriComponents . SchemeAndServer , UriFormat . SafeUnescaped ) ) ;
3739 HostAddress = HostAddress . Create ( host ) ;
3840
39- logger . Trace ( "OriginalUrl: {0}" , HostAddress . ApiUri . Host ) ;
40-
4141 this . keychain = keychain ;
4242 this . processManager = processManager ;
4343 this . taskManager = taskManager ;
@@ -57,8 +57,7 @@ public void CreateRepository(string name, string description, bool isPrivate,
5757
5858 new FuncTask < GitHubRepository > ( taskManager . Token , ( ) =>
5959 {
60- // this validates the user, again
61- GetCurrentUser ( ) ;
60+ EnsureValidCredentials ( ) ;
6261
6362 var command = new StringBuilder ( "publish" ) ;
6463
@@ -91,11 +90,7 @@ public void CreateRepository(string name, string description, bool isPrivate,
9190 command . Append ( " -p" ) ;
9291 }
9392
94- var adapter = keychain . Connect ( HostAddress . ApiUri . Host ) ;
95- if ( adapter . Credential == null )
96- {
97- throw new ApiClientException ( "No Credentials found" ) ;
98- }
93+ var adapter = EnsureKeychainAdapter ( ) ;
9994
10095 var octorunTask = new OctorunTask ( taskManager . Token , environment , command . ToString ( ) , adapter . Credential . Token )
10196 . Configure ( processManager ) ;
@@ -199,11 +194,7 @@ public void GetOrganizations(Action<Organization[]> onSuccess, Action<Exception>
199194 Guard . ArgumentNotNull ( onSuccess , nameof ( onSuccess ) ) ;
200195 new FuncTask < Organization [ ] > ( taskManager . Token , ( ) =>
201196 {
202- var adapter = keychain . Connect ( HostAddress . ApiUri . Host ) ;
203- if ( adapter . Credential == null )
204- {
205- throw new ApiClientException ( "No Credentials found" ) ;
206- }
197+ var adapter = EnsureKeychainAdapter ( ) ;
207198
208199 var command = HostAddress . IsGitHubDotCom ( ) ? "organizations" : "organizations -h " + HostAddress . ApiUri . Host ;
209200 var octorunTask = new OctorunTask ( taskManager . Token , environment ,
@@ -240,6 +231,17 @@ public void GetOrganizations(Action<Organization[]> onSuccess, Action<Exception>
240231 . Start ( ) ;
241232 }
242233
234+ private IKeychainAdapter EnsureKeychainAdapter ( )
235+ {
236+ var adapter = KeychainAdapter ;
237+ if ( adapter . Credential == null )
238+ {
239+ throw new ApiClientException ( "No Credentials found" ) ;
240+ }
241+
242+ return adapter ;
243+ }
244+
243245 public void GetCurrentUser ( Action < GitHubUser > onSuccess , Action < Exception > onError = null )
244246 {
245247 Guard . ArgumentNotNull ( onSuccess , nameof ( onSuccess ) ) ;
@@ -324,68 +326,87 @@ public void ContinueLogin(LoginResult loginResult, string code)
324326 . Start ( ) ;
325327 }
326328
327- public GitHubUser GetCurrentUser ( )
329+ public void EnsureValidCredentials ( )
328330 {
329- var keychainConnection = keychain . Connections . FirstOrDefault ( x => x . Host == ( UriString ) HostAddress . ApiUri . Host ) ;
330- if ( keychainConnection == null )
331- throw new KeychainEmptyException ( ) ;
332-
333- var keychainAdapter = GetValidatedKeychainAdapter ( keychainConnection ) ;
331+ GetCurrentUser ( ) ;
332+ }
334333
334+ public GitHubUser GetCurrentUser ( )
335+ {
335336 // we can't trust that the system keychain has the username filled out correctly.
336337 // if it doesn't, we need to grab the username from the server and check it
337338 // unfortunately this means that things will be slower when the keychain doesn't have all the info
338- if ( keychainConnection . User == null || keychainAdapter . Credential . Username != keychainConnection . Username )
339+ if ( Connection . User == null || KeychainAdapter . Credential . Username != Connection . Username )
339340 {
340- keychainConnection . User = GetValidatedGitHubUser ( keychainConnection , keychainAdapter ) ;
341+ Connection . User = GetValidatedGitHubUser ( ) ;
341342 }
342- return keychainConnection . User ;
343+
344+ return Connection . User ;
343345 }
344346
345- private IKeychainAdapter GetValidatedKeychainAdapter ( Connection keychainConnection )
347+ private Connection Connection
346348 {
347- var keychainAdapter = keychain . LoadFromSystem ( keychainConnection . Host ) ;
348- if ( keychainAdapter == null )
349- throw new KeychainEmptyException ( ) ;
350-
351- if ( string . IsNullOrEmpty ( keychainAdapter . Credential ? . Username ) )
349+ get
352350 {
353- logger . Warning ( "LoadKeychainInternal: Username is empty" ) ;
354- throw new TokenUsernameMismatchException ( keychainConnection . Username ) ;
355- }
351+ if ( connection == null )
352+ {
353+ connection = keychain . Connections . FirstOrDefault ( x => x . Host == ( UriString ) HostAddress . ApiUri . Host ) ;
354+ }
356355
357- if ( keychainAdapter . Credential . Username != keychainConnection . Username )
358- {
359- logger . Warning ( "LoadKeychainInternal: Token username does not match" ) ;
356+ return connection ;
360357 }
361-
362- return keychainAdapter ;
363358 }
364359
365- private GitHubUser GetValidatedGitHubUser ( Connection keychainConnection , IKeychainAdapter keychainAdapter )
360+ private IKeychainAdapter KeychainAdapter
366361 {
367- try
362+ get
368363 {
369- if ( keychainAdapter . Credential == null )
364+ if ( keychainAdapter == null )
370365 {
371- throw new ApiClientException ( "No Credentials found" ) ;
366+ if ( Connection == null )
367+ throw new KeychainEmptyException ( ) ;
368+
369+ var loadedKeychainAdapter = keychain . LoadFromSystem ( Connection . Host ) ;
370+ if ( loadedKeychainAdapter == null )
371+ throw new KeychainEmptyException ( ) ;
372+
373+ if ( string . IsNullOrEmpty ( loadedKeychainAdapter . Credential ? . Username ) )
374+ {
375+ logger . Warning ( "LoadKeychainInternal: Username is empty" ) ;
376+ throw new TokenUsernameMismatchException ( connection . Username ) ;
377+ }
378+
379+ if ( loadedKeychainAdapter . Credential . Username != connection . Username )
380+ {
381+ logger . Warning ( "LoadKeychainInternal: Token username does not match" ) ;
382+ }
383+
384+ keychainAdapter = loadedKeychainAdapter ;
372385 }
373386
374- logger . Trace ( "GetValidatedGitHubUser with GitHub Token: {0} {1}" , keychainAdapter . Credential . Host , keychainAdapter . Credential . Token ) ;
387+ return keychainAdapter ;
388+ }
389+ }
390+
391+ private GitHubUser GetValidatedGitHubUser ( )
392+ {
393+ try
394+ {
395+ var adapter = EnsureKeychainAdapter ( ) ;
375396
376397 var command = HostAddress . IsGitHubDotCom ( ) ? "validate" : "validate -h " + HostAddress . ApiUri . Host ;
377- var octorunTask = new OctorunTask ( taskManager . Token , environment , command , keychainAdapter . Credential . Token )
398+ var octorunTask = new OctorunTask ( taskManager . Token , environment , command , adapter . Credential . Token )
378399 . Configure ( processManager ) ;
379400
380401 var ret = octorunTask . RunSynchronously ( ) ;
381402 if ( ret . IsSuccess )
382403 {
383404 var login = ret . Output [ 1 ] ;
384405
385- if ( login != keychainConnection . Username )
406+ if ( login != Connection . Username )
386407 {
387408 logger . Trace ( "LoadKeychainInternal: Api username does not match" ) ;
388- throw new TokenUsernameMismatchException ( keychainConnection . Username , login ) ;
409+ throw new TokenUsernameMismatchException ( Connection . Username , login ) ;
389410 }
390411
391412 return new GitHubUser
0 commit comments