/// <inheritdoc/>
        public override void DeleteCredentials(TargetUri targetUri, string username)
        {
            BaseSecureStore.ValidateTargetUri(targetUri);

            Trace.WriteLine($"Deleting Bitbucket Credentials for {targetUri.QueryUri}");

            Credential credentials = null;

            if ((credentials = PersonalAccessTokenStore.ReadCredentials(targetUri)) != null)
            {
                // try to delete the credentials for the explicit target uri first
                PersonalAccessTokenStore.DeleteCredentials(targetUri);
                Trace.WriteLine($"host credentials deleted for {targetUri.QueryUri}");
            }

            // tidy up and delete any related refresh tokens
            var refreshTargetUri = GetRefreshTokenTargetUri(targetUri);

            if ((credentials = PersonalAccessTokenStore.ReadCredentials(refreshTargetUri)) != null)
            {
                // try to delete the credentials for the explicit target uri first
                PersonalAccessTokenStore.DeleteCredentials(refreshTargetUri);
                Trace.WriteLine($"host refresh credentials deleted for {refreshTargetUri.QueryUri}");
            }

            // if we deleted per user then we should try and delete the host level credentials too if
            // they match the username
            if (targetUri.TargetUriContainsUsername)
            {
                var hostTargetUri   = new TargetUri(targetUri.ToString(false, true, true));
                var hostCredentials = GetCredentials(hostTargetUri);
                var encodedUsername = Uri.EscapeDataString(targetUri.TargetUriUsername);
                if (encodedUsername != username)
                {
                    Trace.WriteLine($"username {username} != targetUri userInfo {encodedUsername}");
                }

                if (hostCredentials != null && hostCredentials.Username.Equals(encodedUsername))
                {
                    DeleteCredentials(hostTargetUri, username);
                }
            }
        }
        /// <inheritdoc/>
        public async Task <Credential> ValidateCredentials(TargetUri targetUri, string username, Credential credentials)
        {
            BaseSecureStore.ValidateTargetUri(targetUri);
            BaseSecureStore.ValidateCredential(credentials);

            TargetUri userSpecificTargetUri;

            if (targetUri.TargetUriContainsUsername)
            {
                userSpecificTargetUri = targetUri;
            }
            else
            {
                userSpecificTargetUri = targetUri.GetPerUserTargetUri(username);
            }


            if (await BitbucketAuthority.ValidateCredentials(userSpecificTargetUri, username, credentials))
            {
                return(credentials);
            }

            var userSpecificRefreshCredentials = GetCredentials(GetRefreshTokenTargetUri(userSpecificTargetUri), username);

            // if there are refresh credentials it suggests it might be OAuth so we can try and
            // refresh the access_token and try again.
            if (userSpecificRefreshCredentials == null)
            {
                return(null);
            }

            Credential refreshedCredentials;

            if ((refreshedCredentials = await RefreshCredentials(userSpecificTargetUri, userSpecificRefreshCredentials.Password, username ?? credentials.Username)) != null)
            {
                return(refreshedCredentials);
            }

            return(null);
        }
Example #3
0
        /// <summary>
        /// Creates an interactive logon session, using ADAL secure browser GUI, which enables users to authenticate with the Azure tenant and acquire the necessary access tokens to exchange for a VSTS personal access token.
        /// <para/>
        /// Tokens acquired are stored in the secure secret stores provided during initialization.
        /// <para/>
        /// Return a `<see cref="Credential"/>` for resource access if successful; otherwise `<see langword="null"/>`.
        /// </summary>
        /// <param name="targetUri">The URI of the VSTS resource.</param>
        public async Task <Credential> InteractiveLogon(TargetUri targetUri, PersonalAccessTokenOptions options)
        {
            BaseSecureStore.ValidateTargetUri(targetUri);

            try
            {
                Token token;
                if ((token = await Authority.InteractiveAcquireToken(targetUri, ClientId, Resource, new Uri(RedirectUrl), null)) != null)
                {
                    Trace.WriteLine($"token acquisition for '{targetUri}' succeeded.");

                    return(await GeneratePersonalAccessToken(targetUri, token, options));
                }
            }
            catch (AuthenticationException)
            {
                Trace.WriteLine($"token acquisition for '{targetUri}' failed.");
            }

            Trace.WriteLine($"interactive logon for '{targetUri}' failed");
            return(null);
        }
