mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-27 00:40:01 +08:00
Expose more properties of the connection validator context in MQTTnet.Server. Migrate return code to reason code.
This commit is contained in:
@@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace MQTTnet.Server.Configuration
|
||||||
|
{
|
||||||
|
public static class PathHelper
|
||||||
|
{
|
||||||
|
public static string ExpandPath(string path)
|
||||||
|
{
|
||||||
|
if (path == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var uri = new Uri(path, UriKind.RelativeOrAbsolute);
|
||||||
|
if (!uri.IsAbsoluteUri)
|
||||||
|
{
|
||||||
|
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,8 @@ namespace MQTTnet.Server.Configuration
|
|||||||
{
|
{
|
||||||
public class ScriptingSettingsModel
|
public class ScriptingSettingsModel
|
||||||
{
|
{
|
||||||
|
public string ScriptsPath { get; set; }
|
||||||
|
|
||||||
public List<string> IncludePaths { get; set; }
|
public List<string> IncludePaths { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-6
@@ -7,12 +7,12 @@ using MQTTnet.Server.Scripting;
|
|||||||
|
|
||||||
namespace MQTTnet.Server.Mqtt
|
namespace MQTTnet.Server.Mqtt
|
||||||
{
|
{
|
||||||
public class MqttConnectionValidator : IMqttServerConnectionValidator
|
public class MqttServerConnectionValidator : IMqttServerConnectionValidator
|
||||||
{
|
{
|
||||||
private readonly PythonScriptHostService _pythonScriptHostService;
|
private readonly PythonScriptHostService _pythonScriptHostService;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
public MqttConnectionValidator(PythonScriptHostService pythonScriptHostService, ILogger<MqttConnectionValidator> logger)
|
public MqttServerConnectionValidator(PythonScriptHostService pythonScriptHostService, ILogger<MqttServerConnectionValidator> logger)
|
||||||
{
|
{
|
||||||
_pythonScriptHostService = pythonScriptHostService ?? throw new ArgumentNullException(nameof(pythonScriptHostService));
|
_pythonScriptHostService = pythonScriptHostService ?? throw new ArgumentNullException(nameof(pythonScriptHostService));
|
||||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
@@ -24,18 +24,22 @@ namespace MQTTnet.Server.Mqtt
|
|||||||
{
|
{
|
||||||
var pythonContext = new PythonDictionary
|
var pythonContext = new PythonDictionary
|
||||||
{
|
{
|
||||||
{ "client_id", context.ClientId },
|
|
||||||
{ "endpoint", context.Endpoint },
|
{ "endpoint", context.Endpoint },
|
||||||
{ "is_secure_connection", context.IsSecureConnection },
|
{ "is_secure_connection", context.IsSecureConnection },
|
||||||
|
{ "client_id", context.ClientId },
|
||||||
{ "username", context.Username },
|
{ "username", context.Username },
|
||||||
{ "password", context.Password },
|
{ "password", context.Password },
|
||||||
{ "raw_password", context.RawPassword },
|
{ "raw_password", new Bytes(context.RawPassword) },
|
||||||
{ "result", PythonConvert.Pythonfy(context.ReturnCode) }
|
{ "clean_session", context.CleanSession},
|
||||||
|
{ "authentication_method", context.AuthenticationMethod},
|
||||||
|
{ "authentication_data", new Bytes(context.AuthenticationData)},
|
||||||
|
|
||||||
|
{ "result", PythonConvert.Pythonfy(context.ReasonCode) }
|
||||||
};
|
};
|
||||||
|
|
||||||
_pythonScriptHostService.InvokeOptionalFunction("on_validate_client_connection", pythonContext);
|
_pythonScriptHostService.InvokeOptionalFunction("on_validate_client_connection", pythonContext);
|
||||||
|
|
||||||
context.ReturnCode = PythonConvert.ParseEnum<MqttConnectReturnCode>((string)pythonContext["result"]);
|
context.ReasonCode = PythonConvert.ParseEnum<MqttConnectReasonCode>((string)pythonContext["result"]);
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
@@ -30,7 +30,7 @@ namespace MQTTnet.Server.Mqtt
|
|||||||
private readonly MqttClientDisconnectedHandler _mqttClientDisconnectedHandler;
|
private readonly MqttClientDisconnectedHandler _mqttClientDisconnectedHandler;
|
||||||
private readonly MqttClientSubscribedTopicHandler _mqttClientSubscribedTopicHandler;
|
private readonly MqttClientSubscribedTopicHandler _mqttClientSubscribedTopicHandler;
|
||||||
private readonly MqttClientUnsubscribedTopicHandler _mqttClientUnsubscribedTopicHandler;
|
private readonly MqttClientUnsubscribedTopicHandler _mqttClientUnsubscribedTopicHandler;
|
||||||
private readonly MqttConnectionValidator _mqttConnectionValidator;
|
private readonly MqttServerConnectionValidator _mqttConnectionValidator;
|
||||||
private readonly IMqttServer _mqttServer;
|
private readonly IMqttServer _mqttServer;
|
||||||
private readonly MqttSubscriptionInterceptor _mqttSubscriptionInterceptor;
|
private readonly MqttSubscriptionInterceptor _mqttSubscriptionInterceptor;
|
||||||
private readonly PythonScriptHostService _pythonScriptHostService;
|
private readonly PythonScriptHostService _pythonScriptHostService;
|
||||||
@@ -43,7 +43,7 @@ namespace MQTTnet.Server.Mqtt
|
|||||||
MqttClientDisconnectedHandler mqttClientDisconnectedHandler,
|
MqttClientDisconnectedHandler mqttClientDisconnectedHandler,
|
||||||
MqttClientSubscribedTopicHandler mqttClientSubscribedTopicHandler,
|
MqttClientSubscribedTopicHandler mqttClientSubscribedTopicHandler,
|
||||||
MqttClientUnsubscribedTopicHandler mqttClientUnsubscribedTopicHandler,
|
MqttClientUnsubscribedTopicHandler mqttClientUnsubscribedTopicHandler,
|
||||||
MqttConnectionValidator mqttConnectionValidator,
|
MqttServerConnectionValidator mqttConnectionValidator,
|
||||||
MqttSubscriptionInterceptor mqttSubscriptionInterceptor,
|
MqttSubscriptionInterceptor mqttSubscriptionInterceptor,
|
||||||
MqttApplicationMessageInterceptor mqttApplicationMessageInterceptor,
|
MqttApplicationMessageInterceptor mqttApplicationMessageInterceptor,
|
||||||
MqttServerStorage mqttServerStorage,
|
MqttServerStorage mqttServerStorage,
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace MQTTnet.Server.Mqtt
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_path = ExpandPath();
|
_path = PathHelper.ExpandPath(_mqttSettings.RetainedApplicationMessages.Path);
|
||||||
|
|
||||||
// The retained application messages are stored in a separate thread.
|
// The retained application messages are stored in a separate thread.
|
||||||
// This is mandatory because writing them to a slow storage (like RaspberryPi SD card)
|
// This is mandatory because writing them to a slow storage (like RaspberryPi SD card)
|
||||||
@@ -115,18 +115,5 @@ namespace MQTTnet.Server.Mqtt
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ExpandPath()
|
|
||||||
{
|
|
||||||
var path = _mqttSettings.RetainedApplicationMessages.Path;
|
|
||||||
|
|
||||||
var uri = new Uri(path, UriKind.RelativeOrAbsolute);
|
|
||||||
if (!uri.IsAbsoluteUri)
|
|
||||||
{
|
|
||||||
path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace MQTTnet.Server.Scripting
|
|||||||
{
|
{
|
||||||
private readonly IDictionary<string, object> _proxyObjects = new ExpandoObject();
|
private readonly IDictionary<string, object> _proxyObjects = new ExpandoObject();
|
||||||
private readonly List<PythonScriptInstance> _scriptInstances = new List<PythonScriptInstance>();
|
private readonly List<PythonScriptInstance> _scriptInstances = new List<PythonScriptInstance>();
|
||||||
private readonly string _scriptsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Scripts");
|
private readonly string _scriptsPath;
|
||||||
private readonly ScriptingSettingsModel _scriptingSettings;
|
private readonly ScriptingSettingsModel _scriptingSettings;
|
||||||
private readonly ILogger<PythonScriptHostService> _logger;
|
private readonly ILogger<PythonScriptHostService> _logger;
|
||||||
private readonly ScriptEngine _scriptEngine;
|
private readonly ScriptEngine _scriptEngine;
|
||||||
@@ -29,6 +29,8 @@ namespace MQTTnet.Server.Scripting
|
|||||||
|
|
||||||
_scriptEngine = IronPython.Hosting.Python.CreateEngine();
|
_scriptEngine = IronPython.Hosting.Python.CreateEngine();
|
||||||
_scriptEngine.Runtime.IO.SetOutput(pythonIOStream, Encoding.UTF8);
|
_scriptEngine.Runtime.IO.SetOutput(pythonIOStream, Encoding.UTF8);
|
||||||
|
|
||||||
|
_scriptsPath = PathHelper.ExpandPath(scriptingSettings.ScriptsPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Configure()
|
public void Configure()
|
||||||
@@ -186,13 +188,7 @@ namespace MQTTnet.Server.Scripting
|
|||||||
|
|
||||||
foreach (var path in _scriptingSettings.IncludePaths)
|
foreach (var path in _scriptingSettings.IncludePaths)
|
||||||
{
|
{
|
||||||
var effectivePath = path;
|
var effectivePath = PathHelper.ExpandPath(path);
|
||||||
|
|
||||||
var uri = new Uri(effectivePath, UriKind.RelativeOrAbsolute);
|
|
||||||
if (!uri.IsAbsoluteUri)
|
|
||||||
{
|
|
||||||
effectivePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, effectivePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Directory.Exists(effectivePath))
|
if (Directory.Exists(effectivePath))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,20 +25,45 @@ def on_validate_client_connection(context):
|
|||||||
|
|
||||||
print(context)
|
print(context)
|
||||||
|
|
||||||
|
# Access some custom data here which was inserted upon connect and may use it for validation.
|
||||||
mqtt_net_server.write_shared_data(context["client_id"], {"custom_value_1": 1, "custom_value_2": True})
|
mqtt_net_server.write_shared_data(context["client_id"], {"custom_value_1": 1, "custom_value_2": True})
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Supported results:
|
||||||
|
# * success
|
||||||
|
# * unspecified_error
|
||||||
|
# * malformed_packet
|
||||||
|
# * protocol_error
|
||||||
|
# * implementation_specific_error
|
||||||
|
# * unsupported_protocol_version
|
||||||
|
# * client_identifier_not_valid
|
||||||
|
# * bad_user_name_or_password
|
||||||
|
# * not_authorized
|
||||||
|
# * server_unavailable
|
||||||
|
# * server_busy
|
||||||
|
# * banned
|
||||||
|
# * bad_authentication_method
|
||||||
|
# * topic_name_invalid
|
||||||
|
# * packet_too_large
|
||||||
|
# * quota_exceeded
|
||||||
|
# * payload_format_invalid
|
||||||
|
# * retain_not_supported
|
||||||
|
# * qos_not_supported
|
||||||
|
# * use_another_server
|
||||||
|
# * server_moved
|
||||||
|
# * connection_rate_exceeded
|
||||||
|
|
||||||
if context["client_id"] != "test_client":
|
if context["client_id"] != "test_client":
|
||||||
context["result"] = "connection_refused_not_authorized"
|
context["result"] = "bad_user_name_or_password"
|
||||||
return
|
return
|
||||||
|
|
||||||
if context["username"] != "bud spencer":
|
if context["username"] != "bud spencer":
|
||||||
context["result"] = "connection_refused_not_authorized"
|
context["result"] = "bad_user_name_or_password"
|
||||||
return
|
return
|
||||||
|
|
||||||
if context["password_string"] != "secret":
|
if context["password_string"] != "secret":
|
||||||
context["result"] = "connection_refused_not_authorized"
|
context["result"] = "bad_user_name_or_password"
|
||||||
|
|
||||||
print(context)
|
print(context)
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@@ -17,7 +16,6 @@ using MQTTnet.Server.Logging;
|
|||||||
using MQTTnet.Server.Mqtt;
|
using MQTTnet.Server.Mqtt;
|
||||||
using MQTTnet.Server.Scripting;
|
using MQTTnet.Server.Scripting;
|
||||||
using MQTTnet.Server.Scripting.DataSharing;
|
using MQTTnet.Server.Scripting.DataSharing;
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
||||||
using Swashbuckle.AspNetCore.SwaggerUI;
|
using Swashbuckle.AspNetCore.SwaggerUI;
|
||||||
|
|
||||||
namespace MQTTnet.Server.Web
|
namespace MQTTnet.Server.Web
|
||||||
@@ -111,7 +109,7 @@ namespace MQTTnet.Server.Web
|
|||||||
services.AddSingleton<MqttClientDisconnectedHandler>();
|
services.AddSingleton<MqttClientDisconnectedHandler>();
|
||||||
services.AddSingleton<MqttClientSubscribedTopicHandler>();
|
services.AddSingleton<MqttClientSubscribedTopicHandler>();
|
||||||
services.AddSingleton<MqttClientUnsubscribedTopicHandler>();
|
services.AddSingleton<MqttClientUnsubscribedTopicHandler>();
|
||||||
services.AddSingleton<MqttConnectionValidator>();
|
services.AddSingleton<MqttServerConnectionValidator>();
|
||||||
services.AddSingleton<MqttSubscriptionInterceptor>();
|
services.AddSingleton<MqttSubscriptionInterceptor>();
|
||||||
services.AddSingleton<MqttApplicationMessageInterceptor>();
|
services.AddSingleton<MqttApplicationMessageInterceptor>();
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
"EnableDebugLogging": false
|
"EnableDebugLogging": false
|
||||||
},
|
},
|
||||||
"Scripting": {
|
"Scripting": {
|
||||||
|
"ScriptsPath": "Scripts",
|
||||||
"IncludePaths": [
|
"IncludePaths": [
|
||||||
"Lib",
|
"Lib",
|
||||||
"/usr/lib/python2.7",
|
"/usr/lib/python2.7",
|
||||||
|
|||||||
Reference in New Issue
Block a user