@@ -22,6 +22,8 @@ class ApiClient : IApiClient
22
22
private readonly ITaskManager taskManager ;
23
23
private readonly ILoginManager loginManager ;
24
24
private readonly IEnvironment environment ;
25
+ private IKeychainAdapter keychainAdapter ;
26
+ private Connection connection ;
25
27
26
28
public ApiClient ( IKeychain keychain , IProcessManager processManager , ITaskManager taskManager , IEnvironment environment ) :
27
29
this ( UriString . ToUriString ( HostAddress . GitHubDotComHostAddress . WebUri ) , keychain , processManager , taskManager , environment )
@@ -36,8 +38,6 @@ public ApiClient(UriString host, IKeychain keychain, IProcessManager processMana
36
38
host = new UriString ( host . ToRepositoryUri ( ) . GetComponents ( UriComponents . SchemeAndServer , UriFormat . SafeUnescaped ) ) ;
37
39
HostAddress = HostAddress . Create ( host ) ;
38
40
39
- logger . Trace ( "OriginalUrl: {0}" , HostAddress . ApiUri . Host ) ;
40
-
41
41
this . keychain = keychain ;
42
42
this . processManager = processManager ;
43
43
this . taskManager = taskManager ;
@@ -57,8 +57,7 @@ public void CreateRepository(string name, string description, bool isPrivate,
57
57
58
58
new FuncTask < GitHubRepository > ( taskManager . Token , ( ) =>
59
59
{
60
- // this validates the user, again
61
- GetCurrentUser ( ) ;
60
+ EnsureValidCredentials ( ) ;
62
61
63
62
var command = new StringBuilder ( "publish" ) ;
64
63
@@ -91,11 +90,7 @@ public void CreateRepository(string name, string description, bool isPrivate,
91
90
command . Append ( " -p" ) ;
92
91
}
93
92
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 ( ) ;
99
94
100
95
var octorunTask = new OctorunTask ( taskManager . Token , environment , command . ToString ( ) , adapter . Credential . Token )
101
96
. Configure ( processManager ) ;
@@ -199,11 +194,7 @@ public void GetOrganizations(Action<Organization[]> onSuccess, Action<Exception>
199
194
Guard . ArgumentNotNull ( onSuccess , nameof ( onSuccess ) ) ;
200
195
new FuncTask < Organization [ ] > ( taskManager . Token , ( ) =>
201
196
{
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 ( ) ;
207
198
208
199
var command = HostAddress . IsGitHubDotCom ( ) ? "organizations" : "organizations -h " + HostAddress . ApiUri . Host ;
209
200
var octorunTask = new OctorunTask ( taskManager . Token , environment ,
@@ -240,6 +231,17 @@ public void GetOrganizations(Action<Organization[]> onSuccess, Action<Exception>
240
231
. Start ( ) ;
241
232
}
242
233
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
+
243
245
public void GetCurrentUser ( Action < GitHubUser > onSuccess , Action < Exception > onError = null )
244
246
{
245
247
Guard . ArgumentNotNull ( onSuccess , nameof ( onSuccess ) ) ;
@@ -324,68 +326,87 @@ public void ContinueLogin(LoginResult loginResult, string code)
324
326
. Start ( ) ;
325
327
}
326
328
327
- public GitHubUser GetCurrentUser ( )
329
+ public void EnsureValidCredentials ( )
328
330
{
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
+ }
334
333
334
+ public GitHubUser GetCurrentUser ( )
335
+ {
335
336
// we can't trust that the system keychain has the username filled out correctly.
336
337
// if it doesn't, we need to grab the username from the server and check it
337
338
// 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 )
339
340
{
340
- keychainConnection . User = GetValidatedGitHubUser ( keychainConnection , keychainAdapter ) ;
341
+ Connection . User = GetValidatedGitHubUser ( ) ;
341
342
}
342
- return keychainConnection . User ;
343
+
344
+ return Connection . User ;
343
345
}
344
346
345
- private IKeychainAdapter GetValidatedKeychainAdapter ( Connection keychainConnection )
347
+ private Connection Connection
346
348
{
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
352
350
{
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
+ }
356
355
357
- if ( keychainAdapter . Credential . Username != keychainConnection . Username )
358
- {
359
- logger . Warning ( "LoadKeychainInternal: Token username does not match" ) ;
356
+ return connection ;
360
357
}
361
-
362
- return keychainAdapter ;
363
358
}
364
359
365
- private GitHubUser GetValidatedGitHubUser ( Connection keychainConnection , IKeychainAdapter keychainAdapter )
360
+ private IKeychainAdapter KeychainAdapter
366
361
{
367
- try
362
+ get
368
363
{
369
- if ( keychainAdapter . Credential == null )
364
+ if ( keychainAdapter == null )
370
365
{
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 ;
372
385
}
373
386
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 ( ) ;
375
396
376
397
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 )
378
399
. Configure ( processManager ) ;
379
400
380
401
var ret = octorunTask . RunSynchronously ( ) ;
381
402
if ( ret . IsSuccess )
382
403
{
383
404
var login = ret . Output [ 1 ] ;
384
405
385
- if ( login != keychainConnection . Username )
406
+ if ( login != Connection . Username )
386
407
{
387
408
logger . Trace ( "LoadKeychainInternal: Api username does not match" ) ;
388
- throw new TokenUsernameMismatchException ( keychainConnection . Username , login ) ;
409
+ throw new TokenUsernameMismatchException ( Connection . Username , login ) ;
389
410
}
390
411
391
412
return new GitHubUser
0 commit comments