Example #4
0
        public async Task <Credential> NoninteractiveLogon(TargetUri targetUri, bool requestCompactToken)
        {
            BaseSecureStore.ValidateTargetUri(targetUri);

            try
            {
                Token token;
                if ((token = await Authority.NoninteractiveAcquireToken(targetUri, ClientId, Resource, new Uri(RedirectUrl))) != null)
                {
                    Trace.WriteLine($"token acquisition for '{targetUri}' succeeded");

                    return(await GeneratePersonalAccessToken(targetUri, token, requestCompactToken));
                }
            }
            catch (AuthenticationException)
            {
                Trace.WriteLine($"failed to acquire for '{targetUri}' token from VstsAuthority.");
            }

            Trace.WriteLine($"non-interactive logon for '{targetUri}' failed");
            return(null);
        }
Example #5
0
        /// <summary>
        /// Opens an interactive logon prompt to acquire an authentication token from the Microsoft Live authentication and identity service.
        /// <para/>
        /// Returns a `<see cref="Credential"/>` for packing into a basic authentication header; otherwise `<see langword="null"/>`.
        /// </summary>
        /// <param name="targetUri">The URI of the resource access is being requested for.</param>
        /// <param name="requestCompactToken">`<see langword="true"/>` if requesting a compact format token; otherwise `<see langword="false"/>`.</param>
        public async Task <Credential> InteractiveLogon(TargetUri targetUri, bool requestCompactToken)
        {
            BaseSecureStore.ValidateTargetUri(targetUri);

            try
            {
                Token token;
                if ((token = await Authority.InteractiveAcquireToken(targetUri, ClientId, Resource, new Uri(RedirectUrl), QueryParameters)) != null)
                {
                    Trace.WriteLine($"token '{targetUri}' successfully acquired.");

                    return(await GeneratePersonalAccessToken(targetUri, token, requestCompactToken));
                }
            }
            catch (AuthenticationException exception)
            {
                Debug.Write(exception);
            }

            Trace.WriteLine($"failed to acquire token for '{targetUri}'.");
            return(null);
        }
        public async Task <bool> ValidateCredentials(TargetUri targetUri, Credential credentials)
        {
            const string ValidationUrl = "https://api.github.com/user/subscriptions";

            BaseSecureStore.ValidateTargetUri(targetUri);
            BaseSecureStore.ValidateCredential(credentials);

            string authString = String.Format("{0}:{1}", credentials.Username, credentials.Password);

            byte[] authBytes  = Encoding.UTF8.GetBytes(authString);
            string authEncode = Convert.ToBase64String(authBytes);

            // craft the request header for the GitHub v3 API w/ credentials
            using (HttpClientHandler handler = targetUri.HttpClientHandler)
                using (HttpClient httpClient = new HttpClient(handler)
                {
                    Timeout = TimeSpan.FromMilliseconds(RequestTimeout)
                })
                {
                    httpClient.DefaultRequestHeaders.Add("User-Agent", Global.UserAgent);
                    httpClient.DefaultRequestHeaders.Add("Accept", GitHubApiAcceptsHeaderValue);
                    httpClient.DefaultRequestHeaders.Add("Authorization", "Basic " + authEncode);

                    using (HttpResponseMessage response = await httpClient.GetAsync(ValidationUrl))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            Git.Trace.WriteLine($"credential validation for '{targetUri}' succeeded.");
                            return(true);
                        }
                        else
                        {
                            Git.Trace.WriteLine($"credential validation for '{targetUri}' failed.");
                            return(false);
                        }
                    }
                }
        }
        /// <summary>
        /// Identify the Hosting service from the the targetUri.
        /// </summary>
        /// <param name="targetUri"></param>
        /// <returns>
        /// A <see cref="BaseAuthentication"/> instance if the targetUri represents Bitbucket, null otherwise.
        /// </returns>
        public static BaseAuthentication GetAuthentication(TargetUri targetUri, ICredentialStore personalAccessTokenStore, AcquireCredentialsDelegate acquireCredentialsCallback, AcquireAuthenticationOAuthDelegate acquireAuthenticationOAuthCallback)
        {
            BaseAuthentication authentication = null;

            BaseSecureStore.ValidateTargetUri(targetUri);

            if (personalAccessTokenStore == null)
            {
                throw new ArgumentNullException(nameof(personalAccessTokenStore), $"The `{nameof(personalAccessTokenStore)}` is null or invalid.");
            }

            if (targetUri.QueryUri.DnsSafeHost.EndsWith(BitbucketBaseUrlHost, StringComparison.OrdinalIgnoreCase))
            {
                authentication = new Authentication(personalAccessTokenStore, acquireCredentialsCallback, acquireAuthenticationOAuthCallback);
                Trace.WriteLine("authentication for Bitbucket created");
            }
            else
            {
                authentication = null;
            }

            return(authentication);
        }
        /// <summary>
        /// Gets a configured authentication object for 'github.com'.
        /// </summary>
        /// <param name="targetUri">
        /// The uniform resource indicator of the resource which requires authentication.
        /// </param>
        /// <param name="tokenScope">The desired scope of any personal access tokens acquired.</param>
        /// <param name="personalAccessTokenStore">
        /// A secure secret store for any personal access tokens acquired.
        /// </param>
        /// <param name="authentication">(out) The authentication object if successful.</param>
        /// <returns>True if success; otherwise false.</returns>
        public static BaseAuthentication GetAuthentication(
            RuntimeContext context,
            TargetUri targetUri,
            TokenScope tokenScope,
            ICredentialStore personalAccessTokenStore,
            AcquireCredentialsDelegate acquireCredentialsCallback,
            AcquireAuthenticationCodeDelegate acquireAuthenticationCodeCallback,
            AuthenticationResultDelegate authenticationResultCallback)
        {
            BaseAuthentication authentication = null;

            BaseSecureStore.ValidateTargetUri(targetUri);
            if (personalAccessTokenStore == null)
            {
                throw new ArgumentNullException("personalAccessTokenStore", "The `personalAccessTokenStore` is null or invalid.");
            }

            if (targetUri.DnsSafeHost.EndsWith(GitHubBaseUrlHost, StringComparison.OrdinalIgnoreCase))
            {
                var normalizedTargetUri = NormalizeUri(targetUri);
                authentication = new Authentication(context,
                                                    normalizedTargetUri,
                                                    tokenScope,
                                                    personalAccessTokenStore,
                                                    acquireCredentialsCallback,
                                                    acquireAuthenticationCodeCallback,
                                                    authenticationResultCallback);
                context.Trace.WriteLine($"created GitHub authentication for '{normalizedTargetUri}'.");
            }
            else
            {
                authentication = null;
                context.Trace.WriteLine($"not github.com, authentication creation aborted.");
            }

            return(authentication);
        }
