249 lines
8.1 KiB
C#
249 lines
8.1 KiB
C#
using AmtScanner.Api.Data;
|
|
using AmtScanner.Api.Models;
|
|
using AmtScanner.Api.Services;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace AmtScanner.Api.Controllers;
|
|
|
|
/// <summary>
|
|
/// 远程桌面控制器
|
|
/// </summary>
|
|
[ApiController]
|
|
[Route("api/remote-desktop")]
|
|
public class RemoteDesktopController : ControllerBase
|
|
{
|
|
private readonly ILogger<RemoteDesktopController> _logger;
|
|
private readonly GuacamoleService _guacamoleService;
|
|
private readonly AppDbContext _db;
|
|
private readonly IConfiguration _config;
|
|
|
|
public RemoteDesktopController(
|
|
ILogger<RemoteDesktopController> logger,
|
|
GuacamoleService guacamoleService,
|
|
AppDbContext db,
|
|
IConfiguration config)
|
|
{
|
|
_logger = logger;
|
|
_guacamoleService = guacamoleService;
|
|
_db = db;
|
|
_config = config;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 连接到设备的远程桌面 (RDP)
|
|
/// </summary>
|
|
[HttpPost("connect/rdp")]
|
|
public async Task<IActionResult> ConnectRdp([FromBody] RdpConnectRequest request)
|
|
{
|
|
if (string.IsNullOrEmpty(request.Hostname))
|
|
{
|
|
return BadRequest(ApiResponse.Fail(400, "主机地址不能为空"));
|
|
}
|
|
|
|
try
|
|
{
|
|
var connectionName = $"RDP-{request.Hostname}-{DateTime.Now:yyyyMMddHHmmss}";
|
|
|
|
var connectionId = await _guacamoleService.CreateRdpConnectionAsync(
|
|
connectionName,
|
|
request.Hostname,
|
|
request.Username ?? "",
|
|
request.Password ?? "",
|
|
request.Port);
|
|
|
|
if (string.IsNullOrEmpty(connectionId))
|
|
{
|
|
return BadRequest(ApiResponse.Fail(500, "创建远程连接失败,请检查 Guacamole 服务是否正常"));
|
|
}
|
|
|
|
var connectionUrl = await _guacamoleService.GetConnectionUrlAsync(connectionId);
|
|
|
|
return Ok(ApiResponse.Success(new
|
|
{
|
|
connectionId,
|
|
connectionUrl,
|
|
guacamoleUrl = _config["Guacamole:BaseUrl"] ?? "http://localhost:8080/guacamole"
|
|
}));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "创建 RDP 连接失败");
|
|
return BadRequest(ApiResponse.Fail(500, $"创建连接失败: {ex.Message}"));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 连接到设备的远程桌面 (VNC)
|
|
/// </summary>
|
|
[HttpPost("connect/vnc")]
|
|
public async Task<IActionResult> ConnectVnc([FromBody] VncConnectRequest request)
|
|
{
|
|
if (string.IsNullOrEmpty(request.Hostname))
|
|
{
|
|
return BadRequest(ApiResponse.Fail(400, "主机地址不能为空"));
|
|
}
|
|
|
|
try
|
|
{
|
|
var connectionName = $"VNC-{request.Hostname}-{DateTime.Now:yyyyMMddHHmmss}";
|
|
|
|
var connectionId = await _guacamoleService.CreateVncConnectionAsync(
|
|
connectionName,
|
|
request.Hostname,
|
|
request.Password ?? "",
|
|
request.Port);
|
|
|
|
if (string.IsNullOrEmpty(connectionId))
|
|
{
|
|
return BadRequest(ApiResponse.Fail(500, "创建远程连接失败,请检查 Guacamole 服务是否正常"));
|
|
}
|
|
|
|
var connectionUrl = await _guacamoleService.GetConnectionUrlAsync(connectionId);
|
|
|
|
return Ok(ApiResponse.Success(new
|
|
{
|
|
connectionId,
|
|
connectionUrl,
|
|
guacamoleUrl = _config["Guacamole:BaseUrl"] ?? "http://localhost:8080/guacamole"
|
|
}));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "创建 VNC 连接失败");
|
|
return BadRequest(ApiResponse.Fail(500, $"创建连接失败: {ex.Message}"));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 通过设备 UUID 连接远程桌面
|
|
/// </summary>
|
|
[HttpPost("connect/device/{uuid}")]
|
|
public async Task<IActionResult> ConnectByDevice(string uuid, [FromBody] DeviceConnectRequest request)
|
|
{
|
|
// 先查找 Agent 设备
|
|
var agentDevice = await _db.AgentDevices_new.FirstOrDefaultAsync(d => d.Uuid == uuid);
|
|
if (agentDevice != null)
|
|
{
|
|
var connectionName = $"RDP-{agentDevice.Hostname ?? agentDevice.IpAddress}-{DateTime.Now:yyyyMMddHHmmss}";
|
|
|
|
var connectionId = await _guacamoleService.CreateRdpConnectionAsync(
|
|
connectionName,
|
|
agentDevice.IpAddress,
|
|
request.Username ?? "",
|
|
request.Password ?? "",
|
|
request.Port > 0 ? request.Port : 3389);
|
|
|
|
if (string.IsNullOrEmpty(connectionId))
|
|
{
|
|
return BadRequest(ApiResponse.Fail(500, "创建远程连接失败"));
|
|
}
|
|
|
|
var connectionUrl = await _guacamoleService.GetConnectionUrlAsync(connectionId);
|
|
|
|
return Ok(ApiResponse.Success(new
|
|
{
|
|
connectionId,
|
|
connectionUrl,
|
|
deviceName = agentDevice.Hostname ?? agentDevice.IpAddress,
|
|
guacamoleUrl = _config["Guacamole:BaseUrl"] ?? "http://localhost:8080/guacamole"
|
|
}));
|
|
}
|
|
|
|
// 再查找 AMT 设备
|
|
var amtDevice = await _db.AmtDevices_new.FirstOrDefaultAsync(d => d.Uuid == uuid);
|
|
if (amtDevice != null)
|
|
{
|
|
var connectionName = $"RDP-{amtDevice.Hostname ?? amtDevice.IpAddress}-{DateTime.Now:yyyyMMddHHmmss}";
|
|
|
|
var connectionId = await _guacamoleService.CreateRdpConnectionAsync(
|
|
connectionName,
|
|
amtDevice.IpAddress,
|
|
request.Username ?? "",
|
|
request.Password ?? "",
|
|
request.Port > 0 ? request.Port : 3389);
|
|
|
|
if (string.IsNullOrEmpty(connectionId))
|
|
{
|
|
return BadRequest(ApiResponse.Fail(500, "创建远程连接失败"));
|
|
}
|
|
|
|
var connectionUrl = await _guacamoleService.GetConnectionUrlAsync(connectionId);
|
|
|
|
return Ok(ApiResponse.Success(new
|
|
{
|
|
connectionId,
|
|
connectionUrl,
|
|
deviceName = amtDevice.Hostname ?? amtDevice.IpAddress,
|
|
guacamoleUrl = _config["Guacamole:BaseUrl"] ?? "http://localhost:8080/guacamole"
|
|
}));
|
|
}
|
|
|
|
return NotFound(ApiResponse.Fail(404, "设备不存在"));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 断开连接(删除 Guacamole 连接)
|
|
/// </summary>
|
|
[HttpDelete("disconnect/{connectionId}")]
|
|
public async Task<IActionResult> Disconnect(string connectionId)
|
|
{
|
|
var result = await _guacamoleService.DeleteConnectionAsync(connectionId);
|
|
|
|
if (result)
|
|
{
|
|
return Ok(ApiResponse.Success("连接已断开"));
|
|
}
|
|
else
|
|
{
|
|
return BadRequest(ApiResponse.Fail(500, "断开连接失败"));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取所有远程连接
|
|
/// </summary>
|
|
[HttpGet("connections")]
|
|
public async Task<IActionResult> GetConnections()
|
|
{
|
|
var connections = await _guacamoleService.GetConnectionsAsync();
|
|
return Ok(ApiResponse.Success(connections));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取 Guacamole 配置信息
|
|
/// </summary>
|
|
[HttpGet("config")]
|
|
public IActionResult GetConfig()
|
|
{
|
|
return Ok(ApiResponse.Success(new
|
|
{
|
|
guacamoleUrl = _config["Guacamole:BaseUrl"] ?? "http://localhost:8080/guacamole",
|
|
enabled = !string.IsNullOrEmpty(_config["Guacamole:BaseUrl"])
|
|
}));
|
|
}
|
|
}
|
|
|
|
public class RdpConnectRequest
|
|
{
|
|
public string Hostname { get; set; } = "";
|
|
public string? Username { get; set; }
|
|
public string? Password { get; set; }
|
|
public int Port { get; set; } = 3389;
|
|
}
|
|
|
|
public class VncConnectRequest
|
|
{
|
|
public string Hostname { get; set; } = "";
|
|
public string? Password { get; set; }
|
|
public int Port { get; set; } = 5900;
|
|
}
|
|
|
|
public class DeviceConnectRequest
|
|
{
|
|
public string? Username { get; set; }
|
|
public string? Password { get; set; }
|
|
public int Port { get; set; } = 3389;
|
|
public string Protocol { get; set; } = "rdp"; // rdp 或 vnc
|
|
}
|