diff --git a/src/DynamoCore/Core/AuthenticationManager.cs b/src/DynamoCore/Core/AuthenticationManager.cs index 55c0fb05fee..37d743863bf 100644 --- a/src/DynamoCore/Core/AuthenticationManager.cs +++ b/src/DynamoCore/Core/AuthenticationManager.cs @@ -126,5 +126,20 @@ private void OnLoginStateChanged(LoginState status) } } + /// + /// Returns whether the IDSDK is initialized or not for Dynamo Sandbox, in host environment defaults to true. + /// + internal bool IsIDSDKInitialized() + { + if (authProvider is IDSDKManager idsdkProvider) + { + if (!idsdkProvider.IsIDSDKInitialized) + { + return false; + } + } + return true; + } + } } diff --git a/src/DynamoCore/Core/IDSDKManager.cs b/src/DynamoCore/Core/IDSDKManager.cs index 52666abe369..f5640547e24 100644 --- a/src/DynamoCore/Core/IDSDKManager.cs +++ b/src/DynamoCore/Core/IDSDKManager.cs @@ -24,29 +24,27 @@ public class IDSDKManager : IOAuth2AuthProvider, IOAuth2AccessTokenProvider, IOA public event Action LoginStateChanged; /// - /// The event is fired when IDSDK initialization fails - /// - internal event EventHandler ErrorInitializingIDSDK; - - /// - /// The flag is used to prevent multiple error messages from being shown, since initialization error can be thrown multiple times. + /// Returns the login status of the current session. /// - internal bool isErrorInitializingMsgShown; - private void OnErrorInitializingIDSDK() + /// LoginState Enum value + public LoginState LoginState { - ErrorInitializingIDSDK?.Invoke(this, EventArgs.Empty); + get + { + var result = IDSDK_IsLoggedIn(); + return result ? LoginState.LoggedIn : LoginState.LoggedOut; + } } /// - /// Returns the login status of the current session. + /// Returns the status of IDSDK installation, will return false if IDSDK fails to initialize. /// /// LoginState Enum value - public LoginState LoginState + public bool IsIDSDKInitialized { get { - var result = IDSDK_IsLoggedIn(); - return result ? LoginState.LoggedIn : LoginState.LoggedOut; + return Initialize(); } } @@ -167,7 +165,7 @@ private bool IDSDK_Login() } else { - if (Initialize()) + if (IsIDSDKInitialized) { idsdk_status_code statusCode = Client.Login(); if (Client.IsSuccess(statusCode)) @@ -180,7 +178,7 @@ private bool IDSDK_Login() } private bool IDSDK_IsLoggedIn() { - if (Initialize()) + if (IsIDSDKInitialized) { bool ret = Client.IsLoggedIn(); return ret; @@ -244,7 +242,6 @@ private bool Initialize() { if (Client.IsInitialized()) { - isErrorInitializingMsgShown = false; return true; } @@ -264,7 +261,6 @@ private bool Initialize() Client.LoginCompleteEvent += AuthCompleteEventHandler; ret = SetProductConfigs(Configurations.DynamoAsString, server, client_id); Client.SetServer(server); - isErrorInitializingMsgShown = false; return ret; } } @@ -274,8 +270,6 @@ private bool Initialize() { DynamoConsoleLogger.OnLogMessageToDynamoConsole("An error occurred while initializing Auth Service (IDSDK)."); } - - OnErrorInitializingIDSDK(); return false; } private bool Deinitialize() diff --git a/src/DynamoCore/PublicAPI.Unshipped.txt b/src/DynamoCore/PublicAPI.Unshipped.txt index 1f44be2830e..f87678d8cef 100644 --- a/src/DynamoCore/PublicAPI.Unshipped.txt +++ b/src/DynamoCore/PublicAPI.Unshipped.txt @@ -364,6 +364,7 @@ Dynamo.Core.IDSDKManager Dynamo.Core.IDSDKManager.Dispose() -> void Dynamo.Core.IDSDKManager.GetAccessToken() -> string Dynamo.Core.IDSDKManager.IDSDKManager() -> void +Dynamo.Core.IDSDKManager.IsIDSDKInitialized.get -> bool Dynamo.Core.IDSDKManager.IsLoggedIn() -> bool Dynamo.Core.IDSDKManager.Login() -> bool Dynamo.Core.IDSDKManager.LoginState.get -> Greg.AuthProviders.LoginState diff --git a/src/DynamoCoreWpf/Controls/ShortcutToolbar.xaml.cs b/src/DynamoCoreWpf/Controls/ShortcutToolbar.xaml.cs index a5a9539799a..4656a03dd1d 100644 --- a/src/DynamoCoreWpf/Controls/ShortcutToolbar.xaml.cs +++ b/src/DynamoCoreWpf/Controls/ShortcutToolbar.xaml.cs @@ -126,6 +126,7 @@ private void exportMenu_MouseLeave(object sender, System.Windows.Input.MouseEven private void LoginButton_OnClick(object sender, RoutedEventArgs e) { + if(!DynamoViewModel.IsIDSDKInitialized()) return; if (authManager.LoginState == LoginState.LoggedIn) { var button = (Button)sender; @@ -149,6 +150,7 @@ private void LoginButton_OnClick(object sender, RoutedEventArgs e) private void LogoutOption_Click(object sender, RoutedEventArgs e) { + if (!DynamoViewModel.IsIDSDKInitialized()) return; if (authManager.LoginState == LoginState.LoggedIn) { var result = Wpf.Utilities.MessageBoxService.Show(Application.Current?.MainWindow, Wpf.Properties.Resources.SignOutConfirmationDialogText, Wpf.Properties.Resources.SignOutConfirmationDialogTitle,MessageBoxButton.OKCancel, new List() { "Sign Out", "Cancel"}, MessageBoxImage.Information); diff --git a/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs b/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs index 634637d2c01..3194dace4b5 100644 --- a/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs @@ -863,10 +863,7 @@ protected DynamoViewModel(StartConfiguration startConfiguration) FileTrustViewModel = new FileTrustWarningViewModel(); MLDataPipelineExtension = model.ExtensionManager.Extensions.OfType().FirstOrDefault(); - if (Model.AuthenticationManager?.AuthProvider is IDSDKManager idsdkProvider) - { - idsdkProvider.ErrorInitializingIDSDK += OnErrorInitializingIDSDK; - } + IsIDSDKInitialized(); } private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) @@ -1088,18 +1085,22 @@ internal void OnNodeViewReady(object nodeView) } /// - /// The event handler for cases when IDSDK fails to initialize, probably because of missing Adsk Identity Manager. - /// A flag is used to show the error message only once per session. + /// Returns whether the IDSDK is initialized or not for Dynamo Sandbox, in host environment defaults to true. + /// If showWarning is true, a warning message will be shown to the user if the IDSDK is not initialized. + /// If owner is not null, the warning message will be shown as a dialog with the owner as the parent. /// - private void OnErrorInitializingIDSDK(object sender, EventArgs e) + internal bool IsIDSDKInitialized(bool showWarning = true, Window owner = null) { - if (Model.AuthenticationManager?.AuthProvider is IDSDKManager idsdkProvider) + if (!Model.AuthenticationManager.IsIDSDKInitialized()) { - if (idsdkProvider.isErrorInitializingMsgShown) return; - - DynamoMessageBox.Show(Owner, WpfResources.IDSDKErrorMessage, WpfResources.IDSDKErrorMessageTitle, true, MessageBoxButton.OK, MessageBoxImage.Information); - idsdkProvider.isErrorInitializingMsgShown = true; + if (showWarning) + { + var ownerWindow = owner ?? Owner ?? System.Windows.Application.Current.MainWindow; + DynamoMessageBox.Show(ownerWindow, WpfResources.IDSDKErrorMessage, WpfResources.IDSDKErrorMessageTitle, true, MessageBoxButton.OK, MessageBoxImage.Information); + } + return false; } + return true; } #region Event handler destroy/create @@ -1123,10 +1124,6 @@ protected virtual void UnsubscribeAllEvents() DynamoSelection.Instance.Selection.CollectionChanged -= SelectionOnCollectionChanged; UsageReportingManager.Instance.PropertyChanged -= CollectInfoManager_PropertyChanged; - if (Model.AuthenticationManager?.AuthProvider is IDSDKManager idsdkProvider) - { - idsdkProvider.ErrorInitializingIDSDK -= OnErrorInitializingIDSDK; - } } private void InitializeRecentFiles() diff --git a/src/DynamoCoreWpf/ViewModels/Core/PortViewModel.cs b/src/DynamoCoreWpf/ViewModels/Core/PortViewModel.cs index c18c7cf5015..84771b2bca9 100644 --- a/src/DynamoCoreWpf/ViewModels/Core/PortViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/Core/PortViewModel.cs @@ -502,8 +502,15 @@ private void AutoCompleteCluster(object parameter) if (wsViewModel.DynamoViewModel.IsDNAClusterPlacementEnabled) { - MLNodeClusterAutoCompletionResponse results = wsViewModel.NodeAutoCompleteSearchViewModel.GetMLNodeClusterAutocompleteResults(); - wsViewModel.OnRequestNodeAutoCompleteViewExtension(results); + try + { + MLNodeClusterAutoCompletionResponse results = wsViewModel.NodeAutoCompleteSearchViewModel.GetMLNodeClusterAutocompleteResults(); + wsViewModel.OnRequestNodeAutoCompleteViewExtension(results); + } + catch (Exception e) + { + // Log the exception and show a notification to the user + } } } diff --git a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerClientViewModel.cs b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerClientViewModel.cs index 14fa58bd383..116a616f867 100644 --- a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerClientViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerClientViewModel.cs @@ -284,6 +284,7 @@ internal PackageManagerClientViewModel(DynamoViewModel dynamoViewModel, PackageM private void ToggleLoginState() { + if(!this.DynamoViewModel.IsIDSDKInitialized()) return; if (AuthenticationManager.LoginState == LoginState.LoggedIn) { AuthenticationManager.Logout(); @@ -301,6 +302,7 @@ private bool CanToggleLoginState() public void PublishCurrentWorkspace(object m) { + if (!this.DynamoViewModel.IsIDSDKInitialized(true, ViewModelOwner)) return; var ws = (CustomNodeWorkspaceModel)DynamoViewModel.CurrentSpace; CustomNodeDefinition currentFunDef; @@ -346,6 +348,7 @@ public bool CanPublishCurrentWorkspace(object m) public void PublishNewPackage(object m) { + if (!this.DynamoViewModel.IsIDSDKInitialized(true, ViewModelOwner)) return; var termsOfUseCheck = new TermsOfUseHelper(new TermsOfUseHelperParams { PackageManagerClient = Model, @@ -365,6 +368,7 @@ public bool CanPublishNewPackage(object m) public void PublishCustomNode(Function m) { + if (!this.DynamoViewModel.IsIDSDKInitialized(true, ViewModelOwner)) return; CustomNodeInfo currentFunInfo; if (DynamoViewModel.Model.CustomNodeManager.TryGetNodeInfo( m.Definition.FunctionId, @@ -394,6 +398,7 @@ public bool CanPublishCustomNode(Function m) public void PublishSelectedNodes(object m) { + if (!this.DynamoViewModel.IsIDSDKInitialized(true, ViewModelOwner)) return; var nodeList = DynamoSelection.Instance.Selection .Where(x => x is Function) .Cast() @@ -453,12 +458,14 @@ public bool CanPublishSelectedNodes(object m) private void ShowNodePublishInfo() { + if (!this.DynamoViewModel.IsIDSDKInitialized(true, ViewModelOwner)) return; var newPkgVm = new PublishPackageViewModel(DynamoViewModel); DynamoViewModel.OnRequestPackagePublishDialog(newPkgVm); } private void ShowNodePublishInfo(ICollection> funcDefs) { + if (!this.DynamoViewModel.IsIDSDKInitialized(true, ViewModelOwner)) return; foreach (var f in funcDefs) { var pkg = PackageManagerExtension.PackageLoader.GetOwnerPackage(f.Item1); @@ -513,6 +520,7 @@ public List ListAll() /// public List GetInfectedPackages() { + if (!this.DynamoViewModel.IsIDSDKInitialized(true, ViewModelOwner)) return null; InfectedPackageList = new List(); var latestPkgs = Model.GetUsersLatestPackages(); if (latestPkgs != null && latestPkgs.maintains?.Count > 0) @@ -537,6 +545,7 @@ public List GetInfectedPackages() public void DownloadAndInstallPackage(IPackageInfo packageInfo, string downloadPath = null) { // User needs to accept terms of use before any packages can be downloaded from package manager + if (!this.DynamoViewModel.IsIDSDKInitialized(true, ViewModelOwner)) return; var prefSettings = DynamoViewModel.Model.PreferenceSettings; var touAccepted = prefSettings.PackageDownloadTouAccepted; if (!touAccepted) diff --git a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageViewModel.cs b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageViewModel.cs index b10af531d78..fa85655ac7c 100644 --- a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageViewModel.cs @@ -467,6 +467,7 @@ private void PublishNewPackage() private void ExecuteWithTou(Action acceptanceCallback) { + if (!dynamoViewModel.IsIDSDKInitialized(true, packageManagerClientViewModel.ViewModelOwner)) return; // create TermsOfUseHelper object to check asynchronously whether the Terms of Use has // been accepted, and if so, continue to execute the provided Action. var termsOfUseCheck = new TermsOfUseHelper(new TermsOfUseHelperParams diff --git a/src/DynamoCoreWpf/ViewModels/PackageManager/PublishPackageViewModel.cs b/src/DynamoCoreWpf/ViewModels/PackageManager/PublishPackageViewModel.cs index e238dcd1d9e..c36dcdb13fa 100644 --- a/src/DynamoCoreWpf/ViewModels/PackageManager/PublishPackageViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/PackageManager/PublishPackageViewModel.cs @@ -2277,6 +2277,7 @@ private void AddDllFile(string filename) /// Delegate used to submit the publish online request private void Submit() { + if (!dynamoViewModel.IsIDSDKInitialized(true, Owner)) return; MessageBoxResult response = DynamoModel.IsTestMode ? MessageBoxResult.OK : MessageBoxService.Show(Owner, Resources.PrePackagePublishMessage, Resources.PrePackagePublishTitle, MessageBoxButton.OKCancel, MessageBoxImage.Information); if (response == MessageBoxResult.Cancel) { diff --git a/src/DynamoCoreWpf/ViewModels/Search/NodeAutoCompleteSearchViewModel.cs b/src/DynamoCoreWpf/ViewModels/Search/NodeAutoCompleteSearchViewModel.cs index 031134a577e..4599b4dd77a 100644 --- a/src/DynamoCoreWpf/ViewModels/Search/NodeAutoCompleteSearchViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/Search/NodeAutoCompleteSearchViewModel.cs @@ -429,11 +429,15 @@ internal void ShowNodeAutocompleMLResults() private MLNodeAutoCompletionResponse GetMLNodeAutocompleteResults(string requestJSON) { MLNodeAutoCompletionResponse results = null; - var authProvider = dynamoViewModel.Model.AuthenticationManager.AuthProvider; - - if (authProvider is IOAuth2AuthProvider oauth2AuthProvider && authProvider is IOAuth2AccessTokenProvider tokenprovider) + try { - try + var authProvider = dynamoViewModel.Model.AuthenticationManager.AuthProvider; + if (!dynamoViewModel.IsIDSDKInitialized()) + { + throw new Exception("IDSDK missing or failed initialization."); + } + + if (authProvider is IOAuth2AuthProvider oauth2AuthProvider && authProvider is IOAuth2AccessTokenProvider tokenprovider) { var uri = DynamoUtilities.PathHelper.GetServiceBackendAddress(this, nodeAutocompleteMLEndpoint); var client = new RestClient(uri); @@ -450,11 +454,11 @@ private MLNodeAutoCompletionResponse GetMLNodeAutocompleteResults(string request //TODO maybe worth moving to system.text json in phases? results = JsonConvert.DeserializeObject(response.Content); } - catch (Exception ex) - { - dynamoViewModel.Model.Logger.Log(ex.Message); - throw new Exception("Authentication failed."); - } + } + catch (Exception ex) + { + dynamoViewModel.Model.Logger.Log(ex.Message); + throw new Exception("Authentication failed."); } return results; @@ -464,37 +468,48 @@ private MLNodeAutoCompletionResponse GetMLNodeAutocompleteResults(string request internal MLNodeClusterAutoCompletionResponse GetMLNodeClusterAutocompleteResults() { MLNodeClusterAutoCompletionResponse results = null; + try + { + var MLRequest = GenerateRequestForMLAutocomplete(); + string jsonRequest = JsonConvert.SerializeObject(MLRequest); - var MLRequest = GenerateRequestForMLAutocomplete(); - string jsonRequest = JsonConvert.SerializeObject(MLRequest); - - var authProvider = dynamoViewModel.Model.AuthenticationManager.AuthProvider; + var authProvider = dynamoViewModel.Model.AuthenticationManager.AuthProvider; + if (!dynamoViewModel.IsIDSDKInitialized()) + { + throw new Exception("IDSDK missing or failed initialization."); + } - if (authProvider is IOAuth2AuthProvider oauth2AuthProvider && authProvider is IOAuth2AccessTokenProvider tokenprovider) - { - try + if (authProvider is IOAuth2AuthProvider oauth2AuthProvider && authProvider is IOAuth2AccessTokenProvider tokenprovider) { - var uri = DynamoUtilities.PathHelper.GetServiceBackendAddress(this, nodeClusterAutocompleteMLEndpoint); - var client = new RestClient(uri); - var request = new RestRequest(string.Empty, Method.Post); - var tkn = tokenprovider?.GetAccessToken(); - if (string.IsNullOrEmpty(tkn)) + try { - throw new Exception("Authentication required."); - } - request.AddHeader("Authorization", $"Bearer {tkn}"); - request = request.AddJsonBody(jsonRequest); - request.RequestFormat = DataFormat.Json; - RestResponse response = client.Execute(request); + var uri = DynamoUtilities.PathHelper.GetServiceBackendAddress(this, nodeClusterAutocompleteMLEndpoint); + var client = new RestClient(uri); + var request = new RestRequest(string.Empty, Method.Post); + var tkn = tokenprovider?.GetAccessToken(); + if (string.IsNullOrEmpty(tkn)) + { + throw new Exception("Authentication required."); + } + request.AddHeader("Authorization", $"Bearer {tkn}"); + request = request.AddJsonBody(jsonRequest); + request.RequestFormat = DataFormat.Json; + RestResponse response = client.Execute(request); - results = JsonConvert.DeserializeObject(response.Content); - } - catch (Exception ex) - { - dynamoViewModel.Model.Logger.Log(ex.Message); - throw new Exception("Authentication failed."); + results = JsonConvert.DeserializeObject(response.Content); + } + catch (Exception ex) + { + dynamoViewModel.Model.Logger.Log(ex.Message); + throw new Exception("Authentication failed."); + } } } + catch (Exception ex) + { + dynamoViewModel.Model.Logger.Log(ex.Message); + throw new Exception("Authentication failed."); + } return results; }