Skip to content

Commit

Permalink
Use dedicated class for public API.
Browse files Browse the repository at this point in the history
  • Loading branch information
chkr1011 committed Dec 23, 2024
1 parent 96c5e57 commit 3d9734e
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 42 deletions.
14 changes: 12 additions & 2 deletions Samples/Client/Client_Connection_Samples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -498,14 +498,24 @@ public async Task HandleEnhancedAuthenticationAsync(MqttEnhancedAuthenticationEv
throw new InvalidOperationException("Wrong authentication method");
}

await eventArgs.SendAsync("initial context token"u8.ToArray());
var sendOptions = new SendMqttEnhancedAuthenticationDataOptions
{
Data = "initial context token"u8.ToArray()
};

await eventArgs.SendAsync(sendOptions);

var response = await eventArgs.ReceiveAsync(CancellationToken.None);

Console.WriteLine($"Received AUTH data from server: {Encoding.UTF8.GetString(response.AuthenticationData)}");

// No further data is required, but we have to fulfil the exchange.
await eventArgs.SendAsync([], CancellationToken.None);
sendOptions = new SendMqttEnhancedAuthenticationDataOptions
{
Data = []
};

await eventArgs.SendAsync(sendOptions, CancellationToken.None);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public async Task ConnectTimeout_Throws_Exception()
var disconnectHandlerCalled = false;
try
{
client.DisconnectedAsync += args =>
client.DisconnectedAsync += _ =>
{
disconnectHandlerCalled = true;
return CompletedTask.Instance;
Expand Down Expand Up @@ -164,14 +164,24 @@ public async Task HandleEnhancedAuthenticationAsync(MqttEnhancedAuthenticationEv
throw new InvalidOperationException("Wrong authentication method");
}

await eventArgs.SendAsync("initial context token"u8.ToArray());
var sendOptions = new SendMqttEnhancedAuthenticationDataOptions
{
Data = "initial context token"u8.ToArray()
};

var response = await eventArgs.ReceiveAsync(CancellationToken.None);
await eventArgs.SendAsync(sendOptions, eventArgs.CancellationToken);

var response = await eventArgs.ReceiveAsync(eventArgs.CancellationToken);

Assert.AreEqual(Encoding.UTF8.GetString(response.AuthenticationData), "reply context token");

// No further data is required, but we have to fulfil the exchange.
await eventArgs.SendAsync([], CancellationToken.None);
sendOptions = new SendMqttEnhancedAuthenticationDataOptions
{
Data = []
};

await eventArgs.SendAsync(sendOptions, eventArgs.CancellationToken);
}
}

Expand Down Expand Up @@ -248,10 +258,7 @@ public async Task Return_Non_Success()

server.ValidatingConnectionAsync += args =>
{
args.ResponseUserProperties = new List<MqttUserProperty>
{
new MqttUserProperty("Property", "Value")
};
args.ResponseUserProperties = [new("Property", "Value")];

args.ReasonCode = MqttConnectReasonCode.QuotaExceeded;

Expand Down
15 changes: 8 additions & 7 deletions Source/MQTTnet/MqttClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ async Task<MqttClientConnectResult> Authenticate(IMqttChannelAdapter channelAdap

if (receivedPacket is MqttAuthPacket authPacket)
{
await HandleEnhancedAuthentication(authPacket);
await HandleEnhancedAuthentication(authPacket, cancellationToken);
continue;
}

Expand Down Expand Up @@ -473,9 +473,9 @@ async Task<MqttClientConnectResult> Authenticate(IMqttChannelAdapter channelAdap
return result;
}

async Task HandleEnhancedAuthentication(MqttAuthPacket authPacket)
async Task HandleEnhancedAuthentication(MqttAuthPacket authPacket, CancellationToken cancellationToken)
{
var eventArgs = new MqttEnhancedAuthenticationEventArgs(authPacket, _adapter);
var eventArgs = new MqttEnhancedAuthenticationEventArgs(authPacket, _adapter, cancellationToken);
await Options.EnhancedAuthenticationHandler.HandleEnhancedAuthenticationAsync(eventArgs);
}

Expand Down Expand Up @@ -655,7 +655,7 @@ Task OnConnected(MqttClientConnectResult connectResult)
return _events.ConnectedEvent.InvokeAsync(eventArgs);
}

Task ProcessReceivedAuthPacket(MqttAuthPacket authPacket)
Task ProcessReceivedAuthPacket(MqttAuthPacket authPacket, CancellationToken cancellationToken)
{
if (Options.EnhancedAuthenticationHandler == null)
{
Expand All @@ -667,12 +667,13 @@ Task ProcessReceivedAuthPacket(MqttAuthPacket authPacket)
{
Reason = MqttClientDisconnectOptionsReason.ImplementationSpecificError,
ReasonString = "Unable to handle AUTH packet"
});
},
cancellationToken);

return CompletedTask.Instance;
}

var eventArgs = new MqttEnhancedAuthenticationEventArgs(authPacket, _adapter);
var eventArgs = new MqttEnhancedAuthenticationEventArgs(authPacket, _adapter, cancellationToken);
return Options.EnhancedAuthenticationHandler.HandleEnhancedAuthenticationAsync(eventArgs);
}

