net8, language features, bugfixes
This commit is contained in:
parent
1591618c2c
commit
ce99053a10
353 changed files with 3245 additions and 3944 deletions
|
|
@ -39,6 +39,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Insight.Remote.Shared", "sr
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Insight.Remote.Windows", "src\Remote\Insight.Remote.Windows\Insight.Remote.Windows.csproj", "{AF313B47-3079-407F-91D1-9989C1E1AF2A}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Insight.Remote.Windows", "src\Remote\Insight.Remote.Windows\Insight.Remote.Windows.csproj", "{AF313B47-3079-407F-91D1-9989C1E1AF2A}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Insight.Infrastructure.Web", "src\Core\Insight.Infrastructure.Web\Insight.Infrastructure.Web.csproj", "{39B81A0D-A88C-44D3-9624-1A19C78A4310}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
@ -85,6 +87,10 @@ Global
|
||||||
{AF313B47-3079-407F-91D1-9989C1E1AF2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{AF313B47-3079-407F-91D1-9989C1E1AF2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{AF313B47-3079-407F-91D1-9989C1E1AF2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{AF313B47-3079-407F-91D1-9989C1E1AF2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{AF313B47-3079-407F-91D1-9989C1E1AF2A}.Release|Any CPU.Build.0 = Release|Any CPU
|
{AF313B47-3079-407F-91D1-9989C1E1AF2A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{39B81A0D-A88C-44D3-9624-1A19C78A4310}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{39B81A0D-A88C-44D3-9624-1A19C78A4310}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{39B81A0D-A88C-44D3-9624-1A19C78A4310}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{39B81A0D-A88C-44D3-9624-1A19C78A4310}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -100,6 +106,7 @@ Global
|
||||||
{2A391CA2-F96B-4DB7-80AA-0668A5141640} = {140F73DD-29D3-4C44-809B-5B470880AA0D}
|
{2A391CA2-F96B-4DB7-80AA-0668A5141640} = {140F73DD-29D3-4C44-809B-5B470880AA0D}
|
||||||
{5C4697BD-BC97-484F-9DB1-CA87E2BEAA4B} = {D4D7BF4A-B2E3-470A-A14C-FC658FF7461D}
|
{5C4697BD-BC97-484F-9DB1-CA87E2BEAA4B} = {D4D7BF4A-B2E3-470A-A14C-FC658FF7461D}
|
||||||
{AF313B47-3079-407F-91D1-9989C1E1AF2A} = {D4D7BF4A-B2E3-470A-A14C-FC658FF7461D}
|
{AF313B47-3079-407F-91D1-9989C1E1AF2A} = {D4D7BF4A-B2E3-470A-A14C-FC658FF7461D}
|
||||||
|
{39B81A0D-A88C-44D3-9624-1A19C78A4310} = {88B03853-2215-4E52-8986-0E76602E5F21}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {F376A326-7590-4E7E-AB9B-76CED8527AB0}
|
SolutionGuid = {F376A326-7590-4E7E-AB9B-76CED8527AB0}
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,24 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
<RootNamespace>Insight.Agent</RootNamespace>
|
<RootNamespace>Insight.Agent</RootNamespace>
|
||||||
<Product>Insight</Product>
|
<Product>Insight</Product>
|
||||||
<AssemblyName>agent</AssemblyName>
|
<AssemblyName>agent</AssemblyName>
|
||||||
<AssemblyVersion>2023.12.14.0</AssemblyVersion>
|
<AssemblyVersion>2023.12.14.0</AssemblyVersion>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<SatelliteResourceLanguages>none</SatelliteResourceLanguages>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<!--WMI / System.Management-->
|
||||||
|
<RuntimeHostConfigurationOption Include="System.Runtime.Loader.UseRidGraph" Value="true" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
<DebugType>none</DebugType>
|
<DebugType>none</DebugType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||||
|
|
@ -20,14 +27,14 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="7.0.1" />
|
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.3.10" />
|
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.3.10" />
|
||||||
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
|
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
|
||||||
<PackageReference Include="System.Management" Version="7.0.2" />
|
<PackageReference Include="System.Management" Version="8.0.0" />
|
||||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="7.0.1" />
|
<PackageReference Include="System.ServiceProcess.ServiceController" Version="8.0.0" />
|
||||||
<PackageReference Include="Vaitr.Snmp" Version="2023.3.3" />
|
<PackageReference Include="Vaitr.Snmp" Version="2023.12.15.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,10 @@ using Vaitr.Network;
|
||||||
|
|
||||||
namespace Insight.Agent.Network;
|
namespace Insight.Agent.Network;
|
||||||
|
|
||||||
public class AgentSession : TcpSession<IMessage>
|
public class AgentSession(IEnumerable<IMessageHandler<AgentSession>> handlers, ISerializer<IMessage> serializer, ILogger<AgentSession> logger)
|
||||||
|
: TcpSession<IMessage>(serializer, logger)
|
||||||
{
|
{
|
||||||
private readonly IEnumerable<IMessageHandler<AgentSession>> _handlers;
|
private readonly IEnumerable<IMessageHandler<AgentSession>> _handlers = handlers;
|
||||||
|
|
||||||
public AgentSession(IEnumerable<IMessageHandler<AgentSession>> handlers, ISerializer<IMessage> serializer, ILogger<AgentSession> logger) : base(serializer, logger)
|
|
||||||
{
|
|
||||||
_handlers = handlers;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override ValueTask OnConnectedAsync(CancellationToken cancellationToken)
|
protected override ValueTask OnConnectedAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,20 +2,12 @@
|
||||||
using Insight.Domain.Interfaces;
|
using Insight.Domain.Interfaces;
|
||||||
using Insight.Domain.Network;
|
using Insight.Domain.Network;
|
||||||
using Insight.Domain.Network.Agent.Messages;
|
using Insight.Domain.Network.Agent.Messages;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace Insight.Agent.Network.Handlers;
|
namespace Insight.Agent.Network.Handlers;
|
||||||
|
|
||||||
public class CustomHandler : IMessageHandler<AgentSession>
|
public class CustomHandler(ScriptService scriptService) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly ScriptService _scriptService;
|
private readonly ScriptService _scriptService = scriptService;
|
||||||
private readonly ILogger<CustomHandler> _logger;
|
|
||||||
|
|
||||||
public CustomHandler(ScriptService scriptService, ILogger<CustomHandler> logger)
|
|
||||||
{
|
|
||||||
_scriptService = scriptService;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -29,6 +21,7 @@ public class CustomHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
private async ValueTask OnRequestAsync(AgentSession sender, Request request, CancellationToken cancellationToken)
|
private async ValueTask OnRequestAsync(AgentSession sender, Request request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
if (request.RequestData is null) return;
|
||||||
var result = await _scriptService.QueryAsync(request.RequestData);
|
var result = await _scriptService.QueryAsync(request.RequestData);
|
||||||
|
|
||||||
await sender.SendAsync(new Response(request)
|
await sender.SendAsync(new Response(request)
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ public class DriveHandler : IMessageHandler<AgentSession>
|
||||||
drive.InterfaceType = @object.GetValue<string>(properties, "interfacetype")?.Trim();
|
drive.InterfaceType = @object.GetValue<string>(properties, "interfacetype")?.Trim();
|
||||||
drive.FirmwareRevision = @object.GetValue<string>(properties, "firmwarerevision")?.Trim();
|
drive.FirmwareRevision = @object.GetValue<string>(properties, "firmwarerevision")?.Trim();
|
||||||
drive.PNPDeviceID = @object.GetValue<string>(properties, "pnpdeviceid")?.Trim();
|
drive.PNPDeviceID = @object.GetValue<string>(properties, "pnpdeviceid")?.Trim();
|
||||||
drive.Volumes = new List<Volume>();
|
drive.Volumes = [];
|
||||||
|
|
||||||
var diskpartition = @object.GetRelated("win32_diskpartition");
|
var diskpartition = @object.GetRelated("win32_diskpartition");
|
||||||
using (diskpartition)
|
using (diskpartition)
|
||||||
|
|
@ -155,7 +155,7 @@ public class DriveHandler : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
using (collection2)
|
using (collection2)
|
||||||
{
|
{
|
||||||
foreach (ManagementObject @object2 in collection2)
|
foreach (ManagementObject @object2 in collection2.Cast<ManagementObject>())
|
||||||
{
|
{
|
||||||
var properties2 = @object2.GetPropertyHashes();
|
var properties2 = @object2.GetPropertyHashes();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||||
case InventoryRequest:
|
case InventoryRequest:
|
||||||
{
|
{
|
||||||
var result = new Collection<Interface>();
|
var result = new Collection<Interface>();
|
||||||
result.AddRange(GetInterfaces());
|
if (GetInterfaces() is List<Interface> interfaces) result.AddRange(interfaces);
|
||||||
|
|
||||||
await sender.SendAsync(result, cancellationToken);
|
await sender.SendAsync(result, cancellationToken);
|
||||||
break;
|
break;
|
||||||
|
|
@ -27,10 +27,10 @@ public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Interface> GetInterfaces()
|
private static List<Interface>? GetInterfaces()
|
||||||
{
|
{
|
||||||
if (NetworkInterface.GetIsNetworkAvailable() is false) return null;
|
if (NetworkInterface.GetIsNetworkAvailable() is false) return null;
|
||||||
if (NetworkInterface.GetAllNetworkInterfaces().Any() is false) return null;
|
if (NetworkInterface.GetAllNetworkInterfaces().Length == 0) return null;
|
||||||
|
|
||||||
var interfaces = new List<Interface>();
|
var interfaces = new List<Interface>();
|
||||||
|
|
||||||
|
|
@ -99,7 +99,7 @@ public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
using (collection)
|
using (collection)
|
||||||
{
|
{
|
||||||
foreach (ManagementObject @object in collection)
|
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||||
{
|
{
|
||||||
var properties = @object.GetPropertyHashes();
|
var properties = @object.GetPropertyHashes();
|
||||||
|
|
||||||
|
|
@ -185,7 +185,7 @@ public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
var addresses = new List<Unicast>();
|
var addresses = new List<Unicast>();
|
||||||
|
|
||||||
if (unicastCollection.Any() is false) return addresses;
|
if (unicastCollection.Count == 0) return addresses;
|
||||||
|
|
||||||
foreach (var unicast in unicastCollection)
|
foreach (var unicast in unicastCollection)
|
||||||
{
|
{
|
||||||
|
|
@ -210,7 +210,7 @@ public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
var addresses = new List<IPAddress2>();
|
var addresses = new List<IPAddress2>();
|
||||||
|
|
||||||
if (addressCollection.Any() is false) return addresses;
|
if (addressCollection.Count == 0) return addresses;
|
||||||
|
|
||||||
foreach (var address in addressCollection)
|
foreach (var address in addressCollection)
|
||||||
{
|
{
|
||||||
|
|
@ -224,7 +224,7 @@ public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
var addresses = new List<IPAddress2>();
|
var addresses = new List<IPAddress2>();
|
||||||
|
|
||||||
if (addressCollection.Any() is false) return addresses;
|
if (addressCollection.Count == 0) return addresses;
|
||||||
|
|
||||||
foreach (var address in addressCollection)
|
foreach (var address in addressCollection)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,12 @@ public class MainboardHandler : IMessageHandler<AgentSession>
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
case InventoryRequest:
|
case InventoryRequest:
|
||||||
await sender.SendAsync(GetMainboard(), cancellationToken);
|
if (GetMainboard() is Mainboard mainboard) await sender.SendAsync(mainboard, cancellationToken);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Mainboard GetMainboard()
|
private static Mainboard? GetMainboard()
|
||||||
{
|
{
|
||||||
using var searcher = new ManagementObjectSearcher
|
using var searcher = new ManagementObjectSearcher
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ public class OperationSystemHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
using (collection)
|
using (collection)
|
||||||
{
|
{
|
||||||
foreach (ManagementObject @object in collection)
|
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||||
{
|
{
|
||||||
var properties = @object.GetPropertyHashes();
|
var properties = @object.GetPropertyHashes();
|
||||||
|
|
||||||
|
|
@ -51,7 +51,8 @@ public class OperationSystemHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
if (@object.TryGetValue<string>(properties, "osarchitecture", out var architecture))
|
if (@object.TryGetValue<string>(properties, "osarchitecture", out var architecture))
|
||||||
{
|
{
|
||||||
if (architecture is not null && architecture.ToLower().Contains("64")) os.Architecture = Architecture.X64;
|
if (architecture is not null && architecture.Contains("64", StringComparison.CurrentCultureIgnoreCase))
|
||||||
|
os.Architecture = Architecture.X64;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,20 +2,12 @@
|
||||||
using Insight.Domain.Interfaces;
|
using Insight.Domain.Interfaces;
|
||||||
using Insight.Domain.Network;
|
using Insight.Domain.Network;
|
||||||
using Insight.Domain.Network.Agent.Messages;
|
using Insight.Domain.Network.Agent.Messages;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace Insight.Agent.Network.Handlers;
|
namespace Insight.Agent.Network.Handlers;
|
||||||
|
|
||||||
public class ProxyHandler : IMessageHandler<AgentSession>
|
public class ProxyHandler(ScriptService scriptService) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly ScriptService _scriptService;
|
private readonly ScriptService _scriptService = scriptService;
|
||||||
private readonly ILogger<ProxyHandler> _logger;
|
|
||||||
|
|
||||||
public ProxyHandler(ScriptService scriptService, ILogger<ProxyHandler> logger)
|
|
||||||
{
|
|
||||||
_scriptService = scriptService;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -29,6 +21,7 @@ public class ProxyHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
private async ValueTask OnProxyRequestAsync(AgentSession sender, Proxy<Request> proxyRequest, CancellationToken cancellationToken)
|
private async ValueTask OnProxyRequestAsync(AgentSession sender, Proxy<Request> proxyRequest, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
if (proxyRequest.Message?.RequestData is null) return;
|
||||||
var result = await _scriptService.QueryAsync(proxyRequest.Message.RequestData);
|
var result = await _scriptService.QueryAsync(proxyRequest.Message.RequestData);
|
||||||
|
|
||||||
await sender.SendAsync(new Proxy<Response>()
|
await sender.SendAsync(new Proxy<Response>()
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ public class ServiceHandler : IMessageHandler<AgentSession>
|
||||||
var services = new List<Service>();
|
var services = new List<Service>();
|
||||||
|
|
||||||
var serviceControllers = ServiceController.GetServices()?.OrderBy(s => s.DisplayName)?.ToList();
|
var serviceControllers = ServiceController.GetServices()?.OrderBy(s => s.DisplayName)?.ToList();
|
||||||
if (serviceControllers is null || serviceControllers.Any() is false) throw new InvalidOperationException("SERVICE Collection NULL");
|
if (serviceControllers is null || serviceControllers.Count == 0) throw new InvalidOperationException("SERVICE Collection NULL");
|
||||||
|
|
||||||
foreach (var sc in serviceControllers)
|
foreach (var sc in serviceControllers)
|
||||||
{
|
{
|
||||||
|
|
@ -102,7 +102,7 @@ public class ServiceHandler : IMessageHandler<AgentSession>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (services2.Any() is false) return services;
|
if (services2.Count == 0) return services;
|
||||||
|
|
||||||
foreach (var svc in services)
|
foreach (var svc in services)
|
||||||
{
|
{
|
||||||
|
|
@ -117,6 +117,6 @@ public class ServiceHandler : IMessageHandler<AgentSession>
|
||||||
svc.Delay = map.Delay;
|
svc.Delay = map.Delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
return services.OrderBy(x => x.Name).ToList();
|
return [.. services.OrderBy(x => x.Name)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -48,7 +48,7 @@ public class SessionHandler : IMessageHandler<AgentSession>
|
||||||
//public const int WTS_CURRENT_SESSION = -1;
|
//public const int WTS_CURRENT_SESSION = -1;
|
||||||
|
|
||||||
[DllImport("wtsapi32.dll")]
|
[DllImport("wtsapi32.dll")]
|
||||||
static extern int WTSEnumerateSessions(
|
private static extern int WTSEnumerateSessions(
|
||||||
nint pServer,
|
nint pServer,
|
||||||
[MarshalAs(UnmanagedType.U4)] int iReserved,
|
[MarshalAs(UnmanagedType.U4)] int iReserved,
|
||||||
[MarshalAs(UnmanagedType.U4)] int iVersion,
|
[MarshalAs(UnmanagedType.U4)] int iVersion,
|
||||||
|
|
@ -64,7 +64,7 @@ public class SessionHandler : IMessageHandler<AgentSession>
|
||||||
out uint iBytesReturned);
|
out uint iBytesReturned);
|
||||||
|
|
||||||
[DllImport("wtsapi32.dll")]
|
[DllImport("wtsapi32.dll")]
|
||||||
static extern void WTSFreeMemory(
|
private static extern void WTSFreeMemory(
|
||||||
nint pMemory);
|
nint pMemory);
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
|
|
||||||
|
|
@ -89,121 +89,6 @@ public class StoragePoolHandler : IMessageHandler<AgentSession>
|
||||||
return pools;
|
return pools;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<PhysicalDisk> GetPhysicalDisks()
|
|
||||||
{
|
|
||||||
using var searcher = new ManagementObjectSearcher
|
|
||||||
{
|
|
||||||
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
|
||||||
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname from msft_physicaldisk")
|
|
||||||
};
|
|
||||||
|
|
||||||
if (searcher.TryGet(out var collection) is false)
|
|
||||||
{
|
|
||||||
searcher.Query = new ObjectQuery("select * from msft_physicaldisk");
|
|
||||||
|
|
||||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
|
||||||
}
|
|
||||||
|
|
||||||
var disks = new List<PhysicalDisk>();
|
|
||||||
|
|
||||||
using (collection)
|
|
||||||
{
|
|
||||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
|
||||||
{
|
|
||||||
var disk = new PhysicalDisk();
|
|
||||||
|
|
||||||
var properties = @object.GetPropertyHashes();
|
|
||||||
|
|
||||||
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
|
||||||
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
|
||||||
disk.Manufacturer = @object.GetValue<string>(properties, "manufacturer")?.Trim();
|
|
||||||
disk.Model = @object.GetValue<string>(properties, "model")?.Trim();
|
|
||||||
disk.MediaType = @object.GetValue<ushort>(properties, "mediatype");
|
|
||||||
disk.BusType = @object.GetValue<ushort>(properties, "bustype");
|
|
||||||
|
|
||||||
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
|
||||||
{
|
|
||||||
disk.States = operationals.Select(p => (PhysicalDisk.OperationalState)p).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
disk.Health = (PhysicalDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
|
||||||
|
|
||||||
if (@object.TryGetValue<ushort[]>(properties, "supportedusages", out var supportedusages) && supportedusages is not null)
|
|
||||||
{
|
|
||||||
disk.SupportedUsages = supportedusages.Select(p => (SupportedUsagesEnum)p).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
disk.Usage = @object.GetValue<ushort>(properties, "usage");
|
|
||||||
disk.PhysicalLocation = @object.GetValue<string>(properties, "physicallocation")?.Trim();
|
|
||||||
disk.SerialNumber = @object.GetValue<string>(properties, "serialnumber")?.Trim();
|
|
||||||
disk.FirmwareVersion = @object.GetValue<string>(properties, "firmwareversion")?.Trim();
|
|
||||||
disk.Size = @object.GetValue<ulong>(properties, "size");
|
|
||||||
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
|
||||||
disk.LogicalSectorSize = @object.GetValue<ulong>(properties, "logicalsectorsize");
|
|
||||||
disk.PhysicalSectorSize = @object.GetValue<ulong>(properties, "physicalsectorsize");
|
|
||||||
disk.VirtualDiskFootprint = @object.GetValue<ulong>(properties, "virtualdiskfootprint");
|
|
||||||
|
|
||||||
disks.Add(disk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return disks;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<VirtualDisk> GetVirtualDisks()
|
|
||||||
{
|
|
||||||
using var searcher = new ManagementObjectSearcher
|
|
||||||
{
|
|
||||||
Scope = new ManagementScope(@"root\microsoft\windows\storage"),
|
|
||||||
Query = new ObjectQuery("select objectid, uniqueid, name, friendlyname, access, provisioningtype, physicaldiskredundancy, resiliencysettingname, isdeduplicationenabled, issnapshot, operationalstatus, healthstatus, size, allocatedsize, footprintonpool, readcachesize, writecachesize from msft_virtualdisk")
|
|
||||||
};
|
|
||||||
|
|
||||||
if (searcher.TryGet(out var collection) is false)
|
|
||||||
{
|
|
||||||
searcher.Query = new ObjectQuery("select * from msft_virtualdisk");
|
|
||||||
|
|
||||||
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
|
|
||||||
}
|
|
||||||
|
|
||||||
var disks = new List<VirtualDisk>();
|
|
||||||
|
|
||||||
using (collection)
|
|
||||||
{
|
|
||||||
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
|
||||||
{
|
|
||||||
var disk = new VirtualDisk();
|
|
||||||
|
|
||||||
var properties = @object.GetPropertyHashes();
|
|
||||||
|
|
||||||
disk.UniqueId = @object.GetValue<string>(properties, "uniqueid")?.Trim();
|
|
||||||
disk.Name = @object.GetValue<string>(properties, "name")?.Trim();
|
|
||||||
disk.FriendlyName = @object.GetValue<string>(properties, "friendlyname")?.Trim();
|
|
||||||
disk.AccessType = (AccessTypeEnum)@object.GetValue<ushort>(properties, "access");
|
|
||||||
disk.ProvisioningType = (ProvisioningTypeEnum)@object.GetValue<ushort>(properties, "provisioningtype");
|
|
||||||
disk.PhysicalDiskRedundancy = @object.GetValue<ushort>(properties, "physicaldiskredundancy");
|
|
||||||
disk.ResiliencySettingName = @object.GetValue<string>(properties, "resiliencysettingname")?.Trim();
|
|
||||||
disk.Deduplication = @object.GetValue<bool>(properties, "isdeduplicationenabled");
|
|
||||||
disk.IsSnapshot = @object.GetValue<bool>(properties, "issnapshot");
|
|
||||||
|
|
||||||
if (@object.TryGetValue<ushort[]>(properties, "operationalstatus", out var operationals) && operationals is not null)
|
|
||||||
{
|
|
||||||
disk.States = operationals.Select(p => (VirtualDisk.OperationalState)p).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
disk.Health = (VirtualDisk.HealthState)@object.GetValue<ushort>(properties, "healthstatus");
|
|
||||||
disk.Size = @object.GetValue<ulong>(properties, "size");
|
|
||||||
disk.AllocatedSize = @object.GetValue<ulong>(properties, "allocatedsize");
|
|
||||||
disk.FootprintOnPool = @object.GetValue<ulong>(properties, "footprintonpool");
|
|
||||||
disk.ReadCacheSize = @object.GetValue<ulong>(properties, "readcachesize");
|
|
||||||
disk.WriteCacheSize = @object.GetValue<ulong>(properties, "writecachesize");
|
|
||||||
|
|
||||||
disks.Add(disk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return disks;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<PhysicalDisk> QueryPhysicalDisksByStoragePool(string storagePoolObjectId)
|
private static List<PhysicalDisk> QueryPhysicalDisksByStoragePool(string storagePoolObjectId)
|
||||||
{
|
{
|
||||||
using var searcher = new ManagementObjectSearcher
|
using var searcher = new ManagementObjectSearcher
|
||||||
|
|
@ -218,7 +103,7 @@ public class StoragePoolHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
using (collection)
|
using (collection)
|
||||||
{
|
{
|
||||||
foreach (ManagementObject @object in collection)
|
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||||
{
|
{
|
||||||
var disk = new PhysicalDisk();
|
var disk = new PhysicalDisk();
|
||||||
|
|
||||||
|
|
@ -275,7 +160,7 @@ public class StoragePoolHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
using (collection)
|
using (collection)
|
||||||
{
|
{
|
||||||
foreach (ManagementObject @object in collection)
|
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||||
{
|
{
|
||||||
var disk = new VirtualDisk();
|
var disk = new VirtualDisk();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,6 @@ public class SystemInfoHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
private static string GetWindowsProductKeyFromDigitalProductId(byte[] digitalProductId, DigitalProductIdVersion digitalProductIdVersion)
|
private static string GetWindowsProductKeyFromDigitalProductId(byte[] digitalProductId, DigitalProductIdVersion digitalProductIdVersion)
|
||||||
{
|
{
|
||||||
|
|
||||||
var productKey = digitalProductIdVersion == DigitalProductIdVersion.Windows8AndUp
|
var productKey = digitalProductIdVersion == DigitalProductIdVersion.Windows8AndUp
|
||||||
? DecodeProductKeyWin8AndUp(digitalProductId)
|
? DecodeProductKeyWin8AndUp(digitalProductId)
|
||||||
: DecodeProductKey(digitalProductId);
|
: DecodeProductKey(digitalProductId);
|
||||||
|
|
@ -124,7 +123,7 @@ public class SystemInfoHandler : IMessageHandler<AgentSession>
|
||||||
var digitMapIndex = 0;
|
var digitMapIndex = 0;
|
||||||
for (var j = decodeStringLength - 1; j >= 0; j--)
|
for (var j = decodeStringLength - 1; j >= 0; j--)
|
||||||
{
|
{
|
||||||
var byteValue = digitMapIndex << 8 | (byte)hexPid[j];
|
var byteValue = digitMapIndex << 8 | (byte)hexPid[j]!;
|
||||||
hexPid[j] = (byte)(byteValue / 24);
|
hexPid[j] = (byte)(byteValue / 24);
|
||||||
digitMapIndex = byteValue % 24;
|
digitMapIndex = byteValue % 24;
|
||||||
decodedChars[i] = digits[digitMapIndex];
|
decodedChars[i] = digits[digitMapIndex];
|
||||||
|
|
@ -148,17 +147,17 @@ public class SystemInfoHandler : IMessageHandler<AgentSession>
|
||||||
var current = 0;
|
var current = 0;
|
||||||
for (var j = 14; j >= 0; j--)
|
for (var j = 14; j >= 0; j--)
|
||||||
{
|
{
|
||||||
current = current * 256;
|
current *= 256;
|
||||||
current = digitalProductId[j + keyOffset] + current;
|
current = digitalProductId[j + keyOffset] + current;
|
||||||
digitalProductId[j + keyOffset] = (byte)(current / 24);
|
digitalProductId[j + keyOffset] = (byte)(current / 24);
|
||||||
current = current % 24;
|
current %= 24;
|
||||||
last = current;
|
last = current;
|
||||||
}
|
}
|
||||||
key = digits[current] + key;
|
key = digits[current] + key;
|
||||||
}
|
}
|
||||||
|
|
||||||
var keypart1 = key.Substring(1, last);
|
var keypart1 = key.Substring(1, last);
|
||||||
var keypart2 = key.Substring(last + 1, key.Length - (last + 1));
|
var keypart2 = key[(last + 1)..];
|
||||||
key = keypart1 + "N" + keypart2;
|
key = keypart1 + "N" + keypart2;
|
||||||
|
|
||||||
for (var i = 5; i < key.Length; i += 6)
|
for (var i = 5; i < key.Length; i += 6)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ using UpdateCollection = Insight.Domain.Network.Agent.Messages.UpdateCollection;
|
||||||
namespace Insight.Agent.Network.Handlers;
|
namespace Insight.Agent.Network.Handlers;
|
||||||
|
|
||||||
[SupportedOSPlatform("windows")]
|
[SupportedOSPlatform("windows")]
|
||||||
public class UpdateHandler : IMessageHandler<AgentSession>
|
public partial class UpdateHandler : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -60,7 +60,7 @@ public class UpdateHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var rx = new Regex(@"KB(\d+)");
|
var rx = KnowledgeBaseRegex();
|
||||||
update.Hotfix = rx.Match(wupdate.Title).Value;
|
update.Hotfix = rx.Match(wupdate.Title).Value;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|
@ -125,4 +125,7 @@ public class UpdateHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
return updates;
|
return updates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex(@"KB(\d+)")]
|
||||||
|
private static partial Regex KnowledgeBaseRegex();
|
||||||
}
|
}
|
||||||
|
|
@ -32,7 +32,7 @@ public class UserHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
foreach (var u in users)
|
foreach (var u in users)
|
||||||
{
|
{
|
||||||
u.Groups = new List<Group>();
|
u.Groups = [];
|
||||||
|
|
||||||
foreach (var ug in usergrouping.Where(ug => ug.UserDomain == u.Domain && ug.UserName == u.Name))
|
foreach (var ug in usergrouping.Where(ug => ug.UserDomain == u.Domain && ug.UserName == u.Name))
|
||||||
{
|
{
|
||||||
|
|
@ -67,7 +67,7 @@ public class UserHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
using (collection)
|
using (collection)
|
||||||
{
|
{
|
||||||
foreach (ManagementObject @object in collection)
|
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||||
{
|
{
|
||||||
var group = new Group();
|
var group = new Group();
|
||||||
|
|
||||||
|
|
@ -83,7 +83,7 @@ public class UserHandler : IMessageHandler<AgentSession>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return groups.OrderBy(x => x.Name)?.ToList();
|
return [.. groups.OrderBy(x => x.Name)];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<User> QueryUsers()
|
private static List<User> QueryUsers()
|
||||||
|
|
@ -105,7 +105,7 @@ public class UserHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
using (collection)
|
using (collection)
|
||||||
{
|
{
|
||||||
foreach (ManagementObject @object in collection)
|
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||||
{
|
{
|
||||||
var user = new User();
|
var user = new User();
|
||||||
|
|
||||||
|
|
@ -150,7 +150,7 @@ public class UserHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
using (collection)
|
using (collection)
|
||||||
{
|
{
|
||||||
foreach (ManagementObject @object in collection)
|
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
|
||||||
{
|
{
|
||||||
var usergroup = new UserGroupMap();
|
var usergroup = new UserGroupMap();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -341,7 +341,7 @@ public class VirtualMaschineHandler : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
conf.ParentId = parentGuid.ToString();
|
conf.ParentId = parentGuid.ToString();
|
||||||
|
|
||||||
parentConfig.Childs ??= new List<VirtualMaschineConfiguration>();
|
parentConfig.Childs ??= [];
|
||||||
parentConfig.Childs.Add(conf);
|
parentConfig.Childs.Add(conf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System.Runtime.Versioning;
|
||||||
using Vaitr.Network;
|
using Vaitr.Network;
|
||||||
using Vaitr.Network.Hosting;
|
using Vaitr.Network.Hosting;
|
||||||
|
|
||||||
|
|
@ -66,29 +67,13 @@ internal class Program
|
||||||
options.UseSerializer<AgentSession, IMessage, MemPackSerializer<IMessage>>();
|
options.UseSerializer<AgentSession, IMessage, MemPackSerializer<IMessage>>();
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, CustomHandler>();
|
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, ProxyHandler>();
|
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, AuthenticationHandler>();
|
services.AddSingleton<IMessageHandler<AgentSession>, AuthenticationHandler>();
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, DriveHandler>();
|
services.AddSingleton<IMessageHandler<AgentSession>, ProxyHandler>();
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, InterfaceHandler>();
|
services.AddSingleton<IMessageHandler<AgentSession>, CustomHandler>();
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, MainboardHandler>();
|
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, MemoryHandler>();
|
if (OperatingSystem.IsWindows()) ServiceCollectionExtensions.InjectWindowsHandler(services);
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, OperationSystemHandler>();
|
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, PrinterHandler>();
|
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, ProcessorHandler>();
|
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, ServiceHandler>();
|
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, SessionHandler>();
|
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, SoftwareHandler>();
|
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, StoragePoolHandler>();
|
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, SystemInfoHandler>();
|
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, UpdateHandler>();
|
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, UserHandler>();
|
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, VideocardHandler>();
|
|
||||||
services.AddSingleton<IMessageHandler<AgentSession>, VirtualMaschineHandler>();
|
|
||||||
|
|
||||||
|
|
||||||
// GLOBAL DEPENDENCIES
|
// GLOBAL DEPENDENCIES
|
||||||
//services.AddSingleton<Bus>();
|
|
||||||
services.AddTransient(provider => new HttpClient(new HttpClientHandler
|
services.AddTransient(provider => new HttpClient(new HttpClientHandler
|
||||||
{
|
{
|
||||||
ClientCertificateOptions = ClientCertificateOption.Manual,
|
ClientCertificateOptions = ClientCertificateOption.Manual,
|
||||||
|
|
@ -99,4 +84,30 @@ internal class Program
|
||||||
var host = builder.Build();
|
var host = builder.Build();
|
||||||
await host.RunAsync().ConfigureAwait(false);
|
await host.RunAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class ServiceCollectionExtensions
|
||||||
|
{
|
||||||
|
[SupportedOSPlatform("windows")]
|
||||||
|
internal static IServiceCollection InjectWindowsHandler(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddSingleton<IMessageHandler<AgentSession>, DriveHandler>();
|
||||||
|
services.AddSingleton<IMessageHandler<AgentSession>, InterfaceHandler>();
|
||||||
|
services.AddSingleton<IMessageHandler<AgentSession>, MainboardHandler>();
|
||||||
|
services.AddSingleton<IMessageHandler<AgentSession>, MemoryHandler>();
|
||||||
|
services.AddSingleton<IMessageHandler<AgentSession>, OperationSystemHandler>();
|
||||||
|
services.AddSingleton<IMessageHandler<AgentSession>, PrinterHandler>();
|
||||||
|
services.AddSingleton<IMessageHandler<AgentSession>, ProcessorHandler>();
|
||||||
|
services.AddSingleton<IMessageHandler<AgentSession>, ServiceHandler>();
|
||||||
|
services.AddSingleton<IMessageHandler<AgentSession>, SessionHandler>();
|
||||||
|
services.AddSingleton<IMessageHandler<AgentSession>, SoftwareHandler>();
|
||||||
|
services.AddSingleton<IMessageHandler<AgentSession>, StoragePoolHandler>();
|
||||||
|
services.AddSingleton<IMessageHandler<AgentSession>, SystemInfoHandler>();
|
||||||
|
services.AddSingleton<IMessageHandler<AgentSession>, UpdateHandler>();
|
||||||
|
services.AddSingleton<IMessageHandler<AgentSession>, UserHandler>();
|
||||||
|
services.AddSingleton<IMessageHandler<AgentSession>, VideocardHandler>();
|
||||||
|
services.AddSingleton<IMessageHandler<AgentSession>, VirtualMaschineHandler>();
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5,12 +5,7 @@ using System.Runtime.Versioning;
|
||||||
namespace Insight.Agent.Services;
|
namespace Insight.Agent.Services;
|
||||||
|
|
||||||
[SupportedOSPlatform("linux")]
|
[SupportedOSPlatform("linux")]
|
||||||
public partial class CollectorService
|
public partial class CollectorService(ILogger<CollectorService>? logger = null)
|
||||||
{
|
{
|
||||||
public ILogger<CollectorService> Logger { get; }
|
public ILogger<CollectorService> Logger { get; } = logger ?? NullLogger<CollectorService>.Instance;
|
||||||
|
|
||||||
public CollectorService(ILogger<CollectorService>? logger = null)
|
|
||||||
{
|
|
||||||
Logger = logger ?? NullLogger<CollectorService>.Instance;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -4,12 +4,14 @@ namespace Insight.Agent.Services;
|
||||||
|
|
||||||
public static class Configurator
|
public static class Configurator
|
||||||
{
|
{
|
||||||
|
private static readonly JsonSerializerOptions _serializerOptions = new() { PropertyNameCaseInsensitive = true, WriteIndented = true };
|
||||||
|
|
||||||
public static async ValueTask<TConfig> ReadAsync<TConfig>(string file, CancellationToken cancellationToken = default)
|
public static async ValueTask<TConfig> ReadAsync<TConfig>(string file, CancellationToken cancellationToken = default)
|
||||||
where TConfig : class
|
where TConfig : class
|
||||||
{
|
{
|
||||||
var json = await File.ReadAllTextAsync(file, cancellationToken);
|
var json = await File.ReadAllTextAsync(file, cancellationToken);
|
||||||
|
|
||||||
if (JsonSerializer.Deserialize<TConfig>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true, WriteIndented = true }) is not TConfig config)
|
if (JsonSerializer.Deserialize<TConfig>(json, _serializerOptions) is not TConfig config)
|
||||||
{
|
{
|
||||||
throw new InvalidDataException($"Failed to deserialize ({file})");
|
throw new InvalidDataException($"Failed to deserialize ({file})");
|
||||||
}
|
}
|
||||||
|
|
@ -31,7 +33,7 @@ public static class Configurator
|
||||||
{
|
{
|
||||||
var json = await File.ReadAllTextAsync(file, cancellationToken);
|
var json = await File.ReadAllTextAsync(file, cancellationToken);
|
||||||
|
|
||||||
if (JsonSerializer.Deserialize<IDictionary<string, object>>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true, WriteIndented = true }) is not IDictionary<string, object> config)
|
if (JsonSerializer.Deserialize<IDictionary<string, object>>(json, _serializerOptions) is not IDictionary<string, object> config)
|
||||||
{
|
{
|
||||||
throw new InvalidDataException($"Failed to deserialize ({file})");
|
throw new InvalidDataException($"Failed to deserialize ({file})");
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +91,7 @@ public static class Configurator
|
||||||
|
|
||||||
private static async ValueTask WriteToFileAsync<TData>(TData data, string file, CancellationToken cancellationToken)
|
private static async ValueTask WriteToFileAsync<TData>(TData data, string file, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var json = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true });
|
var json = JsonSerializer.Serialize(data, _serializerOptions);
|
||||||
|
|
||||||
await File.WriteAllTextAsync(file, json, cancellationToken);
|
await File.WriteAllTextAsync(file, json, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ internal class EventService : BackgroundService
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_queue.Writer.WriteAsync(@event, default);
|
_ = _queue.Writer.WriteAsync(@event, default);
|
||||||
}
|
}
|
||||||
catch (Exception) { } // app crash
|
catch (Exception) { } // app crash
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,17 +4,14 @@ using System.Management.Automation.Runspaces;
|
||||||
|
|
||||||
namespace Insight.Agent.Services;
|
namespace Insight.Agent.Services;
|
||||||
|
|
||||||
public class ScriptService
|
public class ScriptService(ILogger<ScriptService> logger)
|
||||||
{
|
{
|
||||||
private readonly ILogger<ScriptService> _logger;
|
private readonly ILogger<ScriptService> _logger = logger;
|
||||||
|
|
||||||
public ScriptService(ILogger<ScriptService> logger)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<QueryResult> QueryAsync(string query)
|
public async Task<QueryResult> QueryAsync(string query)
|
||||||
{
|
{
|
||||||
|
_logger.LogDebug("QueryAsync ({query})", query);
|
||||||
|
|
||||||
var result = new QueryResult();
|
var result = new QueryResult();
|
||||||
var errors = new List<string>();
|
var errors = new List<string>();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,19 +12,12 @@ using System.Text.Json;
|
||||||
|
|
||||||
namespace Insight.Agent.Services;
|
namespace Insight.Agent.Services;
|
||||||
|
|
||||||
internal class UpdateService : BackgroundService
|
internal class UpdateService(HttpClient httpClient, IConfiguration configuration, ILogger<UpdateService> logger) : BackgroundService
|
||||||
{
|
{
|
||||||
private readonly Uri _uri;
|
private readonly Uri _uri = configuration.GetValue<Uri?>("api") ?? throw new Exception($"api value not set (appsettings)");
|
||||||
|
|
||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient = httpClient;
|
||||||
private readonly ILogger<UpdateService> _logger;
|
private readonly ILogger<UpdateService> _logger = logger;
|
||||||
|
|
||||||
public UpdateService(HttpClient httpClient, IConfiguration configuration, ILogger<UpdateService> logger)
|
|
||||||
{
|
|
||||||
_httpClient = httpClient;
|
|
||||||
_uri = configuration.GetValue<Uri?>("api") ?? throw new Exception($"api value not set (appsettings)");
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
|
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|
@ -42,7 +35,7 @@ internal class UpdateService : BackgroundService
|
||||||
_logger.LogInformation("Update Result: {result}", result?.Success);
|
_logger.LogInformation("Update Result: {result}", result?.Success);
|
||||||
if (result?.UpdateErrors is not null)
|
if (result?.UpdateErrors is not null)
|
||||||
{
|
{
|
||||||
_logger.LogError("Update Errors: {errors}", string.Concat(result?.UpdateErrors));
|
_logger.LogError("Update Errors: {errors}", string.Concat(result.UpdateErrors));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException) { }
|
catch (OperationCanceledException) { }
|
||||||
|
|
@ -198,7 +191,7 @@ internal class UpdateService : BackgroundService
|
||||||
await File.WriteAllBytesAsync(updateFile.FullName, await update.Content.ReadAsByteArrayAsync(cancellationToken), cancellationToken);
|
await File.WriteAllBytesAsync(updateFile.FullName, await update.Content.ReadAsByteArrayAsync(cancellationToken), cancellationToken);
|
||||||
|
|
||||||
// extract update archive from temp to app dir (overwrite)
|
// extract update archive from temp to app dir (overwrite)
|
||||||
ZipFile.ExtractToDirectory(updateFile.FullName, bin.Directory?.FullName, true);
|
ZipFile.ExtractToDirectory(updateFile.FullName, bin.Directory!.FullName, true);
|
||||||
|
|
||||||
// delete temp folder
|
// delete temp folder
|
||||||
if (temp.Exists) temp.Delete(true);
|
if (temp.Exists) temp.Delete(true);
|
||||||
|
|
@ -229,7 +222,7 @@ internal class UpdateService : BackgroundService
|
||||||
|
|
||||||
var matched = System.Diagnostics.Process.GetProcessesByName(bin.FullName);
|
var matched = System.Diagnostics.Process.GetProcessesByName(bin.FullName);
|
||||||
|
|
||||||
if (matched is null || matched.Any() is false) return false;
|
if (matched is null || matched.Length == 0) return false;
|
||||||
|
|
||||||
if (matched.Any(p =>
|
if (matched.Any(p =>
|
||||||
p.MainModule is not null &&
|
p.MainModule is not null &&
|
||||||
|
|
@ -262,7 +255,7 @@ internal class UpdateService : BackgroundService
|
||||||
|
|
||||||
var matched = System.Diagnostics.Process.GetProcessesByName(bin.FullName);
|
var matched = System.Diagnostics.Process.GetProcessesByName(bin.FullName);
|
||||||
|
|
||||||
if (matched is null || matched.Any() is false) return true;
|
if (matched is null || matched.Length == 0) return true;
|
||||||
|
|
||||||
foreach (var procsInfo in matched.Where(p =>
|
foreach (var procsInfo in matched.Where(p =>
|
||||||
p.MainModule is not null &&
|
p.MainModule is not null &&
|
||||||
|
|
@ -312,7 +305,7 @@ internal class UpdateService : BackgroundService
|
||||||
await File.WriteAllBytesAsync(updateFile.FullName, await update.Content.ReadAsByteArrayAsync(cancellationToken), cancellationToken);
|
await File.WriteAllBytesAsync(updateFile.FullName, await update.Content.ReadAsByteArrayAsync(cancellationToken), cancellationToken);
|
||||||
|
|
||||||
// extract update archive from temp to app dir (overwrite)
|
// extract update archive from temp to app dir (overwrite)
|
||||||
ZipFile.ExtractToDirectory(updateFile.FullName, bin.Directory?.FullName, true);
|
ZipFile.ExtractToDirectory(updateFile.FullName, bin.Directory!.FullName, true);
|
||||||
|
|
||||||
// delete temp folder
|
// delete temp folder
|
||||||
if (temp.Exists) temp.Delete(true);
|
if (temp.Exists) temp.Delete(true);
|
||||||
|
|
@ -353,7 +346,7 @@ internal class UpdateService : BackgroundService
|
||||||
public bool ApiAvailable { get; set; } = false;
|
public bool ApiAvailable { get; set; } = false;
|
||||||
public bool UpdateAvailable { get; set; } = false;
|
public bool UpdateAvailable { get; set; } = false;
|
||||||
public bool Success { get; set; } = false;
|
public bool Success { get; set; } = false;
|
||||||
public List<string> ApiErrors { get; } = new();
|
public List<string> ApiErrors { get; } = [];
|
||||||
public List<string> UpdateErrors { get; } = new();
|
public List<string> UpdateErrors { get; } = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -21,10 +21,9 @@ public partial class CollectorService
|
||||||
output = stream.ReadToEnd();
|
output = stream.ReadToEnd();
|
||||||
|
|
||||||
// clean output
|
// clean output
|
||||||
var clean = Regex
|
var clean = CleanRegex().Replace(output
|
||||||
.Replace(output
|
|
||||||
.Trim()
|
.Trim()
|
||||||
.Replace("\t", " "), @"[ ]{2,}", " ");
|
.Replace("\t", " "), " ");
|
||||||
|
|
||||||
var elements = clean.Split(Array.Empty<char>(), StringSplitOptions.RemoveEmptyEntries);
|
var elements = clean.Split(Array.Empty<char>(), StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
|
@ -36,13 +35,12 @@ public partial class CollectorService
|
||||||
|
|
||||||
// linebreak list conversion
|
// linebreak list conversion
|
||||||
var lines = new List<string>(output
|
var lines = new List<string>(output
|
||||||
.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
|
.Split(separator, StringSplitOptions.RemoveEmptyEntries))
|
||||||
.Select(l =>
|
.Select(l =>
|
||||||
{
|
{
|
||||||
return Regex
|
return CleanRegex().Replace(l
|
||||||
.Replace(l
|
|
||||||
.Trim()
|
.Trim()
|
||||||
.Replace("\t", " "), @"[ ]{2,}", " ");
|
.Replace("\t", " "), " ");
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
|
@ -62,13 +60,12 @@ public partial class CollectorService
|
||||||
|
|
||||||
// linebreak list conversion
|
// linebreak list conversion
|
||||||
lines = new List<string>(output
|
lines = new List<string>(output
|
||||||
.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
|
.Split(separator, StringSplitOptions.RemoveEmptyEntries))
|
||||||
.Select(l =>
|
.Select(l =>
|
||||||
{
|
{
|
||||||
return Regex
|
return CleanRegex().Replace(l
|
||||||
.Replace(l
|
|
||||||
.Trim()
|
.Trim()
|
||||||
.Replace("\t", " "), @"[ ]{2,}", " ");
|
.Replace("\t", " "), " ");
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
|
@ -102,4 +99,9 @@ public partial class CollectorService
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readonly string[] separator = ["\n", "\r\n"];
|
||||||
|
|
||||||
|
[GeneratedRegex(@"[ ]{2,}")]
|
||||||
|
private static partial Regex CleanRegex();
|
||||||
}
|
}
|
||||||
|
|
@ -17,11 +17,11 @@ public partial class CollectorService
|
||||||
var output = "w".Bash();
|
var output = "w".Bash();
|
||||||
|
|
||||||
// linebreak list conversion
|
// linebreak list conversion
|
||||||
var lines = output.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
var lines = output.Split(separatorArray, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||||
|
|
||||||
lines = lines.Select(l =>
|
lines = lines.Select(l =>
|
||||||
{
|
{
|
||||||
return Regex.Replace(l.Trim().Replace("\t", " "), @"[ ]{2,}", " ");
|
return CleanOutputRegex().Replace(l.Trim().Replace("\t", " "), " ");
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
// cleaning
|
// cleaning
|
||||||
|
|
@ -46,4 +46,9 @@ public partial class CollectorService
|
||||||
|
|
||||||
return sessions;
|
return sessions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readonly string[] separatorArray = ["\n", "\r\n"];
|
||||||
|
|
||||||
|
[GeneratedRegex(@"[ ]{2,}")]
|
||||||
|
private static partial Regex CleanOutputRegex();
|
||||||
}
|
}
|
||||||
|
|
@ -1,31 +1,29 @@
|
||||||
using Insight.Api.Models;
|
using Insight.Api.Models;
|
||||||
|
using Insight.Infrastructure.Entities;
|
||||||
using Insight.Infrastructure.Models;
|
using Insight.Infrastructure.Models;
|
||||||
using Insight.Infrastructure.Services;
|
using Insight.Infrastructure.Services;
|
||||||
|
using Insight.Infrastructure.Web;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Api.Controllers;
|
namespace Insight.Api.Controllers;
|
||||||
|
|
||||||
[ApiController, Route("api/accounts")]
|
[ApiController, Route("api/accounts")]
|
||||||
public class AccountController : ControllerBase
|
public class AccountController(IdentityService identityService, IServiceScopeFactory scopeFactory) : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly IdentityService _identityService;
|
private readonly IdentityService _identityService = identityService;
|
||||||
private readonly AccountService _accountService;
|
private readonly IServiceScopeFactory _scopeFactory = scopeFactory;
|
||||||
private readonly ILogger<AccountController> _logger;
|
|
||||||
|
|
||||||
public AccountController(IdentityService identityService, AccountService accountService, ILogger<AccountController> logger)
|
|
||||||
{
|
|
||||||
_identityService = identityService;
|
|
||||||
_accountService = accountService;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet, Authorize]
|
[HttpGet, Authorize]
|
||||||
public async Task<IActionResult> Get([FromQuery] PagedDataRequest request, CancellationToken cancellationToken)
|
public async Task<IActionResult> Get([FromQuery] PagedDataRequest request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
using var scope = _scopeFactory.CreateScope();
|
||||||
|
var collection = scope.ServiceProvider.GetRequiredService<IMongoDatabase>().User();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = await _accountService.GetAsync(
|
var result = await collection.GetPagedAsync(
|
||||||
offset: request.Offset,
|
offset: request.Offset,
|
||||||
limit: request.Limit,
|
limit: request.Limit,
|
||||||
request: Request,
|
request: Request,
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,26 @@
|
||||||
using Insight.Infrastructure.Models;
|
using Insight.Infrastructure.Entities;
|
||||||
using Insight.Infrastructure.Services;
|
using Insight.Infrastructure.Models;
|
||||||
|
using Insight.Infrastructure.Web;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Api.Controllers;
|
namespace Insight.Api.Controllers;
|
||||||
|
|
||||||
[ApiController, Route("api/agents")]
|
[ApiController, Route("api/agents")]
|
||||||
public class AgentController : ControllerBase
|
public class AgentController(IServiceScopeFactory scopeFactory) : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly AgentService _agentService;
|
private readonly IServiceScopeFactory _scopeFactory = scopeFactory;
|
||||||
private readonly ILogger<AgentController> _logger;
|
|
||||||
|
|
||||||
public AgentController(AgentService agentService, ILogger<AgentController> logger)
|
|
||||||
{
|
|
||||||
_agentService = agentService;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet, Authorize]
|
[HttpGet, Authorize]
|
||||||
public async Task<IActionResult> Get([FromQuery] PagedDataRequest request, CancellationToken cancellationToken)
|
public async Task<IActionResult> Get([FromQuery] PagedDataRequest request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
using var scope = _scopeFactory.CreateScope();
|
||||||
|
var collection = scope.ServiceProvider.GetRequiredService<IMongoDatabase>().Agent();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = await _agentService.GetAsync(
|
var result = await collection.GetPagedAsync(
|
||||||
offset: request.Offset,
|
offset: request.Offset,
|
||||||
limit: request.Limit,
|
limit: request.Limit,
|
||||||
request: Request,
|
request: Request,
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,26 @@
|
||||||
using Insight.Infrastructure.Models;
|
using Insight.Infrastructure.Entities;
|
||||||
using Insight.Infrastructure.Services;
|
using Insight.Infrastructure.Models;
|
||||||
|
using Insight.Infrastructure.Web;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Api.Controllers;
|
namespace Insight.Api.Controllers;
|
||||||
|
|
||||||
[ApiController, Route("api/customers")]
|
[ApiController, Route("api/customers")]
|
||||||
public class CustomerController : ControllerBase
|
public class CustomerController(IServiceScopeFactory scopeFactory) : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly CustomerService _customerService;
|
private readonly IServiceScopeFactory _scopeFactory = scopeFactory;
|
||||||
private readonly ILogger<CustomerController> _logger;
|
|
||||||
|
|
||||||
public CustomerController(CustomerService customerService, ILogger<CustomerController> logger)
|
|
||||||
{
|
|
||||||
_customerService = customerService;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet, Authorize]
|
[HttpGet, Authorize]
|
||||||
public async Task<IActionResult> Get([FromQuery] PagedDataRequest request, CancellationToken cancellationToken)
|
public async Task<IActionResult> Get([FromQuery] PagedDataRequest request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
using var scope = _scopeFactory.CreateScope();
|
||||||
|
var collection = scope.ServiceProvider.GetRequiredService<IMongoDatabase>().Customer();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = await _customerService.GetAsync(
|
var result = await collection.GetPagedAsync(
|
||||||
offset: request.Offset,
|
offset: request.Offset,
|
||||||
limit: request.Limit,
|
limit: request.Limit,
|
||||||
request: Request,
|
request: Request,
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,26 @@
|
||||||
using Insight.Infrastructure.Models;
|
using Insight.Infrastructure.Entities;
|
||||||
using Insight.Infrastructure.Services;
|
using Insight.Infrastructure.Models;
|
||||||
|
using Insight.Infrastructure.Web;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Api.Controllers;
|
namespace Insight.Api.Controllers;
|
||||||
|
|
||||||
[ApiController, Route("api/hosts")]
|
[ApiController, Route("api/hosts")]
|
||||||
public class HostController : ControllerBase
|
public class HostController(IServiceScopeFactory scopeFactory) : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly HostService _hostService;
|
private readonly IServiceScopeFactory _scopeFactory = scopeFactory;
|
||||||
private readonly ILogger<HostController> _logger;
|
|
||||||
|
|
||||||
public HostController(HostService hostService, ILogger<HostController> logger)
|
|
||||||
{
|
|
||||||
_hostService = hostService;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet, Authorize]
|
[HttpGet, Authorize]
|
||||||
public async Task<IActionResult> Get([FromQuery] PagedDataRequest request, CancellationToken cancellationToken)
|
public async Task<IActionResult> Get([FromQuery] PagedDataRequest request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
using var scope = _scopeFactory.CreateScope();
|
||||||
|
var collection = scope.ServiceProvider.GetRequiredService<IMongoDatabase>().Host();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = await _hostService.GetAsync(
|
var result = await collection.GetPagedAsync(
|
||||||
offset: request.Offset,
|
offset: request.Offset,
|
||||||
limit: request.Limit,
|
limit: request.Limit,
|
||||||
request: Request,
|
request: Request,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using Insight.Infrastructure.Entities;
|
using Insight.Infrastructure.Entities;
|
||||||
using Insight.Infrastructure.Models;
|
using Insight.Infrastructure.Models;
|
||||||
using Insight.Infrastructure.Services;
|
using Insight.Infrastructure.Web;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using MongoDB.Bson;
|
using MongoDB.Bson;
|
||||||
|
|
@ -11,20 +11,16 @@ using System.Text.RegularExpressions;
|
||||||
namespace Insight.Api.Controllers;
|
namespace Insight.Api.Controllers;
|
||||||
|
|
||||||
[ApiController, Route("api/inventory")]
|
[ApiController, Route("api/inventory")]
|
||||||
public class InventoryController : ControllerBase
|
public class InventoryController(IServiceScopeFactory scopeFactory) : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly InventoryService _inventoryService;
|
private readonly IServiceScopeFactory _scopeFactory = scopeFactory;
|
||||||
private readonly ILogger<InventoryController> _logger;
|
|
||||||
|
|
||||||
public InventoryController(InventoryService inventoryService, ILogger<InventoryController> logger)
|
|
||||||
{
|
|
||||||
_inventoryService = inventoryService;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet, Authorize]
|
[HttpGet, Authorize]
|
||||||
public async Task<IActionResult> Get([FromQuery] HostApplicationEntity request, [FromQuery] PagedDataRequest meta, CancellationToken cancellationToken)
|
public async Task<IActionResult> Get([FromQuery] HostApplicationEntity request, [FromQuery] PagedDataRequest meta, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
using var scope = _scopeFactory.CreateScope();
|
||||||
|
var collection = scope.ServiceProvider.GetRequiredService<IMongoDatabase>().HostApplication();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var filter = Builders<HostApplicationEntity>.Filter.Empty;
|
var filter = Builders<HostApplicationEntity>.Filter.Empty;
|
||||||
|
|
@ -38,7 +34,7 @@ public class InventoryController : ControllerBase
|
||||||
if (request.Name is not null)
|
if (request.Name is not null)
|
||||||
filter &= Builders<HostApplicationEntity>.Filter.Regex(p => p.Name, new BsonRegularExpression(new Regex(request.Name, RegexOptions.IgnoreCase)));
|
filter &= Builders<HostApplicationEntity>.Filter.Regex(p => p.Name, new BsonRegularExpression(new Regex(request.Name, RegexOptions.IgnoreCase)));
|
||||||
|
|
||||||
var result = await _inventoryService.GetAsync(
|
var result = await collection.GetPagedAsync(
|
||||||
filter: filter,
|
filter: filter,
|
||||||
offset: meta.Offset,
|
offset: meta.Offset,
|
||||||
limit: meta.Limit,
|
limit: meta.Limit,
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,9 @@
|
||||||
namespace Insight.Server.Controllers;
|
namespace Insight.Server.Controllers;
|
||||||
|
|
||||||
[ApiController, Route("api/setup")]
|
[ApiController, Route("api/setup")]
|
||||||
public class SetupController : ControllerBase
|
public class SetupController(ILogger<SetupController> logger) : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly ILogger<SetupController> _logger;
|
private readonly ILogger<SetupController> _logger = logger;
|
||||||
|
|
||||||
public SetupController(ILogger<SetupController> logger)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("windows")]
|
[HttpGet("windows")]
|
||||||
public async Task<IActionResult> GetAsync(CancellationToken cancellationToken)
|
public async Task<IActionResult> GetAsync(CancellationToken cancellationToken)
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,9 @@ using Microsoft.AspNetCore.Mvc;
|
||||||
namespace Insight.Api.Controllers;
|
namespace Insight.Api.Controllers;
|
||||||
|
|
||||||
[ApiController, Route("api/token", Order = 0)]
|
[ApiController, Route("api/token", Order = 0)]
|
||||||
public class TokenController : ControllerBase
|
public class TokenController(TokenService tokenService) : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly TokenService _tokenService;
|
private readonly TokenService _tokenService = tokenService;
|
||||||
|
|
||||||
public TokenController(TokenService tokenService)
|
|
||||||
{
|
|
||||||
_tokenService = tokenService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Access Token Request
|
/// Access Token Request
|
||||||
|
|
@ -21,6 +16,9 @@ public class TokenController : ControllerBase
|
||||||
[HttpPost, AllowAnonymous]
|
[HttpPost, AllowAnonymous]
|
||||||
public async Task<IActionResult> Authentication([FromBody] TokenRequest request)
|
public async Task<IActionResult> Authentication([FromBody] TokenRequest request)
|
||||||
{
|
{
|
||||||
|
if (request.Username is null) return BadRequest("username is null");
|
||||||
|
if (request.Password is null) return BadRequest("password is null");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = await _tokenService.GetAsync(request.Username, request.Password, request.Code, HttpContext.Connection.RemoteIpAddress).ConfigureAwait(false);
|
var result = await _tokenService.GetAsync(request.Username, request.Password, request.Code, HttpContext.Connection.RemoteIpAddress).ConfigureAwait(false);
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,9 @@ using Microsoft.AspNetCore.Mvc;
|
||||||
namespace Insight.Server.Controllers;
|
namespace Insight.Server.Controllers;
|
||||||
|
|
||||||
[ApiController, Route("api/update")]
|
[ApiController, Route("api/update")]
|
||||||
public class UpdateController : ControllerBase
|
public class UpdateController(ILogger<UpdateController> logger) : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly ILogger<UpdateController> _logger;
|
private readonly ILogger<UpdateController> _logger = logger;
|
||||||
|
|
||||||
public UpdateController(ILogger<UpdateController> logger)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("updater/windows")]
|
[HttpGet("updater/windows")]
|
||||||
public IActionResult UpdaterWindows()
|
public IActionResult UpdaterWindows()
|
||||||
|
|
@ -35,7 +30,7 @@ public class UpdateController : ControllerBase
|
||||||
|
|
||||||
var versions = updateDir.GetFiles("*.zip", SearchOption.TopDirectoryOnly);
|
var versions = updateDir.GetFiles("*.zip", SearchOption.TopDirectoryOnly);
|
||||||
|
|
||||||
if (versions is null || versions.Any() is false) return NotFound();
|
if (versions is null || versions.Length == 0) return NotFound();
|
||||||
|
|
||||||
var latest = versions.OrderBy(x => x.Name).FirstOrDefault();
|
var latest = versions.OrderBy(x => x.Name).FirstOrDefault();
|
||||||
|
|
||||||
|
|
@ -73,7 +68,7 @@ public class UpdateController : ControllerBase
|
||||||
|
|
||||||
var versions = updateDir.GetFiles("*.zip", SearchOption.TopDirectoryOnly);
|
var versions = updateDir.GetFiles("*.zip", SearchOption.TopDirectoryOnly);
|
||||||
|
|
||||||
if (versions is null || versions.Any() is false) return NotFound();
|
if (versions is null || versions.Length == 0) return NotFound();
|
||||||
|
|
||||||
var latest = versions.OrderBy(x => x.Name).FirstOrDefault();
|
var latest = versions.OrderBy(x => x.Name).FirstOrDefault();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ namespace Insight.Api.Hosting;
|
||||||
|
|
||||||
public static class ServiceExtensions
|
public static class ServiceExtensions
|
||||||
{
|
{
|
||||||
internal static IServiceCollection AddSwaggerServices(this IServiceCollection services, IConfiguration configuration)
|
internal static IServiceCollection AddSwaggerServices(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddEndpointsApiExplorer();
|
services.AddEndpointsApiExplorer();
|
||||||
services.AddSwaggerGen(options =>
|
services.AddSwaggerGen(options =>
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,36 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<Product>Insight</Product>
|
<LangVersion>latest</LangVersion>
|
||||||
<AssemblyName>api</AssemblyName>
|
<Product>Insight</Product>
|
||||||
<AssemblyVersion>2023.12.14.0</AssemblyVersion>
|
<AssemblyName>api</AssemblyName>
|
||||||
<RootNamespace>Insight.Api</RootNamespace>
|
<AssemblyVersion>2023.12.15.0</AssemblyVersion>
|
||||||
<Nullable>enable</Nullable>
|
<RootNamespace>Insight.Api</RootNamespace>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<Nullable>enable</Nullable>
|
||||||
<UserSecretsId>4ae1d3bf-869e-4963-8a19-35634507d3b3</UserSecretsId>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<UserSecretsId>4ae1d3bf-869e-4963-8a19-35634507d3b3</UserSecretsId>
|
||||||
<PublishAot>false</PublishAot>
|
<PublishAot>false</PublishAot>
|
||||||
<PublishTrimmed>false</PublishTrimmed>
|
<PublishTrimmed>false</PublishTrimmed>
|
||||||
<!--<ServerGarbageCollection>false</ServerGarbageCollection>
|
<!--<ServerGarbageCollection>false</ServerGarbageCollection>
|
||||||
<ConcurrentGarbageCollection>false</ConcurrentGarbageCollection>-->
|
<ConcurrentGarbageCollection>false</ConcurrentGarbageCollection>-->
|
||||||
|
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||||
<NoWarn>$(NoWarn);1591</NoWarn>
|
<SatelliteResourceLanguages>none</SatelliteResourceLanguages>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
|
||||||
<DebugType>none</DebugType>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
|
||||||
<DebugType>none</DebugType>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="7.0.1" />
|
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.13" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||||
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
|
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
|
||||||
<!--Unix Serilog stuff-->
|
<!--Unix Serilog stuff-->
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\Core\Insight.Infrastructure.Web\Insight.Infrastructure.Web.csproj" />
|
||||||
<ProjectReference Include="..\..\Core\Insight.Infrastructure\Insight.Infrastructure.csproj" />
|
<ProjectReference Include="..\..\Core\Insight.Infrastructure\Insight.Infrastructure.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -40,12 +40,12 @@ internal class Program
|
||||||
builder.Services.AddAuthorization();
|
builder.Services.AddAuthorization();
|
||||||
|
|
||||||
// WEBSERVICES
|
// WEBSERVICES
|
||||||
builder.Services.AddProxyServices(builder.Configuration);
|
builder.Services.AddProxyServices();
|
||||||
builder.Services.AddRoutingServices(builder.Configuration);
|
builder.Services.AddRoutingServices();
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
|
|
||||||
// SWAGGER
|
// SWAGGER
|
||||||
builder.Services.AddSwaggerServices(builder.Configuration);
|
builder.Services.AddSwaggerServices();
|
||||||
|
|
||||||
//builder.Services.AddControllers();
|
//builder.Services.AddControllers();
|
||||||
//builder.Services.AddEndpointsApiExplorer();
|
//builder.Services.AddEndpointsApiExplorer();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Net;
|
using System.Diagnostics;
|
||||||
|
using System.Net;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace Insight.Domain.Constants;
|
namespace Insight.Domain.Constants;
|
||||||
|
|
@ -7,6 +8,14 @@ public static class Configuration
|
||||||
{
|
{
|
||||||
public static string Hostname => Dns.GetHostEntry("localhost").HostName;
|
public static string Hostname => Dns.GetHostEntry("localhost").HostName;
|
||||||
public static Version Version => Assembly.GetEntryAssembly()?.GetName().Version ?? throw new ArgumentNullException("Version");
|
public static Version Version => Assembly.GetEntryAssembly()?.GetName().Version ?? throw new ArgumentNullException("Version");
|
||||||
public static DirectoryInfo? AppDirectory => string.IsNullOrWhiteSpace(Environment.ProcessPath) ? null : new DirectoryInfo(Environment.ProcessPath).Parent;
|
public static DirectoryInfo? AppDirectory => AppDirectoryHelper();
|
||||||
public static string DefaultConfig => Path.Combine(AppDirectory?.FullName ?? string.Empty, "config.json");
|
public static string DefaultConfig => Path.Combine(AppDirectory?.FullName ?? string.Empty, "config.json");
|
||||||
|
|
||||||
|
private static DirectoryInfo? AppDirectoryHelper()
|
||||||
|
{
|
||||||
|
using var proc = Process.GetCurrentProcess();
|
||||||
|
|
||||||
|
if (proc?.MainModule?.FileName is null) throw new InvalidOperationException("MainModule not found");
|
||||||
|
return new DirectoryInfo(proc.MainModule.FileName).Parent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
public enum CategoryEnum
|
public enum CategoryEnum
|
||||||
{
|
{
|
||||||
|
None = 0,
|
||||||
Network = 1,
|
Network = 1,
|
||||||
System = 2,
|
System = 2,
|
||||||
Application = 3,
|
Application = 3,
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,25 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<ImplicitUsings>true</ImplicitUsings>
|
<LangVersion>latest</LangVersion>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<RootNamespace>Insight.Domain</RootNamespace>
|
<RootNamespace>Insight.Domain</RootNamespace>
|
||||||
<Product>Insight</Product>
|
<Product>Insight</Product>
|
||||||
<AssemblyVersion>2023.12.14.0</AssemblyVersion>
|
<AssemblyVersion>2023.12.15.0</AssemblyVersion>
|
||||||
|
<SatelliteResourceLanguages>none</SatelliteResourceLanguages>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
<!--Ignore MemoryPack Warning-->
|
||||||
|
<NoWarn>9193</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Vaitr.Bus" Version="2023.12.13" />
|
<PackageReference Include="System.Text.Json" Version="8.0.0" />
|
||||||
<PackageReference Include="Vaitr.Network" Version="2023.12.14" />
|
<PackageReference Include="Vaitr.Bus" Version="2023.12.15.1" />
|
||||||
|
<PackageReference Include="Vaitr.Network" Version="2023.12.16" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
|
||||||
<DebugType>none</DebugType>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
|
||||||
<DebugType>none</DebugType>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
using MessagePack;
|
using MessagePack;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
|
@ -31,17 +30,17 @@ public class Result
|
||||||
}
|
}
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public Exception? Exception { get; init; }
|
public Exception? Exception { get; set; }
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
[MemberNotNullWhen(true, nameof(Exception))]
|
//[MemberNotNullWhen(true, nameof(Exception))]
|
||||||
public bool HadException => Exception is not null;
|
public bool HadException => Exception is not null;
|
||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public bool IsSuccess { get; init; }
|
public bool IsSuccess { get; set; }
|
||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public string Reason { get; init; } = string.Empty;
|
public string Reason { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
|
||||||
public static Result Fail(string reason)
|
public static Result Fail(string reason)
|
||||||
|
|
@ -130,19 +129,19 @@ public class Result<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
public Exception? Exception { get; init; }
|
public Exception? Exception { get; set; }
|
||||||
|
|
||||||
[IgnoreDataMember]
|
[IgnoreDataMember]
|
||||||
[MemberNotNullWhen(true, nameof(Exception))]
|
//[MemberNotNullWhen(true, nameof(Exception))]
|
||||||
public bool HadException => Exception is not null;
|
public bool HadException => Exception is not null;
|
||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
[MemberNotNullWhen(true, nameof(Value))]
|
//[MemberNotNullWhen(true, nameof(Value))]
|
||||||
public bool IsSuccess { get; init; }
|
public bool IsSuccess { get; set; }
|
||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public string Reason { get; init; } = string.Empty;
|
public string Reason { get; set; } = string.Empty;
|
||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public T? Value { get; init; }
|
public T? Value { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,28 +27,17 @@ public class TokenResponse
|
||||||
public string? RefreshToken { get; set; }
|
public string? RefreshToken { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TokenRevokeRequest
|
public class TokenRevokeRequest(string token, string? reason)
|
||||||
{
|
{
|
||||||
[JsonPropertyName("token"), Required]
|
[JsonPropertyName("token"), Required]
|
||||||
public string? Token { get; set; }
|
public string? Token { get; set; } = token;
|
||||||
|
|
||||||
[JsonPropertyName("reason")]
|
[JsonPropertyName("reason")]
|
||||||
public string? Reason { get; set; }
|
public string? Reason { get; set; } = reason;
|
||||||
|
|
||||||
public TokenRevokeRequest(string token, string? reason)
|
|
||||||
{
|
|
||||||
Token = token;
|
|
||||||
Reason = reason;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TokenRefreshRequest
|
public class TokenRefreshRequest(string token)
|
||||||
{
|
{
|
||||||
[JsonPropertyName("token"), Required]
|
[JsonPropertyName("token"), Required]
|
||||||
public string? Token { get; set; }
|
public string? Token { get; set; } = token;
|
||||||
|
|
||||||
public TokenRefreshRequest(string token)
|
|
||||||
{
|
|
||||||
Token = token;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -182,6 +182,6 @@ public partial class IPAddress2 : IMessage
|
||||||
IsIPv6Multicast = address.IsIPv6Multicast;
|
IsIPv6Multicast = address.IsIPv6Multicast;
|
||||||
IsIPv6SiteLocal = address.IsIPv6SiteLocal;
|
IsIPv6SiteLocal = address.IsIPv6SiteLocal;
|
||||||
IsIPv6Teredo = address.IsIPv6Teredo;
|
IsIPv6Teredo = address.IsIPv6Teredo;
|
||||||
IsIPv6UniqueLocal = address.IsIPv6UniqueLocal;
|
//IsIPv6UniqueLocal = address.IsIPv6UniqueLocal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6,10 +6,6 @@ namespace Insight.Domain.Network;
|
||||||
[MemoryPackUnion(0, typeof(Agent.Messages.AuthenticationRequest))]
|
[MemoryPackUnion(0, typeof(Agent.Messages.AuthenticationRequest))]
|
||||||
[MemoryPackUnion(1, typeof(Agent.Messages.AuthenticationResponse))]
|
[MemoryPackUnion(1, typeof(Agent.Messages.AuthenticationResponse))]
|
||||||
[MemoryPackUnion(2, typeof(Agent.Messages.InventoryRequest))]
|
[MemoryPackUnion(2, typeof(Agent.Messages.InventoryRequest))]
|
||||||
//[MemoryPackUnion(3, typeof(Agent.Messages.ConsoleQueryRequest))]
|
|
||||||
//[MemoryPackUnion(4, typeof(Agent.Messages.ConsoleQueryResponse))]
|
|
||||||
//[MemoryPackUnion(5, typeof(Proxy<Agent.Messages.ConsoleQueryResponse>))]
|
|
||||||
//[MemoryPackUnion(6, typeof(Proxy<Agent.Messages.ConsoleQueryRequest>))]
|
|
||||||
[MemoryPackUnion(7, typeof(Agent.Messages.Event))]
|
[MemoryPackUnion(7, typeof(Agent.Messages.Event))]
|
||||||
[MemoryPackUnion(8, typeof(Agent.Messages.Trap))]
|
[MemoryPackUnion(8, typeof(Agent.Messages.Trap))]
|
||||||
[MemoryPackUnion(9, typeof(Agent.Messages.Mainboard))]
|
[MemoryPackUnion(9, typeof(Agent.Messages.Mainboard))]
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Http.Extensions;
|
||||||
|
|
||||||
namespace Insight.Infrastructure;
|
namespace Insight.Infrastructure;
|
||||||
|
|
||||||
public static class HttpRequestExtensions
|
public static partial class HttpRequestExtensions
|
||||||
{
|
{
|
||||||
public static void AddPagination<TData>(this HttpRequest request, PagedList<TData> pagelist)
|
public static void AddPagination<TData>(this HttpRequest request, PagedList<TData> pagelist)
|
||||||
{
|
{
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
using Insight.Infrastructure.Models;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace Insight.Infrastructure;
|
||||||
|
|
||||||
|
public static partial class HttpResponseExtensions
|
||||||
|
{
|
||||||
|
private static readonly JsonSerializerOptions _options = new()
|
||||||
|
{
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void AddPagination<TData>(this HttpResponse response, PagedList<TData> pagelist)
|
||||||
|
{
|
||||||
|
response.Headers.Append("X-Pagination", JsonSerializer.Serialize(pagelist.Meta as PagedHeaderData, _options));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
using Insight.Infrastructure.Models;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
|
||||||
|
namespace Insight.Infrastructure.Web;
|
||||||
|
|
||||||
|
public static class MongoCollectionExtensions
|
||||||
|
{
|
||||||
|
public static async Task<PagedList<TData>> GetPagedAsync<TData>(
|
||||||
|
this IMongoCollection<TData> collection,
|
||||||
|
HttpRequest request,
|
||||||
|
HttpResponse response,
|
||||||
|
FilterDefinition<TData>? filter = null,
|
||||||
|
SortDefinition<TData>? sort = null,
|
||||||
|
int offset = 0,
|
||||||
|
int limit = 10,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var result = await Infrastructure.MongoCollectionExtensions.GetPagedAsync(collection, filter, sort, offset, limit, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
request?.AddPagination(result);
|
||||||
|
response?.AddPagination(result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<PagedList<TResult>> GetPagedAsync<TData, TResult>(
|
||||||
|
this IMongoCollection<TData> collection,
|
||||||
|
HttpRequest request,
|
||||||
|
HttpResponse response,
|
||||||
|
IAggregateFluent<BsonDocument> query,
|
||||||
|
int offset = 0,
|
||||||
|
int limit = 10,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var result = await Infrastructure.MongoCollectionExtensions.GetPagedAsync<TData, TResult>(collection, query, offset, limit, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
request?.AddPagination(result);
|
||||||
|
response?.AddPagination(result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,229 @@
|
||||||
|
using AspNetCore.Identity.MongoDbCore.Extensions;
|
||||||
|
using AspNetCore.Identity.MongoDbCore.Infrastructure;
|
||||||
|
using Insight.Infrastructure.Entities;
|
||||||
|
using Insight.Infrastructure.Services;
|
||||||
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Primitives;
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using Microsoft.Net.Http.Headers;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Insight.Infrastructure;
|
||||||
|
|
||||||
|
public static partial class ServiceExtensions
|
||||||
|
{
|
||||||
|
public static IServiceCollection AddTokenServices(this IServiceCollection services, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
var options = new Models.TokenOptions(
|
||||||
|
key: configuration.GetValue<string?>(Appsettings.JwtKey) ?? throw new Exception($"{Appsettings.JwtKey} value not set (appsettings)"),
|
||||||
|
expires: configuration.GetValue<int?>(Appsettings.JwtExp) ?? throw new Exception($"{Appsettings.JwtExp} value not set (appsettings)"),
|
||||||
|
audience: configuration.GetValue<Uri?>(Appsettings.JwtAudience) ?? throw new Exception($"{Appsettings.JwtAudience} value not set (appsettings)"),
|
||||||
|
issuer: configuration.GetValue<Uri?>(Appsettings.JwtIssuer) ?? throw new Exception($"{Appsettings.JwtIssuer} value not set (appsettings)"));
|
||||||
|
|
||||||
|
services.AddSingleton(options);
|
||||||
|
services.AddTransient<TokenService>();
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IServiceCollection AddProxyServices(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
// add before routing
|
||||||
|
services.Configure<ForwardedHeadersOptions>(options =>
|
||||||
|
{
|
||||||
|
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
|
||||||
|
});
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IServiceCollection AddRoutingServices(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
// add after proxy
|
||||||
|
services.AddRouting(options =>
|
||||||
|
{
|
||||||
|
options.LowercaseUrls = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IServiceCollection AddIdentityServices(this IServiceCollection services, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
var connectionString = configuration.GetValue<string?>(Appsettings.Database) ?? throw new Exception($"{Appsettings.Database} value not set (appsettings)");
|
||||||
|
|
||||||
|
services.AddIdentity<InsightUser, InsightRole>(options =>
|
||||||
|
{
|
||||||
|
|
||||||
|
})
|
||||||
|
.AddMongoDbStores<InsightUser, InsightRole, ObjectId>(connectionString, Settings.Database)
|
||||||
|
.AddDefaultTokenProviders()
|
||||||
|
.AddSignInManager();
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
// REWRITE TO COOKIE ONLY FOR WEB
|
||||||
|
|
||||||
|
services.AddAuthentication(options =>
|
||||||
|
{
|
||||||
|
options.DefaultScheme = "Custom";
|
||||||
|
options.DefaultChallengeScheme = "Custom";
|
||||||
|
})
|
||||||
|
.AddCookie("Cookies", options =>
|
||||||
|
{
|
||||||
|
//options.Cookie.Domain = "insight.webmatic.de";
|
||||||
|
options.Cookie.Name = "insight";
|
||||||
|
options.LoginPath = "/account/login";
|
||||||
|
options.LogoutPath = "/account/logout";
|
||||||
|
options.ExpireTimeSpan = TimeSpan.FromHours(1);
|
||||||
|
options.SlidingExpiration = true;
|
||||||
|
|
||||||
|
options.Events.OnRedirectToLogin = options =>
|
||||||
|
{
|
||||||
|
if (options.Request.Path.StartsWithSegments("/api") && options.Response.StatusCode == 200)
|
||||||
|
options.Response.StatusCode = 401;
|
||||||
|
else
|
||||||
|
options.Response.Redirect(options.RedirectUri);
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.AddJwtBearer("Bearer", options =>
|
||||||
|
{
|
||||||
|
options.RequireHttpsMetadata = false;
|
||||||
|
options.SaveToken = true;
|
||||||
|
|
||||||
|
options.TokenValidationParameters.ValidateActor = false;
|
||||||
|
|
||||||
|
options.TokenValidationParameters.ValidAudience = configuration.GetSection("Jwt:Audience").Value;
|
||||||
|
options.TokenValidationParameters.ValidateAudience = true;
|
||||||
|
|
||||||
|
options.TokenValidationParameters.ValidIssuer = configuration.GetSection("Jwt:Issuer").Value;
|
||||||
|
options.TokenValidationParameters.ValidateIssuer = true;
|
||||||
|
|
||||||
|
options.TokenValidationParameters.IssuerSigningKey = new SymmetricSecurityKey(
|
||||||
|
Encoding.UTF8.GetBytes(configuration.GetSection("Jwt:Key").Value ?? throw new Exception("Configuration for [Jwt:Key] not found"))
|
||||||
|
);
|
||||||
|
|
||||||
|
options.TokenValidationParameters.ValidateIssuerSigningKey = true;
|
||||||
|
options.TokenValidationParameters.ValidateLifetime = true;
|
||||||
|
})
|
||||||
|
.AddPolicyScheme("Custom", "Custom", options =>
|
||||||
|
{
|
||||||
|
options.ForwardDefaultSelector = context =>
|
||||||
|
{
|
||||||
|
if (context.Request.Headers[HeaderNames.Authorization] is StringValues auth && auth.ToString().StartsWith("Bearer "))
|
||||||
|
return "Bearer";
|
||||||
|
else
|
||||||
|
return "Cookies";
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IServiceCollection AddBearerAuthentication(this IServiceCollection services, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
services.AddAuthentication(options =>
|
||||||
|
{
|
||||||
|
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
|
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
|
options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
|
})
|
||||||
|
.AddJwtBearer(options =>
|
||||||
|
{
|
||||||
|
options.RequireHttpsMetadata = false;
|
||||||
|
options.SaveToken = true;
|
||||||
|
|
||||||
|
options.TokenValidationParameters.ValidateActor = false;
|
||||||
|
|
||||||
|
options.TokenValidationParameters.ValidAudience = configuration.GetValue<string?>(Appsettings.JwtAudience) ?? throw new Exception($"{Appsettings.JwtAudience} value not set (appsettings)");
|
||||||
|
options.TokenValidationParameters.ValidateAudience = true;
|
||||||
|
|
||||||
|
options.TokenValidationParameters.ValidIssuer = configuration.GetValue<string?>(Appsettings.JwtIssuer) ?? throw new Exception($"{Appsettings.JwtIssuer} value not set (appsettings)");
|
||||||
|
options.TokenValidationParameters.ValidateIssuer = true;
|
||||||
|
|
||||||
|
options.TokenValidationParameters.IssuerSigningKey = new SymmetricSecurityKey(
|
||||||
|
Encoding.UTF8.GetBytes(configuration.GetValue<string?>(Appsettings.JwtKey) ?? throw new Exception($"{Appsettings.JwtKey} value not set (appsettings)"))
|
||||||
|
);
|
||||||
|
|
||||||
|
options.TokenValidationParameters.ValidateIssuerSigningKey = true;
|
||||||
|
options.TokenValidationParameters.ValidateLifetime = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
//private static IServiceCollection AddIdentityServices2(this IServiceCollection services, IConfiguration configuration)
|
||||||
|
//{
|
||||||
|
// var identityOptions = new MongoDbIdentityConfiguration
|
||||||
|
// {
|
||||||
|
// MongoDbSettings = new MongoDbSettings
|
||||||
|
// {
|
||||||
|
// ConnectionString = configuration.GetSection("ConnectionStrings:Mongo").Value,
|
||||||
|
// DatabaseName = "insight"
|
||||||
|
// },
|
||||||
|
// IdentityOptionsAction = options =>
|
||||||
|
// {
|
||||||
|
// options.User.RequireUniqueEmail = true;
|
||||||
|
// options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@.-_";
|
||||||
|
|
||||||
|
// options.Password.RequireDigit = false;
|
||||||
|
// options.Password.RequiredLength = 8;
|
||||||
|
// options.Password.RequireNonAlphanumeric = false;
|
||||||
|
// options.Password.RequireUppercase = false;
|
||||||
|
// options.Password.RequireLowercase = false;
|
||||||
|
|
||||||
|
// options.SignIn.RequireConfirmedAccount = false;
|
||||||
|
// options.SignIn.RequireConfirmedEmail = false;
|
||||||
|
// options.SignIn.RequireConfirmedPhoneNumber = false;
|
||||||
|
|
||||||
|
// options.Lockout.MaxFailedAccessAttempts = 5;
|
||||||
|
// options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// services.ConfigureMongoDbIdentity<InsightUser, InsightRole, ObjectId>(identityOptions)
|
||||||
|
// .AddDefaultTokenProviders()
|
||||||
|
// .AddSignInManager<InsightUser>();
|
||||||
|
|
||||||
|
// return services;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//private static IServiceCollection AddIdentityAuthentication(this IServiceCollection services, IConfiguration configuration)
|
||||||
|
//{
|
||||||
|
// services.AddAuthentication(options =>
|
||||||
|
// {
|
||||||
|
// options.DefaultAuthenticateScheme =
|
||||||
|
// });
|
||||||
|
// cookieBuilder.ApplicationCookie = builder.AddApplicationCookie();
|
||||||
|
// cookieBuilder.ExternalCookie = builder.AddExternalCookie();
|
||||||
|
// cookieBuilder.TwoFactorRememberMeCookie = builder.AddTwoFactorRememberMeCookie();
|
||||||
|
// cookieBuilder.TwoFactorUserIdCookie = builder.AddTwoFactorUserIdCookie();
|
||||||
|
// .AddCookie(options =>
|
||||||
|
// {
|
||||||
|
// options.
|
||||||
|
// };
|
||||||
|
// .AddIdentityCookies();
|
||||||
|
// .AddCookie(options =>
|
||||||
|
// {
|
||||||
|
// // Specify where to redirect un-authenticated users
|
||||||
|
// options.LoginPath = "/account/login";
|
||||||
|
|
||||||
|
// // Specify the name of the auth cookie.
|
||||||
|
// // ASP.NET picks a dumb name by default.
|
||||||
|
// options.Cookie.Name = "insight";
|
||||||
|
// });
|
||||||
|
|
||||||
|
// return services;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<RootNamespace>Insight.Infrastructure.Web</RootNamespace>
|
||||||
|
<Product>Insight</Product>
|
||||||
|
<AssemblyVersion>2023.12.15.0</AssemblyVersion>
|
||||||
|
<SatelliteResourceLanguages>none</SatelliteResourceLanguages>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.0.3" />
|
||||||
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Insight.Infrastructure\Insight.Infrastructure.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace Insight.Infrastructure.Models;
|
||||||
|
|
||||||
|
public class TokenOptions(string key, int expires, Uri? audience = null, Uri? issuer = null)
|
||||||
|
{
|
||||||
|
public string Key { get; set; } = key;
|
||||||
|
public int Expires { get; set; } = expires;
|
||||||
|
public Uri? Audience { get; set; } = audience;
|
||||||
|
public Uri? Issuer { get; set; } = issuer;
|
||||||
|
}
|
||||||
|
|
@ -10,24 +10,17 @@ using System.Text;
|
||||||
|
|
||||||
namespace Insight.Infrastructure.Services;
|
namespace Insight.Infrastructure.Services;
|
||||||
|
|
||||||
public class TokenService
|
public class TokenService(TokenOptions options, IdentityService identityService, IMongoDatabase database)
|
||||||
{
|
{
|
||||||
private readonly TokenOptions _options;
|
private readonly TokenOptions _options = options;
|
||||||
private readonly IdentityService _identityService;
|
private readonly IdentityService _identityService = identityService;
|
||||||
private readonly IMongoDatabase _database;
|
private readonly IMongoDatabase _database = database;
|
||||||
|
|
||||||
public TokenService(TokenOptions options, IdentityService identityService, IMongoDatabase database)
|
|
||||||
{
|
|
||||||
_options = options;
|
|
||||||
_identityService = identityService;
|
|
||||||
_database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<TokenResponse> GetAsync(string email, string password, string? code = null, IPAddress? ipa = null)
|
public async Task<TokenResponse> GetAsync(string email, string password, string? code = null, IPAddress? ipa = null)
|
||||||
{
|
{
|
||||||
var user = await _identityService.LoginAsync(email, password, code).ConfigureAwait(false);
|
var user = await _identityService.LoginAsync(email, password, code).ConfigureAwait(false);
|
||||||
|
|
||||||
var accessToken = await CreateAccessTokenAsync(user, ipa).ConfigureAwait(false);
|
var accessToken = await CreateAccessTokenAsync(user).ConfigureAwait(false);
|
||||||
var refreshToken = await CreateRefreshTokenAsync(user, ipa).ConfigureAwait(false);
|
var refreshToken = await CreateRefreshTokenAsync(user, ipa).ConfigureAwait(false);
|
||||||
|
|
||||||
return new TokenResponse
|
return new TokenResponse
|
||||||
|
|
@ -42,7 +35,7 @@ public class TokenService
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(refreshToken)) throw new ArgumentNullException(nameof(refreshToken));
|
if (string.IsNullOrWhiteSpace(refreshToken)) throw new ArgumentNullException(nameof(refreshToken));
|
||||||
|
|
||||||
var user = await _database.User().Find(p => p.RefreshTokens.Any(t => t.Token == refreshToken)).FirstOrDefaultAsync();
|
var user = await _database.User().Find(p => p.RefreshTokens != null && p.RefreshTokens.Any(t => t.Token == refreshToken)).FirstOrDefaultAsync();
|
||||||
if (user is null || user.RefreshTokens is null) throw new InvalidDataException("Invalid Refresh Token");
|
if (user is null || user.RefreshTokens is null) throw new InvalidDataException("Invalid Refresh Token");
|
||||||
|
|
||||||
var token = user.RefreshTokens.First(p => p.Token == refreshToken);
|
var token = user.RefreshTokens.First(p => p.Token == refreshToken);
|
||||||
|
|
@ -73,7 +66,7 @@ public class TokenService
|
||||||
var newRefreshToken = await CreateRefreshTokenAsync(user, ipa).ConfigureAwait(false);
|
var newRefreshToken = await CreateRefreshTokenAsync(user, ipa).ConfigureAwait(false);
|
||||||
|
|
||||||
// create access token
|
// create access token
|
||||||
var accessToken = await CreateAccessTokenAsync(user, ipa).ConfigureAwait(false);
|
var accessToken = await CreateAccessTokenAsync(user).ConfigureAwait(false);
|
||||||
|
|
||||||
return new TokenResponse
|
return new TokenResponse
|
||||||
{
|
{
|
||||||
|
|
@ -87,7 +80,7 @@ public class TokenService
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(refreshToken)) throw new ArgumentNullException(nameof(refreshToken));
|
if (string.IsNullOrWhiteSpace(refreshToken)) throw new ArgumentNullException(nameof(refreshToken));
|
||||||
|
|
||||||
var user = await _database.User().Find(p => p.RefreshTokens.Any(t => t.Token == refreshToken)).FirstOrDefaultAsync();
|
var user = await _database.User().Find(p => p.RefreshTokens != null && p.RefreshTokens.Any(t => t.Token == refreshToken)).FirstOrDefaultAsync();
|
||||||
if (user is null || user.RefreshTokens is null) throw new InvalidDataException("Invalid Refresh Token");
|
if (user is null || user.RefreshTokens is null) throw new InvalidDataException("Invalid Refresh Token");
|
||||||
|
|
||||||
var token = user.RefreshTokens.First(p => p.Token == refreshToken);
|
var token = user.RefreshTokens.First(p => p.Token == refreshToken);
|
||||||
|
|
@ -102,7 +95,7 @@ public class TokenService
|
||||||
token.ReasonRevoked = reason;
|
token.ReasonRevoked = reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<(string, int)> CreateAccessTokenAsync(InsightUser user, IPAddress? ipa = null)
|
private async Task<(string, int)> CreateAccessTokenAsync(InsightUser user)
|
||||||
{
|
{
|
||||||
var claims = await _identityService.GetClaimsAsync(user).ConfigureAwait(false);
|
var claims = await _identityService.GetClaimsAsync(user).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
using Insight.Infrastructure.Models;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using System.Text.Json;
|
|
||||||
|
|
||||||
namespace Insight.Infrastructure;
|
|
||||||
|
|
||||||
public static class HttpResponseExtensions
|
|
||||||
{
|
|
||||||
public static void AddPagination<TData>(this HttpResponse response, PagedList<TData> pagelist)
|
|
||||||
{
|
|
||||||
response.Headers.Add("X-Pagination", JsonSerializer.Serialize(pagelist.Meta as PagedHeaderData, new JsonSerializerOptions
|
|
||||||
{
|
|
||||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
using Insight.Infrastructure.Models;
|
using Insight.Infrastructure.Models;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using MongoDB.Bson;
|
using MongoDB.Bson;
|
||||||
using MongoDB.Bson.Serialization;
|
using MongoDB.Bson.Serialization;
|
||||||
using MongoDB.Driver;
|
using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Infrastructure;
|
namespace Insight.Infrastructure;
|
||||||
|
|
||||||
public static class MongoCollectionExtensions
|
public static partial class MongoCollectionExtensions
|
||||||
{
|
{
|
||||||
private const int _maximumLimit = 100;
|
private const int _maximumLimit = 100;
|
||||||
|
|
||||||
|
|
@ -30,24 +29,6 @@ public static class MongoCollectionExtensions
|
||||||
return new PagedList<TData>(data, offset, limit, total);
|
return new PagedList<TData>(data, offset, limit, total);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<PagedList<TData>> GetPagedAsync<TData>(
|
|
||||||
this IMongoCollection<TData> collection,
|
|
||||||
HttpRequest request,
|
|
||||||
HttpResponse response,
|
|
||||||
FilterDefinition<TData>? filter = null,
|
|
||||||
SortDefinition<TData>? sort = null,
|
|
||||||
int offset = 0,
|
|
||||||
int limit = 10,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
var result = await GetPagedAsync(collection, filter, sort, offset, limit, cancellationToken).ConfigureAwait(false);
|
|
||||||
|
|
||||||
request?.AddPagination(result);
|
|
||||||
response?.AddPagination(result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<PagedList<TResult>> GetPagedAsync<TData, TResult>(
|
public static async Task<PagedList<TResult>> GetPagedAsync<TData, TResult>(
|
||||||
this IMongoCollection<TData> collection,
|
this IMongoCollection<TData> collection,
|
||||||
IAggregateFluent<BsonDocument> query,
|
IAggregateFluent<BsonDocument> query,
|
||||||
|
|
@ -62,21 +43,4 @@ public static class MongoCollectionExtensions
|
||||||
|
|
||||||
return new PagedList<TResult>(data.Select(x => BsonSerializer.Deserialize<TResult>(x)), offset, limit, total);
|
return new PagedList<TResult>(data.Select(x => BsonSerializer.Deserialize<TResult>(x)), offset, limit, total);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<PagedList<TResult>> GetPagedAsync<TData, TResult>(
|
|
||||||
this IMongoCollection<TData> collection,
|
|
||||||
HttpRequest request,
|
|
||||||
HttpResponse response,
|
|
||||||
IAggregateFluent<BsonDocument> query,
|
|
||||||
int offset = 0,
|
|
||||||
int limit = 10,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
var result = await GetPagedAsync<TData, TResult>(collection, query, offset, limit, cancellationToken).ConfigureAwait(false);
|
|
||||||
|
|
||||||
request?.AddPagination(result);
|
|
||||||
response?.AddPagination(result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,24 +1,13 @@
|
||||||
using AspNetCore.Identity.MongoDbCore.Extensions;
|
using Insight.Infrastructure.Services;
|
||||||
using AspNetCore.Identity.MongoDbCore.Infrastructure;
|
|
||||||
using Insight.Infrastructure.Entities;
|
|
||||||
using Insight.Infrastructure.Services;
|
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
|
||||||
using Microsoft.AspNetCore.Identity;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
|
||||||
using Microsoft.Net.Http.Headers;
|
|
||||||
using MongoDB.Bson;
|
|
||||||
using MongoDB.Driver;
|
using MongoDB.Driver;
|
||||||
using MongoDB.Driver.Core.Configuration;
|
using MongoDB.Driver.Core.Configuration;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Insight.Infrastructure;
|
namespace Insight.Infrastructure;
|
||||||
|
|
||||||
public static class ServiceExtensions
|
public static partial class ServiceExtensions
|
||||||
{
|
{
|
||||||
public static IServiceCollection AddDatabase(this IServiceCollection services, IConfiguration configuration, ILoggerFactory? loggerFactory = null)
|
public static IServiceCollection AddDatabase(this IServiceCollection services, IConfiguration configuration, ILoggerFactory? loggerFactory = null)
|
||||||
{
|
{
|
||||||
|
|
@ -42,221 +31,6 @@ public static class ServiceExtensions
|
||||||
{
|
{
|
||||||
services.AddTransient<IdentityService>();
|
services.AddTransient<IdentityService>();
|
||||||
services.AddTransient<AuthenticatorService>();
|
services.AddTransient<AuthenticatorService>();
|
||||||
services.AddTransient<AccountService>();
|
|
||||||
services.AddTransient<CustomerService>();
|
|
||||||
services.AddTransient<HostService>();
|
|
||||||
services.AddTransient<AgentService>();
|
|
||||||
services.AddTransient<InventoryService>();
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IServiceCollection AddIdentityServices(this IServiceCollection services, IConfiguration configuration)
|
|
||||||
{
|
|
||||||
var connectionString = configuration.GetValue<string?>(Appsettings.Database) ?? throw new Exception($"{Appsettings.Database} value not set (appsettings)");
|
|
||||||
|
|
||||||
services.AddIdentity<InsightUser, InsightRole>(options =>
|
|
||||||
{
|
|
||||||
|
|
||||||
})
|
|
||||||
.AddMongoDbStores<InsightUser, InsightRole, ObjectId>(connectionString, Settings.Database)
|
|
||||||
.AddDefaultTokenProviders()
|
|
||||||
.AddSignInManager();
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IServiceCollection AddTokenServices(this IServiceCollection services, IConfiguration configuration)
|
|
||||||
{
|
|
||||||
var options = new Models.TokenOptions(
|
|
||||||
key: configuration.GetValue<string?>(Appsettings.JwtKey) ?? throw new Exception($"{Appsettings.JwtKey} value not set (appsettings)"),
|
|
||||||
expires: configuration.GetValue<int?>(Appsettings.JwtExp) ?? throw new Exception($"{Appsettings.JwtExp} value not set (appsettings)"),
|
|
||||||
audience: configuration.GetValue<Uri?>(Appsettings.JwtAudience) ?? throw new Exception($"{Appsettings.JwtAudience} value not set (appsettings)"),
|
|
||||||
issuer: configuration.GetValue<Uri?>(Appsettings.JwtIssuer) ?? throw new Exception($"{Appsettings.JwtIssuer} value not set (appsettings)"));
|
|
||||||
|
|
||||||
services.AddSingleton(options);
|
|
||||||
services.AddTransient<TokenService>();
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration)
|
|
||||||
{
|
|
||||||
// REWRITE TO COOKIE ONLY FOR WEB
|
|
||||||
|
|
||||||
services.AddAuthentication(options =>
|
|
||||||
{
|
|
||||||
options.DefaultScheme = "Custom";
|
|
||||||
options.DefaultChallengeScheme = "Custom";
|
|
||||||
})
|
|
||||||
.AddCookie("Cookies", options =>
|
|
||||||
{
|
|
||||||
//options.Cookie.Domain = "insight.webmatic.de";
|
|
||||||
options.Cookie.Name = "insight";
|
|
||||||
options.LoginPath = "/account/login";
|
|
||||||
options.LogoutPath = "/account/logout";
|
|
||||||
options.ExpireTimeSpan = TimeSpan.FromHours(1);
|
|
||||||
options.SlidingExpiration = true;
|
|
||||||
|
|
||||||
options.Events.OnRedirectToLogin = options =>
|
|
||||||
{
|
|
||||||
if (options.Request.Path.StartsWithSegments("/api") && options.Response.StatusCode == 200)
|
|
||||||
options.Response.StatusCode = 401;
|
|
||||||
else
|
|
||||||
options.Response.Redirect(options.RedirectUri);
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.AddJwtBearer("Bearer", options =>
|
|
||||||
{
|
|
||||||
options.RequireHttpsMetadata = false;
|
|
||||||
options.SaveToken = true;
|
|
||||||
|
|
||||||
options.TokenValidationParameters.ValidateActor = false;
|
|
||||||
|
|
||||||
options.TokenValidationParameters.ValidAudience = configuration.GetSection("Jwt:Audience").Value;
|
|
||||||
options.TokenValidationParameters.ValidateAudience = true;
|
|
||||||
|
|
||||||
options.TokenValidationParameters.ValidIssuer = configuration.GetSection("Jwt:Issuer").Value;
|
|
||||||
options.TokenValidationParameters.ValidateIssuer = true;
|
|
||||||
|
|
||||||
options.TokenValidationParameters.IssuerSigningKey = new SymmetricSecurityKey(
|
|
||||||
Encoding.UTF8.GetBytes(configuration.GetSection("Jwt:Key").Value ?? throw new ArgumentNullException(nameof(TokenValidationParameters), "Jwt:Key"))
|
|
||||||
);
|
|
||||||
|
|
||||||
options.TokenValidationParameters.ValidateIssuerSigningKey = true;
|
|
||||||
options.TokenValidationParameters.ValidateLifetime = true;
|
|
||||||
})
|
|
||||||
.AddPolicyScheme("Custom", "Custom", options =>
|
|
||||||
{
|
|
||||||
options.ForwardDefaultSelector = context =>
|
|
||||||
{
|
|
||||||
string authorization = context.Request.Headers[HeaderNames.Authorization];
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(authorization) && authorization.StartsWith("Bearer ")) return "Bearer";
|
|
||||||
|
|
||||||
return "Cookies";
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IServiceCollection AddBearerAuthentication(this IServiceCollection services, IConfiguration configuration)
|
|
||||||
{
|
|
||||||
services.AddAuthentication(options =>
|
|
||||||
{
|
|
||||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
||||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
||||||
options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
||||||
})
|
|
||||||
.AddJwtBearer(options =>
|
|
||||||
{
|
|
||||||
options.RequireHttpsMetadata = false;
|
|
||||||
options.SaveToken = true;
|
|
||||||
|
|
||||||
options.TokenValidationParameters.ValidateActor = false;
|
|
||||||
|
|
||||||
options.TokenValidationParameters.ValidAudience = configuration.GetValue<string?>(Appsettings.JwtAudience) ?? throw new Exception($"{Appsettings.JwtAudience} value not set (appsettings)");
|
|
||||||
options.TokenValidationParameters.ValidateAudience = true;
|
|
||||||
|
|
||||||
options.TokenValidationParameters.ValidIssuer = configuration.GetValue<string?>(Appsettings.JwtIssuer) ?? throw new Exception($"{Appsettings.JwtIssuer} value not set (appsettings)");
|
|
||||||
options.TokenValidationParameters.ValidateIssuer = true;
|
|
||||||
|
|
||||||
options.TokenValidationParameters.IssuerSigningKey = new SymmetricSecurityKey(
|
|
||||||
Encoding.UTF8.GetBytes(configuration.GetValue<string?>(Appsettings.JwtKey) ?? throw new Exception($"{Appsettings.JwtKey} value not set (appsettings)"))
|
|
||||||
);
|
|
||||||
|
|
||||||
options.TokenValidationParameters.ValidateIssuerSigningKey = true;
|
|
||||||
options.TokenValidationParameters.ValidateLifetime = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IServiceCollection AddProxyServices(this IServiceCollection services, IConfiguration configuration)
|
|
||||||
{
|
|
||||||
// add before routing
|
|
||||||
services.Configure<ForwardedHeadersOptions>(options =>
|
|
||||||
{
|
|
||||||
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
|
|
||||||
});
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IServiceCollection AddRoutingServices(this IServiceCollection services, IConfiguration configuration)
|
|
||||||
{
|
|
||||||
// add after proxy
|
|
||||||
services.AddRouting(options =>
|
|
||||||
{
|
|
||||||
options.LowercaseUrls = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IServiceCollection AddIdentityServices2(this IServiceCollection services, IConfiguration configuration)
|
|
||||||
{
|
|
||||||
var identityOptions = new MongoDbIdentityConfiguration
|
|
||||||
{
|
|
||||||
MongoDbSettings = new MongoDbSettings
|
|
||||||
{
|
|
||||||
ConnectionString = configuration.GetSection("ConnectionStrings:Mongo").Value,
|
|
||||||
DatabaseName = "insight"
|
|
||||||
},
|
|
||||||
IdentityOptionsAction = options =>
|
|
||||||
{
|
|
||||||
options.User.RequireUniqueEmail = true;
|
|
||||||
options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@.-_";
|
|
||||||
|
|
||||||
options.Password.RequireDigit = false;
|
|
||||||
options.Password.RequiredLength = 8;
|
|
||||||
options.Password.RequireNonAlphanumeric = false;
|
|
||||||
options.Password.RequireUppercase = false;
|
|
||||||
options.Password.RequireLowercase = false;
|
|
||||||
|
|
||||||
options.SignIn.RequireConfirmedAccount = false;
|
|
||||||
options.SignIn.RequireConfirmedEmail = false;
|
|
||||||
options.SignIn.RequireConfirmedPhoneNumber = false;
|
|
||||||
|
|
||||||
options.Lockout.MaxFailedAccessAttempts = 5;
|
|
||||||
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
services.ConfigureMongoDbIdentity<InsightUser, InsightRole, ObjectId>(identityOptions)
|
|
||||||
.AddDefaultTokenProviders()
|
|
||||||
.AddSignInManager<InsightUser>();
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IServiceCollection AddIdentityAuthentication(this IServiceCollection services, IConfiguration configuration)
|
|
||||||
{
|
|
||||||
services.AddAuthentication(options =>
|
|
||||||
{
|
|
||||||
//options.DefaultAuthenticateScheme =
|
|
||||||
});
|
|
||||||
//cookieBuilder.ApplicationCookie = builder.AddApplicationCookie();
|
|
||||||
//cookieBuilder.ExternalCookie = builder.AddExternalCookie();
|
|
||||||
//cookieBuilder.TwoFactorRememberMeCookie = builder.AddTwoFactorRememberMeCookie();
|
|
||||||
//cookieBuilder.TwoFactorUserIdCookie = builder.AddTwoFactorUserIdCookie();
|
|
||||||
//.AddCookie(options =>
|
|
||||||
//{
|
|
||||||
// options.
|
|
||||||
//};
|
|
||||||
//.AddIdentityCookies();
|
|
||||||
//.AddCookie(options =>
|
|
||||||
//{
|
|
||||||
// // Specify where to redirect un-authenticated users
|
|
||||||
// options.LoginPath = "/account/login";
|
|
||||||
|
|
||||||
// // Specify the name of the auth cookie.
|
|
||||||
// // ASP.NET picks a dumb name by default.
|
|
||||||
// options.Cookie.Name = "insight";
|
|
||||||
//});
|
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,28 +1,21 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
<RootNamespace>Insight.Infrastructure</RootNamespace>
|
<RootNamespace>Insight.Infrastructure</RootNamespace>
|
||||||
<Product>Insight</Product>
|
<Product>Insight</Product>
|
||||||
<AssemblyVersion>2023.12.14.0</AssemblyVersion>
|
<AssemblyVersion>2023.12.15.0</AssemblyVersion>
|
||||||
<ImplicitUsings>true</ImplicitUsings>
|
<SatelliteResourceLanguages>none</SatelliteResourceLanguages>
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
|
||||||
<DebugType>none</DebugType>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
|
||||||
<DebugType>none</DebugType>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.13" />
|
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
|
||||||
<PackageReference Include="MongoDB.Driver" Version="2.23.0" />
|
|
||||||
<PackageReference Include="AspNetCore.Identity.MongoDbCore" Version="3.1.2" />
|
<PackageReference Include="AspNetCore.Identity.MongoDbCore" Version="3.1.2" />
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.0.3" />
|
<PackageReference Include="MongoDB.Driver" Version="2.23.1" />
|
||||||
<PackageReference Include="Vaitr.Scheduler" Version="2023.12.6" />
|
<PackageReference Include="Vaitr.Scheduler" Version="2023.12.15.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
namespace Insight.Infrastructure.Models;
|
|
||||||
|
|
||||||
public class TokenOptions
|
|
||||||
{
|
|
||||||
public string Key { get; set; }
|
|
||||||
public int Expires { get; set; }
|
|
||||||
public Uri? Audience { get; set; }
|
|
||||||
public Uri? Issuer { get; set; }
|
|
||||||
|
|
||||||
public TokenOptions(string key, int expires, Uri? audience = null, Uri? issuer = null)
|
|
||||||
{
|
|
||||||
Key = key;
|
|
||||||
Expires = expires;
|
|
||||||
Audience = audience;
|
|
||||||
Issuer = issuer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
using Insight.Infrastructure.Entities;
|
|
||||||
using Insight.Infrastructure.Models;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using MongoDB.Driver;
|
|
||||||
|
|
||||||
namespace Insight.Infrastructure.Services;
|
|
||||||
|
|
||||||
public class AccountService
|
|
||||||
{
|
|
||||||
private readonly IMongoDatabase _database;
|
|
||||||
private readonly ILogger<AccountService> _logger;
|
|
||||||
|
|
||||||
public AccountService(IMongoDatabase database, ILogger<AccountService> logger)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<PagedList<InsightUser>> GetAsync(
|
|
||||||
FilterDefinition<InsightUser>? filter = null,
|
|
||||||
SortDefinition<InsightUser>? sort = null,
|
|
||||||
int offset = 0,
|
|
||||||
int limit = 10,
|
|
||||||
CancellationToken cancellationToken = default) => _database.User().GetPagedAsync(filter, sort, offset, limit, cancellationToken);
|
|
||||||
|
|
||||||
public Task<PagedList<InsightUser>> GetAsync(
|
|
||||||
HttpRequest request,
|
|
||||||
HttpResponse response,
|
|
||||||
FilterDefinition<InsightUser>? filter = null,
|
|
||||||
SortDefinition<InsightUser>? sort = null,
|
|
||||||
int offset = 0,
|
|
||||||
int limit = 10,
|
|
||||||
CancellationToken cancellationToken = default) => _database.User().GetPagedAsync(request, response, filter, sort, offset, limit, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
using Insight.Infrastructure.Entities;
|
|
||||||
using Insight.Infrastructure.Models;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using MongoDB.Driver;
|
|
||||||
|
|
||||||
namespace Insight.Infrastructure.Services;
|
|
||||||
|
|
||||||
public class AgentService
|
|
||||||
{
|
|
||||||
private readonly IMongoDatabase _database;
|
|
||||||
private readonly ILogger<AgentService> _logger;
|
|
||||||
|
|
||||||
public AgentService(IMongoDatabase database, ILogger<AgentService> logger)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<PagedList<AgentEntity>> GetAsync(
|
|
||||||
FilterDefinition<AgentEntity>? filter = null,
|
|
||||||
SortDefinition<AgentEntity>? sort = null,
|
|
||||||
int offset = 0,
|
|
||||||
int limit = 10,
|
|
||||||
CancellationToken cancellationToken = default) => _database.Agent().GetPagedAsync(filter, sort, offset, limit, cancellationToken);
|
|
||||||
|
|
||||||
public Task<PagedList<AgentEntity>> GetAsync(
|
|
||||||
HttpRequest request,
|
|
||||||
HttpResponse response,
|
|
||||||
FilterDefinition<AgentEntity>? filter = null,
|
|
||||||
SortDefinition<AgentEntity>? sort = null,
|
|
||||||
int offset = 0,
|
|
||||||
int limit = 10,
|
|
||||||
CancellationToken cancellationToken = default) => _database.Agent().GetPagedAsync(request, response, filter, sort, offset, limit, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
@ -7,16 +7,9 @@ using System.Text.Encodings.Web;
|
||||||
|
|
||||||
namespace Insight.Infrastructure.Services;
|
namespace Insight.Infrastructure.Services;
|
||||||
|
|
||||||
public class AuthenticatorService
|
public class AuthenticatorService(UserManager<InsightUser> userManager)
|
||||||
{
|
{
|
||||||
private readonly IMongoDatabase _database;
|
private readonly UserManager<InsightUser> _userManager = userManager;
|
||||||
private readonly UserManager<InsightUser> _userManager;
|
|
||||||
|
|
||||||
public AuthenticatorService(IMongoDatabase database, UserManager<InsightUser> userManager)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
_userManager = userManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<bool> GetStatusAsync(InsightUser user)
|
public async Task<bool> GetStatusAsync(InsightUser user)
|
||||||
{
|
{
|
||||||
|
|
@ -79,7 +72,7 @@ public class AuthenticatorService
|
||||||
return await _userManager.GenerateNewTwoFactorRecoveryCodesAsync(user, count).ConfigureAwait(false);
|
return await _userManager.GenerateNewTwoFactorRecoveryCodesAsync(user, count).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GenerateQrCode(string email, string unformattedKey)
|
public static string GenerateQrCode(string email, string unformattedKey)
|
||||||
{
|
{
|
||||||
var encoder = UrlEncoder.Default;
|
var encoder = UrlEncoder.Default;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
using Insight.Infrastructure.Entities;
|
|
||||||
using Insight.Infrastructure.Models;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using MongoDB.Driver;
|
|
||||||
|
|
||||||
namespace Insight.Infrastructure.Services;
|
|
||||||
|
|
||||||
public class CustomerService
|
|
||||||
{
|
|
||||||
private readonly IMongoDatabase _database;
|
|
||||||
private readonly ILogger<CustomerService> _logger;
|
|
||||||
|
|
||||||
public CustomerService(IMongoDatabase database, ILogger<CustomerService> logger)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<PagedList<CustomerEntity>> GetAsync(
|
|
||||||
FilterDefinition<CustomerEntity>? filter = null,
|
|
||||||
SortDefinition<CustomerEntity>? sort = null,
|
|
||||||
int offset = 0,
|
|
||||||
int limit = 10,
|
|
||||||
CancellationToken cancellationToken = default) => _database.Customer().GetPagedAsync(filter, sort, offset, limit, cancellationToken);
|
|
||||||
|
|
||||||
public Task<PagedList<CustomerEntity>> GetAsync(
|
|
||||||
HttpRequest request,
|
|
||||||
HttpResponse response,
|
|
||||||
FilterDefinition<CustomerEntity>? filter = null,
|
|
||||||
SortDefinition<CustomerEntity>? sort = null,
|
|
||||||
int offset = 0,
|
|
||||||
int limit = 10,
|
|
||||||
CancellationToken cancellationToken = default) => _database.Customer().GetPagedAsync(request, response, filter, sort, offset, limit, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
using Insight.Infrastructure.Entities;
|
|
||||||
using Insight.Infrastructure.Models;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using MongoDB.Driver;
|
|
||||||
|
|
||||||
namespace Insight.Infrastructure.Services;
|
|
||||||
|
|
||||||
public class HostService
|
|
||||||
{
|
|
||||||
private readonly IMongoDatabase _database;
|
|
||||||
private readonly ILogger<HostService> _logger;
|
|
||||||
|
|
||||||
public HostService(IMongoDatabase database, ILogger<HostService> logger)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<PagedList<HostEntity>> GetAsync(
|
|
||||||
FilterDefinition<HostEntity>? filter = null,
|
|
||||||
SortDefinition<HostEntity>? sort = null,
|
|
||||||
int offset = 0,
|
|
||||||
int limit = 10,
|
|
||||||
CancellationToken cancellationToken = default) => _database.Host().GetPagedAsync(filter, sort, offset, limit, cancellationToken);
|
|
||||||
|
|
||||||
public Task<PagedList<HostEntity>> GetAsync(
|
|
||||||
HttpRequest request,
|
|
||||||
HttpResponse response,
|
|
||||||
FilterDefinition<HostEntity>? filter = null,
|
|
||||||
SortDefinition<HostEntity>? sort = null,
|
|
||||||
int offset = 0,
|
|
||||||
int limit = 10,
|
|
||||||
CancellationToken cancellationToken = default) => _database.Host().GetPagedAsync(request, response, filter, sort, offset, limit, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
@ -5,18 +5,10 @@ using System.Security.Claims;
|
||||||
|
|
||||||
namespace Insight.Infrastructure.Services;
|
namespace Insight.Infrastructure.Services;
|
||||||
|
|
||||||
public class IdentityService
|
public class IdentityService(UserManager<InsightUser> userManager, RoleManager<InsightRole> roleManager)
|
||||||
{
|
{
|
||||||
private readonly UserManager<InsightUser> _userManager;
|
private readonly UserManager<InsightUser> _userManager = userManager;
|
||||||
private readonly RoleManager<InsightRole> _roleManager;
|
private readonly RoleManager<InsightRole> _roleManager = roleManager;
|
||||||
private readonly ILogger<IdentityService> _logger;
|
|
||||||
|
|
||||||
public IdentityService(UserManager<InsightUser> userManager, RoleManager<InsightRole> roleManager, ILogger<IdentityService> logger)
|
|
||||||
{
|
|
||||||
_userManager = userManager;
|
|
||||||
_roleManager = roleManager;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task SeedAsync()
|
public async Task SeedAsync()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
using Insight.Infrastructure.Entities;
|
|
||||||
using Insight.Infrastructure.Models;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using MongoDB.Driver;
|
|
||||||
|
|
||||||
namespace Insight.Infrastructure.Services;
|
|
||||||
|
|
||||||
public class InventoryService
|
|
||||||
{
|
|
||||||
private readonly IMongoDatabase _database;
|
|
||||||
private readonly ILogger<InventoryService> _logger;
|
|
||||||
|
|
||||||
public InventoryService(IMongoDatabase database, ILogger<InventoryService> logger)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<PagedList<HostApplicationEntity>> GetAsync(
|
|
||||||
FilterDefinition<HostApplicationEntity>? filter = null,
|
|
||||||
SortDefinition<HostApplicationEntity>? sort = null,
|
|
||||||
int offset = 0,
|
|
||||||
int limit = 10,
|
|
||||||
CancellationToken cancellationToken = default) => _database.HostApplication().GetPagedAsync(filter, sort, offset, limit, cancellationToken);
|
|
||||||
|
|
||||||
public Task<PagedList<HostApplicationEntity>> GetAsync(
|
|
||||||
HttpRequest request,
|
|
||||||
HttpResponse response,
|
|
||||||
FilterDefinition<HostApplicationEntity>? filter = null,
|
|
||||||
SortDefinition<HostApplicationEntity>? sort = null,
|
|
||||||
int offset = 0,
|
|
||||||
int limit = 10,
|
|
||||||
CancellationToken cancellationToken = default) => _database.HostApplication().GetPagedAsync(request, response, filter, sort, offset, limit, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +1,22 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
<RootNamespace>Insight.Remote.Shared</RootNamespace>
|
<RootNamespace>Insight.Remote.Shared</RootNamespace>
|
||||||
<Product>Insight</Product>
|
<Product>Insight</Product>
|
||||||
<AssemblyName>Insight.Remote.Shared</AssemblyName>
|
<AssemblyName>Insight.Remote.Shared</AssemblyName>
|
||||||
<AssemblyVersion>2023.12.14.0</AssemblyVersion>
|
<AssemblyVersion>2023.12.15.0</AssemblyVersion>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||||
|
<SatelliteResourceLanguages>none</SatelliteResourceLanguages>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.0" />
|
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.0" />
|
||||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="7.0.1" />
|
<PackageReference Include="System.ServiceProcess.ServiceController" Version="8.0.0" />
|
||||||
<PackageReference Include="SkiaSharp.Views.Desktop.Common" Version="2.88.6" />
|
<PackageReference Include="SkiaSharp.Views.Desktop.Common" Version="2.88.6" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,9 @@
|
||||||
|
|
||||||
namespace Insight.Remote.Shared.Models;
|
namespace Insight.Remote.Shared.Models;
|
||||||
|
|
||||||
public class CursorInfo
|
public class CursorInfo(byte[] imageBytes, Point hotspot, string cssOverride = "")
|
||||||
{
|
{
|
||||||
public byte[] ImageBytes { get; set; }
|
public byte[] ImageBytes { get; set; } = imageBytes;
|
||||||
public Point HotSpot { get; set; }
|
public Point HotSpot { get; set; } = hotspot;
|
||||||
public string CssOverride { get; set; }
|
public string CssOverride { get; set; } = cssOverride;
|
||||||
|
|
||||||
public CursorInfo(byte[] imageBytes, Point hotspot, string cssOverride = "")
|
|
||||||
{
|
|
||||||
ImageBytes = imageBytes;
|
|
||||||
HotSpot = hotspot;
|
|
||||||
CssOverride = cssOverride;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,13 +1,7 @@
|
||||||
namespace Insight.Remote.Shared.Models;
|
namespace Insight.Remote.Shared.Models;
|
||||||
|
|
||||||
public readonly struct SentFrame
|
public readonly struct SentFrame(int frameSize, DateTimeOffset timestamp)
|
||||||
{
|
{
|
||||||
public SentFrame(int frameSize, DateTimeOffset timestamp)
|
public DateTimeOffset Timestamp { get; } = timestamp;
|
||||||
{
|
public int FrameSize { get; } = frameSize;
|
||||||
FrameSize = frameSize;
|
|
||||||
Timestamp = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DateTimeOffset Timestamp { get; }
|
|
||||||
public int FrameSize { get; }
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ public static class SECUR32
|
||||||
MaxTokenInfoClass
|
MaxTokenInfoClass
|
||||||
}
|
}
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct QUOTA_LIMITS
|
public readonly struct QUOTA_LIMITS
|
||||||
{
|
{
|
||||||
readonly UInt32 PagedPoolLimit;
|
readonly UInt32 PagedPoolLimit;
|
||||||
readonly UInt32 NonPagedPoolLimit;
|
readonly UInt32 NonPagedPoolLimit;
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,11 @@ using Vaitr.Bus;
|
||||||
|
|
||||||
namespace Insight.Remote.Shared.Network.Handlers;
|
namespace Insight.Remote.Shared.Network.Handlers;
|
||||||
|
|
||||||
public class RemoteHandler : IMessageHandler<RemoteSession>
|
public class RemoteHandler(Bus bus, Streamer streamer, ILogger<RemoteHandler> logger) : IMessageHandler<RemoteSession>
|
||||||
{
|
{
|
||||||
private readonly Bus _bus;
|
private readonly Bus _bus = bus;
|
||||||
private readonly Streamer _streamer;
|
private readonly Streamer _streamer = streamer;
|
||||||
private readonly ILogger<RemoteHandler> _logger;
|
private readonly ILogger<RemoteHandler> _logger = logger;
|
||||||
|
|
||||||
public RemoteHandler(Bus bus, Streamer streamer, ILogger<RemoteHandler> logger)
|
|
||||||
{
|
|
||||||
_bus = bus;
|
|
||||||
_streamer = streamer;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(RemoteSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(RemoteSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -48,16 +41,18 @@ public class RemoteHandler : IMessageHandler<RemoteSession>
|
||||||
|
|
||||||
private async Task OnSessionResponse(RemoteSession session, RemoteSessionResponse sessionResponse, CancellationToken cancellationToken)
|
private async Task OnSessionResponse(RemoteSession session, RemoteSessionResponse sessionResponse, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"Remote {session.Id} => SessionResponse");
|
if (session.Id is not string sessionId) return;
|
||||||
|
|
||||||
|
_logger.LogInformation("Remote {session} => SessionResponse", sessionId);
|
||||||
|
|
||||||
session.Id = sessionResponse.SessionId;
|
session.Id = sessionResponse.SessionId;
|
||||||
|
|
||||||
await _bus.PublishAsync(new IdentityChanged(session.Id));
|
await _bus.PublishAsync(new IdentityChanged(sessionId), cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnCastRequest(RemoteSession session, CastRequest castRequest, CancellationToken cancellationToken)
|
private async Task OnCastRequest(RemoteSession session, CastRequest castRequest, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"Remote {session.Id} => CastRequest");
|
_logger.LogInformation("Remote {session.Id} => CastRequest", session.Id);
|
||||||
|
|
||||||
//if (request.RequesterName is null || request.ConnectionId is null) return;
|
//if (request.RequesterName is null || request.ConnectionId is null) return;
|
||||||
|
|
||||||
|
|
@ -105,7 +100,7 @@ public class RemoteHandler : IMessageHandler<RemoteSession>
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.Message);
|
_logger.LogError("{exception}", ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
//DesktopStream? viewer = _viewerPool.Values.FirstOrDefault(p => p.ConnectionId == request.ConnectionId);
|
//DesktopStream? viewer = _viewerPool.Values.FirstOrDefault(p => p.ConnectionId == request.ConnectionId);
|
||||||
|
|
@ -121,7 +116,7 @@ public class RemoteHandler : IMessageHandler<RemoteSession>
|
||||||
|
|
||||||
private async Task OnCastAbort(RemoteSession session, CastAbort castAbort, CancellationToken cancellationToken)
|
private async Task OnCastAbort(RemoteSession session, CastAbort castAbort, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"Remote {session.Id} => CastAbort");
|
_logger.LogInformation("Remote {session} => CastAbort", session.Id);
|
||||||
|
|
||||||
await _streamer.CancelAsync(castAbort, cancellationToken);
|
await _streamer.CancelAsync(castAbort, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
@ -148,7 +143,7 @@ public class RemoteHandler : IMessageHandler<RemoteSession>
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.ToString());
|
_logger.LogError("{exception}", ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,26 +4,23 @@ using Insight.Domain.Network;
|
||||||
using Insight.Domain.Network.Remote.Messages;
|
using Insight.Domain.Network.Remote.Messages;
|
||||||
using Insight.Remote.Shared.Messages;
|
using Insight.Remote.Shared.Messages;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System.ServiceProcess;
|
|
||||||
using Vaitr.Bus;
|
using Vaitr.Bus;
|
||||||
using Vaitr.Network;
|
using Vaitr.Network;
|
||||||
|
|
||||||
namespace Insight.Remote.Shared.Network;
|
namespace Insight.Remote.Shared.Network;
|
||||||
|
|
||||||
public class RemoteSession : TcpSession<IMessage>
|
public class RemoteSession(
|
||||||
|
Bus bus,
|
||||||
|
IEnumerable<IMessageHandler<RemoteSession>> handlers,
|
||||||
|
ISerializer<IMessage> serializer,
|
||||||
|
ILogger<RemoteSession> logger) : TcpSession<IMessage>(serializer, logger)
|
||||||
{
|
{
|
||||||
public string? Id { get; set; }
|
public string? Id { get; set; }
|
||||||
public string? AccessKey { get; set; }
|
public string? AccessKey { get; set; }
|
||||||
public RemoteControlMode Mode { get; } = RunningAsService() ? RemoteControlMode.Unattended : RemoteControlMode.Attended;
|
public RemoteControlMode Mode { get; } = RunningAsService() ? RemoteControlMode.Unattended : RemoteControlMode.Attended;
|
||||||
|
|
||||||
private readonly Bus _bus;
|
private readonly Bus _bus = bus;
|
||||||
private readonly IEnumerable<IMessageHandler<RemoteSession>> _handlers;
|
private readonly IEnumerable<IMessageHandler<RemoteSession>> _handlers = handlers;
|
||||||
|
|
||||||
public RemoteSession(Bus bus, IEnumerable<IMessageHandler<RemoteSession>> handlers, ISerializer<IMessage> serializer, ILogger<RemoteSession> logger) : base(serializer, logger)
|
|
||||||
{
|
|
||||||
_bus = bus;
|
|
||||||
_handlers = handlers;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async ValueTask OnConnectedAsync(CancellationToken cancellationToken)
|
protected override async ValueTask OnConnectedAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|
@ -45,9 +42,10 @@ public class RemoteSession : TcpSession<IMessage>
|
||||||
await _bus.PublishAsync(new ConnectionStateChanged(ConnectionState.Disconnected));
|
await _bus.PublishAsync(new ConnectionStateChanged(ConnectionState.Disconnected));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async ValueTask OnSentAsync(IPacketContext<IMessage> context, CancellationToken cancellationToken)
|
protected override ValueTask OnSentAsync(IPacketContext<IMessage> context, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
//await base.OnSentAsync(context, cancellationToken);
|
//await base.OnSentAsync(context, cancellationToken);
|
||||||
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async ValueTask OnReceivedAsync(IPacketContext<IMessage> context, CancellationToken cancellationToken)
|
protected override async ValueTask OnReceivedAsync(IPacketContext<IMessage> context, CancellationToken cancellationToken)
|
||||||
|
|
@ -67,12 +65,14 @@ public class RemoteSession : TcpSession<IMessage>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async ValueTask OnHeartbeatAsync(CancellationToken cancellationToken)
|
protected override ValueTask OnHeartbeatAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Remote ({ep?}) Heartbeat", RemoteEndPoint);
|
_logger.LogInformation("Remote ({ep?}) Heartbeat", RemoteEndPoint);
|
||||||
|
|
||||||
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async ValueTask OnWindowsSessionSwitchedAsync(WindowsSessionSwitched message, CancellationToken cancellationToken)
|
private ValueTask OnWindowsSessionSwitchedAsync(WindowsSessionSwitched message, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -80,23 +80,24 @@ public class RemoteSession : TcpSession<IMessage>
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.Message);
|
_logger.LogError("{exception}", ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async ValueTask OnWindowsSessionEndingAsync(WindowsSessionEnding message, CancellationToken cancellationToken)
|
private static ValueTask OnWindowsSessionEndingAsync(WindowsSessionEnding message, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
//await DisconnectViewersAsync();
|
//await DisconnectViewersAsync();
|
||||||
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool RunningAsService()
|
private static bool RunningAsService()
|
||||||
{
|
{
|
||||||
return false;
|
//if (OperatingSystem.IsWindows())
|
||||||
|
//{
|
||||||
if (OperatingSystem.IsWindows())
|
// return ServiceController.GetServices().Any(serviceController => serviceController.ServiceName.Equals("remotecontrol"));
|
||||||
{
|
//}
|
||||||
return ServiceController.GetServices().Any(serviceController => serviceController.ServiceName.Equals("remotecontrol"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ public class Runtime : IHostedService
|
||||||
private readonly CancellationTokenSource _cts = new();
|
private readonly CancellationTokenSource _cts = new();
|
||||||
|
|
||||||
private Task? _desktopTask;
|
private Task? _desktopTask;
|
||||||
private Thread? _uiThread;
|
private readonly Thread? _uiThread;
|
||||||
|
|
||||||
private readonly IDesktopApp _desktopApp;
|
private readonly IDesktopApp _desktopApp;
|
||||||
private readonly IDispatcher _dispatcher;
|
private readonly IDispatcher _dispatcher;
|
||||||
|
|
@ -31,20 +31,21 @@ public class Runtime : IHostedService
|
||||||
_lifetime.ApplicationStopping.Register(_cts.Cancel);
|
_lifetime.ApplicationStopping.Register(_cts.Cancel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StartAsync(CancellationToken cancellationToken)
|
public Task StartAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// init app (os specific providers)
|
// init app (os specific providers)
|
||||||
_desktopTask = _desktopApp.InitAsync(RemoteControlMode.Attended, _cts.Token);
|
_desktopTask = _desktopApp.InitAsync(RemoteControlMode.Attended, _cts.Token);
|
||||||
|
|
||||||
// init dispatcher
|
// init ui dispatcher / if mode is attended (interactive)
|
||||||
if (false) // if mode is attended (interactive)
|
//if (true)
|
||||||
{
|
//{
|
||||||
// init ui thread
|
// _uiThread = await _dispatcher.RunAsync(_cts.Token);
|
||||||
_uiThread = await _dispatcher.RunAsync(_cts.Token);
|
//}
|
||||||
}
|
|
||||||
|
|
||||||
// todo
|
// todo
|
||||||
// report unattended accesskey to api ($"https://localhost:7024?mode=Unattended&sessionId={appState.SessionId}&accessKey={appState.AccessKey}")
|
// report unattended accesskey to api ($"https://localhost:7024?mode=Unattended&sessionId={appState.SessionId}&accessKey={appState.AccessKey}")
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StopAsync(CancellationToken cancellationToken)
|
public async Task StopAsync(CancellationToken cancellationToken)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,16 @@ using Vaitr.Network;
|
||||||
|
|
||||||
namespace Insight.Remote.Shared.Services;
|
namespace Insight.Remote.Shared.Services;
|
||||||
|
|
||||||
public class Streamer : IDisposable
|
public class Streamer(
|
||||||
|
Bus bus,
|
||||||
|
ISessionPool<RemoteSession, IMessage> remotePool,
|
||||||
|
IFileProvider fileProvider,
|
||||||
|
IClipboardProvider clipboardProvider,
|
||||||
|
IAudioProvider audioProvider,
|
||||||
|
IInputProvider inputProvider,
|
||||||
|
ICursorProvider cursorProvider,
|
||||||
|
IScreenProvider screenProvider,
|
||||||
|
ILogger<Streamer> logger) : IDisposable
|
||||||
{
|
{
|
||||||
public int ImageQuality { get; set; } = 50;
|
public int ImageQuality { get; set; } = 50;
|
||||||
public bool HasControl { get; set; } = true;
|
public bool HasControl { get; set; } = true;
|
||||||
|
|
@ -34,37 +43,15 @@ public class Streamer : IDisposable
|
||||||
private readonly ConcurrentQueue<DateTimeOffset> _fpsQueue = new();
|
private readonly ConcurrentQueue<DateTimeOffset> _fpsQueue = new();
|
||||||
private readonly ConcurrentQueue<SentFrame> _sentFrames = new();
|
private readonly ConcurrentQueue<SentFrame> _sentFrames = new();
|
||||||
|
|
||||||
private readonly Bus _bus;
|
private readonly Bus _bus = bus;
|
||||||
private readonly ISessionPool<RemoteSession, IMessage> _remotePool;
|
private readonly ISessionPool<RemoteSession, IMessage> _remotePool = remotePool;
|
||||||
private readonly IFileProvider _fileProvider;
|
private readonly IFileProvider _fileProvider = fileProvider;
|
||||||
private readonly IClipboardProvider _clipboardProvider;
|
private readonly IClipboardProvider _clipboardProvider = clipboardProvider;
|
||||||
private readonly IAudioProvider _audioProvider;
|
private readonly IAudioProvider _audioProvider = audioProvider;
|
||||||
private readonly IInputProvider _inputProvider;
|
private readonly IInputProvider _inputProvider = inputProvider;
|
||||||
private readonly ICursorProvider _cursorProvider;
|
private readonly ICursorProvider _cursorProvider = cursorProvider;
|
||||||
private readonly IScreenProvider _screenProvider;
|
private readonly IScreenProvider _screenProvider = screenProvider;
|
||||||
private readonly ILogger<Streamer> _logger;
|
private readonly ILogger<Streamer> _logger = logger;
|
||||||
|
|
||||||
public Streamer(
|
|
||||||
Bus bus,
|
|
||||||
ISessionPool<RemoteSession, IMessage> remotePool,
|
|
||||||
IFileProvider fileProvider,
|
|
||||||
IClipboardProvider clipboardProvider,
|
|
||||||
IAudioProvider audioProvider,
|
|
||||||
IInputProvider inputProvider,
|
|
||||||
ICursorProvider cursorProvider,
|
|
||||||
IScreenProvider screenProvider,
|
|
||||||
ILogger<Streamer> logger)
|
|
||||||
{
|
|
||||||
_bus = bus;
|
|
||||||
_remotePool = remotePool;
|
|
||||||
_fileProvider = fileProvider;
|
|
||||||
_clipboardProvider = clipboardProvider;
|
|
||||||
_audioProvider = audioProvider;
|
|
||||||
_inputProvider = inputProvider;
|
|
||||||
_cursorProvider = cursorProvider;
|
|
||||||
_screenProvider = screenProvider;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task InitAsync(CastRequest request, CancellationToken cancellationToken)
|
public async Task InitAsync(CastRequest request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|
@ -108,7 +95,7 @@ public class Streamer : IDisposable
|
||||||
catch (OperationCanceledException) { }
|
catch (OperationCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.Message);
|
_logger.LogError("{exception}", ex.Message);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
@ -260,7 +247,7 @@ public class Streamer : IDisposable
|
||||||
{
|
{
|
||||||
var cursor = await _cursorProvider.GetAsync(cancellationToken);
|
var cursor = await _cursorProvider.GetAsync(cancellationToken);
|
||||||
if (cursor is null || cursor == cacheCursor) continue;
|
if (cursor is null || cursor == cacheCursor) continue;
|
||||||
|
|
||||||
cursor.Id = remoteSession.Id;
|
cursor.Id = remoteSession.Id;
|
||||||
|
|
||||||
await remoteSession.SendAsync(cursor, cancellationToken);
|
await remoteSession.SendAsync(cursor, cancellationToken);
|
||||||
|
|
@ -268,7 +255,7 @@ public class Streamer : IDisposable
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
_logger.LogError("{exception}", ex.Message);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
@ -331,15 +318,20 @@ public class Streamer : IDisposable
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public async Task CancelAsync(CastAbort castAbort, CancellationToken cancellationToken)
|
public Task CancelAsync(CastAbort castAbort, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_cts?.Cancel();
|
_cts?.Cancel();
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task FrameReceivedAsync(CastScreenReceived screenDataReceived, CancellationToken cancellationToken)
|
public Task FrameReceivedAsync(CastScreenReceived screenDataReceived, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
if (screenDataReceived.Timestamp is null) return Task.CompletedTask;
|
||||||
|
|
||||||
_lastFrameReceived = screenDataReceived.Timestamp.Value.ToLocalTime();
|
_lastFrameReceived = screenDataReceived.Timestamp.Value.ToLocalTime();
|
||||||
_framesSentSinceLastReceipt = 0;
|
_framesSentSinceLastReceipt = 0;
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CursorReceivedAsync(CastCursorReceived cursorCallbackData, CancellationToken cancellationToken)
|
public async Task CursorReceivedAsync(CastCursorReceived cursorCallbackData, CancellationToken cancellationToken)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net7.0-windows</TargetFramework>
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
<Product>Remote Control</Product>
|
<Product>Remote Control</Product>
|
||||||
|
|
@ -12,10 +13,11 @@
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||||
|
<SatelliteResourceLanguages>none</SatelliteResourceLanguages>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="7.0.1" />
|
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
|
||||||
<PackageReference Include="NAudio.Wasapi" Version="2.2.1" />
|
<PackageReference Include="NAudio.Wasapi" Version="2.2.1" />
|
||||||
<PackageReference Include="SharpDX.Direct3D11" Version="4.2.0" />
|
<PackageReference Include="SharpDX.Direct3D11" Version="4.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -4,28 +4,18 @@ using SharpDX.DXGI;
|
||||||
|
|
||||||
namespace Insight.Remote.Windows.Models;
|
namespace Insight.Remote.Windows.Models;
|
||||||
|
|
||||||
public class DirectXOutput : IDisposable
|
public class DirectXOutput(Adapter1 adapter,
|
||||||
|
SharpDX.Direct3D11.Device device,
|
||||||
|
OutputDuplication outputDuplication,
|
||||||
|
Texture2D texture2D,
|
||||||
|
DisplayModeRotation rotation) : IDisposable
|
||||||
{
|
{
|
||||||
public DirectXOutput(Adapter1 adapter,
|
public Adapter1 Adapter { get; } = adapter;
|
||||||
SharpDX.Direct3D11.Device device,
|
public Rectangle Bounds { get; set; } = new Rectangle(0, 0, texture2D.Description.Width, texture2D.Description.Height);
|
||||||
OutputDuplication outputDuplication,
|
public SharpDX.Direct3D11.Device Device { get; } = device;
|
||||||
Texture2D texture2D,
|
public OutputDuplication OutputDuplication { get; } = outputDuplication;
|
||||||
DisplayModeRotation rotation)
|
public DisplayModeRotation Rotation { get; } = rotation;
|
||||||
{
|
public Texture2D Texture2D { get; } = texture2D;
|
||||||
Adapter = adapter;
|
|
||||||
Device = device;
|
|
||||||
OutputDuplication = outputDuplication;
|
|
||||||
Texture2D = texture2D;
|
|
||||||
Rotation = rotation;
|
|
||||||
Bounds = new Rectangle(0, 0, texture2D.Description.Width, texture2D.Description.Height);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Adapter1 Adapter { get; }
|
|
||||||
public Rectangle Bounds { get; set; }
|
|
||||||
public SharpDX.Direct3D11.Device Device { get; }
|
|
||||||
public OutputDuplication OutputDuplication { get; }
|
|
||||||
public DisplayModeRotation Rotation { get; }
|
|
||||||
public Texture2D Texture2D { get; }
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -9,44 +9,33 @@ using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Windows;
|
using System.Runtime.Versioning;
|
||||||
using Vaitr.Bus;
|
using Vaitr.Bus;
|
||||||
|
|
||||||
namespace Insight.Remote.Windows.Services;
|
namespace Insight.Remote.Windows.Services;
|
||||||
|
|
||||||
internal class WinApp : IDesktopApp
|
[SupportedOSPlatform("windows")]
|
||||||
|
internal class WinApp(
|
||||||
|
IInputProvider inputProvider,
|
||||||
|
ICursorProvider cursorProvider,
|
||||||
|
IAudioProvider audioProvider,
|
||||||
|
IClipboardProvider clipboardProvider,
|
||||||
|
IDispatcher dispatcher,
|
||||||
|
MainViewModel mainViewModel,
|
||||||
|
Bus bus,
|
||||||
|
ILogger<WinApp> logger) : IDesktopApp
|
||||||
{
|
{
|
||||||
private MainWindow? _mainWindow;
|
private MainWindow? _mainWindow;
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
|
||||||
private readonly IInputProvider _inputProvider;
|
private readonly IInputProvider _inputProvider = inputProvider;
|
||||||
private readonly ICursorProvider _cursorProvider;
|
private readonly ICursorProvider _cursorProvider = cursorProvider;
|
||||||
private readonly IAudioProvider _audioProvider;
|
private readonly IAudioProvider _audioProvider = audioProvider;
|
||||||
private readonly IClipboardProvider _clipboardProvider;
|
private readonly IClipboardProvider _clipboardProvider = clipboardProvider;
|
||||||
private readonly IDispatcher _dispatcher;
|
private readonly IDispatcher _dispatcher = dispatcher;
|
||||||
private readonly MainViewModel _maiViewModel;
|
private readonly MainViewModel _maiViewModel = mainViewModel;
|
||||||
private readonly Bus _bus;
|
private readonly Bus _bus = bus;
|
||||||
private readonly ILogger<WinApp> _logger;
|
private readonly ILogger<WinApp> _logger = logger;
|
||||||
|
|
||||||
public WinApp(
|
|
||||||
IInputProvider inputProvider,
|
|
||||||
ICursorProvider cursorProvider,
|
|
||||||
IAudioProvider audioProvider,
|
|
||||||
IClipboardProvider clipboardProvider,
|
|
||||||
IDispatcher dispatcher,
|
|
||||||
MainViewModel mainViewModel,
|
|
||||||
Bus bus,
|
|
||||||
ILogger<WinApp> logger)
|
|
||||||
{
|
|
||||||
_inputProvider = inputProvider;
|
|
||||||
_cursorProvider = cursorProvider;
|
|
||||||
_audioProvider = audioProvider;
|
|
||||||
_clipboardProvider = clipboardProvider;
|
|
||||||
_dispatcher = dispatcher;
|
|
||||||
_maiViewModel = mainViewModel;
|
|
||||||
_bus = bus;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task InitAsync(RemoteControlMode mode, CancellationToken cancellationToken)
|
public async Task InitAsync(RemoteControlMode mode, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|
@ -100,7 +89,7 @@ internal class WinApp : IDesktopApp
|
||||||
catch (TaskCanceledException) { }
|
catch (TaskCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.Message);
|
_logger.LogError("{exception}", ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -143,7 +132,7 @@ internal class WinApp : IDesktopApp
|
||||||
catch (TaskCanceledException) { }
|
catch (TaskCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.Message);
|
_logger.LogError("{exception}", ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -153,26 +142,21 @@ internal class WinApp : IDesktopApp
|
||||||
|
|
||||||
private async ValueTask OnCastRequestAsync(CastRequest request, CancellationToken cancellationToken)
|
private async ValueTask OnCastRequestAsync(CastRequest request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (true) // test
|
// test (bypass)
|
||||||
{
|
//if (request.Mode != RemoteControlMode.Unattended)
|
||||||
await _bus.PublishAsync(new CastRequestDemand(request, true), cancellationToken);
|
//{
|
||||||
return;
|
// var result = await _dispatcher.InvokeAsync(() =>
|
||||||
}
|
// {
|
||||||
|
// return System.Windows.MessageBox.Show($"Accept connection request from {request.RequesterName}?", "Connection Request",
|
||||||
|
// MessageBoxButton.YesNo,
|
||||||
|
// MessageBoxImage.Question);
|
||||||
|
// }, cancellationToken);
|
||||||
|
|
||||||
if (request.Mode != RemoteControlMode.Unattended)
|
// switch (result)
|
||||||
{
|
// {
|
||||||
var result = await _dispatcher.InvokeAsync(() =>
|
// case MessageBoxResult.No: await _bus.PublishAsync(new CastRequestDemand(request, false), cancellationToken); return;
|
||||||
{
|
// }
|
||||||
return System.Windows.MessageBox.Show($"Accept connection request from {request.RequesterName}?", "Connection Request",
|
//}
|
||||||
MessageBoxButton.YesNo,
|
|
||||||
MessageBoxImage.Question);
|
|
||||||
}, cancellationToken);
|
|
||||||
|
|
||||||
switch (result)
|
|
||||||
{
|
|
||||||
case MessageBoxResult.No: await _bus.PublishAsync(new CastRequestDemand(request, false), cancellationToken); return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await _bus.PublishAsync(new CastRequestDemand(request, true), cancellationToken);
|
await _bus.PublishAsync(new CastRequestDemand(request, true), cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,19 +7,13 @@ using Vaitr.Bus;
|
||||||
|
|
||||||
namespace Insight.Remote.Windows.Services;
|
namespace Insight.Remote.Windows.Services;
|
||||||
|
|
||||||
internal class WinAudioProvider : IAudioProvider
|
internal class WinAudioProvider(Bus bus, ILogger<WinAudioProvider> logger) : IAudioProvider
|
||||||
{
|
{
|
||||||
private WasapiLoopbackCapture? _capturer;
|
private WasapiLoopbackCapture? _capturer;
|
||||||
private WaveFormat? _targetFormat;
|
private WaveFormat? _targetFormat;
|
||||||
|
|
||||||
private readonly Bus _bus;
|
private readonly Bus _bus = bus;
|
||||||
private readonly ILogger<WinAudioProvider> _logger;
|
private readonly ILogger<WinAudioProvider> _logger = logger;
|
||||||
|
|
||||||
public WinAudioProvider(Bus bus, ILogger<WinAudioProvider> logger)
|
|
||||||
{
|
|
||||||
_bus = bus;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task InitAsync(CancellationToken cancellationToken)
|
public async Task InitAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,18 +8,12 @@ using Clipboard = System.Windows.Clipboard;
|
||||||
|
|
||||||
namespace Insight.Remote.Windows.Services;
|
namespace Insight.Remote.Windows.Services;
|
||||||
|
|
||||||
internal class WinClipboardProvider : IClipboardProvider
|
internal class WinClipboardProvider(Bus bus, ILogger<WinClipboardProvider> logger) : IClipboardProvider
|
||||||
{
|
{
|
||||||
private readonly ConcurrentQueue<string> _setQueue = new();
|
private readonly ConcurrentQueue<string> _setQueue = new();
|
||||||
|
|
||||||
private readonly Bus _bus;
|
private readonly Bus _bus = bus;
|
||||||
private readonly ILogger<WinClipboardProvider> _logger;
|
private readonly ILogger<WinClipboardProvider> _logger = logger;
|
||||||
|
|
||||||
public WinClipboardProvider(Bus bus, ILogger<WinClipboardProvider> logger)
|
|
||||||
{
|
|
||||||
_bus = bus;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task InitAsync(CancellationToken cancellationToken)
|
public async Task InitAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|
@ -79,7 +73,7 @@ internal class WinClipboardProvider : IClipboardProvider
|
||||||
catch (TaskCanceledException) { }
|
catch (TaskCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.Message);
|
_logger.LogError("{exception}", ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,20 +8,15 @@ using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Insight.Remote.Windows.Services;
|
namespace Insight.Remote.Windows.Services;
|
||||||
|
|
||||||
internal class WinCursorProvider : ICursorProvider
|
internal class WinCursorProvider(ILogger<WinCursorProvider> logger) : ICursorProvider
|
||||||
{
|
{
|
||||||
private readonly SemaphoreSlim _semaphore = new(1, 1);
|
private readonly SemaphoreSlim _semaphore = new(1, 1);
|
||||||
private readonly ILogger<WinCursorProvider> _logger;
|
private readonly ILogger<WinCursorProvider> _logger = logger;
|
||||||
|
|
||||||
private User32.CursorInfo _cursor = new();
|
private User32.CursorInfo _cursor = new();
|
||||||
private CastCursor _lastCursor = new();
|
private CastCursor _lastCursor = new();
|
||||||
private nint _lastHandle = 0;
|
private nint _lastHandle = 0;
|
||||||
private byte[] _lastIconBytes = Array.Empty<byte>();
|
private byte[] _lastIconBytes = [];
|
||||||
|
|
||||||
public WinCursorProvider(ILogger<WinCursorProvider> logger)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<CastCursor?> GetAsync(CancellationToken cancellationToken)
|
public async Task<CastCursor?> GetAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|
@ -73,7 +68,7 @@ internal class WinCursorProvider : ICursorProvider
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.Message);
|
_logger.LogError("{exception}", ex.Message);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
@ -92,10 +87,10 @@ internal class WinCursorProvider : ICursorProvider
|
||||||
|
|
||||||
User32.SetCursorPos(x, y);
|
User32.SetCursorPos(x, y);
|
||||||
}
|
}
|
||||||
catch (TaskCanceledException) { }
|
catch (OperationCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.Message);
|
_logger.LogError("{exception}", ex.Message);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
@ -107,6 +102,6 @@ internal class WinCursorProvider : ICursorProvider
|
||||||
{
|
{
|
||||||
X = 0,
|
X = 0,
|
||||||
Y = 0,
|
Y = 0,
|
||||||
Icon = Array.Empty<byte>()
|
Icon = []
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -6,20 +6,14 @@ using Application = System.Windows.Application;
|
||||||
|
|
||||||
namespace Insight.Remote.Windows.Services;
|
namespace Insight.Remote.Windows.Services;
|
||||||
|
|
||||||
internal class WinDispatcher : IDispatcher
|
internal class WinDispatcher(IHostApplicationLifetime lifetime, ILogger<WinDispatcher> logger) : IDispatcher
|
||||||
{
|
{
|
||||||
private Application? _app;
|
private Application? _app;
|
||||||
|
|
||||||
private readonly ManualResetEvent _appSignal = new(false);
|
private readonly ManualResetEvent _appSignal = new(false);
|
||||||
|
|
||||||
private readonly IHostApplicationLifetime _lifetime;
|
private readonly IHostApplicationLifetime _lifetime = lifetime;
|
||||||
private readonly ILogger<WinDispatcher> _logger;
|
private readonly ILogger<WinDispatcher> _logger = logger;
|
||||||
|
|
||||||
public WinDispatcher(IHostApplicationLifetime lifetime, ILogger<WinDispatcher> logger)
|
|
||||||
{
|
|
||||||
_lifetime = lifetime;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Thread> RunAsync(CancellationToken cancellationToken)
|
public async Task<Thread> RunAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|
@ -56,7 +50,7 @@ internal class WinDispatcher : IDispatcher
|
||||||
catch (TaskCanceledException) { }
|
catch (TaskCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.Message);
|
_logger.LogError("{exception}", ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Runtime.Versioning;
|
||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
|
@ -12,17 +13,13 @@ using MessageBoxOptions = System.Windows.MessageBoxOptions;
|
||||||
|
|
||||||
namespace Insight.Remote.Windows.Services;
|
namespace Insight.Remote.Windows.Services;
|
||||||
|
|
||||||
internal class WinFileProvider : IFileProvider
|
[SupportedOSPlatform("windows")]
|
||||||
|
internal class WinFileProvider(ILogger<WinFileProvider> logger) : IFileProvider
|
||||||
{
|
{
|
||||||
private static MessageBoxResult? _result;
|
private static MessageBoxResult? _result;
|
||||||
private static readonly ConcurrentDictionary<string, FileStream> _partialTransfers = new();
|
private static readonly ConcurrentDictionary<string, FileStream> _partialTransfers = new();
|
||||||
private static readonly SemaphoreSlim _writeLock = new(1, 1);
|
private static readonly SemaphoreSlim _writeLock = new(1, 1);
|
||||||
private readonly ILogger<WinFileProvider> _logger;
|
private readonly ILogger<WinFileProvider> _logger = logger;
|
||||||
|
|
||||||
public WinFileProvider(ILogger<WinFileProvider> logger)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetBaseDirectory()
|
public string GetBaseDirectory()
|
||||||
{
|
{
|
||||||
|
|
@ -89,7 +86,7 @@ internal class WinFileProvider : IFileProvider
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UploadFile(FileUpload fileUpload, Streamer viewer, Action<double> progressUpdateCallback, CancellationToken cancelToken)
|
public Task UploadFile(FileUpload fileUpload, Streamer viewer, Action<double> progressUpdateCallback, CancellationToken cancelToken)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -99,9 +96,11 @@ internal class WinFileProvider : IFileProvider
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Error while uploading file.");
|
_logger.LogError(ex, "Error while uploading file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetFileOrFolderPermissions(string path)
|
private static void SetFileOrFolderPermissions(string path)
|
||||||
{
|
{
|
||||||
FileSystemSecurity ds;
|
FileSystemSecurity ds;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,20 +6,14 @@ using System.Threading.Channels;
|
||||||
|
|
||||||
namespace Insight.Remote.Windows.Services;
|
namespace Insight.Remote.Windows.Services;
|
||||||
|
|
||||||
internal class WinInputProvider : IInputProvider
|
internal class WinInputProvider(IScreenProvider screenProvider, ILogger<WinInputProvider> logger) : IInputProvider
|
||||||
{
|
{
|
||||||
private volatile bool _inputBlocked;
|
private volatile bool _inputBlocked;
|
||||||
|
|
||||||
private readonly Channel<Action> _inputs = Channel.CreateUnbounded<Action>(new UnboundedChannelOptions { AllowSynchronousContinuations = false });
|
private readonly Channel<Action> _inputs = Channel.CreateUnbounded<Action>(new UnboundedChannelOptions { AllowSynchronousContinuations = false });
|
||||||
|
|
||||||
private readonly IScreenProvider _screenProvider;
|
private readonly IScreenProvider _screenProvider = screenProvider;
|
||||||
private readonly ILogger<WinInputProvider> _logger;
|
private readonly ILogger<WinInputProvider> _logger = logger;
|
||||||
|
|
||||||
public WinInputProvider(IScreenProvider screenProvider, ILogger<WinInputProvider> logger)
|
|
||||||
{
|
|
||||||
_screenProvider = screenProvider;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task InitAsync(CancellationToken cancellationToken)
|
public async Task InitAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|
@ -31,10 +25,10 @@ internal class WinInputProvider : IInputProvider
|
||||||
await Task.Delay(1000, cancellationToken);
|
await Task.Delay(1000, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (TaskCanceledException) { }
|
catch (OperationCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.ToString());
|
_logger.LogError("{exception}", ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,7 +62,7 @@ internal class WinInputProvider : IInputProvider
|
||||||
catch (OperationCanceledException) { }
|
catch (OperationCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.Message);
|
_logger.LogError("{exception}", ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,10 +77,10 @@ internal class WinInputProvider : IInputProvider
|
||||||
{
|
{
|
||||||
await semaphore.WaitAsync(cancellationToken);
|
await semaphore.WaitAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
catch (TaskCanceledException) { }
|
catch (OperationCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.ToString());
|
_logger.LogError("{exception}", ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,13 +104,13 @@ internal class WinInputProvider : IInputProvider
|
||||||
};
|
};
|
||||||
|
|
||||||
var input = new User32.INPUT() { type = User32.InputType.KEYBOARD, U = union };
|
var input = new User32.INPUT() { type = User32.InputType.KEYBOARD, U = union };
|
||||||
_ = User32.SendInput(1, new User32.INPUT[] { input }, User32.INPUT.Size);
|
_ = User32.SendInput(1, [input], User32.INPUT.Size);
|
||||||
}, cancellationToken);
|
}, cancellationToken);
|
||||||
}
|
}
|
||||||
catch (TaskCanceledException) { }
|
catch (OperationCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.ToString());
|
_logger.LogError("{exception}", ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,13 +134,13 @@ internal class WinInputProvider : IInputProvider
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var input = new User32.INPUT() { type = User32.InputType.KEYBOARD, U = union };
|
var input = new User32.INPUT() { type = User32.InputType.KEYBOARD, U = union };
|
||||||
_ = User32.SendInput(1, new User32.INPUT[] { input }, User32.INPUT.Size);
|
_ = User32.SendInput(1, [input], User32.INPUT.Size);
|
||||||
}, cancellationToken);
|
}, cancellationToken);
|
||||||
}
|
}
|
||||||
catch (TaskCanceledException) { }
|
catch (OperationCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.ToString());
|
_logger.LogError("{exception}", ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -209,13 +203,13 @@ internal class WinInputProvider : IInputProvider
|
||||||
var normalizedY = xyPercent.Item2 * 65535D;
|
var normalizedY = xyPercent.Item2 * 65535D;
|
||||||
var union = new User32.InputUnion() { mi = new User32.MOUSEINPUT() { dwFlags = User32.MOUSEEVENTF.ABSOLUTE | mouseEvent | User32.MOUSEEVENTF.VIRTUALDESK, dx = (int)normalizedX, dy = (int)normalizedY, time = 0, mouseData = 0, dwExtraInfo = User32.GetMessageExtraInfo() } };
|
var union = new User32.InputUnion() { mi = new User32.MOUSEINPUT() { dwFlags = User32.MOUSEEVENTF.ABSOLUTE | mouseEvent | User32.MOUSEEVENTF.VIRTUALDESK, dx = (int)normalizedX, dy = (int)normalizedY, time = 0, mouseData = 0, dwExtraInfo = User32.GetMessageExtraInfo() } };
|
||||||
var input = new User32.INPUT() { type = User32.InputType.MOUSE, U = union };
|
var input = new User32.INPUT() { type = User32.InputType.MOUSE, U = union };
|
||||||
_ = User32.SendInput(1, new User32.INPUT[] { input }, User32.INPUT.Size);
|
_ = User32.SendInput(1, [input], User32.INPUT.Size);
|
||||||
}, cancellationToken);
|
}, cancellationToken);
|
||||||
}
|
}
|
||||||
catch (TaskCanceledException) { }
|
catch (OperationCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.ToString());
|
_logger.LogError("{exception}", ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -231,13 +225,13 @@ internal class WinInputProvider : IInputProvider
|
||||||
var normalizedY = xyPercent.Item2 * 65535D;
|
var normalizedY = xyPercent.Item2 * 65535D;
|
||||||
var union = new User32.InputUnion() { mi = new User32.MOUSEINPUT() { dwFlags = User32.MOUSEEVENTF.ABSOLUTE | User32.MOUSEEVENTF.MOVE | User32.MOUSEEVENTF.VIRTUALDESK, dx = (int)normalizedX, dy = (int)normalizedY, time = 0, mouseData = 0, dwExtraInfo = User32.GetMessageExtraInfo() } };
|
var union = new User32.InputUnion() { mi = new User32.MOUSEINPUT() { dwFlags = User32.MOUSEEVENTF.ABSOLUTE | User32.MOUSEEVENTF.MOVE | User32.MOUSEEVENTF.VIRTUALDESK, dx = (int)normalizedX, dy = (int)normalizedY, time = 0, mouseData = 0, dwExtraInfo = User32.GetMessageExtraInfo() } };
|
||||||
var input = new User32.INPUT() { type = User32.InputType.MOUSE, U = union };
|
var input = new User32.INPUT() { type = User32.InputType.MOUSE, U = union };
|
||||||
_ = User32.SendInput(1, new User32.INPUT[] { input }, User32.INPUT.Size);
|
_ = User32.SendInput(1, [input], User32.INPUT.Size);
|
||||||
}, cancellationToken);
|
}, cancellationToken);
|
||||||
}
|
}
|
||||||
catch (TaskCanceledException) { }
|
catch (OperationCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.ToString());
|
_logger.LogError("{exception}", ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,13 +251,13 @@ internal class WinInputProvider : IInputProvider
|
||||||
}
|
}
|
||||||
var union = new User32.InputUnion() { mi = new User32.MOUSEINPUT() { dwFlags = User32.MOUSEEVENTF.WHEEL, dx = 0, dy = 0, time = 0, mouseData = deltaY, dwExtraInfo = User32.GetMessageExtraInfo() } };
|
var union = new User32.InputUnion() { mi = new User32.MOUSEINPUT() { dwFlags = User32.MOUSEEVENTF.WHEEL, dx = 0, dy = 0, time = 0, mouseData = deltaY, dwExtraInfo = User32.GetMessageExtraInfo() } };
|
||||||
var input = new User32.INPUT() { type = User32.InputType.MOUSE, U = union };
|
var input = new User32.INPUT() { type = User32.InputType.MOUSE, U = union };
|
||||||
_ = User32.SendInput(1, new User32.INPUT[] { input }, User32.INPUT.Size);
|
_ = User32.SendInput(1, [input], User32.INPUT.Size);
|
||||||
}, cancellationToken);
|
}, cancellationToken);
|
||||||
}
|
}
|
||||||
catch (TaskCanceledException) { }
|
catch (OperationCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.ToString());
|
_logger.LogError("{exception}", ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -276,10 +270,10 @@ internal class WinInputProvider : IInputProvider
|
||||||
SendKeys.SendWait(transferText);
|
SendKeys.SendWait(transferText);
|
||||||
}, cancellationToken);
|
}, cancellationToken);
|
||||||
}
|
}
|
||||||
catch (TaskCanceledException) { }
|
catch (OperationCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.ToString());
|
_logger.LogError("{exception}", ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -308,7 +302,7 @@ internal class WinInputProvider : IInputProvider
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var input = new User32.INPUT() { type = User32.InputType.KEYBOARD, U = union };
|
var input = new User32.INPUT() { type = User32.InputType.KEYBOARD, U = union };
|
||||||
_ = User32.SendInput(1, new User32.INPUT[] { input }, User32.INPUT.Size);
|
_ = User32.SendInput(1, [input], User32.INPUT.Size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
@ -318,7 +312,7 @@ internal class WinInputProvider : IInputProvider
|
||||||
catch (TaskCanceledException) { }
|
catch (TaskCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.ToString());
|
_logger.LogError("{exception}", ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -337,7 +331,7 @@ internal class WinInputProvider : IInputProvider
|
||||||
catch (TaskCanceledException) { }
|
catch (TaskCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex.ToString());
|
_logger.LogError("{exception}", ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,13 @@ using SkiaSharp.Views.Desktop;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.Versioning;
|
||||||
using Vaitr.Bus;
|
using Vaitr.Bus;
|
||||||
using Result = RemoteControl.Shared.Result;
|
using Result = RemoteControl.Shared.Result;
|
||||||
|
|
||||||
namespace Insight.Remote.Windows.Services;
|
namespace Insight.Remote.Windows.Services;
|
||||||
|
|
||||||
|
[SupportedOSPlatform("windows")]
|
||||||
internal class WinScreenCapturer : IScreenProvider
|
internal class WinScreenCapturer : IScreenProvider
|
||||||
{
|
{
|
||||||
public event EventHandler<Rectangle>? ScreenChanged;
|
public event EventHandler<Rectangle>? ScreenChanged;
|
||||||
|
|
@ -72,8 +74,8 @@ internal class WinScreenCapturer : IScreenProvider
|
||||||
private bool _initialized;
|
private bool _initialized;
|
||||||
|
|
||||||
private readonly SemaphoreSlim _semaphore = new(1, 1);
|
private readonly SemaphoreSlim _semaphore = new(1, 1);
|
||||||
private readonly Dictionary<string, int> _bitBltScreens = new();
|
private readonly Dictionary<string, int> _bitBltScreens = [];
|
||||||
private readonly Dictionary<string, DirectXOutput> _directxScreens = new();
|
private readonly Dictionary<string, DirectXOutput> _directxScreens = [];
|
||||||
|
|
||||||
private readonly Bus _bus;
|
private readonly Bus _bus;
|
||||||
private readonly ILogger<WinScreenCapturer> _logger;
|
private readonly ILogger<WinScreenCapturer> _logger;
|
||||||
|
|
@ -86,7 +88,7 @@ internal class WinScreenCapturer : IScreenProvider
|
||||||
SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
|
SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task InitAsync(CancellationToken cancellationToken)
|
public Task InitAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Win32Interop.SwitchToInputDesktop();
|
Win32Interop.SwitchToInputDesktop();
|
||||||
|
|
||||||
|
|
@ -94,6 +96,8 @@ internal class WinScreenCapturer : IScreenProvider
|
||||||
InitDirectX();
|
InitDirectX();
|
||||||
|
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetSelectedScreen(string displayName)
|
public void SetSelectedScreen(string displayName)
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,7 @@
|
||||||
using Insight.Remote.Shared.Messages;
|
using Insight.Remote.Shared.Messages;
|
||||||
using Insight.Remote.Shared.Native.Windows;
|
using Insight.Remote.Shared.Native.Windows;
|
||||||
using Insight.Remote.Shared.Reactive;
|
using Insight.Remote.Shared.Reactive;
|
||||||
using Insight.Remote.Shared.Services;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using Vaitr.Bus;
|
using Vaitr.Bus;
|
||||||
|
|
@ -28,7 +26,7 @@ public class MainViewModel : ViewModelBase
|
||||||
|
|
||||||
private string? _lastId;
|
private string? _lastId;
|
||||||
|
|
||||||
private readonly List<IDisposable> _subscriptions = new();
|
private readonly List<IDisposable> _subscriptions = [];
|
||||||
|
|
||||||
private readonly Bus _bus;
|
private readonly Bus _bus;
|
||||||
private readonly IDispatcher _dispatcher;
|
private readonly IDispatcher _dispatcher;
|
||||||
|
|
@ -152,6 +150,6 @@ public class FakeMainViewModel : ViewModelBase
|
||||||
public RelayCommand ElevateToAdminCommand { get; } = new(() => { });
|
public RelayCommand ElevateToAdminCommand { get; } = new(() => { });
|
||||||
public RelayCommand ElevateToServiceCommand { get; } = new(() => { });
|
public RelayCommand ElevateToServiceCommand { get; } = new(() => { });
|
||||||
|
|
||||||
public bool IsAdministrator => false;
|
public static bool IsAdministrator => false;
|
||||||
public string StatusMessage { get; set; } = "test";
|
public string StatusMessage { get; set; } = "test";
|
||||||
}
|
}
|
||||||
|
|
@ -25,7 +25,7 @@ public partial class MainWindow : Window
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (DesignerProperties.GetIsInDesignMode(this)) return;
|
if (DesignerProperties.GetIsInDesignMode(this)) return;
|
||||||
if (DataContext is not MainViewModel vm) return;
|
if (DataContext is not MainViewModel) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_Closing(object sender, CancelEventArgs e)
|
private void Window_Closing(object sender, CancelEventArgs e)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ public static class Async
|
||||||
this IAsyncEnumerable<T> source,
|
this IAsyncEnumerable<T> source,
|
||||||
Func<T, Task> body,
|
Func<T, Task> body,
|
||||||
int maxDegreeOfParallelism = DataflowBlockOptions.Unbounded,
|
int maxDegreeOfParallelism = DataflowBlockOptions.Unbounded,
|
||||||
TaskScheduler scheduler = null)
|
TaskScheduler? scheduler = null)
|
||||||
{
|
{
|
||||||
var options = new ExecutionDataflowBlockOptions
|
var options = new ExecutionDataflowBlockOptions
|
||||||
{
|
{
|
||||||
|
|
@ -31,7 +31,7 @@ public static class Async
|
||||||
this IEnumerable<T> source,
|
this IEnumerable<T> source,
|
||||||
Func<T, Task> body,
|
Func<T, Task> body,
|
||||||
int maxDegreeOfParallelism = DataflowBlockOptions.Unbounded,
|
int maxDegreeOfParallelism = DataflowBlockOptions.Unbounded,
|
||||||
TaskScheduler scheduler = null)
|
TaskScheduler? scheduler = null)
|
||||||
{
|
{
|
||||||
var options = new ExecutionDataflowBlockOptions
|
var options = new ExecutionDataflowBlockOptions
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,15 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
<Product>Insight</Product>
|
<Product>Insight</Product>
|
||||||
<AssemblyName>server</AssemblyName>
|
<AssemblyName>server</AssemblyName>
|
||||||
<AssemblyVersion>2023.12.14.0</AssemblyVersion>
|
<AssemblyVersion>2023.12.14.0</AssemblyVersion>
|
||||||
<RootNamespace>Insight.Server</RootNamespace>
|
<RootNamespace>Insight.Server</RootNamespace>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<SatelliteResourceLanguages>none</SatelliteResourceLanguages>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
|
@ -38,8 +40,8 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="7.0.1" />
|
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
|
||||||
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
|
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
|
||||||
<!--Unix Serilog stuff-->
|
<!--Unix Serilog stuff-->
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -7,18 +7,16 @@ using Vaitr.Network;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent;
|
namespace Insight.Server.Network.Agent;
|
||||||
|
|
||||||
public class AgentSession : TcpSession<IMessage>
|
public class AgentSession(
|
||||||
|
AgentHandler agentHandler,
|
||||||
|
IEnumerable<IMessageHandler<AgentSession>> handlers,
|
||||||
|
ISerializer<IMessage> serializer,
|
||||||
|
ILogger<AgentSession> logger) : TcpSession<IMessage>(serializer, logger)
|
||||||
{
|
{
|
||||||
public string? Id { get; set; }
|
public string? Id { get; set; }
|
||||||
|
|
||||||
private readonly AgentHandler _agentHandler;
|
private readonly AgentHandler _agentHandler = agentHandler;
|
||||||
private readonly IEnumerable<IMessageHandler<AgentSession>> _handlers;
|
private readonly IEnumerable<IMessageHandler<AgentSession>> _handlers = handlers;
|
||||||
|
|
||||||
public AgentSession(AgentHandler agentHandler, IEnumerable<IMessageHandler<AgentSession>> handlers, ISerializer<IMessage> serializer, ILogger<AgentSession> logger) : base(serializer, logger)
|
|
||||||
{
|
|
||||||
_agentHandler = agentHandler;
|
|
||||||
_handlers = handlers;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async ValueTask OnConnectedAsync(CancellationToken cancellationToken)
|
protected override async ValueTask OnConnectedAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,10 @@ using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent.Handlers;
|
namespace Insight.Server.Network.Agent.Handlers;
|
||||||
|
|
||||||
public class AgentHandler : IMessageHandler<AgentSession>
|
public class AgentHandler(IMongoDatabase database, ILogger<AgentHandler> logger) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly IMongoDatabase _database;
|
private readonly IMongoDatabase _database = database;
|
||||||
private readonly ILogger<AgentHandler> _logger;
|
private readonly ILogger<AgentHandler> _logger = logger;
|
||||||
|
|
||||||
public AgentHandler(IMongoDatabase database, ILogger<AgentHandler> logger)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,9 @@ using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent.Handlers;
|
namespace Insight.Server.Network.Agent.Handlers;
|
||||||
|
|
||||||
public class CustomHandler : IMessageHandler<AgentSession>
|
public class CustomHandler(ILogger<CustomHandler> logger) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly ILogger<CustomHandler> _logger;
|
private readonly ILogger<CustomHandler> _logger = logger;
|
||||||
|
|
||||||
public CustomHandler(ILogger<CustomHandler> logger)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -24,8 +19,9 @@ public class CustomHandler : IMessageHandler<AgentSession>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async ValueTask OnResponseAsync(AgentSession sender, Response response, CancellationToken cancellationToken)
|
private ValueTask OnResponseAsync(AgentSession sender, Response response, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_logger.LogWarning($"Response: {response.ResponseData}");
|
_logger.LogWarning("Response: {response}", response.ResponseData);
|
||||||
|
return default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -7,14 +7,9 @@ using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent.Handlers;
|
namespace Insight.Server.Network.Agent.Handlers;
|
||||||
|
|
||||||
public class DriveHandler : IMessageHandler<AgentSession>
|
public class DriveHandler(IMongoDatabase database) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly IMongoDatabase _database;
|
private readonly IMongoDatabase _database = database;
|
||||||
|
|
||||||
public DriveHandler(IMongoDatabase database)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +34,7 @@ public class DriveHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
var driveBulk = new List<WriteModel<HostDriveEntity>>();
|
var driveBulk = new List<WriteModel<HostDriveEntity>>();
|
||||||
|
|
||||||
if (drives is not null && drives.Any())
|
if (drives is not null && drives.Count != 0)
|
||||||
{
|
{
|
||||||
foreach (var drive in drives)
|
foreach (var drive in drives)
|
||||||
{
|
{
|
||||||
|
|
@ -83,16 +78,16 @@ public class DriveHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
var volumeBulk = new List<WriteModel<HostVolumeEntity>>();
|
var volumeBulk = new List<WriteModel<HostVolumeEntity>>();
|
||||||
|
|
||||||
if (drives is not null && drives.Any())
|
if (drives is not null && drives.Count != 0)
|
||||||
{
|
{
|
||||||
foreach (var drive in drives)
|
foreach (var drive in drives)
|
||||||
{
|
{
|
||||||
var driveId = await _database.HostDrive()
|
var driveId = await _database.HostDrive()
|
||||||
.Find(p => p.Host == hostEntity.Id && p.Index == drive.Index)
|
.Find(p => p.Host == hostEntity.Id && p.Index == drive.Index)
|
||||||
.Project(p => p.Id)
|
.Project(p => p.Id)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync(cancellationToken: default);
|
||||||
|
|
||||||
if (drive.Volumes is not null && drive.Volumes.Any())
|
if (drive.Volumes is not null && drive.Volumes.Count != 0)
|
||||||
{
|
{
|
||||||
foreach (var volume in drive.Volumes)
|
foreach (var volume in drive.Volumes)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,22 +3,14 @@ using Insight.Domain.Interfaces;
|
||||||
using Insight.Domain.Network;
|
using Insight.Domain.Network;
|
||||||
using Insight.Domain.Network.Agent.Messages;
|
using Insight.Domain.Network.Agent.Messages;
|
||||||
using Insight.Infrastructure.Entities;
|
using Insight.Infrastructure.Entities;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using MongoDB.Driver;
|
using MongoDB.Driver;
|
||||||
using static Insight.Domain.Network.Agent.Messages.Event;
|
using static Insight.Domain.Network.Agent.Messages.Event;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent.Handlers;
|
namespace Insight.Server.Network.Agent.Handlers;
|
||||||
|
|
||||||
public class EventHandler : IMessageHandler<AgentSession>
|
public class EventHandler(IMongoDatabase database) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly IMongoDatabase _database;
|
private readonly IMongoDatabase _database = database;
|
||||||
private readonly ILogger<EventHandler> _logger;
|
|
||||||
|
|
||||||
public EventHandler(IMongoDatabase database, ILogger<EventHandler> logger)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -75,13 +67,13 @@ public class EventHandler : IMessageHandler<AgentSession>
|
||||||
_ => null
|
_ => null
|
||||||
};
|
};
|
||||||
|
|
||||||
CategoryEnum? category = @event.Category.ToLower() switch
|
CategoryEnum? category = @event.Category?.ToLower() switch
|
||||||
{
|
{
|
||||||
"network" => CategoryEnum.Network,
|
"network" => CategoryEnum.Network,
|
||||||
"application" => CategoryEnum.Application,
|
"application" => CategoryEnum.Application,
|
||||||
"security" => CategoryEnum.Security,
|
"security" => CategoryEnum.Security,
|
||||||
"system" => CategoryEnum.System,
|
"system" => CategoryEnum.System,
|
||||||
_ => null
|
_ => CategoryEnum.None
|
||||||
};
|
};
|
||||||
|
|
||||||
var date = DateTime.Now;
|
var date = DateTime.Now;
|
||||||
|
|
@ -114,55 +106,59 @@ public class EventHandler : IMessageHandler<AgentSession>
|
||||||
_ => null
|
_ => null
|
||||||
};
|
};
|
||||||
|
|
||||||
CategoryEnum? category = null;
|
var category = CategoryEnum.None;
|
||||||
switch (@event.Category)
|
|
||||||
|
if (@event.Category is not null)
|
||||||
{
|
{
|
||||||
case var _ when @event.Category.Contains("network", StringComparison.InvariantCultureIgnoreCase):
|
switch (@event.Category)
|
||||||
category = CategoryEnum.Network;
|
{
|
||||||
break;
|
case var _ when @event.Category.Contains("network", StringComparison.InvariantCultureIgnoreCase):
|
||||||
|
category = CategoryEnum.Network;
|
||||||
|
break;
|
||||||
|
|
||||||
case var _ when @event.Category.Contains("application", StringComparison.InvariantCultureIgnoreCase):
|
case var _ when @event.Category.Contains("application", StringComparison.InvariantCultureIgnoreCase):
|
||||||
category = CategoryEnum.Application;
|
category = CategoryEnum.Application;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case var _ when @event.Category.Contains("security", StringComparison.InvariantCultureIgnoreCase):
|
case var _ when @event.Category.Contains("security", StringComparison.InvariantCultureIgnoreCase):
|
||||||
category = CategoryEnum.Security;
|
category = CategoryEnum.Security;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case var _ when @event.Category.Contains("system", StringComparison.InvariantCultureIgnoreCase):
|
case var _ when @event.Category.Contains("system", StringComparison.InvariantCultureIgnoreCase):
|
||||||
category = CategoryEnum.System;
|
category = CategoryEnum.System;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case var _ when @event.Category.Contains("printservice", StringComparison.InvariantCultureIgnoreCase):
|
case var _ when @event.Category.Contains("printservice", StringComparison.InvariantCultureIgnoreCase):
|
||||||
category = CategoryEnum.Printer;
|
category = CategoryEnum.Printer;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case var _ when @event.Category.Contains("taskscheduler", StringComparison.InvariantCultureIgnoreCase):
|
case var _ when @event.Category.Contains("taskscheduler", StringComparison.InvariantCultureIgnoreCase):
|
||||||
category = CategoryEnum.Task;
|
category = CategoryEnum.Task;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case var _ when @event.Category.Contains("terminalservices", StringComparison.InvariantCultureIgnoreCase):
|
case var _ when @event.Category.Contains("terminalservices", StringComparison.InvariantCultureIgnoreCase):
|
||||||
category = CategoryEnum.RDP;
|
category = CategoryEnum.RDP;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case var _ when @event.Category.Contains("smbclient", StringComparison.InvariantCultureIgnoreCase):
|
case var _ when @event.Category.Contains("smbclient", StringComparison.InvariantCultureIgnoreCase):
|
||||||
category = CategoryEnum.Network;
|
category = CategoryEnum.Network;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case var _ when @event.Category.Contains("smbserver", StringComparison.InvariantCultureIgnoreCase):
|
case var _ when @event.Category.Contains("smbserver", StringComparison.InvariantCultureIgnoreCase):
|
||||||
category = CategoryEnum.Network;
|
category = CategoryEnum.Network;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case var _ when @event.Category.Contains("storagespaces", StringComparison.InvariantCultureIgnoreCase):
|
case var _ when @event.Category.Contains("storagespaces", StringComparison.InvariantCultureIgnoreCase):
|
||||||
category = CategoryEnum.System;
|
category = CategoryEnum.System;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case var _ when @event.Category.Contains("diagnostics", StringComparison.InvariantCultureIgnoreCase):
|
case var _ when @event.Category.Contains("diagnostics", StringComparison.InvariantCultureIgnoreCase):
|
||||||
category = CategoryEnum.System;
|
category = CategoryEnum.System;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var date = DateTime.Now;
|
var date = DateTime.Now;
|
||||||
|
|
@ -175,7 +171,7 @@ public class EventHandler : IMessageHandler<AgentSession>
|
||||||
EventId = @event.EventId.ToString(),
|
EventId = @event.EventId.ToString(),
|
||||||
Status = status.ToString(),
|
Status = status.ToString(),
|
||||||
Source = @event.Source,
|
Source = @event.Source,
|
||||||
Category = category?.ToString(),
|
Category = category.ToString(),
|
||||||
Message = @event.Message
|
Message = @event.Message
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -183,7 +179,7 @@ public class EventHandler : IMessageHandler<AgentSession>
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool FilterEventId(Event @event)
|
private static bool FilterEventId(Event @event)
|
||||||
{
|
{
|
||||||
var filter = new List<int>
|
var filter = new List<int>
|
||||||
{
|
{
|
||||||
|
|
@ -234,10 +230,8 @@ public class EventHandler : IMessageHandler<AgentSession>
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool FilterMonitoringHostLog(HostLogEntity hostLog)
|
private static bool FilterMonitoringHostLog(HostLogEntity hostLog)
|
||||||
{
|
{
|
||||||
//_logger.LogDebug($"try filter event: {hostLog.Category}.{hostLog.Source}.{hostLog.Status}");
|
|
||||||
|
|
||||||
if (Enum.TryParse(hostLog.Status, out StatusType status) is false) return true;
|
if (Enum.TryParse(hostLog.Status, out StatusType status) is false) return true;
|
||||||
|
|
||||||
if (hostLog.Category == CategoryEnum.System.ToString())
|
if (hostLog.Category == CategoryEnum.System.ToString())
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,9 @@ using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent.Handlers;
|
namespace Insight.Server.Network.Agent.Handlers;
|
||||||
|
|
||||||
public class InterfaceHandler : IMessageHandler<AgentSession>
|
public class InterfaceHandler(IMongoDatabase database) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly IMongoDatabase _database;
|
private readonly IMongoDatabase _database = database;
|
||||||
|
|
||||||
public InterfaceHandler(IMongoDatabase database)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +34,7 @@ public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
// interfaces
|
// interfaces
|
||||||
|
|
||||||
if (interfaces is not null && interfaces.Any())
|
if (interfaces is not null && interfaces.Count != 0)
|
||||||
{
|
{
|
||||||
var interfaceBulk = new List<WriteModel<HostInterfaceEntity>>();
|
var interfaceBulk = new List<WriteModel<HostInterfaceEntity>>();
|
||||||
|
|
||||||
|
|
@ -95,7 +90,7 @@ public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
// addresses
|
// addresses
|
||||||
|
|
||||||
if (interfaces is not null && interfaces.Any())
|
if (interfaces is not null && interfaces.Count != 0)
|
||||||
{
|
{
|
||||||
var addressBulk = new List<WriteModel<HostInterfaceAddressEntity>>();
|
var addressBulk = new List<WriteModel<HostInterfaceAddressEntity>>();
|
||||||
|
|
||||||
|
|
@ -104,9 +99,9 @@ public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||||
var interfaceId = await _database.HostInterface()
|
var interfaceId = await _database.HostInterface()
|
||||||
.Find(p => p.Host == hostEntity.Id && p.Index == @interface.Index)
|
.Find(p => p.Host == hostEntity.Id && p.Index == @interface.Index)
|
||||||
.Project(p => p.Id)
|
.Project(p => p.Id)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync(cancellationToken: default);
|
||||||
|
|
||||||
if (@interface.Addresses is not null && @interface.Addresses.Any())
|
if (@interface.Addresses is not null && @interface.Addresses.Count != 0)
|
||||||
{
|
{
|
||||||
foreach (var address in @interface.Addresses)
|
foreach (var address in @interface.Addresses)
|
||||||
{
|
{
|
||||||
|
|
@ -146,7 +141,7 @@ public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
// gateways
|
// gateways
|
||||||
|
|
||||||
if (interfaces is not null && interfaces.Any())
|
if (interfaces is not null && interfaces.Count != 0)
|
||||||
{
|
{
|
||||||
var gatewayBulk = new List<WriteModel<HostInterfaceGatewayEntity>>();
|
var gatewayBulk = new List<WriteModel<HostInterfaceGatewayEntity>>();
|
||||||
|
|
||||||
|
|
@ -155,9 +150,9 @@ public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||||
var interfaceId = await _database.HostInterface()
|
var interfaceId = await _database.HostInterface()
|
||||||
.Find(p => p.Host == hostEntity.Id && p.Index == @interface.Index)
|
.Find(p => p.Host == hostEntity.Id && p.Index == @interface.Index)
|
||||||
.Project(p => p.Id)
|
.Project(p => p.Id)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync(cancellationToken: default);
|
||||||
|
|
||||||
if (@interface.Gateways is not null && @interface.Gateways.Any())
|
if (@interface.Gateways is not null && @interface.Gateways.Count != 0)
|
||||||
{
|
{
|
||||||
foreach (var gateway in @interface.Gateways)
|
foreach (var gateway in @interface.Gateways)
|
||||||
{
|
{
|
||||||
|
|
@ -195,7 +190,7 @@ public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
// nameservers
|
// nameservers
|
||||||
|
|
||||||
if (interfaces is not null && interfaces.Any())
|
if (interfaces is not null && interfaces.Count != 0)
|
||||||
{
|
{
|
||||||
var nameserverBulk = new List<WriteModel<HostInterfaceNameserverEntity>>();
|
var nameserverBulk = new List<WriteModel<HostInterfaceNameserverEntity>>();
|
||||||
|
|
||||||
|
|
@ -204,9 +199,9 @@ public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||||
var interfaceId = await _database.HostInterface()
|
var interfaceId = await _database.HostInterface()
|
||||||
.Find(p => p.Host == hostEntity.Id && p.Index == @interface.Index)
|
.Find(p => p.Host == hostEntity.Id && p.Index == @interface.Index)
|
||||||
.Project(p => p.Id)
|
.Project(p => p.Id)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync(cancellationToken: default);
|
||||||
|
|
||||||
if (@interface.Dns is not null && @interface.Dns.Any())
|
if (@interface.Dns is not null && @interface.Dns.Count != 0)
|
||||||
{
|
{
|
||||||
foreach (var nameserver in @interface.Dns)
|
foreach (var nameserver in @interface.Dns)
|
||||||
{
|
{
|
||||||
|
|
@ -244,7 +239,7 @@ public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
// routes
|
// routes
|
||||||
|
|
||||||
if (interfaces is not null && interfaces.Any())
|
if (interfaces is not null && interfaces.Count != 0)
|
||||||
{
|
{
|
||||||
var routeBulk = new List<WriteModel<HostInterfaceRouteEntity>>();
|
var routeBulk = new List<WriteModel<HostInterfaceRouteEntity>>();
|
||||||
|
|
||||||
|
|
@ -253,9 +248,9 @@ public class InterfaceHandler : IMessageHandler<AgentSession>
|
||||||
var interfaceId = await _database.HostInterface()
|
var interfaceId = await _database.HostInterface()
|
||||||
.Find(p => p.Host == hostEntity.Id && p.Index == @interface.Index)
|
.Find(p => p.Host == hostEntity.Id && p.Index == @interface.Index)
|
||||||
.Project(p => p.Id)
|
.Project(p => p.Id)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync(cancellationToken: default);
|
||||||
|
|
||||||
if (@interface.Routes is not null && @interface.Routes.Any())
|
if (@interface.Routes is not null && @interface.Routes.Count != 0)
|
||||||
{
|
{
|
||||||
foreach (var route in @interface.Routes)
|
foreach (var route in @interface.Routes)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,9 @@ using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent.Handlers
|
namespace Insight.Server.Network.Agent.Handlers
|
||||||
{
|
{
|
||||||
public class MainboardHandler : IMessageHandler<AgentSession>
|
public class MainboardHandler(IMongoDatabase database) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly IMongoDatabase _database;
|
private readonly IMongoDatabase _database = database;
|
||||||
|
|
||||||
public MainboardHandler(IMongoDatabase database)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,9 @@ using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent.Handlers;
|
namespace Insight.Server.Network.Agent.Handlers;
|
||||||
|
|
||||||
public class MemoryHandler : IMessageHandler<AgentSession>
|
public class MemoryHandler(IMongoDatabase database) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly IMongoDatabase _database;
|
private readonly IMongoDatabase _database = database;
|
||||||
|
|
||||||
public MemoryHandler(IMongoDatabase database)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +34,7 @@ public class MemoryHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
var bulk = new List<WriteModel<HostMemoryEntity>>();
|
var bulk = new List<WriteModel<HostMemoryEntity>>();
|
||||||
|
|
||||||
if (memory is not null && memory.Any())
|
if (memory is not null && memory.Count != 0)
|
||||||
{
|
{
|
||||||
foreach (var mem in memory)
|
foreach (var mem in memory)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,9 @@ using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent.Handlers;
|
namespace Insight.Server.Network.Agent.Handlers;
|
||||||
|
|
||||||
public class OperationSystemHandler : IMessageHandler<AgentSession>
|
public class OperationSystemHandler(IMongoDatabase database) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly IMongoDatabase _database;
|
private readonly IMongoDatabase _database = database;
|
||||||
|
|
||||||
public OperationSystemHandler(IMongoDatabase database)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,9 @@ using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent.Handlers;
|
namespace Insight.Server.Network.Agent.Handlers;
|
||||||
|
|
||||||
public class PrinterHandler : IMessageHandler<AgentSession>
|
public class PrinterHandler(IMongoDatabase database) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly IMongoDatabase _database;
|
private readonly IMongoDatabase _database = database;
|
||||||
|
|
||||||
public PrinterHandler(IMongoDatabase database)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +34,7 @@ public class PrinterHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
var bulk = new List<WriteModel<HostPrinterEntity>>();
|
var bulk = new List<WriteModel<HostPrinterEntity>>();
|
||||||
|
|
||||||
if (printers is not null && printers.Any())
|
if (printers is not null && printers.Count != 0)
|
||||||
{
|
{
|
||||||
foreach (var printer in printers)
|
foreach (var printer in printers)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,9 @@ using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent.Handlers;
|
namespace Insight.Server.Network.Agent.Handlers;
|
||||||
|
|
||||||
public class ProcessorHandler : IMessageHandler<AgentSession>
|
public class ProcessorHandler(IMongoDatabase database) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly IMongoDatabase _database;
|
private readonly IMongoDatabase _database = database;
|
||||||
|
|
||||||
public ProcessorHandler(IMongoDatabase database)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +34,7 @@ public class ProcessorHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
var bulk = new List<WriteModel<HostProcessorEntity>>();
|
var bulk = new List<WriteModel<HostProcessorEntity>>();
|
||||||
|
|
||||||
if (processors is not null && processors.Any())
|
if (processors is not null && processors.Count != 0)
|
||||||
{
|
{
|
||||||
foreach (var processor in processors)
|
foreach (var processor in processors)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,9 @@ using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent.Handlers;
|
namespace Insight.Server.Network.Agent.Handlers;
|
||||||
|
|
||||||
public class ServiceHandler : IMessageHandler<AgentSession>
|
public class ServiceHandler(IMongoDatabase database) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly IMongoDatabase _database;
|
private readonly IMongoDatabase _database = database;
|
||||||
|
|
||||||
public ServiceHandler(IMongoDatabase database)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +34,7 @@ public class ServiceHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
var bulk = new List<WriteModel<HostServiceEntity>>();
|
var bulk = new List<WriteModel<HostServiceEntity>>();
|
||||||
|
|
||||||
if (services is not null && services.Any())
|
if (services is not null && services.Count != 0)
|
||||||
{
|
{
|
||||||
foreach (var service in services)
|
foreach (var service in services)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,9 @@ using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent.Handlers;
|
namespace Insight.Server.Network.Agent.Handlers;
|
||||||
|
|
||||||
public class SessionHandler : IMessageHandler<AgentSession>
|
public class SessionHandler(IMongoDatabase database) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly IMongoDatabase _database;
|
private readonly IMongoDatabase _database = database;
|
||||||
|
|
||||||
public SessionHandler(IMongoDatabase database)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +34,7 @@ public class SessionHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
var bulk = new List<WriteModel<HostSessionEntity>>();
|
var bulk = new List<WriteModel<HostSessionEntity>>();
|
||||||
|
|
||||||
if (sessions is not null && sessions.Any())
|
if (sessions is not null && sessions.Count != 0)
|
||||||
{
|
{
|
||||||
foreach (var sess in sessions)
|
foreach (var sess in sessions)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,9 @@ using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent.Handlers;
|
namespace Insight.Server.Network.Agent.Handlers;
|
||||||
|
|
||||||
public class SoftwareHandler : IMessageHandler<AgentSession>
|
public class SoftwareHandler(IMongoDatabase database) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly IMongoDatabase _database;
|
private readonly IMongoDatabase _database = database;
|
||||||
|
|
||||||
public SoftwareHandler(IMongoDatabase database)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +34,7 @@ public class SoftwareHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
var bulk = new List<WriteModel<HostApplicationEntity>>();
|
var bulk = new List<WriteModel<HostApplicationEntity>>();
|
||||||
|
|
||||||
if (applications is not null && applications.Any())
|
if (applications is not null && applications.Count != 0)
|
||||||
{
|
{
|
||||||
foreach (var app in applications)
|
foreach (var app in applications)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,9 @@ using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent.Handlers;
|
namespace Insight.Server.Network.Agent.Handlers;
|
||||||
|
|
||||||
public class StoragePoolHandler : IMessageHandler<AgentSession>
|
public class StoragePoolHandler(IMongoDatabase database) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly IMongoDatabase _database;
|
private readonly IMongoDatabase _database = database;
|
||||||
|
|
||||||
public StoragePoolHandler(IMongoDatabase database)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +34,7 @@ public class StoragePoolHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
// storagepools
|
// storagepools
|
||||||
|
|
||||||
if (storagePools is not null && storagePools.Any())
|
if (storagePools is not null && storagePools.Count != 0)
|
||||||
{
|
{
|
||||||
var storagepoolBulk = new List<WriteModel<HostStoragePoolEntity>>();
|
var storagepoolBulk = new List<WriteModel<HostStoragePoolEntity>>();
|
||||||
|
|
||||||
|
|
@ -55,12 +50,10 @@ public class StoragePoolHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
if (storagePool.States is not null)
|
if (storagePool.States is not null)
|
||||||
{
|
{
|
||||||
states = new List<string>();
|
states = [];
|
||||||
|
|
||||||
foreach (var state in storagePool.States)
|
foreach (var state in storagePool.States)
|
||||||
{
|
|
||||||
states.Add(state.ToString());
|
states.Add(state.ToString());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var storagePoolUpdate = Builders<HostStoragePoolEntity>.Update
|
var storagePoolUpdate = Builders<HostStoragePoolEntity>.Update
|
||||||
|
|
@ -98,7 +91,7 @@ public class StoragePoolHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
// physicaldisks
|
// physicaldisks
|
||||||
|
|
||||||
if (storagePools is not null && storagePools.Any())
|
if (storagePools is not null && storagePools.Count != 0)
|
||||||
{
|
{
|
||||||
var physicalDiskBulk = new List<WriteModel<HostStoragePoolPhysicalDiskEntity>>();
|
var physicalDiskBulk = new List<WriteModel<HostStoragePoolPhysicalDiskEntity>>();
|
||||||
|
|
||||||
|
|
@ -107,9 +100,9 @@ public class StoragePoolHandler : IMessageHandler<AgentSession>
|
||||||
var storagePoolId = await _database.HostStoragePool()
|
var storagePoolId = await _database.HostStoragePool()
|
||||||
.Find(p => p.Host == hostEntity.Id && p.UniqueId == storagePool.UniqueId)
|
.Find(p => p.Host == hostEntity.Id && p.UniqueId == storagePool.UniqueId)
|
||||||
.Project(p => p.Id)
|
.Project(p => p.Id)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync(cancellationToken: default);
|
||||||
|
|
||||||
if (storagePool.PhysicalDisks is not null && storagePool.PhysicalDisks.Any())
|
if (storagePool.PhysicalDisks is not null && storagePool.PhysicalDisks.Count != 0)
|
||||||
{
|
{
|
||||||
foreach (var physicalDisk in storagePool.PhysicalDisks)
|
foreach (var physicalDisk in storagePool.PhysicalDisks)
|
||||||
{
|
{
|
||||||
|
|
@ -124,12 +117,10 @@ public class StoragePoolHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
if (physicalDisk.States is not null)
|
if (physicalDisk.States is not null)
|
||||||
{
|
{
|
||||||
states = new List<string>();
|
states = [];
|
||||||
|
|
||||||
foreach (var state in physicalDisk.States)
|
foreach (var state in physicalDisk.States)
|
||||||
{
|
|
||||||
states.Add(state.ToString());
|
states.Add(state.ToString());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var physicalDiskUpdate = Builders<HostStoragePoolPhysicalDiskEntity>.Update
|
var physicalDiskUpdate = Builders<HostStoragePoolPhysicalDiskEntity>.Update
|
||||||
|
|
@ -177,20 +168,20 @@ public class StoragePoolHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
// virtual disks
|
// virtual disks
|
||||||
|
|
||||||
if (storagePools is not null && storagePools.Any())
|
if (storagePools is not null && storagePools.Count != 0)
|
||||||
{
|
{
|
||||||
var virtualDiskBulk = new List<WriteModel<HostStoragePoolVirtualDiskEntity>>();
|
var virtualDiskBulk = new List<WriteModel<HostStoragePoolVirtualDiskEntity>>();
|
||||||
|
|
||||||
foreach (var storagePool in storagePools)
|
foreach (var storagePool in storagePools)
|
||||||
{
|
{
|
||||||
if (storagePool.VirtualDisks is not null && storagePool.VirtualDisks.Any())
|
if (storagePool.VirtualDisks is not null && storagePool.VirtualDisks.Count != 0)
|
||||||
{
|
{
|
||||||
foreach (var virtualDisk in storagePool.VirtualDisks)
|
foreach (var virtualDisk in storagePool.VirtualDisks)
|
||||||
{
|
{
|
||||||
var storagePoolId = await _database.HostStoragePool()
|
var storagePoolId = await _database.HostStoragePool()
|
||||||
.Find(p => p.Host == hostEntity.Id && p.UniqueId == storagePool.UniqueId)
|
.Find(p => p.Host == hostEntity.Id && p.UniqueId == storagePool.UniqueId)
|
||||||
.Project(p => p.Id)
|
.Project(p => p.Id)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync(cancellationToken: default);
|
||||||
|
|
||||||
var virtualDiskFilter = Builders<HostStoragePoolVirtualDiskEntity>.Filter.And(new List<FilterDefinition<HostStoragePoolVirtualDiskEntity>>
|
var virtualDiskFilter = Builders<HostStoragePoolVirtualDiskEntity>.Filter.And(new List<FilterDefinition<HostStoragePoolVirtualDiskEntity>>
|
||||||
{
|
{
|
||||||
|
|
@ -203,12 +194,10 @@ public class StoragePoolHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
if (virtualDisk.States is not null)
|
if (virtualDisk.States is not null)
|
||||||
{
|
{
|
||||||
states = new List<string>();
|
states = [];
|
||||||
|
|
||||||
foreach (var state in virtualDisk.States)
|
foreach (var state in virtualDisk.States)
|
||||||
{
|
|
||||||
states.Add(state.ToString());
|
states.Add(state.ToString());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var virtualDiskUpdate = Builders<HostStoragePoolVirtualDiskEntity>.Update
|
var virtualDiskUpdate = Builders<HostStoragePoolVirtualDiskEntity>.Update
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,9 @@ using MongoDB.Driver;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent.Handlers;
|
namespace Insight.Server.Network.Agent.Handlers;
|
||||||
|
|
||||||
public class SystemInfoHandler : IMessageHandler<AgentSession>
|
public class SystemInfoHandler(IMongoDatabase database) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly IMongoDatabase _database;
|
private readonly IMongoDatabase _database = database;
|
||||||
|
|
||||||
public SystemInfoHandler(IMongoDatabase database)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -27,22 +22,24 @@ public class SystemInfoHandler : IMessageHandler<AgentSession>
|
||||||
|
|
||||||
private async ValueTask OnSystemInfoAsync(AgentSession session, SystemInfo? system, CancellationToken cancellationToken)
|
private async ValueTask OnSystemInfoAsync(AgentSession session, SystemInfo? system, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var agentEntity = await _database.Agent().Find(Builders<AgentEntity>.Filter.Eq(p => p.Id, session.Id)).FirstOrDefaultAsync(cancellationToken);
|
var agentEntity = await _database.Agent().Find(Builders<AgentEntity>.Filter.Eq(p => p.Id, session?.Id)).FirstOrDefaultAsync(cancellationToken);
|
||||||
if (agentEntity is null) return;
|
if (agentEntity is null) return;
|
||||||
|
|
||||||
var hostEntity = await _database.Host().Find(Builders<HostEntity>.Filter.Eq(p => p.Agent, agentEntity.Id)).FirstOrDefaultAsync(cancellationToken);
|
var hostEntity = await _database.Host().Find(Builders<HostEntity>.Filter.Eq(p => p.Agent, agentEntity?.Id)).FirstOrDefaultAsync(cancellationToken);
|
||||||
if (hostEntity is null) return;
|
if (hostEntity is null) return;
|
||||||
|
|
||||||
var date = DateTime.Now;
|
var date = DateTime.Now;
|
||||||
|
|
||||||
|
if (hostEntity.Id is null) return;
|
||||||
|
|
||||||
await _database.HostSystem().UpdateOneAsync(p => p.Host == hostEntity.Id, Builders<HostSystemEntity>.Update
|
await _database.HostSystem().UpdateOneAsync(p => p.Host == hostEntity.Id, Builders<HostSystemEntity>.Update
|
||||||
.SetOnInsert(p => p.Insert, date)
|
.SetOnInsert(p => p.Insert, date)
|
||||||
.SetOnInsert(p => p.Host, hostEntity.Id)
|
.SetOnInsert(p => p.Host, hostEntity.Id)
|
||||||
.Set(p => p.Update, date)
|
.Set(p => p.Update, date)
|
||||||
.Set(p => p.BootUpTime, system.LastBootUpTime)
|
.Set(p => p.BootUpTime, system?.LastBootUpTime)
|
||||||
.Set(p => p.LocalTime, system.LocalDateTime)
|
.Set(p => p.LocalTime, system?.LocalDateTime)
|
||||||
.Set(p => p.Processes, system.Processes)
|
.Set(p => p.Processes, system?.Processes)
|
||||||
.Set(p => p.License, system.License), new UpdateOptions
|
.Set(p => p.License, system?.License), new UpdateOptions
|
||||||
{
|
{
|
||||||
IsUpsert = true
|
IsUpsert = true
|
||||||
}, cancellationToken);
|
}, cancellationToken);
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,9 @@ using static Insight.Server.Models.MonitorMessage;
|
||||||
|
|
||||||
namespace Insight.Server.Network.Agent.Handlers;
|
namespace Insight.Server.Network.Agent.Handlers;
|
||||||
|
|
||||||
public class TrapHandler : IMessageHandler<AgentSession>
|
public partial class TrapHandler(IMongoDatabase database) : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
private readonly IMongoDatabase _database;
|
private readonly IMongoDatabase _database = database;
|
||||||
|
|
||||||
public TrapHandler(IMongoDatabase database)
|
|
||||||
{
|
|
||||||
_database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
|
||||||
{
|
{
|
||||||
|
|
@ -85,7 +80,8 @@ public class TrapHandler : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
monitoring = null;
|
monitoring = null;
|
||||||
|
|
||||||
if (packet is null || packet.Data is null || packet.Data.Any() is false) return false;
|
if (packet is null || packet.Data is null || packet.Data.Count == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
monitoring = new MonitorMessage
|
monitoring = new MonitorMessage
|
||||||
{
|
{
|
||||||
|
|
@ -96,9 +92,7 @@ public class TrapHandler : IMessageHandler<AgentSession>
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Enum.TryParse<ApplicationEnum>(packet.Community, true, out var application))
|
if (Enum.TryParse<ApplicationEnum>(packet.Community, true, out var application))
|
||||||
{
|
|
||||||
monitoring.Application = application;
|
monitoring.Application = application;
|
||||||
}
|
|
||||||
|
|
||||||
StatusEnum? status;
|
StatusEnum? status;
|
||||||
string? task;
|
string? task;
|
||||||
|
|
@ -131,9 +125,12 @@ public class TrapHandler : IMessageHandler<AgentSession>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool ParseAcronis(List<KeyValuePair<string, string>> data, out StatusEnum? status, out string? task, out string? message)
|
[GeneratedRegex(@"\s+")]
|
||||||
|
private static partial Regex AcronisRegex();
|
||||||
|
|
||||||
|
private static bool ParseAcronis(List<KeyValuePair<string, string?>> data, out StatusEnum? status, out string? task, out string? message)
|
||||||
{
|
{
|
||||||
status = data[0].Value.ToLower() switch
|
status = data[0].Value?.ToLower() switch
|
||||||
{
|
{
|
||||||
"erfolgreich" => StatusEnum.Information,
|
"erfolgreich" => StatusEnum.Information,
|
||||||
"success" => StatusEnum.Information,
|
"success" => StatusEnum.Information,
|
||||||
|
|
@ -149,49 +146,32 @@ public class TrapHandler : IMessageHandler<AgentSession>
|
||||||
task = null;
|
task = null;
|
||||||
message = null;
|
message = null;
|
||||||
|
|
||||||
var parsed = false;
|
var trim = data[1].Value?.Split(':', StringSplitOptions.None);
|
||||||
|
if (trim is null || trim.Length == 0) return false;
|
||||||
|
|
||||||
try
|
task = trim[1].Split("'", StringSplitOptions.None)[1].Split("'")[0].Trim();
|
||||||
{
|
message = trim[1].Split("' ", StringSplitOptions.None)[1].Trim();
|
||||||
var trim = data[1].Value.Split(new string[] { ":" }, StringSplitOptions.None);
|
if (message is not null) return true;
|
||||||
task = trim[1].Split(new string[] { "'" }, StringSplitOptions.None)[1].Split("'")[0].Trim();
|
|
||||||
message = trim[1].Split(new string[] { "' " }, StringSplitOptions.None)[1].Trim();
|
|
||||||
|
|
||||||
parsed = true;
|
if (data[1].Value is not string val) return false;
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
// skipped for base64 parse
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parsed) return true;
|
var content = AcronisRegex().Replace(val, "");
|
||||||
|
var bytes = Enumerable.Range(0, content.Length)
|
||||||
|
.Where(x => x % 2 == 0)
|
||||||
|
.Select(x => Convert.ToByte(content.Substring(x, 2), 16))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
try
|
content = Encoding.UTF8.GetString(bytes);
|
||||||
{
|
|
||||||
var content = Regex.Replace(data[1].Value, @"\s+", "");
|
|
||||||
var bytes = Enumerable.Range(0, content.Length)
|
|
||||||
.Where(x => x % 2 == 0)
|
|
||||||
.Select(x => Convert.ToByte(content.Substring(x, 2), 16))
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
content = Encoding.UTF8.GetString(bytes);
|
trim = content.Split(':', StringSplitOptions.None);
|
||||||
|
if (trim is null || trim.Length == 0) return false;
|
||||||
|
|
||||||
var trim = content.Split(new string[] { ":" }, StringSplitOptions.None);
|
task = trim[1].Split("'", StringSplitOptions.None)[1].Split("'")[0].Trim();
|
||||||
task = trim[1].Split(new string[] { "'" }, StringSplitOptions.None)[1].Split("'")[0].Trim();
|
message = trim[1].Split("' ", StringSplitOptions.None)[1].Trim();
|
||||||
message = trim[1].Split(new string[] { "' " }, StringSplitOptions.None)[1].Trim();
|
return message is not null;
|
||||||
|
|
||||||
parsed = true;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
//_logger.LogError("{ex}", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parsed) return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool ParseVeeam(List<KeyValuePair<string, string>> data, out StatusEnum? status, out string? task, out string? message)
|
private static bool ParseVeeam(List<KeyValuePair<string, string?>> data, out StatusEnum? status, out string? task, out string? message)
|
||||||
{
|
{
|
||||||
status = null;
|
status = null;
|
||||||
task = null;
|
task = null;
|
||||||
|
|
@ -203,13 +183,13 @@ public class TrapHandler : IMessageHandler<AgentSession>
|
||||||
{
|
{
|
||||||
var summary = false;
|
var summary = false;
|
||||||
|
|
||||||
if (Guid.TryParse(data[0].Value, out _))
|
if (Guid.TryParse(data[0].Value, out _))
|
||||||
summary = true;
|
summary = true;
|
||||||
|
|
||||||
if (data[1].Value.ToLower() == "backup configuration job")
|
if (data[1].Value?.ToLower() == "backup configuration job")
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
status = (summary ? data[2].Value.ToLower() : data[3].Value.ToLower()) switch
|
status = (summary ? data[2].Value?.ToLower() : data[3].Value?.ToLower()) switch
|
||||||
{
|
{
|
||||||
"success" => StatusEnum.Information,
|
"success" => StatusEnum.Information,
|
||||||
"warning" => StatusEnum.Warning,
|
"warning" => StatusEnum.Warning,
|
||||||
|
|
@ -230,7 +210,7 @@ public class TrapHandler : IMessageHandler<AgentSession>
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool ParseQnap(List<KeyValuePair<string, string>> data, out StatusEnum? status, out string? task, out string? message)
|
private static bool ParseQnap(List<KeyValuePair<string, string?>> data, out StatusEnum? status, out string? task, out string? message)
|
||||||
{
|
{
|
||||||
status = StatusEnum.Information;
|
status = StatusEnum.Information;
|
||||||
task = null;
|
task = null;
|
||||||
|
|
@ -265,21 +245,15 @@ public class TrapHandler : IMessageHandler<AgentSession>
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var key in keywords)
|
foreach (var key in keywords)
|
||||||
{
|
|
||||||
if (Regex.IsMatch(string.Concat(data).ToLowerInvariant(), $@"\b{key.Key}\b"))
|
if (Regex.IsMatch(string.Concat(data).ToLowerInvariant(), $@"\b{key.Key}\b"))
|
||||||
{
|
|
||||||
status = key.Value;
|
status = key.Value;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var kv in data)
|
foreach (var kv in data)
|
||||||
{
|
|
||||||
message += kv.Value;
|
message += kv.Value;
|
||||||
}
|
|
||||||
|
|
||||||
parsed = true;
|
parsed = true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
//_logger.LogError("{ex}", ex);
|
//_logger.LogError("{ex}", ex);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue