mirror of
https://github.com/immense/Remotely.git
synced 2025-10-26 11:27:15 +00:00
Unattended remote control session invitees require an authorized account with access to the device. Refactored remote control session info organization.
This commit is contained in:
parent
04f7de98ac
commit
a694765e9c
@ -83,22 +83,26 @@ namespace Remotely.Server.API
|
||||
{
|
||||
return BadRequest("There are already the maximum amount of active remote control sessions for your organization.");
|
||||
}
|
||||
|
||||
var existingSessions = RCDeviceSocketHub.SessionInfoList.Where(x => x.Value.MachineName == targetDevice.Value.DeviceName);
|
||||
|
||||
await DeviceHub.Clients.Client(targetDevice.Key).SendAsync("RemoteControl", Request.HttpContext.Connection.Id, targetDevice.Key);
|
||||
|
||||
var stopWatch = Stopwatch.StartNew();
|
||||
while (!RCDeviceSocketHub.MachineNameToSessionIDLookup.ContainsKey(targetDevice.Value.DeviceName) && stopWatch.Elapsed.TotalSeconds < 5)
|
||||
|
||||
while (!RCDeviceSocketHub.SessionInfoList.Values.Any(x=>x.MachineName == targetDevice.Value.DeviceName && !existingSessions.Any(y=>y.Key != x.RCSocketID)) && stopWatch.Elapsed.TotalSeconds < 5)
|
||||
{
|
||||
await Task.Delay(10);
|
||||
}
|
||||
|
||||
if (!RCDeviceSocketHub.MachineNameToSessionIDLookup.ContainsKey(targetDevice.Value.DeviceName))
|
||||
if (!RCDeviceSocketHub.SessionInfoList.Values.Any(x => x.MachineName == targetDevice.Value.DeviceName && !existingSessions.Any(y => y.Key != x.RCSocketID)))
|
||||
{
|
||||
return StatusCode(500, "The remote control process failed to start in time on the remote device.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var rcSessionID = RCDeviceSocketHub.MachineNameToSessionIDLookup[targetDevice.Value.DeviceName];
|
||||
return Ok($"{HttpContext.Request.Scheme}://{Request.Host}/RemoteControl?clientID={rcSessionID}&serviceID={targetDevice.Key}");
|
||||
var rcSession = RCDeviceSocketHub.SessionInfoList.Values.FirstOrDefault(x=>x.MachineName == targetDevice.Value.DeviceName && !existingSessions.Any(y=>y.Key != x.RCSocketID));
|
||||
return Ok($"{HttpContext.Request.Scheme}://{Request.Host}/RemoteControl?clientID={rcSession.RCSocketID}&serviceID={targetDevice.Key}");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@ -109,6 +109,19 @@ namespace Remotely.Server.Data
|
||||
targetDevice.DevicePermissionLinks.Any(x => x.PermissionGroup.UserPermissionLinks.Any(y => y.RemotelyUserID == remotelyUser.Id));
|
||||
}
|
||||
|
||||
public bool DoesUserHaveAccessToDevice(string deviceID, string remotelyUserID)
|
||||
{
|
||||
var remotelyUser = RemotelyContext.Users.Find(remotelyUserID);
|
||||
|
||||
var targetDevice = RemotelyContext.Devices
|
||||
.Include(x => x.DevicePermissionLinks)
|
||||
.FirstOrDefault(x => x.ID == deviceID && x.OrganizationID == remotelyUser.OrganizationID);
|
||||
|
||||
return remotelyUser.IsAdministrator ||
|
||||
targetDevice.DevicePermissionLinks.Count == 0 ||
|
||||
targetDevice.DevicePermissionLinks.Any(x => x.PermissionGroup.UserPermissionLinks.Any(y => y.RemotelyUserID == remotelyUser.Id));
|
||||
}
|
||||
|
||||
public string[] FilterDeviceIDsByUserPermission(string[] deviceIDs, RemotelyUser remotelyUser)
|
||||
{
|
||||
return RemotelyContext.Devices.Where(x =>
|
||||
|
||||
19
Server/Models/RCSessionInfo.cs
Normal file
19
Server/Models/RCSessionInfo.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using Remotely.Shared.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Remotely.Server.Models
|
||||
{
|
||||
public class RCSessionInfo
|
||||
{
|
||||
public string AttendedSessionID { get; set; }
|
||||
public string MachineName { get; set; }
|
||||
public RemoteControlMode Mode { get; set; }
|
||||
public string RCSocketID { get; set; }
|
||||
public string RequesterName { get; set; }
|
||||
public string ServiceID { get; set; }
|
||||
public DateTime StartTime { get; set; }
|
||||
}
|
||||
}
|
||||
@ -21,7 +21,7 @@ namespace Remotely.Server.Services
|
||||
RCBrowserHub = rcBrowserHub;
|
||||
}
|
||||
|
||||
public static ConcurrentDictionary<string, Device> ServiceConnections { get; set; } = new ConcurrentDictionary<string, Device>();
|
||||
public static ConcurrentDictionary<string, Device> ServiceConnections { get; } = new ConcurrentDictionary<string, Device>();
|
||||
public IHubContext<RCBrowserSocketHub> RCBrowserHub { get; }
|
||||
private IHubContext<BrowserSocketHub> BrowserHub { get; }
|
||||
private DataService DataService { get; }
|
||||
|
||||
@ -167,13 +167,13 @@ namespace Remotely.Server.Services
|
||||
{
|
||||
if ((RemoteControlMode)remoteControlMode == RemoteControlMode.Normal)
|
||||
{
|
||||
if (!RCDeviceSocketHub.AttendedSessionList.ContainsKey(screenCasterID))
|
||||
if (!RCDeviceSocketHub.SessionInfoList.Any(x => x.Value.AttendedSessionID == screenCasterID))
|
||||
{
|
||||
await Clients.Caller.SendAsync("SessionIDNotFound");
|
||||
return;
|
||||
}
|
||||
|
||||
screenCasterID = RCDeviceSocketHub.AttendedSessionList[screenCasterID];
|
||||
screenCasterID = RCDeviceSocketHub.SessionInfoList.First(x => x.Value.AttendedSessionID == screenCasterID).Value.RCSocketID;
|
||||
}
|
||||
|
||||
DataService.WriteEvent(new EventLog()
|
||||
@ -194,7 +194,12 @@ namespace Remotely.Server.Services
|
||||
RequesterName = requesterName;
|
||||
if (Mode == RemoteControlMode.Unattended)
|
||||
{
|
||||
await RCDeviceHub.Clients.Client(screenCasterID).SendAsync("GetScreenCast", Context.ConnectionId, requesterName);
|
||||
var serviceID = RCDeviceSocketHub.SessionInfoList.FirstOrDefault(x => x.Value.RCSocketID == screenCasterID).Value?.ServiceID;
|
||||
var deviceID = DeviceSocketHub.ServiceConnections[serviceID].ID;
|
||||
if (Context.User.Identity.IsAuthenticated && DataService.DoesUserHaveAccessToDevice(deviceID, Context.UserIdentifier))
|
||||
{
|
||||
await RCDeviceHub.Clients.Client(screenCasterID).SendAsync("GetScreenCast", Context.ConnectionId, requesterName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using System.IO;
|
||||
using System.Drawing;
|
||||
using Remotely.Shared.Models;
|
||||
using Remotely.Server.Models;
|
||||
|
||||
namespace Remotely.Server.Services
|
||||
{
|
||||
@ -29,9 +30,7 @@ namespace Remotely.Server.Services
|
||||
AppConfig = appConfig;
|
||||
}
|
||||
|
||||
public static ConcurrentDictionary<string, string> AttendedSessionList { get; set; } = new ConcurrentDictionary<string, string>();
|
||||
|
||||
public static ConcurrentDictionary<string, string> MachineNameToSessionIDLookup { get; set; } = new ConcurrentDictionary<string, string>();
|
||||
public static ConcurrentDictionary<string, RCSessionInfo> SessionInfoList { get; } = new ConcurrentDictionary<string, RCSessionInfo>();
|
||||
public ApplicationConfig AppConfig { get; }
|
||||
public RemoteControlSessionRecorder RCSessionRecorder { get; }
|
||||
private IHubContext<BrowserSocketHub> BrowserHub { get; }
|
||||
@ -53,65 +52,30 @@ namespace Remotely.Server.Services
|
||||
Context.Items["CurrentScreenSize"] = value;
|
||||
}
|
||||
}
|
||||
private RCSessionInfo SessionInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Context.Items.ContainsKey("SessionInfo"))
|
||||
{
|
||||
return (RCSessionInfo)Context.Items["SessionInfo"];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
Context.Items["SessionInfo"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private DataService DataService { get; }
|
||||
private IHubContext<DeviceSocketHub> DeviceHub { get; }
|
||||
private string MachineName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Context.Items.ContainsKey("MachineName"))
|
||||
{
|
||||
return Context.Items["MachineName"] as string;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
Context.Items["MachineName"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
private IHubContext<RCBrowserSocketHub> RCBrowserHub { get; }
|
||||
private string ServiceID
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Context.Items.ContainsKey("ServiceID"))
|
||||
{
|
||||
return Context.Items["ServiceID"] as string;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
Context.Items["ServiceID"] = value;
|
||||
}
|
||||
}
|
||||
private DateTime StartTime
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Context.Items.ContainsKey("StartTime"))
|
||||
{
|
||||
return (DateTime)Context.Items["StartTime"];
|
||||
}
|
||||
else
|
||||
{
|
||||
return DateTime.Now;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
Context.Items["StartTime"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
private List<string> ViewerList
|
||||
{
|
||||
@ -127,7 +91,7 @@ namespace Remotely.Server.Services
|
||||
|
||||
public async Task CtrlAltDel()
|
||||
{
|
||||
await DeviceHub.Clients.Client(ServiceID).SendAsync("CtrlAltDel");
|
||||
await DeviceHub.Clients.Client(SessionInfo.ServiceID).SendAsync("CtrlAltDel");
|
||||
}
|
||||
public async Task GetSessionID()
|
||||
{
|
||||
@ -139,10 +103,7 @@ namespace Remotely.Server.Services
|
||||
}
|
||||
Context.Items["SessionID"] = sessionID;
|
||||
|
||||
while (!AttendedSessionList.TryAdd(sessionID, Context.ConnectionId))
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
SessionInfoList[Context.ConnectionId].AttendedSessionID = sessionID;
|
||||
|
||||
await Clients.Caller.SendAsync("SessionID", sessionID);
|
||||
}
|
||||
@ -157,44 +118,46 @@ namespace Remotely.Server.Services
|
||||
await RCBrowserHub.Clients.Clients(viewerIDs).SendAsync("RelaunchedScreenCasterReady", Context.ConnectionId);
|
||||
}
|
||||
|
||||
public override Task OnConnectedAsync()
|
||||
public override async Task OnConnectedAsync()
|
||||
{
|
||||
StartTime = DateTime.Now;
|
||||
return base.OnConnectedAsync();
|
||||
SessionInfo = new RCSessionInfo()
|
||||
{
|
||||
RCSocketID = Context.ConnectionId,
|
||||
StartTime = DateTime.Now
|
||||
};
|
||||
while (!SessionInfoList.TryAdd(Context.ConnectionId, SessionInfo))
|
||||
{
|
||||
await Task.Delay(100);
|
||||
}
|
||||
|
||||
await base.OnConnectedAsync();
|
||||
}
|
||||
public override async Task OnDisconnectedAsync(Exception exception)
|
||||
{
|
||||
if (Context.Items.ContainsKey("SessionID") && AttendedSessionList.ContainsKey(Context.Items["SessionID"].ToString()))
|
||||
{
|
||||
while (!SessionInfoList.TryRemove(Context.ConnectionId, out _))
|
||||
{
|
||||
await Task.Delay(100);
|
||||
}
|
||||
|
||||
if (SessionInfo.Mode == Shared.Enums.RemoteControlMode.Unattended)
|
||||
{
|
||||
while (!AttendedSessionList.TryRemove(Context.Items["SessionID"].ToString(), out var value))
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
await RCBrowserHub.Clients.Clients(ViewerList).SendAsync("ScreenCasterDisconnected");
|
||||
}
|
||||
else
|
||||
else if (SessionInfo.Mode == Shared.Enums.RemoteControlMode.Unattended)
|
||||
{
|
||||
if (ViewerList.Count > 0)
|
||||
{
|
||||
await RCBrowserHub.Clients.Clients(ViewerList).SendAsync("Reconnecting");
|
||||
await DeviceHub.Clients.Client(ServiceID).SendAsync("RestartScreenCaster", ViewerList, ServiceID, Context.ConnectionId);
|
||||
await DeviceHub.Clients.Client(SessionInfo.ServiceID).SendAsync("RestartScreenCaster", ViewerList, SessionInfo.ServiceID, Context.ConnectionId);
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(MachineName) && MachineNameToSessionIDLookup.ContainsKey(MachineName))
|
||||
{
|
||||
while (!MachineNameToSessionIDLookup.TryRemove(MachineName, out _))
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
await base.OnDisconnectedAsync(exception);
|
||||
}
|
||||
public void ReceiveDeviceInfo(string serviceID, string machineName)
|
||||
{
|
||||
ServiceID = serviceID;
|
||||
MachineName = machineName;
|
||||
MachineNameToSessionIDLookup[MachineName] = Context.ConnectionId;
|
||||
SessionInfo.ServiceID = serviceID;
|
||||
SessionInfo.MachineName = machineName;
|
||||
}
|
||||
public async Task SendMachineName(string machineName, string viewerID)
|
||||
{
|
||||
@ -219,7 +182,8 @@ namespace Remotely.Server.Services
|
||||
{
|
||||
if (AppConfig.RecordRemoteControlSessions)
|
||||
{
|
||||
RCSessionRecorder.SaveFrame(captureBytes, left, top, CurrentScreenSize.Width, CurrentScreenSize.Height, rcBrowserHubConnectionID, MachineName, StartTime);
|
||||
RCSessionRecorder.SaveFrame(captureBytes, left, top, CurrentScreenSize.Width, CurrentScreenSize.Height,
|
||||
rcBrowserHubConnectionID, SessionInfo.MachineName, SessionInfo.StartTime);
|
||||
}
|
||||
|
||||
return RCBrowserHub.Clients.Client(rcBrowserHubConnectionID).SendAsync("ScreenCapture", captureBytes, left, top, width, height, captureTime);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"ConnectionStrings": {
|
||||
"SQLite": "DataSource=Server.db",
|
||||
"SQLServer": "Server=(localdb)\\mssqllocaldb;Database=aspnet-Server-53bc9b9d-9d6a-45d4-8429-2a2761773502;Trusted_Connection=True;MultipleActiveResultSets=true",
|
||||
"SQLServer": "Server=(localdb)\\mssqllocaldb;Database=Remotely-Server-53bc9b9d-9d6a-45d4-8429-2a2761773502;Trusted_Connection=True;MultipleActiveResultSets=true",
|
||||
"PostgreSQL": "Host=localhost;Database=;Username=;Password="
|
||||
},
|
||||
"Logging": {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
export var RemoteControlMode;
|
||||
(function (RemoteControlMode) {
|
||||
RemoteControlMode[RemoteControlMode["Unattended"] = 0] = "Unattended";
|
||||
RemoteControlMode[RemoteControlMode["Normal"] = 1] = "Normal";
|
||||
RemoteControlMode[RemoteControlMode["None"] = 0] = "None";
|
||||
RemoteControlMode[RemoteControlMode["Unattended"] = 1] = "Unattended";
|
||||
RemoteControlMode[RemoteControlMode["Normal"] = 2] = "Normal";
|
||||
})(RemoteControlMode || (RemoteControlMode = {}));
|
||||
//# sourceMappingURL=RemoteControlMode.js.map
|
||||
@ -1 +1 @@
|
||||
{"version":3,"file":"RemoteControlMode.js","sourceRoot":"","sources":["RemoteControlMode.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,iBAGX;AAHD,WAAY,iBAAiB;IACzB,qEAAU,CAAA;IACV,6DAAM,CAAA;AACV,CAAC,EAHW,iBAAiB,KAAjB,iBAAiB,QAG5B"}
|
||||
{"version":3,"file":"RemoteControlMode.js","sourceRoot":"","sources":["RemoteControlMode.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,iBAIX;AAJD,WAAY,iBAAiB;IACzB,yDAAI,CAAA;IACJ,qEAAU,CAAA;IACV,6DAAM,CAAA;AACV,CAAC,EAJW,iBAAiB,KAAjB,iBAAiB,QAI5B"}
|
||||
@ -1,4 +1,5 @@
|
||||
export enum RemoteControlMode {
|
||||
None,
|
||||
Unattended,
|
||||
Normal
|
||||
}
|
||||
@ -6,6 +6,7 @@ namespace Remotely.Shared.Enums
|
||||
{
|
||||
public enum RemoteControlMode
|
||||
{
|
||||
None,
|
||||
Unattended,
|
||||
Normal
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user