/// <summary>
        /// Deletes a `<see cref="Credential"/>` from the storage used by the authentication object.
        /// </summary>
        /// <param name="targetUri">The uniform resource indicator used to uniquely identify the credentials.</param>
        public override async Task <bool> DeleteCredentials(TargetUri targetUri)
        {
            if (targetUri is null)
            {
                throw new ArgumentNullException(nameof(targetUri));
            }

            Credential credentials = await PersonalAccessTokenStore.ReadCredentials(targetUri);

            // Attempt to validate the credentials, if they're truly invalid delete them.
            if (!await ValidateCredentials(targetUri, credentials))
            {
                await PersonalAccessTokenStore.DeleteCredentials(targetUri);

                // Remove any related entries from the tenant cache because tenant change
                // could the be source of the invalidation, and not purging the cache will
                // trap the user in a limbo state of invalid credentials.

                // Deserialize the cache and remove any matching entry.
                string tenantUrl = targetUri.ToString();
                var    cache     = await DeserializeTenantCache(Context);

                // Attempt to remove the URL entry, if successful serialize the cache.
                if (cache.Remove(tenantUrl))
                {
                    await SerializeTenantCache(Context, cache);
                }

                return(true);
            }

            return(false);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Returns the properly formatted URL for the Azure authority given a tenant identity.
        /// </summary>
        /// <param name="tenantId">Identity of the tenant.</param>
        internal static string GetTargetUrl(TargetUri targetUri, bool keepUsername)
        {
            if (targetUri is null)
            {
                throw new ArgumentNullException(nameof(targetUri));
            }

            string requestUrl = targetUri.ToString(keepUsername, true, false);

            if (targetUri.Host.EndsWith(AzureBaseUrlHost, StringComparison.OrdinalIgnoreCase))
            {
                // Handle the Azure design where URL path is required to discover the authority.
                if (targetUri.ActualUri != null &&
                    targetUri.ActualUri.IsAbsoluteUri &&
                    targetUri.ActualUri.AbsolutePath.Length > 1)
                {
                    // Use the first segment of the actual URL to build the URL necessary to discover the authority.
                    requestUrl = requestUrl + targetUri.ActualUri.Segments[1];
                }
                // Handle the generic Azure {username}@{host} -> {host}/{username} transformation.
                else if (targetUri.ContainsUserInfo)
                {
                    string escapedUserInfo = Uri.EscapeUriString(targetUri.UserInfo);

                    requestUrl = $"{requestUrl}{escapedUserInfo}/";
                }
            }

            return(requestUrl);
        }
Exemplo n.º 3
0
        public async Task VerifySetCredentialStoresValidCredentials()
        {
            var targetUri       = new TargetUri("https://example.com");
            var credentialStore = new MockCredentialStore();
            var credentials     = new Credential("a", "b");
            var bbAuth          = new Authentication(RuntimeContext.Default, credentialStore, null, null);

            try
            {
                await bbAuth.SetCredentials(targetUri, credentials);

                var writeCalls = credentialStore.MethodCalls
                                 .Where(mc => mc.Key.Equals("WriteCredentials"))
                                 .SelectMany(mc => mc.Value)
                                 .Where(wc => wc.Key.Contains(targetUri.ToString()) &&
                                        wc.Key.Contains(credentials.Username) &&
                                        wc.Key.Contains(credentials.Password));

                Assert.Single(writeCalls);
            }
            catch (AggregateException exception)
            {
                exception = exception.Flatten();
                throw exception.InnerException;
            }
        }
Exemplo n.º 4
0
 public void WriteCredentials(TargetUri targetUri, Credential credentials)
 {
     // do nothing
     RecordMethodCall("WriteCredentials", new List <string>()
     {
         targetUri.ToString(), credentials.Username, credentials.Password
     });
 }
Exemplo n.º 5
0
 public void DeleteCredentials(TargetUri targetUri)
 {
     // do nothing
     RecordMethodCall("DeleteCredentials", new List <string>()
     {
         targetUri.ToString()
     });
 }
Exemplo n.º 6
0
 public Credential ReadCredentials(TargetUri targetUri)
 {
     // do nothing
     RecordMethodCall("ReadCredentials", new List <string>()
     {
         targetUri.ToString()
     });
     return(null);
 }
        /// <inheritdoc/>
        public override async Task <bool> DeleteCredentials(TargetUri targetUri, string username)
        {
            if (targetUri is null)
            {
                throw new ArgumentNullException(nameof(targetUri));
            }

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

            Credential credentials = null;

            if ((credentials = await PersonalAccessTokenStore.ReadCredentials(targetUri)) != null)
            {
                // try to delete the credentials for the explicit target uri first
                await 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 = await PersonalAccessTokenStore.ReadCredentials(refreshTargetUri)) != null)
            {
                // try to delete the credentials for the explicit target uri first
                await 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 = await 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))
                {
                    await DeleteCredentials(hostTargetUri, username);
                }
            }

            return(true);
        }
        internal Credential ModalPromptForCredentials(TargetUri targetUri)
        {
            string message = string.Format("Enter your credentials for {0}.", targetUri.ToString(username: false, port: true, path: true));

            if (!string.IsNullOrEmpty(targetUri.QueryUri.UserInfo))
            {
                string username = targetUri.QueryUri.UserInfo;

                if (!targetUri.QueryUri.UserEscaped)
                {
                    username = Uri.UnescapeDataString(username);
                }

                return(ModalPromptForPassword(targetUri, message, username));
            }

            return(ModalPromptForCredentials(targetUri, message));
        }
        public void VerifySetCredentialStoresValidCredentials()
        {
            var targetUri       = new TargetUri("https://example.com");
            var credentialStore = new MockCredentialStore();
            var credentials     = new Credential("a", "b");
            var bbAuth          = new Authentication(credentialStore, null, null);

            bbAuth.SetCredentials(targetUri, credentials);

            var writeCalls = credentialStore.MethodCalls
                             .Where(mc => mc.Key.Equals("WriteCredentials"))
                             .SelectMany(mc => mc.Value)
                             .Where(wc => wc.Key.Contains(targetUri.ToString()) &&
                                    wc.Key.Contains(credentials.Username) &&
                                    wc.Key.Contains(credentials.Password));

            Assert.Single(writeCalls);
        }
        internal static string GetSecretKey(TargetUri targetUri, string prefix)
        {
            if (targetUri is null)
            {
                throw new ArgumentNullException(nameof(targetUri));
            }
            if (string.IsNullOrWhiteSpace(prefix))
            {
                throw new ArgumentNullException(prefix);
            }

            // When the full path is specified, there's no reason to assume the path; otherwise attempt to
            // detect the actual target path information.
            string targetUrl = (IsAzureDevOpsUrl(targetUri) && !targetUri.HasPath)
                ? GetTargetUrl(targetUri, true)
                : targetUri.ToString(true, true, true);

            targetUrl = targetUrl.TrimEnd('/', '\\');

            return($"{prefix}:{targetUrl}");
        }
        private string GetGrantUrl(TargetUri targetUri, string authCode)
        {
            var tokenUrl = $"{TokenUri}?grant_type=authorization_code&code={authCode}&client_id={ConsumerKey}&client_secret={ConsumerSecret}&state=authenticated";

            return(new Uri(new Uri(targetUri.ToString()), tokenUrl).AbsoluteUri);
        }