/// <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); }
/// <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); }
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; } }
public void WriteCredentials(TargetUri targetUri, Credential credentials) { // do nothing RecordMethodCall("WriteCredentials", new List <string>() { targetUri.ToString(), credentials.Username, credentials.Password }); }
public void DeleteCredentials(TargetUri targetUri) { // do nothing RecordMethodCall("DeleteCredentials", new List <string>() { targetUri.ToString() }); }
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); }