Expand Down Expand Up @@ -981,7 +982,7 @@ async Task TryProcessReceivedPacket(MqttPacket packet, CancellationToken cancell
await ProcessReceivedDisconnectPacket(disconnectPacket).ConfigureAwait(false);
break;
case MqttAuthPacket authPacket:
await ProcessReceivedAuthPacket(authPacket).ConfigureAwait(false);
await ProcessReceivedAuthPacket(authPacket, cancellationToken).ConfigureAwait(false);
break;
case MqttPingRespPacket _:
_packetDispatcher.TryDispatch(packet);
Expand Down
62 changes: 37 additions & 25 deletions Source/MQTTnet/Options/MqttEnhancedAuthenticationEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,43 +16,41 @@ namespace MQTTnet;
public class MqttEnhancedAuthenticationEventArgs : EventArgs
{
readonly IMqttChannelAdapter _channelAdapter;
readonly MqttAuthPacket _initialAuthPacket;

public MqttEnhancedAuthenticationEventArgs(MqttAuthPacket initialAuthPacket, IMqttChannelAdapter channelAdapter)
public MqttEnhancedAuthenticationEventArgs(MqttAuthPacket initialAuthPacket, IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(initialAuthPacket);

_initialAuthPacket = initialAuthPacket ?? throw new ArgumentNullException(nameof(initialAuthPacket));
_channelAdapter = channelAdapter ?? throw new ArgumentNullException(nameof(channelAdapter));

ReasonCode = initialAuthPacket.ReasonCode;
ReasonString = initialAuthPacket.ReasonString;
AuthenticationMethod = initialAuthPacket.AuthenticationMethod;
AuthenticationData = initialAuthPacket.AuthenticationData;
UserProperties = initialAuthPacket.UserProperties;
CancellationToken = cancellationToken;
}

/// <summary>
/// Gets the authentication data.
/// Hint: MQTT 5 feature only.
/// </summary>
public byte[] AuthenticationData { get; }
public byte[] AuthenticationData => _initialAuthPacket.AuthenticationData;

/// <summary>
/// Gets the authentication method.
/// Hint: MQTT 5 feature only.
/// </summary>
public string AuthenticationMethod { get; }
public string AuthenticationMethod => _initialAuthPacket.AuthenticationMethod;

public CancellationToken CancellationToken { get; }

/// <summary>
/// Gets the reason code.
/// Hint: MQTT 5 feature only.
/// </summary>
public MqttAuthenticateReasonCode ReasonCode { get; }
public MqttAuthenticateReasonCode ReasonCode => _initialAuthPacket.ReasonCode;

/// <summary>
/// Gets the reason string.
/// Hint: MQTT 5 feature only.
/// </summary>
public string ReasonString { get; }
public string ReasonString => _initialAuthPacket.ReasonString;

/// <summary>
/// Gets the user properties.
Expand All @@ -63,34 +61,48 @@ public MqttEnhancedAuthenticationEventArgs(MqttAuthPacket initialAuthPacket, IMq
/// The feature is very similar to the HTTP header concept.
/// Hint: MQTT 5 feature only.
/// </summary>
public List<MqttUserProperty> UserProperties { get; }
public List<MqttUserProperty> UserProperties => _initialAuthPacket.UserProperties;

public async Task<MqttAuthPacket> ReceiveAsync(CancellationToken cancellationToken = default)
public async Task<ReceiveMqttEnhancedAuthenticationDataResult> ReceiveAsync(CancellationToken cancellationToken = default)
{
var receivedPacket = await _channelAdapter.ReceivePacketAsync(cancellationToken).ConfigureAwait(false);

if (receivedPacket is MqttAuthPacket authPacket)
{
return authPacket;
return new ReceiveMqttEnhancedAuthenticationDataResult
{
AuthenticationData = authPacket.AuthenticationData,
AuthenticationMethod = authPacket.AuthenticationMethod,
ReasonString = authPacket.ReasonString,
ReasonCode = authPacket.ReasonCode,
UserProperties = authPacket.UserProperties
};
}

if (receivedPacket is MqttConnAckPacket connAckPacket)
if (receivedPacket is MqttConnAckPacket)
{
throw new InvalidOperationException("The enhanced authentication handler must not wait for the CONNACK packet.");
}

throw new MqttProtocolViolationException("Received other packet than AUTH while authenticating.");
}

public Task SendAsync(byte[] authenticationData, CancellationToken cancellationToken = default)
public Task SendAsync(SendMqttEnhancedAuthenticationDataOptions options, CancellationToken cancellationToken = default)
{
return _channelAdapter.SendPacketAsync(
new MqttAuthPacket
{
ReasonCode = MqttAuthenticateReasonCode.ContinueAuthentication,
AuthenticationMethod = AuthenticationMethod,
AuthenticationData = authenticationData
},
cancellationToken);
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}

var authPacket = new MqttAuthPacket
{
ReasonCode = MqttAuthenticateReasonCode.ContinueAuthentication,
AuthenticationMethod = AuthenticationMethod,
AuthenticationData = options.Data,
UserProperties = options.UserProperties,
ReasonString = options.ReasonString
};

return _channelAdapter.SendPacketAsync(authPacket, cancellationToken);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Licensed to the .NET Foundation under one or more agreements.
// 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.Collections.Generic;
using MQTTnet.Packets;
using MQTTnet.Protocol;

namespace MQTTnet;

public sealed class ReceiveMqttEnhancedAuthenticationDataResult
{
public byte[] AuthenticationData { get; init; }

public string AuthenticationMethod { get; init; }

public MqttAuthenticateReasonCode ReasonCode { get; init; }

public string ReasonString { get; init; }

public List<MqttUserProperty> UserProperties { get; init; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// 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.Collections.Generic;
using MQTTnet.Packets;

namespace MQTTnet;

public sealed class SendMqttEnhancedAuthenticationDataOptions
{
public byte[] Data { get; init; }

public string ReasonString { get; init; }

public List<MqttUserProperty> UserProperties { get; init; }
}

0 comments on commit 3d9734e

Please sign in to comment.