mirror of
https://github.com/MeowCraftMC/CrystalConnector
synced 2025-05-22 02:43:00 +00:00
@@ -0,0 +1,23 @@
|
|||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
|
namespace CrystalConnector.Configs;
|
||||||
|
|
||||||
|
public class ConfigAccessor
|
||||||
|
{
|
||||||
|
private IConfiguration Config { get; }
|
||||||
|
|
||||||
|
public ConfigAccessor(IConfiguration config)
|
||||||
|
{
|
||||||
|
Config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsDebug()
|
||||||
|
{
|
||||||
|
return Config.GetValue<bool>("Connector:Debug");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetSecretKey()
|
||||||
|
{
|
||||||
|
return Config.GetValue<string>("Connector:Auth:Secret") ?? "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System.Formats.Cbor;
|
||||||
|
|
||||||
|
namespace CrystalConnector.Connector.Packet;
|
||||||
|
|
||||||
|
public interface IPacket
|
||||||
|
{
|
||||||
|
public void Write(CborWriter writer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Read(CborReader reader)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using System.Formats.Cbor;
|
||||||
|
using CrystalConnector.Handlers;
|
||||||
|
|
||||||
|
namespace CrystalConnector.Connector.Packet;
|
||||||
|
|
||||||
|
public class S2CAuthenticatedPacket : IPacket
|
||||||
|
{
|
||||||
|
public void Write(CborWriter writer)
|
||||||
|
{
|
||||||
|
writer.WriteTextString(HandlerConstants.ResponseAuthenticated);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
public class HandlerConstants
|
public class HandlerConstants
|
||||||
{
|
{
|
||||||
public static readonly string MessageTypeAuthenticate = "Authenticate";
|
public static readonly string OperationAuthenticate = "Authenticate";
|
||||||
public static readonly string MessageTypeRegisterHandler = "Register";
|
public static readonly string OperationRegisterChannel = "Register";
|
||||||
public static readonly string MessageTypeEmit = "Emit";
|
public static readonly string OperationPublish = "Publish";
|
||||||
|
|
||||||
|
public static readonly string ResponseAuthenticated = "Authenticated";
|
||||||
}
|
}
|
||||||
@@ -1,37 +1,39 @@
|
|||||||
using System.Formats.Cbor;
|
using System.Formats.Cbor;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
|
using CrystalConnector.Configs;
|
||||||
|
using CrystalConnector.Connector.Packet;
|
||||||
using CrystalConnector.Utilities;
|
using CrystalConnector.Utilities;
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace CrystalConnector.Handlers;
|
namespace CrystalConnector.Handlers;
|
||||||
|
|
||||||
public class WebSocketHandler
|
public class WebSocketHandler
|
||||||
{
|
{
|
||||||
private IConfiguration Config { get; }
|
private ConfigAccessor Config { get; }
|
||||||
|
|
||||||
private ILogger<WebSocketHandler> Logger { get; }
|
private ILogger<WebSocketHandler> Logger { get; }
|
||||||
|
|
||||||
public WebSocketHandler(IConfiguration config, ILogger<WebSocketHandler> logger)
|
public WebSocketHandler(ConfigAccessor config, ILogger<WebSocketHandler> logger)
|
||||||
{
|
{
|
||||||
Config = config;
|
Config = config;
|
||||||
Logger = logger;
|
Logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(WebSocket webSocket, CborReader reader)
|
public async Task Handle(WebSocket webSocket, CborReader reader)
|
||||||
{
|
{
|
||||||
reader.ReadStartArray();
|
reader.ReadStartArray();
|
||||||
|
|
||||||
var type = reader.ReadTextString();
|
var type = reader.ReadTextString();
|
||||||
if (type == HandlerConstants.MessageTypeAuthenticate)
|
if (type == HandlerConstants.OperationAuthenticate)
|
||||||
{
|
{
|
||||||
if (!webSocket.GetConnectionInfo().Authorized)
|
if (!webSocket.GetConnectionInfo().Authenticated)
|
||||||
{
|
{
|
||||||
var secret = reader.ReadTextString();
|
var secret = reader.ReadTextString();
|
||||||
if (secret == Config.GetValue<string>("Connector:Auth:Secret"))
|
if (secret == Config.GetSecretKey())
|
||||||
{
|
{
|
||||||
Logger.LogInformation("Client {Id} authorized", webSocket.GetConnectionInfo().Id);
|
Logger.LogInformation("Client {Id} authorized", webSocket.GetConnectionInfo().Id);
|
||||||
webSocket.GetConnectionInfo().Authorized = true;
|
webSocket.GetConnectionInfo().Authenticated = true;
|
||||||
|
await webSocket.Send(new S2CAuthenticatedPacket().Write);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using CrystalConnector;
|
using CrystalConnector;
|
||||||
|
using CrystalConnector.Configs;
|
||||||
using CrystalConnector.Handlers;
|
using CrystalConnector.Handlers;
|
||||||
using CrystalConnector.WebSockets;
|
using CrystalConnector.WebSockets;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
@@ -95,4 +96,5 @@ void ConfigureServices(IServiceCollection services)
|
|||||||
{
|
{
|
||||||
services.AddSingleton<IWebSocketManager, WebSocketManager>();
|
services.AddSingleton<IWebSocketManager, WebSocketManager>();
|
||||||
services.AddSingleton<WebSocketHandler>();
|
services.AddSingleton<WebSocketHandler>();
|
||||||
|
services.AddSingleton<ConfigAccessor>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ public class WebSocketConnectionInfo
|
|||||||
|
|
||||||
public required TaskCompletionSource<WebSocketHandleResult> CompletionSource { get; set; }
|
public required TaskCompletionSource<WebSocketHandleResult> CompletionSource { get; set; }
|
||||||
|
|
||||||
public bool Authorized { get; set; } = false;
|
public string? Name { get; set; }
|
||||||
|
|
||||||
|
public bool Authenticated { get; set; } = false;
|
||||||
|
|
||||||
public List<MessageChannel> RegisteredChannels { get; } = new();
|
public List<MessageChannel> RegisteredChannels { get; } = new();
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Net;
|
using System.Formats.Cbor;
|
||||||
|
using System.Net;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using CrystalConnector.Connector;
|
using CrystalConnector.Connector;
|
||||||
|
|
||||||
@@ -32,6 +33,15 @@ public static class WebSocketExtension
|
|||||||
WebSocketConnectionManager.Info.Remove(webSocket);
|
WebSocketConnectionManager.Info.Remove(webSocket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task Send(this WebSocket webSocket, Action<CborWriter> write)
|
||||||
|
{
|
||||||
|
var writer = new CborWriter();
|
||||||
|
writer.WriteStartArray(null);
|
||||||
|
write(writer);
|
||||||
|
writer.WriteEndArray();
|
||||||
|
await webSocket.Send(writer.Encode());
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task Send(this WebSocket webSocket, byte[] data)
|
public static async Task Send(this WebSocket webSocket, byte[] data)
|
||||||
{
|
{
|
||||||
await webSocket.Send(data, 0, data.Length);
|
await webSocket.Send(data, 0, data.Length);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using System.Formats.Cbor;
|
using System.Formats.Cbor;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
|
using CrystalConnector.Configs;
|
||||||
using CrystalConnector.Handlers;
|
using CrystalConnector.Handlers;
|
||||||
using CrystalConnector.Utilities;
|
using CrystalConnector.Utilities;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace CrystalConnector.WebSockets;
|
namespace CrystalConnector.WebSockets;
|
||||||
@@ -13,11 +13,11 @@ public class WebSocketManager : IWebSocketManager
|
|||||||
{
|
{
|
||||||
private ILogger<WebSocketManager> Logger { get; }
|
private ILogger<WebSocketManager> Logger { get; }
|
||||||
|
|
||||||
private IConfiguration Config { get; }
|
private ConfigAccessor Config { get; }
|
||||||
|
|
||||||
private WebSocketHandler Handler { get; }
|
private WebSocketHandler Handler { get; }
|
||||||
|
|
||||||
public WebSocketManager(ILogger<WebSocketManager> logger, IConfiguration config, WebSocketHandler handler)
|
public WebSocketManager(ILogger<WebSocketManager> logger, ConfigAccessor config, WebSocketHandler handler)
|
||||||
{
|
{
|
||||||
Logger = logger;
|
Logger = logger;
|
||||||
Config = config;
|
Config = config;
|
||||||
@@ -42,20 +42,19 @@ public class WebSocketManager : IWebSocketManager
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Handler.Handle(webSocket, reader);
|
await Handler.Handle(webSocket, reader);
|
||||||
}
|
}
|
||||||
catch (CborContentException ex)
|
catch (CborContentException ex)
|
||||||
{
|
{
|
||||||
if (Config.GetValue<bool>("Connector:Debug"))
|
if (Config.IsDebug())
|
||||||
{
|
{
|
||||||
Logger.LogWarning(ex, "Malformed message!");
|
Logger.LogWarning(ex, "Malformed message!");
|
||||||
}
|
}
|
||||||
|
|
||||||
Disconnect(webSocket);
|
Disconnect(webSocket);
|
||||||
}
|
}
|
||||||
catch (InvalidOperationException ex)
|
catch (InvalidOperationException ex)
|
||||||
{
|
{
|
||||||
if (Config.GetValue<bool>("Connector:Debug"))
|
if (Config.IsDebug())
|
||||||
{
|
{
|
||||||
Logger.LogWarning(ex, "Bad message!");
|
Logger.LogWarning(ex, "Bad message!");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user