Example #9
0
        /// <inheritdoc/>
        public async Task <bool> ValidateCredentials(TargetUri targetUri, string username, Credential credentials)
        {
            BaseSecureStore.ValidateTargetUri(targetUri);
            BaseSecureStore.ValidateCredential(credentials);

            // We don't know when the credentials arrive here if they are using OAuth or Basic Auth,
            // so we try both.

            // Try the simplest Basic Auth first
            var authEncode = GetEncodedCredentials(username, credentials);

            if (await ValidateCredentials(targetUri, GetBasicAuthHeader(authEncode)))
            {
                return(true);
            }

            // if the Basic Auth test failed then try again as OAuth
            if (await ValidateCredentials(targetUri, GetBearerHeaderAuthHeader(credentials.Password)))
            {
                return(true);
            }

            return(false);
        }
Example #10
0
        /// <inheritdoc/>
        public async Task <bool> ValidateCredentials(TargetUri targetUri, string username, Credential credentials)
        {
            BaseSecureStore.ValidateTargetUri(targetUri);
            BaseSecureStore.ValidateCredential(credentials);

            // We don't know when the credentials arrive here if they are using OAuth or Basic Auth,
            // so we try both.

            // Try the simplest basic authentication first
            var authEncode = GetEncodedCredentials(username, credentials);

            if (await ValidateCredentials(targetUri, credentials))
            {
                return(true);
            }

            // If the basic authentication test failed then try again as OAuth
            if (await ValidateCredentials(targetUri, new Token(credentials.Password, TokenType.BitbucketPassword)))
            {
                return(true);
            }

            return(false);
        }