示例#1
0
        /// <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));
            }
        }
示例#2
0
        /// <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));
        }