ThrottleTimer _updateDisplayNameTimer; // Updates the display name when the throttle interval expires public SignInStatusControl() { DefaultStyleKey = typeof(SignInStatusControl); DataContext = this; // Initialize the display name update timer. Multiple credential change events may fire in // rapid succession. Throttling them makes it so that the display name update only fires once, // after all the change events are complete. _updateDisplayNameTimer = new ThrottleTimer(20, () => updateUserDisplayName()); updateSignOutVisibility(); }
void rectangle_MouseLeave(object sender, MouseEventArgs e) { ThrottleTimer timer = new ThrottleTimer(200, delegate() { if (!_isMouseOverContextMenu) { rangeContextMenuPopup.IsOpen = false; } timer = null; }); timer.Invoke(); }
private IdentityManager.Credential cachedCredential; // Credential that was just retrieved from sign-in // Raised when an authentication challenge occurs in the application private async void OnChallenge(string url, Action<IdentityManager.Credential, Exception> callback, IdentityManager.GenerateTokenOptions options = null) { if (signedOut) // Sign-out occurred within the last two seconds. Do not prompt for login. { callback(null, null); return; } var uri = new Uri(url); var tree = uri.AbsolutePath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); if (tree[tree.Length - 2].ToLower() == "services" && tree[tree.Length - 3].ToLower() == "rest") { // Challenge is coming from a secure folder. Do not prompt. callback(null, null); return; } // In some cases, multiple challenges are raised for resources at the same endpoint (e.g. tiles from // hosted tile services in ArcGIS Online). To keep the user from being prompted to login multiple times // in succession, each new credential is cached for a half-second. If another challenge is raised // within a half second, and the domain of the current challenge matches that of the cached credential, // then the cached credential is used. // Initialize timer for clearing cached credential if (credentialCacheTimer == null) { credentialCacheTimer = new ThrottleTimer(2000, () => cachedCredential = null); } // If there is a credential cached, then sign-in has just occurred. Check to see if the saved // should also be used for this challenge if (cachedCredential != null) { try { // check whether the domain of the currently requested URL matches that of the cached credential if ((new Uri(url)).Domain().ToLower() == (new Uri(cachedCredential.Url).Domain().ToLower())) { // Domains match, so use the cached credential callback(cachedCredential, null); return; } } catch { } } // Sometimes challenges are raised after sign-in is cancelled. To avoid prompting the user after // cancellation, this timer will suppress challenges for two seconds. // Initialize timer for resetting sign-in cancellation tracking if (signInCancelledTimer == null) { signInCancelledTimer = new ThrottleTimer(2000, () => { // Two seconds has expired since sign-in was cancelled. Reset tracking variables. signInCancelled = false; signInCancelUrl = null; }); } // Check whether sign-in has been cancelled within two seconds if (signInCancelled && !string.IsNullOrEmpty(signInCancelUrl)) { try { // Check whether the domain of the requested URL matches that for the cancelled sign-in Uri requestUri = new Uri(url); Uri cancelUri = new Uri(signInCancelUrl); if (requestUri.Domain().Equals(cancelUri.Domain(), StringComparison.OrdinalIgnoreCase) && requestUri.AbsolutePath.Equals(cancelUri.AbsolutePath, StringComparison.OrdinalIgnoreCase)) { // Domains match - do not prompt user callback(null, null); return; } } catch { } } var proxyUrl = options != null ? options.ProxyUrl : null; // Sign in suppression checks passed. Try to authenticate using existing credentials // Try existing credentials IdentityManager.Credential cred = await ApplicationHelper.TryExistingCredentials(url, proxyUrl); if (cred != null) { // The existing credentials were sufficient for authentication. // If the request was for a URL in the current ArcGIS Portal, sign into Portal if (await url.IsFederatedWithPortal()) await ApplicationHelper.SignInToPortal(cred); // If there is not already a credential in the app's credentials collection that has the // same URL, add this one to the collection if (!UserManagement.Current.Credentials.Any(c => c.Url != null && c.Url.Equals(cred.Url, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(c.Token))) UserManagement.Current.Credentials.Add(cred); // Pass the credential to the callback callback(cred, null); return; } // Try just getting a credential for the URL without specifying login info. This can work if // the browser has authenticated the user (e.g. using PKI or IWA auth) try { cred = await IdentityManager.Current.GenerateCredentialTaskAsyncEx(url, options); } catch { } // Swallow authorization exception if (cred != null) { callback(cred, null); return; } // Existing credentials were insufficient. Prompt user to sign in. SignInCommand signInCommand = null; if (await url.IsFederatedWithPortal()) // Sign into ArcGIS portal signInCommand = new SignInToAGSOLCommand() { ProxyUrl = proxyUrl }; else // Sign into ArcGIS Server signInCommand = new SignInToServerCommand() { Url = url, ProxyUrl = proxyUrl }; signInCommand.SignedIn += (o, e) => { // Temporarily store the credential and start the timer. This allows this credential // to be re-used if there is another challenge with the same domain within a couple // seconds of sign-in. cachedCredential = e.Credential; credentialCacheTimer.Invoke(); // Pass the retrieved credential to the callback callback(e.Credential, null); }; signInCommand.Cancelled += (o, e) => { // Set the flags indicating that sign-in was cancelled and start the timer. If another // challenge for the same resouce is raised within the next couple seconds, it is assumed // that the user should not be prompted because cancellation of sign-in has just occurred. signInCancelled = true; signInCancelUrl = url; signInCancelledTimer.Invoke(); // Pass the retrieved credential to the callback callback(null, null); }; // Promt user to sign-in signInCommand.Execute(null); }
// Raised when the set of credentials retrieved for the application changes private void Credentials_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.OldItems != null || (e.Action == NotifyCollectionChangedAction.Reset)) { if (signedOutTimer == null) signedOutTimer = new ThrottleTimer(2000, () => signedOut = false); signedOut = true; signedOutTimer.Invoke(); } }