From 4a982ea228ca54210b8d2970214103d76476c860 Mon Sep 17 00:00:00 2001 From: Christian <6939810+chkr1011@users.noreply.github.com> Date: Wed, 29 Jun 2022 18:58:02 +0200 Subject: [PATCH] Add Tests. --- Source/MQTTnet.Tests/MQTTv5/Client_Tests.cs | 2 +- Source/MQTTnet.Tests/Server/Security_Tests.cs | 131 ++++++++++++++---- 2 files changed, 105 insertions(+), 28 deletions(-) diff --git a/Source/MQTTnet.Tests/MQTTv5/Client_Tests.cs b/Source/MQTTnet.Tests/MQTTv5/Client_Tests.cs index 8abf63e1..b87ca6af 100644 --- a/Source/MQTTnet.Tests/MQTTv5/Client_Tests.cs +++ b/Source/MQTTnet.Tests/MQTTv5/Client_Tests.cs @@ -212,7 +212,7 @@ namespace MQTTnet.Tests.MQTTv5 var client1 = await testEnvironment.ConnectClient(o => o.WithProtocolVersion(MqttProtocolVersion.V500).WithClientId("client1")); - var testMessageHandler = new TestApplicationMessageReceivedHandler(client1); + var testMessageHandler = testEnvironment.CreateApplicationMessageHandler(client1); await client1.SubscribeAsync("a"); diff --git a/Source/MQTTnet.Tests/Server/Security_Tests.cs b/Source/MQTTnet.Tests/Server/Security_Tests.cs index 57d57a09..226752d0 100644 --- a/Source/MQTTnet.Tests/Server/Security_Tests.cs +++ b/Source/MQTTnet.Tests/Server/Security_Tests.cs @@ -2,7 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; +using System.Collections.Generic; using System.Threading.Tasks; +using Microsoft.CodeAnalysis; using Microsoft.VisualStudio.TestTools.UnitTesting; using MQTTnet.Adapter; using MQTTnet.Client; @@ -15,6 +18,104 @@ namespace MQTTnet.Tests.Server [TestClass] public sealed class Security_Tests : BaseTestClass { + [TestMethod] + public async Task Do_Not_Affect_Authorized_Clients() + { + using (var testEnvironment = CreateTestEnvironment()) + { + testEnvironment.IgnoreClientLogErrors = true; + + await testEnvironment.StartServer(); + + var publishedApplicationMessages = new List(); + testEnvironment.Server.InterceptingPublishAsync += eventArgs => + { + lock (publishedApplicationMessages) + { + publishedApplicationMessages.Add(eventArgs.ApplicationMessage); + } + + return PlatformAbstractionLayer.CompletedTask; + }; + + testEnvironment.Server.ValidatingConnectionAsync += eventArgs => + { + if (eventArgs.Username == "SECRET") + { + eventArgs.ReasonCode = MqttConnectReasonCode.Success; + } + else + { + eventArgs.ReasonCode = MqttConnectReasonCode.NotAuthorized; + } + + return PlatformAbstractionLayer.CompletedTask; + }; + + using (var validClient = testEnvironment.CreateClient()) + { + await validClient.ConnectAsync( + testEnvironment.Factory.CreateClientOptionsBuilder() + .WithTcpServer("localhost", testEnvironment.ServerPort) + .WithCredentials("SECRET") + .WithClientId("CLIENT") + .Build()); + + await validClient.PublishStringAsync("HELLO 1"); + + // The following code tries to connect a new client with the same client ID but invalid + // credentials. This should block the second client but keep the first one up and running. + try + { + using (var invalidClient = testEnvironment.CreateClient()) + { + await invalidClient.ConnectAsync( + testEnvironment.Factory.CreateClientOptionsBuilder() + .WithTcpServer("localhost", testEnvironment.ServerPort) + .WithCredentials("???") + .WithClientId("CLIENT") + .Build()); + } + } + catch + { + // Ignore errors from the second client. + } + + await LongTestDelay(); + + await validClient.PublishStringAsync("HELLO 2"); + + await LongTestDelay(); + + await validClient.PublishStringAsync("HELLO 3"); + + await LongTestDelay(); + + Assert.AreEqual(3, publishedApplicationMessages.Count); + Assert.AreEqual(1, testEnvironment.Server.GetClientsAsync().GetAwaiter().GetResult().Count); + } + } + } + + [TestMethod] + public Task Handle_Wrong_Password() + { + return TestCredentials("UserName", "x"); + } + + [TestMethod] + public Task Handle_Wrong_UserName() + { + return TestCredentials("x", "Password1"); + } + + [TestMethod] + public Task Handle_Wrong_UserName_And_Password() + { + return TestCredentials("x", "x"); + } + [TestMethod] public async Task Use_Username_Null_Password_Empty() { @@ -29,10 +130,7 @@ namespace MQTTnet.Tests.Server var client = testEnvironment.CreateClient(); - var clientOptions = new MqttClientOptionsBuilder() - .WithTcpServer("127.0.0.1", testEnvironment.ServerPort) - .WithCredentials(username, password) - .Build(); + var clientOptions = new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort).WithCredentials(username, password).Build(); var ex = await Assert.ThrowsExceptionAsync(async () => await client.ConnectAsync(clientOptions)); Assert.IsInstanceOfType(ex.InnerException, typeof(MqttProtocolViolationException)); @@ -41,25 +139,7 @@ namespace MQTTnet.Tests.Server } } - [TestMethod] - public Task Handle_Wrong_UserName() - { - return TestCredentials("x", "Password1"); - } - - [TestMethod] - public Task Handle_Wrong_Password() - { - return TestCredentials("UserName", "x"); - } - - [TestMethod] - public Task Handle_Wrong_UserName_And_Password() - { - return TestCredentials("x", "x"); - } - - private async Task TestCredentials(string userName, string password) + async Task TestCredentials(string userName, string password) { using (var testEnvironment = CreateTestEnvironment()) { @@ -84,10 +164,7 @@ namespace MQTTnet.Tests.Server var client = testEnvironment.CreateClient(); - var clientOptions = new MqttClientOptionsBuilder() - .WithTcpServer("127.0.0.1", testEnvironment.ServerPort) - .WithCredentials(userName, password) - .Build(); + var clientOptions = new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort).WithCredentials(userName, password).Build(); var ex = await Assert.ThrowsExceptionAsync(async () => await client.ConnectAsync(clientOptions)); Assert.AreEqual(MqttClientConnectResultCode.BadUserNameOrPassword, ex.Result.ResultCode);