/// <inheritdoc/> public async Task <LoginResultData> Login( UriString host, string username, string password) { Guard.ArgumentNotNull(host, nameof(host)); Guard.ArgumentNotNullOrWhiteSpace(username, nameof(username)); Guard.ArgumentNotNullOrWhiteSpace(password, nameof(password)); // Start by saving the username and password, these will be used by the `IGitHubClient` // until an authorization token has been created and acquired: keychain.Connect(host); keychain.SetCredentials(new Credential(host, username, password)); try { var loginResultData = await TryLogin(host, username, password); if (loginResultData.Code == LoginResultCodes.Success || loginResultData.Code == LoginResultCodes.CodeRequired) { if (string.IsNullOrEmpty(loginResultData.Token)) { throw new InvalidOperationException("Returned token is null or empty"); } if (loginResultData.Code == LoginResultCodes.Success) { username = await RetrieveUsername(loginResultData, username); } keychain.SetToken(host, loginResultData.Token, username); if (loginResultData.Code == LoginResultCodes.Success) { await keychain.Save(host); } return(loginResultData); } return(loginResultData); } catch (Exception e) { logger.Warning(e, "Login Exception"); await keychain.Clear(host, false); return(new LoginResultData(LoginResultCodes.Failed, Localization.LoginFailed, host)); } }
/// <inheritdoc/> public async Task <LoginResultData> Login( UriString host, IGitHubClient client, string username, string password) { Guard.ArgumentNotNull(host, nameof(host)); Guard.ArgumentNotNull(client, nameof(client)); Guard.ArgumentNotNullOrWhiteSpace(username, nameof(username)); Guard.ArgumentNotNullOrWhiteSpace(password, nameof(password)); // Start by saving the username and password, these will be used by the `IGitHubClient` // until an authorization token has been created and acquired: keychain.Connect(host); keychain.SetCredentials(new Credential(host, username, password)); var newAuth = new NewAuthorization { Scopes = scopes, Note = authorizationNote, Fingerprint = fingerprint, }; ApplicationAuthorization auth = null; try { logger.Info("Login Username:{0}", username); auth = await CreateAndDeleteExistingApplicationAuthorization(client, newAuth, null); EnsureNonNullAuthorization(auth); } catch (TwoFactorAuthorizationException e) { LoginResultCodes result; if (e is TwoFactorRequiredException) { result = LoginResultCodes.CodeRequired; logger.Debug("2FA TwoFactorAuthorizationException: {0} {1}", LoginResultCodes.CodeRequired, e.Message); } else { result = LoginResultCodes.CodeFailed; logger.Error(e, "2FA TwoFactorAuthorizationException: {0} {1}", LoginResultCodes.CodeRequired, e.Message); } return(new LoginResultData(result, e.Message, client, host, newAuth)); } catch (LoginAttemptsExceededException e) { logger.Warning(e, "Login LoginAttemptsExceededException: {0}", e.Message); await keychain.Clear(host, false); return(new LoginResultData(LoginResultCodes.LockedOut, Localization.LockedOut, host)); } catch (ApiValidationException e) { logger.Warning(e, "Login ApiValidationException: {0}", e.Message); var message = e.ApiError.FirstErrorMessageSafe(); await keychain.Clear(host, false); return(new LoginResultData(LoginResultCodes.Failed, message, host)); } catch (Exception e) { logger.Warning(e, "Login Exception"); // Some enterprise instances don't support OAUTH, so fall back to using the // supplied password - on instances that don't support OAUTH the user should // be using a personal access token as the password. if (EnterpriseWorkaround(host, e)) { auth = new ApplicationAuthorization(password); } else { await keychain.Clear(host, false); return(new LoginResultData(LoginResultCodes.Failed, Localization.LoginFailed, host)); } } keychain.SetToken(host, auth.Token); await keychain.Save(host); return(new LoginResultData(LoginResultCodes.Success, "Success", host)); }