mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-17 22:11:48 +08:00
200 lines
9.1 KiB
C#
200 lines
9.1 KiB
C#
using mRemoteNG.Connection;
|
|
using mRemoteNG.Container;
|
|
using mRemoteNG.Security;
|
|
using mRemoteNG.Security.Factories;
|
|
using mRemoteNG.Tree;
|
|
using mRemoteNG.Tree.Root;
|
|
using mRemoteNGTests.TestHelpers;
|
|
using NUnit.Framework;
|
|
using System;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using mRemoteNG.Config.Serializers.ConnectionSerializers.Xml;
|
|
|
|
namespace mRemoteNGTests.IntegrationTests
|
|
{
|
|
public class XmlSerializationLifeCycleTests
|
|
{
|
|
private XmlConnectionsSerializer _serializer;
|
|
private XmlConnectionsDeserializer _deserializer;
|
|
private ConnectionTreeModel _originalModel;
|
|
private readonly ICryptoProviderFactory _cryptoFactory = new CryptoProviderFactory(BlockCipherEngines.AES , BlockCipherModes.GCM);
|
|
|
|
[SetUp]
|
|
public void Setup()
|
|
{
|
|
_originalModel = SetupConnectionTreeModel();
|
|
var cryptoProvider = _cryptoFactory.Build();
|
|
var nodeSerializer = new XmlConnectionNodeSerializer28(
|
|
cryptoProvider,
|
|
_originalModel.RootNodes.OfType<RootNodeInfo>().First().PasswordString.ConvertToSecureString(),
|
|
new SaveFilter());
|
|
_serializer = new XmlConnectionsSerializer(cryptoProvider, nodeSerializer);
|
|
_deserializer = new XmlConnectionsDeserializer();
|
|
}
|
|
|
|
[TearDown]
|
|
public void Teardown()
|
|
{
|
|
_serializer = null;
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeThenDeserialize()
|
|
{
|
|
var serializedContent = _serializer.Serialize(_originalModel);
|
|
var deserializedModel = _deserializer.Deserialize(serializedContent);
|
|
var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name);
|
|
var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name);
|
|
Assert.That(nodeNamesFromDeserializedModel, Is.EquivalentTo(nodeNamesFromOriginalModel));
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeThenDeserializeWithFullEncryption()
|
|
{
|
|
_serializer.UseFullEncryption = true;
|
|
var serializedContent = _serializer.Serialize(_originalModel);
|
|
var deserializedModel = _deserializer.Deserialize(serializedContent);
|
|
var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name);
|
|
var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name);
|
|
Assert.That(nodeNamesFromDeserializedModel, Is.EquivalentTo(nodeNamesFromOriginalModel));
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeAndDeserializePropertiesWithInternationalCharacters()
|
|
{
|
|
var originalConnectionInfo = new ConnectionInfo {Name = "con1", Description = "£°úg¶┬ä" };
|
|
var serializedContent = _serializer.Serialize(originalConnectionInfo);
|
|
var deserializedModel = _deserializer.Deserialize(serializedContent);
|
|
var deserializedConnectionInfo = deserializedModel.GetRecursiveChildList().First(node => node.Name == originalConnectionInfo.Name);
|
|
Assert.That(deserializedConnectionInfo.Description, Is.EqualTo(originalConnectionInfo.Description));
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeAndDeserializeWithCustomKdfIterationsValue()
|
|
{
|
|
var cryptoProvider = _cryptoFactory.Build();
|
|
cryptoProvider.KeyDerivationIterations = 5000;
|
|
var nodeSerializer = new XmlConnectionNodeSerializer28(
|
|
cryptoProvider,
|
|
_originalModel.RootNodes.OfType<RootNodeInfo>().First().PasswordString.ConvertToSecureString(),
|
|
new SaveFilter());
|
|
_serializer = new XmlConnectionsSerializer(cryptoProvider, nodeSerializer);
|
|
var serializedContent = _serializer.Serialize(_originalModel);
|
|
var deserializedModel = _deserializer.Deserialize(serializedContent);
|
|
var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name);
|
|
var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name);
|
|
Assert.That(nodeNamesFromDeserializedModel, Is.EquivalentTo(nodeNamesFromOriginalModel));
|
|
}
|
|
|
|
[Test]
|
|
public void GuidCreatedIfNonExistedInXml()
|
|
{
|
|
var originalConnectionInfo = new ConnectionInfo { Name = "con1" };
|
|
var serializedContent = _serializer.Serialize(originalConnectionInfo);
|
|
|
|
// remove GUID from connection xml
|
|
serializedContent = serializedContent.Replace(originalConnectionInfo.ConstantID, "");
|
|
|
|
var deserializedModel = _deserializer.Deserialize(serializedContent);
|
|
var deserializedConnectionInfo = deserializedModel.GetRecursiveChildList().First(node => node.Name == originalConnectionInfo.Name);
|
|
Assert.That(Guid.TryParse(deserializedConnectionInfo.ConstantID, out var guid));
|
|
}
|
|
|
|
[Test]
|
|
public void AllPropertiesCorrectWhenSerializingThenDeserializing()
|
|
{
|
|
var originalConnectionInfo = new ConnectionInfo().RandomizeValues();
|
|
originalConnectionInfo.Inheritance.TurnOffInheritanceCompletely();
|
|
var serializedContent = _serializer.Serialize(originalConnectionInfo);
|
|
var deserializedModel = _deserializer.Deserialize(serializedContent);
|
|
var deserializedConnectionInfo = deserializedModel
|
|
.GetRecursiveChildList()
|
|
.First(info => info.GetTreeNodeType() == TreeNodeType.Connection);
|
|
|
|
var sb = new StringBuilder();
|
|
foreach (var property in originalConnectionInfo.GetSerializableProperties())
|
|
{
|
|
if (property.Name == nameof(ConnectionInfo.Password))
|
|
continue;
|
|
|
|
var originalValue = property.GetValue(originalConnectionInfo);
|
|
var deserializedValue = property.GetValue(deserializedConnectionInfo);
|
|
if (originalValue.Equals(deserializedValue))
|
|
continue;
|
|
|
|
sb.AppendLine($"Property: {property.Name}");
|
|
}
|
|
|
|
Assert.That(sb.Length, Is.EqualTo(0), "Some properties are not being serialized properly:\n" + sb);
|
|
}
|
|
|
|
[Test]
|
|
public void AllInheritanceCorrectWhenSerializingThenDeserializing()
|
|
{
|
|
var originalConnectionInfo = new ConnectionInfo();
|
|
originalConnectionInfo.Inheritance.ToggleAllBooleanProperties(excludeProperties: nameof(ConnectionInfoInheritance.EverythingInherited));
|
|
var container = new ContainerInfo();
|
|
container.AddChild(originalConnectionInfo);
|
|
|
|
var serializedContent = _serializer.Serialize(container);
|
|
var deserializedModel = _deserializer.Deserialize(serializedContent);
|
|
var deserializedConnectionInfo = deserializedModel
|
|
.GetRecursiveChildList()
|
|
.First(info => info.GetTreeNodeType() == TreeNodeType.Connection);
|
|
|
|
var sb = new StringBuilder();
|
|
foreach (var property in originalConnectionInfo.Inheritance.GetProperties())
|
|
{
|
|
if (property.Name == nameof(originalConnectionInfo.Password))
|
|
continue;
|
|
|
|
var originalValue = property.GetValue(originalConnectionInfo.Inheritance);
|
|
var deserializedValue = property.GetValue(deserializedConnectionInfo.Inheritance);
|
|
|
|
if (originalValue.Equals(deserializedValue))
|
|
continue;
|
|
|
|
sb.AppendLine($"Property: Inheritance.{property.Name}");
|
|
}
|
|
|
|
Assert.That(sb.Length, Is.EqualTo(0), "Some properties are not being serialized properly:\n" + sb);
|
|
}
|
|
|
|
|
|
private ConnectionTreeModel SetupConnectionTreeModel()
|
|
{
|
|
/*
|
|
* Root
|
|
* |--- con0
|
|
* |--- folder1
|
|
* | L--- con1
|
|
* L--- folder2
|
|
* |--- con2
|
|
* L--- folder3
|
|
* |--- con3
|
|
* L--- con4
|
|
*/
|
|
var connectionTreeModel = new ConnectionTreeModel();
|
|
var rootNode = new RootNodeInfo(RootNodeType.Connection);
|
|
var folder1 = new ContainerInfo { Name = "folder1" };
|
|
var folder2 = new ContainerInfo { Name = "folder2" };
|
|
var folder3 = new ContainerInfo { Name = "folder3" };
|
|
var con0 = new ConnectionInfo { Name = "con0" };
|
|
var con1 = new ConnectionInfo { Name = "con1" };
|
|
var con2 = new ConnectionInfo { Name = "con2" };
|
|
var con3 = new ConnectionInfo { Name = "con3" };
|
|
var con4 = new ConnectionInfo { Name = "con4" };
|
|
rootNode.AddChild(folder1);
|
|
rootNode.AddChild(folder2);
|
|
rootNode.AddChild(con0);
|
|
folder1.AddChild(con1);
|
|
folder2.AddChild(con2);
|
|
folder2.AddChild(folder3);
|
|
folder3.AddChild(con3);
|
|
folder3.AddChild(con4);
|
|
connectionTreeModel.AddRootNode(rootNode);
|
|
return connectionTreeModel;
|
|
}
|
|
}
|
|
} |