diff --git a/mRemoteNGTests/Config/Serializers/DataTableDeserializerTests.cs b/mRemoteNGTests/Config/Serializers/DataTableDeserializerTests.cs index 8d7cc77f..a01c0027 100644 --- a/mRemoteNGTests/Config/Serializers/DataTableDeserializerTests.cs +++ b/mRemoteNGTests/Config/Serializers/DataTableDeserializerTests.cs @@ -1,4 +1,5 @@ using System.Data; +using System.Linq; using System.Security; using mRemoteNG.Config.Serializers.MsSql; using mRemoteNG.Connection; @@ -6,7 +7,6 @@ using mRemoteNG.Security; using mRemoteNG.Security.SymmetricEncryption; using mRemoteNG.Tree; using mRemoteNGTests.TestHelpers; -using NSubstitute; using NUnit.Framework; namespace mRemoteNGTests.Config.Serializers @@ -29,7 +29,7 @@ namespace mRemoteNGTests.Config.Serializers var dataTable = CreateDataTable(model.RootNodes[0]); _deserializer = new DataTableDeserializer(_cryptographyProvider, new SecureString()); var output = _deserializer.Deserialize(dataTable); - Assert.That(output.GetRecursiveChildList().Count, Is.EqualTo(model.GetRecursiveChildList().Count)); + Assert.That(output.ConnectionRecords.FlattenConnectionTree().Count(), Is.EqualTo(model.GetRecursiveChildList().Count)); } [Test] @@ -38,7 +38,7 @@ namespace mRemoteNGTests.Config.Serializers var dataTable = CreateDataTable(new ConnectionInfo()); _deserializer = new DataTableDeserializer(_cryptographyProvider, new SecureString()); var output = _deserializer.Deserialize(dataTable); - Assert.That(output.GetRecursiveChildList().Count, Is.EqualTo(1)); + Assert.That(output.ConnectionRecords.FlattenConnectionTree().Count(), Is.EqualTo(1)); } diff --git a/mRemoteNGTests/Config/Serializers/DataTableSerializerTests.cs b/mRemoteNGTests/Config/Serializers/DataTableSerializerTests.cs index 6292419a..d530786b 100644 --- a/mRemoteNGTests/Config/Serializers/DataTableSerializerTests.cs +++ b/mRemoteNGTests/Config/Serializers/DataTableSerializerTests.cs @@ -1,15 +1,12 @@ using System.Linq; using System.Security; -using mRemoteNG.Config.Serializers; using mRemoteNG.Config.Serializers.MsSql; using mRemoteNG.Connection; -using mRemoteNG.Container; using mRemoteNG.Security; using mRemoteNG.Security.SymmetricEncryption; +using mRemoteNG.Tools; using mRemoteNG.Tree; -using mRemoteNG.Tree.Root; using mRemoteNGTests.TestHelpers; -using NSubstitute; using NUnit.Framework; namespace mRemoteNGTests.Config.Serializers @@ -45,78 +42,24 @@ namespace mRemoteNGTests.Config.Serializers Assert.That(dataTable.Rows.Count, Is.EqualTo(0)); } - [Test] - public void UsernameSerializedWhenSaveSecurityAllowsIt() - { - var model = CreateConnectionTreeModel(); - _saveFilter.SaveUsername = true; - var dataTable = _dataTableSerializer.Serialize(model); - Assert.That(dataTable.Rows[0]["Username"], Is.Not.EqualTo("")); - } - - [Test] - public void DomainSerializedWhenSaveSecurityAllowsIt() - { - var model = CreateConnectionTreeModel(); - _saveFilter.SaveDomain = true; - var dataTable = _dataTableSerializer.Serialize(model); - Assert.That(dataTable.Rows[0]["DomainName"], Is.Not.EqualTo("")); - } - - [Test] - public void PasswordSerializedWhenSaveSecurityAllowsIt() - { - var model = CreateConnectionTreeModel(); - _saveFilter.SavePassword = true; - var dataTable = _dataTableSerializer.Serialize(model); - Assert.That(dataTable.Rows[0]["Password"], Is.Not.EqualTo("")); - } - [Test] public void InheritanceSerializedWhenSaveSecurityAllowsIt() { var model = CreateConnectionTreeModel(); + model.GetRecursiveChildList().ForEach(c => c.Inheritance.UserField = true); _saveFilter.SaveInheritance = true; var dataTable = _dataTableSerializer.Serialize(model); - Assert.That(dataTable.Rows[0]["InheritUsername"], Is.Not.EqualTo("")); - } - - - - [Test] - public void UsernameNotSerializedWhenSaveSecurityDisabled() - { - var model = CreateConnectionTreeModel(); - _saveFilter.SaveUsername = false; - var dataTable = _dataTableSerializer.Serialize(model); - Assert.That(dataTable.Rows[0]["Username"], Is.EqualTo("")); - } - - [Test] - public void DomainNotSerializedWhenSaveSecurityDisabled() - { - var model = CreateConnectionTreeModel(); - _saveFilter.SaveDomain = false; - var dataTable = _dataTableSerializer.Serialize(model); - Assert.That(dataTable.Rows[0]["DomainName"], Is.EqualTo("")); - } - - [Test] - public void PasswordNotSerializedWhenSaveSecurityDisabled() - { - var model = CreateConnectionTreeModel(); - _saveFilter.SavePassword = false; - var dataTable = _dataTableSerializer.Serialize(model); - Assert.That(dataTable.Rows[0]["Password"], Is.EqualTo("")); + Assert.That(dataTable.Rows[0]["InheritUserField"], Is.EqualTo(true)); } [Test] public void InheritanceNotSerializedWhenSaveSecurityDisabled() { var model = CreateConnectionTreeModel(); + model.GetRecursiveChildList().ForEach(c => c.Inheritance.UserField = true); _saveFilter.SaveInheritance = false; var dataTable = _dataTableSerializer.Serialize(model); - Assert.That(dataTable.Rows[0]["InheritUsername"], Is.False); + Assert.That(dataTable.Rows[0]["InheritUserField"], Is.False); } [Test] diff --git a/mRemoteV1/App/Initialization/CredsAndConsSetup.cs b/mRemoteV1/App/Initialization/CredsAndConsSetup.cs index ea49e355..7fa2fdbc 100644 --- a/mRemoteV1/App/Initialization/CredsAndConsSetup.cs +++ b/mRemoteV1/App/Initialization/CredsAndConsSetup.cs @@ -11,7 +11,9 @@ namespace mRemoteNG.App.Initialization { public void LoadCredsAndCons(ConnectionsService connectionsService, CredentialService credentialService) { - new SaveConnectionsOnEdit(connectionsService); + var saveOnEditService = new SaveConnectionsOnEdit(connectionsService); + connectionsService.ConnectionTreeModel.CollectionChanged += saveOnEditService.ConnectionTreeModelOnCollectionChanged; + connectionsService.ConnectionTreeModel.PropertyChanged += saveOnEditService.ConnectionTreeModelOnPropertyChanged; if (Settings.Default.FirstStart && !Settings.Default.LoadConsFromCustomLocation && !File.Exists(Runtime.ConnectionsService.GetStartupConnectionFileName())) Runtime.ConnectionsService.NewConnectionsFile(Runtime.ConnectionsService.GetStartupConnectionFileName()); diff --git a/mRemoteV1/Config/Connections/ConnectionsLoadedEventArgs.cs b/mRemoteV1/Config/Connections/ConnectionsLoadedEventArgs.cs index f6faaae2..ca0f2127 100644 --- a/mRemoteV1/Config/Connections/ConnectionsLoadedEventArgs.cs +++ b/mRemoteV1/Config/Connections/ConnectionsLoadedEventArgs.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using mRemoteNG.Connection; using mRemoteNG.Tools; using mRemoteNG.Tree; @@ -10,7 +12,7 @@ namespace mRemoteNG.Config.Connections /// The previous that is being /// unloaded. /// - public Optional PreviousConnectionTreeModel { get; } + public List RemovedConnections { get; } /// /// True if the previous was loaded from @@ -21,7 +23,7 @@ namespace mRemoteNG.Config.Connections /// /// The new that is being loaded. /// - public ConnectionTreeModel NewConnectionTreeModel { get; } + public List AddedConnections { get; } /// /// True if the new was loaded from @@ -37,22 +39,15 @@ namespace mRemoteNG.Config.Connections public string NewSourcePath { get; } public ConnectionsLoadedEventArgs( - Optional previousTreeModelModel, ConnectionTreeModel newTreeModelModel, + List removedConnections, List addedConnections, bool previousSourceWasDatabase, bool newSourceIsDatabase, string newSourcePath) { - if (previousTreeModelModel == null) - throw new ArgumentNullException(nameof(previousTreeModelModel)); - if (newTreeModelModel == null) - throw new ArgumentNullException(nameof(newTreeModelModel)); - if (newSourcePath == null) - throw new ArgumentNullException(nameof(newSourcePath)); - - PreviousConnectionTreeModel = previousTreeModelModel; + RemovedConnections = removedConnections.ThrowIfNull(nameof(removedConnections)); PreviousSourceWasDatabase = previousSourceWasDatabase; - NewConnectionTreeModel = newTreeModelModel; + AddedConnections = addedConnections.ThrowIfNull(nameof(addedConnections)); NewSourceIsDatabase = newSourceIsDatabase; - NewSourcePath = newSourcePath; + NewSourcePath = newSourcePath.ThrowIfNull(nameof(newSourcePath)); } } } diff --git a/mRemoteV1/Config/Connections/IConnectionsLoader.cs b/mRemoteV1/Config/Connections/IConnectionsLoader.cs index a4669757..2b00a0a6 100644 --- a/mRemoteV1/Config/Connections/IConnectionsLoader.cs +++ b/mRemoteV1/Config/Connections/IConnectionsLoader.cs @@ -1,9 +1,9 @@ -using mRemoteNG.Tree; +using mRemoteNG.Config.Serializers; namespace mRemoteNG.Config.Connections { public interface IConnectionsLoader { - ConnectionTreeModel Load(); + SerializationResult Load(); } } \ No newline at end of file diff --git a/mRemoteV1/Config/Connections/SaveConnectionsOnEdit.cs b/mRemoteV1/Config/Connections/SaveConnectionsOnEdit.cs index d36648af..46df7a27 100644 --- a/mRemoteV1/Config/Connections/SaveConnectionsOnEdit.cs +++ b/mRemoteV1/Config/Connections/SaveConnectionsOnEdit.cs @@ -1,7 +1,7 @@ -using System; -using System.Collections.Specialized; +using System.Collections.Specialized; using System.ComponentModel; using mRemoteNG.Connection; +using mRemoteNG.Tools; using mRemoteNG.UI.Forms; namespace mRemoteNG.Config.Connections @@ -12,31 +12,15 @@ namespace mRemoteNG.Config.Connections public SaveConnectionsOnEdit(ConnectionsService connectionsService) { - if (connectionsService == null) - throw new ArgumentNullException(nameof(connectionsService)); - - _connectionsService = connectionsService; - connectionsService.ConnectionsLoaded += ConnectionsServiceOnConnectionsLoaded; + _connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService)); } - private void ConnectionsServiceOnConnectionsLoaded(object sender, ConnectionsLoadedEventArgs connectionsLoadedEventArgs) - { - connectionsLoadedEventArgs.NewConnectionTreeModel.CollectionChanged += ConnectionTreeModelOnCollectionChanged; - connectionsLoadedEventArgs.NewConnectionTreeModel.PropertyChanged += ConnectionTreeModelOnPropertyChanged; - - foreach (var oldTree in connectionsLoadedEventArgs.PreviousConnectionTreeModel) - { - oldTree.CollectionChanged -= ConnectionTreeModelOnCollectionChanged; - oldTree.PropertyChanged -= ConnectionTreeModelOnPropertyChanged; - } - } - - private void ConnectionTreeModelOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) + public void ConnectionTreeModelOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) { SaveConnectionOnEdit(propertyChangedEventArgs.PropertyName); } - private void ConnectionTreeModelOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs) + public void ConnectionTreeModelOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs) { SaveConnectionOnEdit(); } diff --git a/mRemoteV1/Config/Connections/SqlConnectionsLoader.cs b/mRemoteV1/Config/Connections/SqlConnectionsLoader.cs index ed566424..f24442d9 100644 --- a/mRemoteV1/Config/Connections/SqlConnectionsLoader.cs +++ b/mRemoteV1/Config/Connections/SqlConnectionsLoader.cs @@ -33,7 +33,7 @@ namespace mRemoteNG.Config.Connections _dataProvider = dataProvider.ThrowIfNull(nameof(dataProvider)); } - public ConnectionTreeModel Load() + public SerializationResult Load() { var connector = DatabaseConnectorFactory.SqlDatabaseConnectorFromSettings(); var dataProvider = new SqlDataProvider(connector); @@ -50,9 +50,9 @@ namespace mRemoteNG.Config.Connections databaseVersionVerifier.VerifyDatabaseVersion(metaData.ConfVersion); var dataTable = dataProvider.Load(); var deserializer = new DataTableDeserializer(cryptoProvider, decryptionKey.First()); - var connectionTree = deserializer.Deserialize(dataTable); - ApplyLocalConnectionProperties(connectionTree.RootNodes.First(i => i is RootNodeInfo)); - return connectionTree; + var serializationResult = deserializer.Deserialize(dataTable); + ApplyLocalConnectionProperties(serializationResult.ConnectionRecords.OfType().First()); + return serializationResult; } private Optional GetDecryptionKey(SqlConnectionListMetaData metaData) diff --git a/mRemoteV1/Config/Connections/XmlConnectionsLoader.cs b/mRemoteV1/Config/Connections/XmlConnectionsLoader.cs index 77129107..6bbe882a 100644 --- a/mRemoteV1/Config/Connections/XmlConnectionsLoader.cs +++ b/mRemoteV1/Config/Connections/XmlConnectionsLoader.cs @@ -4,8 +4,10 @@ using mRemoteNG.Tools; using mRemoteNG.Tree; using System; using System.IO; +using System.Linq; using System.Security; using mRemoteNG.App.Info; +using mRemoteNG.Config.Serializers; using mRemoteNG.Config.Serializers.Versioning; using mRemoteNG.Connection; using mRemoteNG.Credential; @@ -33,7 +35,7 @@ namespace mRemoteNG.Config.Connections _credentialService = credentialService.ThrowIfNull(nameof(credentialService)); } - public ConnectionTreeModel Load() + public SerializationResult Load() { var dataProvider = new FileDataProvider(_connectionFilePath); var xmlString = dataProvider.Load(); @@ -46,7 +48,9 @@ namespace mRemoteNG.Config.Connections ConnectionDeserializer = new XmlConnectionsDeserializer(PromptForPassword) }; - return deserializer.Deserialize(xmlString); + var connectionTreeModel = deserializer.Deserialize(xmlString); + + return new SerializationResult(connectionTreeModel.RootNodes.Cast().ToList(), new ConnectionToCredentialMap()); } private Optional PromptForPassword() diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/DataTableDeserializer.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/DataTableDeserializer.cs index 549a23d1..0129d72e 100644 --- a/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/DataTableDeserializer.cs +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/DataTableDeserializer.cs @@ -1,5 +1,4 @@ -using mRemoteNG.App; -using mRemoteNG.Connection; +using mRemoteNG.Connection; using mRemoteNG.Connection.Protocol; using mRemoteNG.Connection.Protocol.Http; using mRemoteNG.Connection.Protocol.ICA; @@ -8,8 +7,6 @@ using mRemoteNG.Connection.Protocol.VNC; using mRemoteNG.Container; using mRemoteNG.Security; using mRemoteNG.Tools; -using mRemoteNG.Tree; -using mRemoteNG.Tree.Root; using System; using System.Collections.Generic; using System.Data; @@ -18,7 +15,7 @@ using System.Security; namespace mRemoteNG.Config.Serializers.MsSql { - public class DataTableDeserializer : IDeserializer + public class DataTableDeserializer { private readonly ICryptographyProvider _cryptographyProvider; private readonly SecureString _decryptionKey; @@ -29,12 +26,13 @@ namespace mRemoteNG.Config.Serializers.MsSql _decryptionKey = decryptionKey.ThrowIfNull(nameof(decryptionKey)); } - public ConnectionTreeModel Deserialize(DataTable table) + public SerializationResult Deserialize(DataTable table) { var connectionList = CreateNodesFromTable(table); - var connectionTreeModel = CreateNodeHierarchy(connectionList, table); - Runtime.ConnectionsService.IsConnectionsFileLoaded = true; - return connectionTreeModel; + var rootNodes = CreateNodeHierarchy(connectionList, table); + + var serializationResult = new SerializationResult(rootNodes, new ConnectionToCredentialMap()); + return serializationResult; } private List CreateNodesFromTable(DataTable table) @@ -60,7 +58,7 @@ namespace mRemoteNG.Config.Serializers.MsSql { var connectionId = row["ConstantID"] as string ?? Guid.NewGuid().ToString(); var connectionInfo = new ConnectionInfo(connectionId); - PopulateConnectionInfoFromDatarow(row, connectionInfo); + PopulateConnectionInfoFromDataRow(row, connectionInfo); return connectionInfo; } @@ -68,11 +66,11 @@ namespace mRemoteNG.Config.Serializers.MsSql { var containerId = row["ConstantID"] as string ?? Guid.NewGuid().ToString(); var containerInfo = new ContainerInfo(containerId); - PopulateConnectionInfoFromDatarow(row, containerInfo); + PopulateConnectionInfoFromDataRow(row, containerInfo); return containerInfo; } - private void PopulateConnectionInfoFromDatarow(DataRow dataRow, ConnectionInfo connectionInfo) + private void PopulateConnectionInfoFromDataRow(DataRow dataRow, ConnectionInfo connectionInfo) { connectionInfo.Name = (string)dataRow["Name"]; @@ -85,9 +83,12 @@ namespace mRemoteNG.Config.Serializers.MsSql connectionInfo.Panel = (string)dataRow["Panel"]; // TODO: harvest - connectionInfo.Username = (string)dataRow["Username"]; - connectionInfo.Domain = (string)dataRow["DomainName"]; - connectionInfo.Password = DecryptValue((string)dataRow["Password"]); + if (dataRow.Table.Columns.Contains("Username")) + connectionInfo.Username = (string)dataRow["Username"]; + if (dataRow.Table.Columns.Contains("DomainName")) + connectionInfo.Domain = (string)dataRow["DomainName"]; + if (dataRow.Table.Columns.Contains("Password")) + connectionInfo.Password = DecryptValue((string)dataRow["Password"]); connectionInfo.Hostname = (string)dataRow["Hostname"]; connectionInfo.Protocol = (ProtocolType)Enum.Parse(typeof(ProtocolType), (string)dataRow["Protocol"]); @@ -147,10 +148,8 @@ namespace mRemoteNG.Config.Serializers.MsSql connectionInfo.Inheritance.DisplayWallpaper = (bool)dataRow["InheritDisplayWallpaper"]; connectionInfo.Inheritance.EnableFontSmoothing = (bool)dataRow["InheritEnableFontSmoothing"]; connectionInfo.Inheritance.EnableDesktopComposition = (bool)dataRow["InheritEnableDesktopComposition"]; - connectionInfo.Inheritance.Domain = (bool)dataRow["InheritDomain"]; connectionInfo.Inheritance.Icon = (bool)dataRow["InheritIcon"]; connectionInfo.Inheritance.Panel = (bool)dataRow["InheritPanel"]; - connectionInfo.Inheritance.Password = (bool)dataRow["InheritPassword"]; connectionInfo.Inheritance.Port = (bool)dataRow["InheritPort"]; connectionInfo.Inheritance.Protocol = (bool)dataRow["InheritProtocol"]; connectionInfo.Inheritance.PuttySession = (bool)dataRow["InheritPuttySession"]; @@ -167,7 +166,6 @@ namespace mRemoteNG.Config.Serializers.MsSql connectionInfo.Inheritance.UseConsoleSession = (bool)dataRow["InheritUseConsoleSession"]; connectionInfo.Inheritance.UseCredSsp = (bool)dataRow["InheritUseCredSsp"]; connectionInfo.Inheritance.RenderingEngine = (bool)dataRow["InheritRenderingEngine"]; - connectionInfo.Inheritance.Username = (bool)dataRow["InheritUsername"]; connectionInfo.Inheritance.ICAEncryptionStrength = (bool)dataRow["InheritICAEncryptionStrength"]; connectionInfo.Inheritance.RDPAuthenticationLevel = (bool)dataRow["InheritRDPAuthenticationLevel"]; connectionInfo.Inheritance.RDPAlertIdleTimeout = (bool)dataRow["InheritRDPAlertIdleTimeout"]; @@ -210,14 +208,9 @@ namespace mRemoteNG.Config.Serializers.MsSql } } - private ConnectionTreeModel CreateNodeHierarchy(List connectionList, DataTable dataTable) + private List CreateNodeHierarchy(IReadOnlyCollection connectionList, DataTable dataTable) { - var connectionTreeModel = new ConnectionTreeModel(); - var rootNode = new RootNodeInfo(RootNodeType.Connection, "0") - { - PasswordString = _decryptionKey.ConvertToUnsecureString() - }; - connectionTreeModel.AddRootNode(rootNode); + var rootNodes = new List(); foreach (DataRow row in dataTable.Rows) { @@ -225,11 +218,11 @@ namespace mRemoteNG.Config.Serializers.MsSql var connectionInfo = connectionList.First(node => node.ConstantID == id); var parentId = (string) row["ParentID"]; if (parentId == "0" || connectionList.All(node => node.ConstantID != parentId)) - rootNode.AddChild(connectionInfo); + rootNodes.Add(connectionInfo); else (connectionList.First(node => node.ConstantID == parentId) as ContainerInfo)?.AddChild(connectionInfo); } - return connectionTreeModel; + return rootNodes; } } } \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/DataTableSerializer.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/DataTableSerializer.cs index 45052bc8..eb38e6c0 100644 --- a/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/DataTableSerializer.cs +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/DataTableSerializer.cs @@ -77,9 +77,6 @@ namespace mRemoteNG.Config.Serializers.MsSql dataTable.Columns.Add("Description", typeof(string)); dataTable.Columns.Add("Icon", typeof(string)); dataTable.Columns.Add("Panel", typeof(string)); - dataTable.Columns.Add("Username", typeof(string)); - dataTable.Columns.Add("DomainName", typeof(string)); - dataTable.Columns.Add("Password", typeof(string)); dataTable.Columns.Add("Hostname", typeof(string)); dataTable.Columns.Add("Protocol", typeof(string)); dataTable.Columns.Add("PuttySession", typeof(string)); @@ -214,19 +211,10 @@ namespace mRemoteNG.Config.Serializers.MsSql dataRow["ParentID"] = connectionInfo.Parent?.ConstantID ?? ""; dataRow["PositionID"] = _currentNodeIndex; dataRow["LastChange"] = (SqlDateTime)DateTime.Now; - dataRow["Expanded"] = false; // TODO: this column can eventually be removed. we now save this property locally dataRow["Description"] = connectionInfo.Description; dataRow["Icon"] = connectionInfo.Icon; dataRow["Panel"] = connectionInfo.Panel; - // TODO: remove - dataRow["Username"] = _saveFilter.SaveUsername ? connectionInfo.Username : ""; - dataRow["DomainName"] = _saveFilter.SaveDomain ? connectionInfo.Domain : ""; - dataRow["Password"] = _saveFilter.SavePassword - ? _cryptographyProvider.Encrypt(connectionInfo.Password, _encryptionKey) - : ""; - - dataRow["Hostname"] = connectionInfo.Hostname; dataRow["Protocol"] = connectionInfo.Protocol; dataRow["PuttySession"] = connectionInfo.PuttySession; @@ -255,7 +243,6 @@ namespace mRemoteNG.Config.Serializers.MsSql dataRow["RedirectSound"] = connectionInfo.RedirectSound; dataRow["SoundQuality"] = connectionInfo.SoundQuality; dataRow["RedirectKeys"] = connectionInfo.RedirectKeys; - dataRow["Connected"] = false; // TODO: this column can eventually be removed. we now save this property locally dataRow["PreExtApp"] = connectionInfo.PreExtApp; dataRow["PostExtApp"] = connectionInfo.PostExtApp; dataRow["MacAddress"] = connectionInfo.MacAddress; @@ -287,10 +274,8 @@ namespace mRemoteNG.Config.Serializers.MsSql dataRow["InheritDisplayWallpaper"] = connectionInfo.Inheritance.DisplayWallpaper; dataRow["InheritEnableFontSmoothing"] = connectionInfo.Inheritance.EnableFontSmoothing; dataRow["InheritEnableDesktopComposition"] = connectionInfo.Inheritance.EnableDesktopComposition; - dataRow["InheritDomain"] = connectionInfo.Inheritance.Domain; dataRow["InheritIcon"] = connectionInfo.Inheritance.Icon; dataRow["InheritPanel"] = connectionInfo.Inheritance.Panel; - dataRow["InheritPassword"] = connectionInfo.Inheritance.Password; dataRow["InheritPort"] = connectionInfo.Inheritance.Port; dataRow["InheritProtocol"] = connectionInfo.Inheritance.Protocol; dataRow["InheritPuttySession"] = connectionInfo.Inheritance.PuttySession; @@ -307,7 +292,6 @@ namespace mRemoteNG.Config.Serializers.MsSql dataRow["InheritUseConsoleSession"] = connectionInfo.Inheritance.UseConsoleSession; dataRow["InheritUseCredSsp"] = connectionInfo.Inheritance.UseCredSsp; dataRow["InheritRenderingEngine"] = connectionInfo.Inheritance.RenderingEngine; - dataRow["InheritUsername"] = connectionInfo.Inheritance.Username; dataRow["InheritICAEncryptionStrength"] = connectionInfo.Inheritance.ICAEncryptionStrength; dataRow["InheritRDPAuthenticationLevel"] = connectionInfo.Inheritance.RDPAuthenticationLevel; dataRow["InheritRDPMinutesToIdleTimeout"] = connectionInfo.Inheritance.RDPMinutesToIdleTimeout; @@ -345,10 +329,8 @@ namespace mRemoteNG.Config.Serializers.MsSql dataRow["InheritDisplayWallpaper"] = false; dataRow["InheritEnableFontSmoothing"] = false; dataRow["InheritEnableDesktopComposition"] = false; - dataRow["InheritDomain"] = false; dataRow["InheritIcon"] = false; dataRow["InheritPanel"] = false; - dataRow["InheritPassword"] = false; dataRow["InheritPort"] = false; dataRow["InheritProtocol"] = false; dataRow["InheritPuttySession"] = false; @@ -365,7 +347,6 @@ namespace mRemoteNG.Config.Serializers.MsSql dataRow["InheritUseConsoleSession"] = false; dataRow["InheritUseCredSsp"] = false; dataRow["InheritRenderingEngine"] = false; - dataRow["InheritUsername"] = false; dataRow["InheritICAEncryptionStrength"] = false; dataRow["InheritRDPAuthenticationLevel"] = false; dataRow["InheritRDPMinutesToIdleTimeout"] = false; diff --git a/mRemoteV1/Config/Serializers/Versioning/SqlVersion26To27Upgrader.cs b/mRemoteV1/Config/Serializers/Versioning/SqlVersion26To27Upgrader.cs index 26d66b49..e0022589 100644 --- a/mRemoteV1/Config/Serializers/Versioning/SqlVersion26To27Upgrader.cs +++ b/mRemoteV1/Config/Serializers/Versioning/SqlVersion26To27Upgrader.cs @@ -29,7 +29,8 @@ namespace mRemoteNG.Config.Serializers.Versioning const string sqlText = @" ALTER TABLE tblCons ADD RedirectClipboard bit NOT NULL DEFAULT 0, - InheritRedirectClipboard bit NOT NULL DEFAULT 0; + InheritRedirectClipboard bit NOT NULL DEFAULT 0 +DROP COLUMN Username, Domain, Password, InheritUsername, InheritDomain, InheritPassword, Expanded, Connected; UPDATE tblRoot SET ConfVersion='2.7'"; var sqlCommand = new SqlCommand(sqlText, _sqlDatabaseConnector.SqlConnection); diff --git a/mRemoteV1/Connection/ConnectionsService.cs b/mRemoteV1/Connection/ConnectionsService.cs index e4e425cb..960b42d9 100644 --- a/mRemoteV1/Connection/ConnectionsService.cs +++ b/mRemoteV1/Connection/ConnectionsService.cs @@ -13,7 +13,9 @@ using mRemoteNG.Tree; using mRemoteNG.Tree.Root; using mRemoteNG.UI; using System; +using System.Collections.Generic; using System.IO; +using System.Linq; using System.Threading; using System.Windows.Forms; using mRemoteNG.Config; @@ -38,7 +40,7 @@ namespace mRemoteNG.Connection public RemoteConnectionsSyncronizer RemoteConnectionsSyncronizer { get; set; } public DateTime LastSqlUpdate { get; set; } - public ConnectionTreeModel ConnectionTreeModel { get; private set; } + public ConnectionTreeModel ConnectionTreeModel { get; private set; } = new ConnectionTreeModel(); public ConnectionsService(PuttySessionsManager puttySessionsManager, CredentialService credentialService) { @@ -112,19 +114,18 @@ namespace mRemoteNG.Connection /// public void LoadConnections(bool useDatabase, bool import, string connectionFileName) { - var oldConnectionTreeModel = ConnectionTreeModel; var oldIsUsingDatabaseValue = UsingDatabase; var connectionLoader = useDatabase ? (IConnectionsLoader)new SqlConnectionsLoader(_localConnectionPropertiesSerializer, _localConnectionPropertiesDataProvider) : new XmlConnectionsLoader(connectionFileName, _credentialService, this); - var newConnectionTreeModel = connectionLoader.Load(); + var serializationResult = connectionLoader.Load(); if (useDatabase) LastSqlUpdate = DateTime.Now; - if (newConnectionTreeModel == null) + if (serializationResult == null) { DialogFactory.ShowLoadConnectionsFailedDialog(connectionFileName, "Decrypting connection file failed", IsConnectionsFileLoaded); return; @@ -134,15 +135,11 @@ namespace mRemoteNG.Connection ConnectionFileName = connectionFileName; UsingDatabase = useDatabase; - if (!import) - { - _puttySessionsManager.AddSessions(); - newConnectionTreeModel.RootNodes.AddRange(_puttySessionsManager.RootPuttySessionsNodes); - } + ConnectionTreeModel.RemoveRootNode(ConnectionTreeModel.RootNodes.First()); + ConnectionTreeModel.AddRootNode(serializationResult.ConnectionRecords.OfType().First()); - ConnectionTreeModel = newConnectionTreeModel; UpdateCustomConsPathSetting(connectionFileName); - RaiseConnectionsLoadedEvent(oldConnectionTreeModel, newConnectionTreeModel, oldIsUsingDatabaseValue, useDatabase, connectionFileName); + RaiseConnectionsLoadedEvent(new List(), new List(), oldIsUsingDatabaseValue, useDatabase, connectionFileName); Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, $"Connections loaded using {connectionLoader.GetType().Name}"); } @@ -322,13 +319,13 @@ namespace mRemoteNG.Connection public event EventHandler ConnectionsLoaded; public event EventHandler ConnectionsSaved; - private void RaiseConnectionsLoadedEvent(Optional previousTreeModel, ConnectionTreeModel newTreeModel, + private void RaiseConnectionsLoadedEvent(List removedConnections, List addedConnections, bool previousSourceWasDatabase, bool newSourceIsDatabase, string newSourcePath) { ConnectionsLoaded?.Invoke(this, new ConnectionsLoadedEventArgs( - previousTreeModel, - newTreeModel, + removedConnections, + addedConnections, previousSourceWasDatabase, newSourceIsDatabase, newSourcePath)); diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index 5fb2ddba..66af9c36 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -169,8 +169,8 @@ namespace mRemoteNG.UI.Window return; } - olvConnections.ConnectionTreeModel = connectionsLoadedEventArgs.NewConnectionTreeModel; - olvConnections.SelectedObject = connectionsLoadedEventArgs.NewConnectionTreeModel.RootNodes + // TODO: might not need this call anymore + olvConnections.SelectedObject = ConnectionTree.ConnectionTreeModel.RootNodes .OfType().FirstOrDefault(); } #endregion