using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.BL.Entities; using Tango.Core.Commands; using Tango.Core.DI; using Tango.Core.ExtensionMethods; using Tango.Integration.ExternalBridge; using Tango.PMR.Integration; using Tango.PPC.Common; using Tango.PPC.Common.ExternalBridge; using Tango.PPC.Common.Navigation; using Tango.PPC.UI.Dialogs; namespace Tango.PPC.UI.ViewModels { /// /// Represents the external bridge view ViewModel. /// /// [TangoCreateWhenRegistered] public class ExternalBridgeViewVM : PPCViewModel { private bool _disconnecting; private const int KEEP_SAFETY_AUTHENTICATION_MINUTES = 5; #region Properties private ExternalBridgeClientConnectedEventArgs _connection; /// /// Gets or sets the last client connection event arguments. /// public ExternalBridgeClientConnectedEventArgs Connection { get { return _connection; } set { _connection = value; RaisePropertyChangedAuto(); } } private User _user; /// /// Gets or sets the user connected user. /// public User User { get { return _user; } set { _user = value; RaisePropertyChangedAuto(); } } #endregion #region Commands /// /// Gets or sets the close session command. /// public RelayCommand CloseSessionCommand { get; set; } #endregion #region Constructors /// /// Initializes a new instance of the class. /// public ExternalBridgeViewVM() { CloseSessionCommand = new RelayCommand(CloseSession, () => !_disconnecting); } #endregion #region Private Methods /// /// Closes the current session. /// private void CloseSession() { LogManager.Log("Disconnecting current external bridge session."); _disconnecting = true; InvalidateRelayCommands(); ExternalBridgeService.DisconnectFullControlSession(); } #endregion #region Override Methods /// /// Called when the navigation system has navigated to this VM view. /// public override void OnNavigatedTo() { base.OnNavigatedTo(); _disconnecting = false; InvalidateRelayCommands(); } /// /// Called when the application has been started. /// public override void OnApplicationStarted() { ExternalBridgeService.ConnectionRequest += ExternalBridgeService_ConnectionRequest; ExternalBridgeService.FullControlSessionDisconnected += ExternalBridgeService_FullControlSessionDisconnected; } #endregion #region Event Handlers /// /// Handles the event. /// /// The sender. /// The instance containing the event data. private void ExternalBridgeService_FullControlSessionDisconnected(object sender, EventArgs e) { if (IsVisible) { LogManager.Log("External bridge client disconnected. Navigating to home module..."); InvokeUI(() => { NavigationManager.NavigateTo(NavigationView.HomeModule); }); } } /// /// Handles the event. /// /// The sender. /// The instance containing the event data. private async void ExternalBridgeService_ConnectionRequest(object sender, ExternalBridgeClientConnectedEventArgs e) { LogManager.Log($"External bridge connection request received.\n{e.ToJsonString()}"); if (!e.Request.Intent.RequiresPassword() || e.Request.Password == Settings.ExternalBridgePassword) { e.ApplicationInformation.Version = ApplicationManager.VersionAndTag; e.ApplicationInformation.StartupDate = ApplicationManager.StartUpDate.ToUniversalTime().ToString(); Connection = e; User = Adapter.Users.SingleOrDefault(x => x.Guid == e.Request.UserGuid); if (User != null) { LogManager.Log($"External bridge connection user has been identified as {User.Contact.FullName}"); } if (e.Request.RequireSafetyLevelOperations) { DateTime lastAuthenticationTime; bool bypassSafetyConfirmation = false; if (ExternalBridgeReceiver.LastSafetyLevelContactsTimes.TryGetValue(e.Request.UserName, out lastAuthenticationTime)) { if (DateTime.Now < lastAuthenticationTime.AddMinutes(KEEP_SAFETY_AUTHENTICATION_MINUTES)) { bypassSafetyConfirmation = true; e.Confirm(); } } if (!bypassSafetyConfirmation) { SafetyLevelOperationsConfirmationViewVM vm = new SafetyLevelOperationsConfirmationViewVM(e); await NotificationProvider.ShowDialog(vm); if (vm.DialogResult) { e.Confirm(); } else { e.Decline("Safety level connection refused by the remote user."); return; } } } else { e.Confirm(); } if (e.Request.Intent == ExternalBridgeLoginIntent.FullControl) { LogManager.Log("Navigating to external bridge view..."); InvokeUI(() => { NavigationManager.NavigateTo(NavigationView.ExternalBridgeView, false); }); } } else { e.Decline("Connection password did not match the machine external bridge password."); LogManager.Log("Connection password did not match the machine external bridge password."); } } #endregion } }