Beispiel #1
0
        /// <inheritdoc/>
        public async Task <AuthenticationResult> AcquireToken(TargetUri targetUri, string username, string password, AuthenticationResultType resultType, TokenScope scope)
        {
            if (resultType == AuthenticationResultType.TwoFactor)
            {
                // a previous attempt to aquire a token failed in a way that suggests the user has
                // Bitbucket 2FA turned on. so attempt to run the OAuth dance...
                OAuth.OAuthAuthenticator oauth = new OAuth.OAuthAuthenticator();
                try
                {
                    var result = await oauth.GetAuthAsync(targetUri, scope, CancellationToken.None);

                    if (!result.IsSuccess)
                    {
                        Trace.WriteLine($"oauth authentication failed");
                        return(new AuthenticationResult(AuthenticationResultType.Failure));
                    }

                    // we got a toke but lets check to see the usernames match
                    var restRootUri = new Uri(_restRootUrl);
                    var authHeader  = GetBearerHeaderAuthHeader(result.Token.Value);
                    var userResult  = await RestClient.TryGetUser(targetUri, RequestTimeout, restRootUri, authHeader);

                    if (!userResult.IsSuccess)
                    {
                        Trace.WriteLine($"oauth user check failed");
                        return(new AuthenticationResult(AuthenticationResultType.Failure));
                    }

                    if (!string.IsNullOrWhiteSpace(userResult.RemoteUsername) && !username.Equals(userResult.RemoteUsername))
                    {
                        Trace.WriteLine($"Remote username [{userResult.RemoteUsername}] != [{username}] supplied username");
                        // make sure the 'real' username is returned
                        return(new AuthenticationResult(AuthenticationResultType.Success, result.Token, result.RefreshToken, userResult.RemoteUsername));
                    }

                    // everything is hunky dory
                    return(result);
                }
                catch (Exception ex)
                {
                    Trace.WriteLine($"oauth authentication failed [{ex.Message}]");
                    return(new AuthenticationResult(AuthenticationResultType.Failure));
                }
            }
            else
            {
                BasicAuthAuthenticator basicauth = new BasicAuthAuthenticator();
                try
                {
                    var restRootUri = new Uri(_restRootUrl);
                    return(await basicauth.GetAuthAsync(targetUri, scope, RequestTimeout, restRootUri, username, password));
                }
                catch (Exception ex)
                {
                    Trace.WriteLine($"basic auth authentication failed [{ex.Message}]");
                    return(new AuthenticationResult(AuthenticationResultType.Failure));
                }
            }
        }
