Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Commit 5e58f3f

Browse files
Merge branch 'fixes/fix-keychain-missing-exception' into stanley/0.31-rc
# Conflicts: # src/GitHub.Api/Authentication/Keychain.cs
2 parents e9a0b1b + 60da5ec commit 5e58f3f

File tree

3 files changed

+56
-79
lines changed

3 files changed

+56
-79
lines changed

src/GitHub.Api/Application/ApiClient.cs

Lines changed: 56 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ public async Task ValidateCurrentUser(Action onSuccess, Action<Exception> onErro
8686
Guard.ArgumentNotNull(onSuccess, nameof(onSuccess));
8787
try
8888
{
89-
await ValidateCurrentUserInternal();
89+
var keychainConnection = keychain.Connections.First();
90+
var keychainAdapter = await GetValidatedKeychainAdapter(keychainConnection);
91+
await GetValidatedGitHubUser(keychainConnection, keychainAdapter);
9092
onSuccess();
9193
}
9294
catch (Exception e)
@@ -98,7 +100,12 @@ public async Task ValidateCurrentUser(Action onSuccess, Action<Exception> onErro
98100
public async Task GetCurrentUser(Action<GitHubUser> callback)
99101
{
100102
Guard.ArgumentNotNull(callback, "callback");
101-
var user = await GetCurrentUserInternal();
103+
104+
//TODO: ONE_USER_LOGIN This assumes only ever one user can login
105+
var keychainConnection = keychain.Connections.First();
106+
var keychainAdapter = await GetValidatedKeychainAdapter(keychainConnection);
107+
var user = await GetValidatedGitHubUser(keychainConnection, keychainAdapter);
108+
102109
callback(user);
103110
}
104111

@@ -204,11 +211,10 @@ private async Task<GitHubRepository> CreateRepositoryInternal(string repositoryN
204211
{
205212
logger.Trace("Creating repository");
206213

207-
await ValidateKeychain();
208-
await ValidateCurrentUserInternal();
209-
210-
var uriString = keychain.Connections.First().Host;
211-
var keychainAdapter = await keychain.Load(uriString);
214+
//TODO: ONE_USER_LOGIN This assumes only ever one user can login
215+
var keychainConnection = keychain.Connections.First();
216+
var keychainAdapter = await GetValidatedKeychainAdapter(keychainConnection);
217+
await GetValidatedGitHubUser(keychainConnection, keychainAdapter);
212218

213219
var command = new StringBuilder("publish -r \"");
214220
command.Append(repositoryName);
@@ -233,7 +239,7 @@ private async Task<GitHubRepository> CreateRepositoryInternal(string repositoryN
233239
command.Append(" -p");
234240
}
235241

236-
var octorunTask = new OctorunTask(taskManager.Token, nodeJsExecutablePath, octorunScriptPath, command.ToString(),
242+
var octorunTask = new OctorunTask(taskManager.Token, nodeJsExecutablePath, octorunScriptPath, command.ToString(),
237243
user: keychainAdapter.Credential.Username, userToken: keychainAdapter.Credential.Token)
238244
.Configure(processManager);
239245

@@ -262,11 +268,10 @@ private async Task GetOrganizationInternal(Action<Organization[]> onSuccess, Act
262268
{
263269
logger.Trace("Getting Organizations");
264270

265-
await ValidateKeychain();
266-
await ValidateCurrentUserInternal();
267-
268-
var uriString = keychain.Connections.First().Host;
269-
var keychainAdapter = await keychain.Load(uriString);
271+
//TODO: ONE_USER_LOGIN This assumes only ever one user can login
272+
var keychainConnection = keychain.Connections.First();
273+
var keychainAdapter = await GetValidatedKeychainAdapter(keychainConnection);
274+
await GetValidatedGitHubUser(keychainConnection, keychainAdapter);
270275

271276
var octorunTask = new OctorunTask(taskManager.Token, nodeJsExecutablePath, octorunScriptPath, "organizations",
272277
user: keychainAdapter.Credential.Username, userToken: keychainAdapter.Credential.Token)
@@ -298,27 +303,54 @@ private async Task GetOrganizationInternal(Action<Organization[]> onSuccess, Act
298303
}
299304
}
300305

301-
private async Task<GitHubUser> GetCurrentUserInternal()
306+
private async Task<IKeychainAdapter> GetValidatedKeychainAdapter(Connection keychainConnection)
302307
{
303-
try
308+
if (keychain.HasKeys)
304309
{
305-
logger.Trace("Getting Current User");
306-
await ValidateKeychain();
310+
var keychainAdapter = await keychain.Load(keychainConnection.Host);
311+
312+
if (string.IsNullOrEmpty(keychainAdapter.Credential?.Username))
313+
{
314+
logger.Warning("LoadKeychainInternal: Username is empty");
315+
throw new TokenUsernameMismatchException(keychainConnection.Username);
316+
}
317+
318+
if (keychainAdapter.Credential.Username != keychainConnection.Username)
319+
{
320+
logger.Warning("LoadKeychainInternal: Token username does not match");
321+
throw new TokenUsernameMismatchException(keychainConnection.Username, keychainAdapter.Credential.Username);
322+
}
323+
324+
return keychainAdapter;
325+
}
307326

308-
var uriString = keychain.Connections.First().Host;
309-
var keychainAdapter = await keychain.Load(uriString);
327+
logger.Warning("LoadKeychainInternal: No keys to load");
328+
throw new KeychainEmptyException();
329+
}
310330

331+
private async Task<GitHubUser> GetValidatedGitHubUser(Connection keychainConnection, IKeychainAdapter keychainAdapter)
332+
{
333+
try
334+
{
311335
var octorunTask = new OctorunTask(taskManager.Token, nodeJsExecutablePath, octorunScriptPath, "validate",
312-
user: keychainAdapter.Credential.Username, userToken: keychainAdapter.Credential.Token)
336+
user: keychainAdapter.Credential.Username, userToken: keychainAdapter.Credential.Token)
313337
.Configure(processManager);
314338

315339
var ret = await octorunTask.StartAsAsync();
316340
if (ret.IsSuccess)
317341
{
342+
var login = ret.Output[1];
343+
344+
if (login != keychainConnection.Username)
345+
{
346+
logger.Trace("LoadKeychainInternal: Api username does not match");
347+
throw new TokenUsernameMismatchException(keychainConnection.Username, login);
348+
}
349+
318350
return new GitHubUser
319351
{
320352
Name = ret.Output[0],
321-
Login = ret.Output[1]
353+
Login = login
322354
};
323355
}
324356

@@ -335,55 +367,6 @@ private async Task<GitHubUser> GetCurrentUserInternal()
335367
throw;
336368
}
337369
}
338-
339-
private async Task ValidateCurrentUserInternal()
340-
{
341-
logger.Trace("Validating User");
342-
343-
var apiUser = await GetCurrentUserInternal();
344-
var apiUsername = apiUser.Login;
345-
346-
var cachedUsername = keychain.Connections.First().Username;
347-
348-
if (apiUsername != cachedUsername)
349-
{
350-
throw new TokenUsernameMismatchException(cachedUsername, apiUsername);
351-
}
352-
}
353-
354-
private async Task<bool> LoadKeychainInternal()
355-
{
356-
if (keychain.HasKeys)
357-
{
358-
if (!keychain.NeedsLoad)
359-
{
360-
logger.Trace("LoadKeychainInternal: Previously Loaded");
361-
return true;
362-
}
363-
364-
logger.Trace("LoadKeychainInternal: Loading");
365-
366-
//TODO: ONE_USER_LOGIN This assumes only ever one user can login
367-
var uriString = keychain.Connections.First().Host;
368-
369-
var keychainAdapter = await keychain.Load(uriString);
370-
logger.Trace("LoadKeychainInternal: Loaded");
371-
372-
return keychainAdapter.Credential.Token != null;
373-
}
374-
375-
logger.Trace("LoadKeychainInternal: No keys to load");
376-
377-
return false;
378-
}
379-
380-
private async Task ValidateKeychain()
381-
{
382-
if (!await LoadKeychainInternal())
383-
{
384-
throw new KeychainEmptyException();
385-
}
386-
}
387370
}
388371

389372
class GitHubUser
@@ -420,7 +403,7 @@ class TokenUsernameMismatchException : ApiClientException
420403
public string CachedUsername { get; }
421404
public string CurrentUsername { get; }
422405

423-
public TokenUsernameMismatchException(string cachedUsername, string currentUsername)
406+
public TokenUsernameMismatchException(string cachedUsername, string currentUsername = null)
424407
{
425408
CachedUsername = cachedUsername;
426409
CurrentUsername = currentUsername;
@@ -433,12 +416,8 @@ protected TokenUsernameMismatchException(SerializationInfo info, StreamingContex
433416
class KeychainEmptyException : ApiClientException
434417
{
435418
public KeychainEmptyException()
436-
{ }
437-
public KeychainEmptyException(string message) : base(message)
438-
{ }
439-
440-
public KeychainEmptyException(string message, Exception innerException) : base(message, innerException)
441-
{ }
419+
{
420+
}
442421

443422
protected KeychainEmptyException(SerializationInfo info, StreamingContext context) : base(info, context)
444423
{ }

src/GitHub.Api/Authentication/IKeychain.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ public interface IKeychain
1616
Connection[] Connections { get; }
1717
IList<UriString> Hosts { get; }
1818
bool HasKeys { get; }
19-
bool NeedsLoad { get; }
2019
void SetToken(UriString host, string token);
2120

2221
event Action ConnectionsChanged;

src/GitHub.Api/Authentication/Keychain.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,5 @@ private void UpdateConnections(Connection[] conns)
323323
public Connection[] Connections => connections.Values.ToArray();
324324
public IList<UriString> Hosts => connections.Keys.ToArray();
325325
public bool HasKeys => connections.Any();
326-
public bool NeedsLoad => HasKeys && !string.IsNullOrEmpty(FindOrCreateAdapter(connections.First().Value.Host).Credential?.Token);
327326
}
328327
}

0 commit comments

Comments
 (0)