began converting the database serializers to work with cred manager

This commit is contained in:
David Sparer
2019-01-20 14:51:09 -06:00
parent f0d0b5ae21
commit 923b9efd40
13 changed files with 71 additions and 171 deletions

View File

@@ -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));
}

View File

@@ -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]

View File

@@ -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());

View File

@@ -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 <see cref="ConnectionTreeModel"/> that is being
/// unloaded.
/// </summary>
public Optional<ConnectionTreeModel> PreviousConnectionTreeModel { get; }
public List<ConnectionInfo> RemovedConnections { get; }
/// <summary>
/// True if the previous <see cref="ConnectionTreeModel"/> was loaded from
@@ -21,7 +23,7 @@ namespace mRemoteNG.Config.Connections
/// <summary>
/// The new <see cref="ConnectionTreeModel"/> that is being loaded.
/// </summary>
public ConnectionTreeModel NewConnectionTreeModel { get; }
public List<ConnectionInfo> AddedConnections { get; }
/// <summary>
/// True if the new <see cref="ConnectionTreeModel"/> was loaded from
@@ -37,22 +39,15 @@ namespace mRemoteNG.Config.Connections
public string NewSourcePath { get; }
public ConnectionsLoadedEventArgs(
Optional<ConnectionTreeModel> previousTreeModelModel, ConnectionTreeModel newTreeModelModel,
List<ConnectionInfo> removedConnections, List<ConnectionInfo> 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));
}
}
}

View File

@@ -1,9 +1,9 @@
using mRemoteNG.Tree;
using mRemoteNG.Config.Serializers;
namespace mRemoteNG.Config.Connections
{
public interface IConnectionsLoader
{
ConnectionTreeModel Load();
SerializationResult Load();
}
}

View File

@@ -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();
}

View File

@@ -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<RootNodeInfo>().First());
return serializationResult;
}
private Optional<SecureString> GetDecryptionKey(SqlConnectionListMetaData metaData)

View File

@@ -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<ConnectionInfo>().ToList(), new ConnectionToCredentialMap());
}
private Optional<SecureString> PromptForPassword()

View File

@@ -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<DataTable, ConnectionTreeModel>
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<ConnectionInfo> 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<ConnectionInfo> connectionList, DataTable dataTable)
private List<ConnectionInfo> CreateNodeHierarchy(IReadOnlyCollection<ConnectionInfo> connectionList, DataTable dataTable)
{
var connectionTreeModel = new ConnectionTreeModel();
var rootNode = new RootNodeInfo(RootNodeType.Connection, "0")
{
PasswordString = _decryptionKey.ConvertToUnsecureString()
};
connectionTreeModel.AddRootNode(rootNode);
var rootNodes = new List<ConnectionInfo>();
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;
}
}
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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
/// <param name="connectionFileName"></param>
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<RootNodeInfo>().First());
ConnectionTreeModel = newConnectionTreeModel;
UpdateCustomConsPathSetting(connectionFileName);
RaiseConnectionsLoadedEvent(oldConnectionTreeModel, newConnectionTreeModel, oldIsUsingDatabaseValue, useDatabase, connectionFileName);
RaiseConnectionsLoadedEvent(new List<ConnectionInfo>(), new List<ConnectionInfo>(), oldIsUsingDatabaseValue, useDatabase, connectionFileName);
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, $"Connections loaded using {connectionLoader.GetType().Name}");
}
@@ -322,13 +319,13 @@ namespace mRemoteNG.Connection
public event EventHandler<ConnectionsLoadedEventArgs> ConnectionsLoaded;
public event EventHandler<ConnectionsSavedEventArgs> ConnectionsSaved;
private void RaiseConnectionsLoadedEvent(Optional<ConnectionTreeModel> previousTreeModel, ConnectionTreeModel newTreeModel,
private void RaiseConnectionsLoadedEvent(List<ConnectionInfo> removedConnections, List<ConnectionInfo> addedConnections,
bool previousSourceWasDatabase, bool newSourceIsDatabase,
string newSourcePath)
{
ConnectionsLoaded?.Invoke(this, new ConnectionsLoadedEventArgs(
previousTreeModel,
newTreeModel,
removedConnections,
addedConnections,
previousSourceWasDatabase,
newSourceIsDatabase,
newSourcePath));

View File

@@ -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<RootNodeInfo>().FirstOrDefault();
}
#endregion