Beispiel #2
0
        /// <inheritdoc/>
        public async Task <AuthenticationResult> AcquireToken(TargetUri targetUri, Credential credentials, AuthenticationResultType resultType, TokenScope scope)
        {
            if (targetUri is null)
            {
                throw new ArgumentNullException(nameof(targetUri));
            }
            if (credentials is null)
            {
                throw new ArgumentNullException(nameof(credentials));
            }
            if (resultType < AuthenticationResultType.None || resultType > AuthenticationResultType.TwoFactor)
            {
                throw new ArgumentOutOfRangeException(nameof(resultType));
            }
            if (scope is null)
            {
                throw new ArgumentNullException(nameof(scope));
            }

            if (resultType == AuthenticationResultType.TwoFactor)
            {
                // A previous attempt to acquire a token failed in a way that suggests the user has
                // Bitbucket 2FA turned on. so attempt to run the OAuth dance...
                var oauth = new OAuth.OAuthAuthenticator(Context);
                try
                {
                    var result = await oauth.GetAuthAsync(targetUri, scope, CancellationToken.None);

                    if (!result.IsSuccess)
                    {
                        Trace.WriteLine($"oauth authentication failed");
                        return(new AuthenticationResult(AuthenticationResultType.Failure));
                    }

                    // We got a toke but lets check to see the usernames match.
                    var restRootUri = new Uri(_restRootUrl);
                    var userResult  = await(new RestClient(Context)).TryGetUser(targetUri, RequestTimeout, restRootUri, result.Token);

                    if (!userResult.IsSuccess)
                    {
                        Trace.WriteLine($"oauth user check failed");
                        return(new AuthenticationResult(AuthenticationResultType.Failure));
                    }

                    if (!string.IsNullOrWhiteSpace(userResult.RemoteUsername) && !credentials.Username.Equals(userResult.RemoteUsername))
                    {
                        Trace.WriteLine($"Remote username [{userResult.RemoteUsername}] != [{credentials.Username}] supplied username");
                        // Make sure the 'real' username is returned.
                        return(new AuthenticationResult(AuthenticationResultType.Success, result.Token, result.RefreshToken, userResult.RemoteUsername));
                    }

                    // Everything is hunky dory.
                    return(result);
                }
                catch (Exception ex)
                {
                    Trace.WriteLine($"oauth authentication failed [{ex.Message}]");
                    return(new AuthenticationResult(AuthenticationResultType.Failure));
                }
            }
            else
            {
                var basicauth = new BasicAuthAuthenticator(Context);
                try
                {
                    var restRootUri = new Uri(_restRootUrl);
                    return(await basicauth.GetAuthAsync(targetUri, scope, RequestTimeout, restRootUri, credentials));
                }
                catch (Exception ex)
                {
                    Trace.WriteLine($"basic authentication failed [{ex.Message}]");
                    return(new AuthenticationResult(AuthenticationResultType.Failure));
                }
            }
        }
        /// <inheritdoc/>
        public async Task <AuthenticationResult> AcquireToken(TargetUri targetUri, string username, string password, AuthenticationResultType resultType, TokenScope scope)
        {
            if (resultType == AuthenticationResultType.TwoFactor)
            {
                // a previous attempt to aquire a token failed in a way that suggests the user has
                // Bitbucket 2FA turned on. so attempt to run the OAuth dance...
                OAuth.OAuthAuthenticator oauth = new OAuth.OAuthAuthenticator();
                try
                {
                    return(await oauth.GetAuthAsync(targetUri, scope, CancellationToken.None));
                }
                catch (Exception ex)
                {
                    Trace.WriteLine($"oauth authentication failed [{ex.Message}]");
                    return(new AuthenticationResult(AuthenticationResultType.Failure));
                }
            }
            else
            {
                // use the provided username and password and attempt a Basic Auth request to a known
                // REST API resource.
                Token token = null;
                using (HttpClientHandler handler = targetUri.HttpClientHandler)
                {
                    using (HttpClient httpClient = new HttpClient(handler)
                    {
                        Timeout = TimeSpan.FromMilliseconds(RequestTimeout)
                    })
                    {
                        string basicAuthValue = String.Format("{0}:{1}", username, password);
                        byte[] authBytes      = Encoding.UTF8.GetBytes(basicAuthValue);
                        basicAuthValue = Convert.ToBase64String(authBytes);
                        httpClient.DefaultRequestHeaders.Add("Authorization", "Basic " + basicAuthValue);

                        var url = new Uri(new Uri(_restRootUrl), UserUrl).AbsoluteUri;
                        using (HttpResponseMessage response = await httpClient.GetAsync(url))
                        {
                            Trace.WriteLine($"server responded with {response.StatusCode}.");

                            switch (response.StatusCode)
                            {
                            case HttpStatusCode.OK:
                            case HttpStatusCode.Created:
                            {
                                // Success with username/passord indicates 2FA is not on so
                                // the 'token' is actually the password if we had a
                                // successful call then the password is good.
                                token = new Token(password, TokenType.Personal);

                                Trace.WriteLine("authentication success: new password token created.");
                                return(new AuthenticationResult(AuthenticationResultType.Success, token));
                            }

                            case HttpStatusCode.Forbidden:
                            {
                                // A 403/Forbidden response indicates the username/password
                                // are recognized and good but 2FA is on in which case we
                                // want to indicate that with the TwoFactor result
                                Trace.WriteLine("two-factor app authentication code required");
                                return(new AuthenticationResult(AuthenticationResultType.TwoFactor));
                            }

                            case HttpStatusCode.Unauthorized:
                            {
                                // username or password are wrong.
                                Trace.WriteLine("authentication failed");
                                return(new AuthenticationResult(AuthenticationResultType.Failure));
                            }

                            default:
                                // any unexpected result can be treated as a failure.
                                Trace.WriteLine("authentication failed");
                                return(new AuthenticationResult(AuthenticationResultType.Failure));
                            }
                        }
                    }
                }
            }
        }