mirror of
https://github.com/immense/Remotely.git
synced 2025-10-26 11:27:15 +00:00
Begin stubbling out device alert service.
This commit is contained in:
parent
205f846bf2
commit
e56307bc31
@ -10,6 +10,7 @@ using System.ServiceProcess;
|
||||
using System.Threading.Tasks;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Remotely.Agent
|
||||
{
|
||||
@ -17,12 +18,17 @@ namespace Remotely.Agent
|
||||
{
|
||||
public static bool IsDebug { get; set; }
|
||||
|
||||
public static IServiceProvider Services { get; set; }
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
// TODO: Replace static services with scoped instances in IoC container.
|
||||
var serviceCollection = new ServiceCollection();
|
||||
Services = serviceCollection.BuildServiceProvider();
|
||||
|
||||
Task.Run(()=> { Init(args); });
|
||||
Task.Run(() => { Init(args); });
|
||||
|
||||
Thread.Sleep(Timeout.Infinite);
|
||||
|
||||
|
||||
@ -120,7 +120,7 @@ namespace Remotely.Agent.Services
|
||||
var partialResult = new GenericCommandResult()
|
||||
{
|
||||
CommandContextID = LastInputID,
|
||||
DeviceID = Utilities.GetConnectionInfo().DeviceID,
|
||||
DeviceID = ConfigService.GetConnectionInfo().DeviceID,
|
||||
CommandType = "Bash",
|
||||
StandardOutput = StandardOut,
|
||||
ErrorOutput = "WARNING: The command execution froze and was forced to return before finishing. " +
|
||||
@ -136,7 +136,7 @@ namespace Remotely.Agent.Services
|
||||
return new GenericCommandResult()
|
||||
{
|
||||
CommandContextID = LastInputID,
|
||||
DeviceID = Utilities.GetConnectionInfo().DeviceID,
|
||||
DeviceID = ConfigService.GetConnectionInfo().DeviceID,
|
||||
CommandType = "Bash",
|
||||
StandardOutput = StandardOut,
|
||||
ErrorOutput = ErrorOut
|
||||
|
||||
@ -11,44 +11,6 @@ namespace Remotely.Agent.Services
|
||||
{
|
||||
public class CMD
|
||||
{
|
||||
private static ConcurrentDictionary<string, CMD> Sessions { get; set; } = new ConcurrentDictionary<string, CMD>();
|
||||
private string ConnectionID { get; set; }
|
||||
|
||||
private string LastInputID { get; set; }
|
||||
private bool OutputDone { get; set; }
|
||||
private string StandardOut { get; set; }
|
||||
private string ErrorOut { get; set; }
|
||||
private System.Timers.Timer ProcessIdleTimeout { get; set; }
|
||||
public static CMD GetCurrent(string connectionID)
|
||||
{
|
||||
if (Sessions.ContainsKey(connectionID))
|
||||
{
|
||||
var bash = Sessions[connectionID];
|
||||
bash.ProcessIdleTimeout.Stop();
|
||||
bash.ProcessIdleTimeout.Start();
|
||||
return bash;
|
||||
}
|
||||
else
|
||||
{
|
||||
var cmd = new CMD();
|
||||
cmd.ConnectionID = connectionID;
|
||||
cmd.ProcessIdleTimeout = new System.Timers.Timer(600000); // 10 minutes.
|
||||
cmd.ProcessIdleTimeout.AutoReset = false;
|
||||
cmd.ProcessIdleTimeout.Elapsed += cmd.ProcessIdleTimeout_Elapsed;
|
||||
Sessions.AddOrUpdate(connectionID, cmd, (id, c) => cmd);
|
||||
cmd.ProcessIdleTimeout.Start();
|
||||
return cmd;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessIdleTimeout_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
Sessions.Remove(ConnectionID, out var outResult);
|
||||
outResult.CMDProc.Kill();
|
||||
}
|
||||
|
||||
private Process CMDProc { get; }
|
||||
|
||||
private CMD()
|
||||
{
|
||||
var psi = new ProcessStartInfo("cmd.exe");
|
||||
@ -70,24 +32,34 @@ namespace Remotely.Agent.Services
|
||||
CMDProc.BeginOutputReadLine();
|
||||
}
|
||||
|
||||
private void CMDProc_OutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (e?.Data?.Contains(LastInputID) == true)
|
||||
{
|
||||
OutputDone = true;
|
||||
}
|
||||
else if (!OutputDone)
|
||||
{
|
||||
StandardOut += e.Data + Environment.NewLine;
|
||||
}
|
||||
private static ConcurrentDictionary<string, CMD> Sessions { get; set; } = new ConcurrentDictionary<string, CMD>();
|
||||
private Process CMDProc { get; }
|
||||
private string ConnectionID { get; set; }
|
||||
|
||||
}
|
||||
|
||||
private void CMDProc_ErrorDataReceived(object sender, DataReceivedEventArgs e)
|
||||
private string ErrorOut { get; set; }
|
||||
private string LastInputID { get; set; }
|
||||
private bool OutputDone { get; set; }
|
||||
private System.Timers.Timer ProcessIdleTimeout { get; set; }
|
||||
private string StandardOut { get; set; }
|
||||
public static CMD GetCurrent(string connectionID)
|
||||
{
|
||||
if (e?.Data != null)
|
||||
if (Sessions.ContainsKey(connectionID))
|
||||
{
|
||||
ErrorOut += e.Data + Environment.NewLine;
|
||||
var bash = Sessions[connectionID];
|
||||
bash.ProcessIdleTimeout.Stop();
|
||||
bash.ProcessIdleTimeout.Start();
|
||||
return bash;
|
||||
}
|
||||
else
|
||||
{
|
||||
var cmd = new CMD();
|
||||
cmd.ConnectionID = connectionID;
|
||||
cmd.ProcessIdleTimeout = new System.Timers.Timer(600000); // 10 minutes.
|
||||
cmd.ProcessIdleTimeout.AutoReset = false;
|
||||
cmd.ProcessIdleTimeout.Elapsed += cmd.ProcessIdleTimeout_Elapsed;
|
||||
Sessions.AddOrUpdate(connectionID, cmd, (id, c) => cmd);
|
||||
cmd.ProcessIdleTimeout.Start();
|
||||
return cmd;
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,7 +84,40 @@ namespace Remotely.Agent.Services
|
||||
}
|
||||
return GenerateCompletedResult();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void CMDProc_ErrorDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (e?.Data != null)
|
||||
{
|
||||
ErrorOut += e.Data + Environment.NewLine;
|
||||
}
|
||||
}
|
||||
|
||||
private void CMDProc_OutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (e?.Data?.Contains(LastInputID) == true)
|
||||
{
|
||||
OutputDone = true;
|
||||
}
|
||||
else if (!OutputDone)
|
||||
{
|
||||
StandardOut += e.Data + Environment.NewLine;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private GenericCommandResult GenerateCompletedResult()
|
||||
{
|
||||
return new GenericCommandResult()
|
||||
{
|
||||
CommandContextID = LastInputID,
|
||||
DeviceID = ConfigService.GetConnectionInfo().DeviceID,
|
||||
CommandType = "CMD",
|
||||
StandardOutput = StandardOut,
|
||||
ErrorOutput = ErrorOut
|
||||
};
|
||||
}
|
||||
|
||||
private GenericCommandResult GeneratePartialResult()
|
||||
@ -121,7 +126,7 @@ namespace Remotely.Agent.Services
|
||||
var partialResult = new GenericCommandResult()
|
||||
{
|
||||
CommandContextID = LastInputID,
|
||||
DeviceID = Utilities.GetConnectionInfo().DeviceID,
|
||||
DeviceID = ConfigService.GetConnectionInfo().DeviceID,
|
||||
CommandType = "CMD",
|
||||
StandardOutput = StandardOut,
|
||||
ErrorOutput = "WARNING: The command execution froze and was forced to return before finishing. " +
|
||||
@ -132,17 +137,10 @@ namespace Remotely.Agent.Services
|
||||
return partialResult;
|
||||
}
|
||||
|
||||
private GenericCommandResult GenerateCompletedResult()
|
||||
private void ProcessIdleTimeout_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
return new GenericCommandResult()
|
||||
{
|
||||
CommandContextID = LastInputID,
|
||||
DeviceID = Utilities.GetConnectionInfo().DeviceID,
|
||||
CommandType = "CMD",
|
||||
StandardOutput = StandardOut,
|
||||
ErrorOutput = ErrorOut
|
||||
};
|
||||
Sessions.Remove(ConnectionID, out var outResult);
|
||||
outResult.CMDProc.Kill();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
35
Agent/Services/ConfigService.cs
Normal file
35
Agent/Services/ConfigService.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using Remotely.Shared.Models;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Remotely.Agent.Services
|
||||
{
|
||||
public static class ConfigService
|
||||
{
|
||||
private static ConnectionInfo connectionInfo;
|
||||
public static ConnectionInfo GetConnectionInfo()
|
||||
{
|
||||
if (connectionInfo == null)
|
||||
{
|
||||
if (!File.Exists("ConnectionInfo.json"))
|
||||
{
|
||||
Logger.Write(new Exception("No connection info available. Please create ConnectionInfo.json file with appropriate values."));
|
||||
return null;
|
||||
}
|
||||
connectionInfo = JsonConvert.DeserializeObject<ConnectionInfo>(File.ReadAllText("ConnectionInfo.json"));
|
||||
}
|
||||
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
|
||||
public static void SaveConnectionInfo(ConnectionInfo connectionInfo)
|
||||
{
|
||||
File.WriteAllText("ConnectionInfo.json", JsonConvert.SerializeObject(connectionInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -27,7 +27,7 @@ namespace Remotely.Agent.Services
|
||||
|
||||
public static async Task Connect()
|
||||
{
|
||||
ConnectionInfo = Utilities.GetConnectionInfo();
|
||||
ConnectionInfo = ConfigService.GetConnectionInfo();
|
||||
|
||||
HubConnection = new HubConnectionBuilder()
|
||||
.WithUrl(ConnectionInfo.Host + "/DeviceHub")
|
||||
@ -47,18 +47,15 @@ namespace Remotely.Agent.Services
|
||||
IsServerVerified = true;
|
||||
ConnectionInfo.ServerVerificationToken = Guid.NewGuid().ToString();
|
||||
await HubConnection.InvokeAsync("SetServerVerificationToken", ConnectionInfo.ServerVerificationToken);
|
||||
Utilities.SaveConnectionInfo(ConnectionInfo);
|
||||
ConfigService.SaveConnectionInfo(ConnectionInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
await HubConnection.InvokeAsync("SendServerVerificationToken");
|
||||
}
|
||||
|
||||
if (HeartbeatTimer != null)
|
||||
{
|
||||
HeartbeatTimer.Stop();
|
||||
}
|
||||
HeartbeatTimer = new Timer(300000);
|
||||
HeartbeatTimer?.Dispose();
|
||||
HeartbeatTimer = new Timer(TimeSpan.FromMinutes(5).TotalMilliseconds);
|
||||
HeartbeatTimer.Elapsed += HeartbeatTimer_Elapsed;
|
||||
HeartbeatTimer.Start();
|
||||
}
|
||||
@ -171,7 +168,7 @@ namespace Remotely.Agent.Services
|
||||
hubConnection.On("TransferFiles", async (string transferID, List<string> fileIDs, string requesterID) =>
|
||||
{
|
||||
Logger.Write($"File transfer started by {requesterID}.");
|
||||
var connectionInfo = Utilities.GetConnectionInfo();
|
||||
var connectionInfo = ConfigService.GetConnectionInfo();
|
||||
var sharedFilePath = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(),"RemotelySharedFiles")).FullName;
|
||||
|
||||
foreach (var fileID in fileIDs)
|
||||
@ -201,7 +198,7 @@ namespace Remotely.Agent.Services
|
||||
await HubConnection.InvokeAsync("TransferCompleted", transferID, requesterID);
|
||||
});
|
||||
hubConnection.On("DeployScript", async (string mode, string fileID, string commandContextID, string requesterID) => {
|
||||
var connectionInfo = Utilities.GetConnectionInfo();
|
||||
var connectionInfo = ConfigService.GetConnectionInfo();
|
||||
var sharedFilePath = Directory.CreateDirectory(Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
|
||||
"Remotely",
|
||||
@ -253,11 +250,11 @@ namespace Remotely.Agent.Services
|
||||
|
||||
if (Program.IsDebug)
|
||||
{
|
||||
Process.Start(rcBinaryPath, $"-mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {Utilities.GetConnectionInfo().Host} -desktop default");
|
||||
Process.Start(rcBinaryPath, $"-mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {ConfigService.GetConnectionInfo().Host} -desktop default");
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = Win32Interop.OpenInteractiveProcess(rcBinaryPath + $" -mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {Utilities.GetConnectionInfo().Host} -desktop default", "default", true, out _);
|
||||
var result = Win32Interop.OpenInteractiveProcess(rcBinaryPath + $" -mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {ConfigService.GetConnectionInfo().Host} -desktop default", "default", true, out _);
|
||||
if (!result)
|
||||
{
|
||||
await hubConnection.InvokeAsync("DisplayMessage", "Remote control failed to start on target device.", "Failed to start remote control.", requesterID);
|
||||
@ -272,7 +269,7 @@ namespace Remotely.Agent.Services
|
||||
var psi = new ProcessStartInfo()
|
||||
{
|
||||
FileName = "sudo",
|
||||
Arguments = $"-u {username} {rcBinaryPath} -mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {Utilities.GetConnectionInfo().Host} -desktop default & disown"
|
||||
Arguments = $"-u {username} {rcBinaryPath} -mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {ConfigService.GetConnectionInfo().Host} -desktop default & disown"
|
||||
};
|
||||
psi.Environment.Add("DISPLAY", ":0");
|
||||
psi.Environment.Add("XAUTHORITY", $"{homeDir}/.Xauthority");
|
||||
@ -304,7 +301,7 @@ namespace Remotely.Agent.Services
|
||||
Logger.Write("Restarting screen caster.");
|
||||
if (Program.IsDebug)
|
||||
{
|
||||
var proc = Process.Start(rcBinaryPath, $"-mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {Utilities.GetConnectionInfo().Host} -relaunch true -desktop default -viewers {String.Join(",", viewerIDs)}");
|
||||
var proc = Process.Start(rcBinaryPath, $"-mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {ConfigService.GetConnectionInfo().Host} -relaunch true -desktop default -viewers {String.Join(",", viewerIDs)}");
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
while (stopwatch.Elapsed.TotalSeconds < 10)
|
||||
{
|
||||
@ -317,7 +314,7 @@ namespace Remotely.Agent.Services
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = Win32Interop.OpenInteractiveProcess(rcBinaryPath + $" -mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {Utilities.GetConnectionInfo().Host} -relaunch true -desktop default -viewers {String.Join(",", viewerIDs)}", "default", true, out var procInfo);
|
||||
var result = Win32Interop.OpenInteractiveProcess(rcBinaryPath + $" -mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {ConfigService.GetConnectionInfo().Host} -relaunch true -desktop default -viewers {String.Join(",", viewerIDs)}", "default", true, out var procInfo);
|
||||
|
||||
if (result)
|
||||
{
|
||||
@ -332,7 +329,7 @@ namespace Remotely.Agent.Services
|
||||
if (Process.GetProcessesByName(Path.GetFileNameWithoutExtension(rcBinaryPath))?.Where(x=>x.Id == procInfo.dwProcessId)?.Any() != true)
|
||||
{
|
||||
Logger.Write("Restarting screen caster after failed relaunch.");
|
||||
result = Win32Interop.OpenInteractiveProcess(rcBinaryPath + $" -mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {Utilities.GetConnectionInfo().Host} -relaunch true -desktop default -viewers {String.Join(",", viewerIDs)}", "default", true, out procInfo);
|
||||
result = Win32Interop.OpenInteractiveProcess(rcBinaryPath + $" -mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {ConfigService.GetConnectionInfo().Host} -relaunch true -desktop default -viewers {String.Join(",", viewerIDs)}", "default", true, out procInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -353,7 +350,7 @@ namespace Remotely.Agent.Services
|
||||
var psi = new ProcessStartInfo()
|
||||
{
|
||||
FileName = "sudo",
|
||||
Arguments = $"-u {username} {rcBinaryPath} -mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {Utilities.GetConnectionInfo().Host} -relaunch true -desktop default -viewers {String.Join(",", viewerIDs)} & disown"
|
||||
Arguments = $"-u {username} {rcBinaryPath} -mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {ConfigService.GetConnectionInfo().Host} -relaunch true -desktop default -viewers {String.Join(",", viewerIDs)} & disown"
|
||||
};
|
||||
psi.Environment.Add("DISPLAY", ":0");
|
||||
psi.Environment.Add("XAUTHORITY", $"{homeDir}/.Xauthority");
|
||||
@ -375,7 +372,7 @@ namespace Remotely.Agent.Services
|
||||
|
||||
hubConnection.On("ServerVerificationToken", (string verificationToken) =>
|
||||
{
|
||||
if (verificationToken == Utilities.GetConnectionInfo().ServerVerificationToken)
|
||||
if (verificationToken == ConfigService.GetConnectionInfo().ServerVerificationToken)
|
||||
{
|
||||
IsServerVerified = true;
|
||||
if (!Program.IsDebug)
|
||||
@ -394,7 +391,7 @@ namespace Remotely.Agent.Services
|
||||
|
||||
private static void SendResultsViaAjax(string resultType, object result)
|
||||
{
|
||||
var targetURL = Utilities.GetConnectionInfo().Host + $"/API/Commands/{resultType}";
|
||||
var targetURL = ConfigService.GetConnectionInfo().Host + $"/API/Commands/{resultType}";
|
||||
var webRequest = WebRequest.CreateHttp(targetURL);
|
||||
webRequest.Method = "POST";
|
||||
|
||||
|
||||
@ -72,7 +72,7 @@ namespace Remotely.Agent.Services
|
||||
return new PSCoreCommandResult()
|
||||
{
|
||||
CommandContextID = commandID,
|
||||
DeviceID = Utilities.GetConnectionInfo().DeviceID,
|
||||
DeviceID = ConfigService.GetConnectionInfo().DeviceID,
|
||||
DebugOutput = debugOut,
|
||||
ErrorOutput = errorOut,
|
||||
VerboseOutput = verboseOut,
|
||||
|
||||
@ -20,7 +20,7 @@ namespace Remotely.Agent.Services
|
||||
try
|
||||
{
|
||||
var wc = new WebClient();
|
||||
var response = new HttpClient().GetAsync(Utilities.GetConnectionInfo().Host + $"/API/CoreVersion/").Result;
|
||||
var response = new HttpClient().GetAsync(ConfigService.GetConnectionInfo().Host + $"/API/CoreVersion/").Result;
|
||||
var latestVersion = response.Content.ReadAsStringAsync().Result;
|
||||
var thisVersion = FileVersionInfo.GetVersionInfo("Remotely_Agent.dll").FileVersion.ToString().Trim();
|
||||
if (thisVersion != latestVersion)
|
||||
@ -37,7 +37,7 @@ namespace Remotely.Agent.Services
|
||||
{
|
||||
Directory.Delete(tempFolder, true);
|
||||
}
|
||||
wc.DownloadFile(new Uri(Utilities.GetConnectionInfo().Host + $"/Downloads/{fileName}"), tempFile);
|
||||
wc.DownloadFile(new Uri(ConfigService.GetConnectionInfo().Host + $"/Downloads/{fileName}"), tempFile);
|
||||
|
||||
Logger.Write($"Service Updater: Extracting files.");
|
||||
|
||||
@ -187,10 +187,8 @@ namespace Remotely.Agent.Services
|
||||
{
|
||||
throw new Exception("Unsupported operating system.");
|
||||
}
|
||||
var response = await new HttpClient().GetAsync(Utilities.GetConnectionInfo().Host + $"/API/ScreenCastVersion/{platform}");
|
||||
var response = await new HttpClient().GetAsync(ConfigService.GetConnectionInfo().Host + $"/API/ScreenCastVersion/{platform}");
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,65 +0,0 @@
|
||||
using Remotely.Shared.Models;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Remotely.Agent.Services
|
||||
{
|
||||
public static class Utilities
|
||||
{
|
||||
|
||||
|
||||
public static ConnectionInfo GetConnectionInfo()
|
||||
{
|
||||
if (!File.Exists("ConnectionInfo.json"))
|
||||
{
|
||||
Logger.Write(new Exception("No connection info available. Please create ConnectionInfo.json file with appropriate values."));
|
||||
}
|
||||
return JsonConvert.DeserializeObject<ConnectionInfo>(File.ReadAllText("ConnectionInfo.json"));
|
||||
}
|
||||
|
||||
public static string AppDataDir
|
||||
{
|
||||
get
|
||||
{
|
||||
return Directory.CreateDirectory(
|
||||
Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
|
||||
"Remotely")
|
||||
).FullName;
|
||||
}
|
||||
}
|
||||
|
||||
public static void KillProcs()
|
||||
{
|
||||
var procs = Process.GetProcessesByName("Agent_Win").Where(proc => proc.Id != Process.GetCurrentProcess().Id);
|
||||
foreach (var proc in procs)
|
||||
{
|
||||
proc.Kill();
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<string, string> ProcessArgs(string[] args)
|
||||
{
|
||||
var argDict = new Dictionary<string, string>();
|
||||
var argString = String.Join(" ", args).ToLower();
|
||||
var argArray = argString.Split("-".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var arg in argArray)
|
||||
{
|
||||
var split = arg.Split(" ".ToCharArray(), 2, StringSplitOptions.RemoveEmptyEntries);
|
||||
var key = split[0];
|
||||
var value = split.Length == 2 ? split[1] : "";
|
||||
argDict.Add(key, value);
|
||||
}
|
||||
return argDict;
|
||||
}
|
||||
|
||||
public static void SaveConnectionInfo(ConnectionInfo connectionInfo)
|
||||
{
|
||||
File.WriteAllText("ConnectionInfo.json", JsonConvert.SerializeObject(connectionInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,7 +118,7 @@ namespace Remotely.Agent.Services
|
||||
var partialResult = new GenericCommandResult()
|
||||
{
|
||||
CommandContextID = LastInputID,
|
||||
DeviceID = Utilities.GetConnectionInfo().DeviceID,
|
||||
DeviceID = ConfigService.GetConnectionInfo().DeviceID,
|
||||
CommandType = "WinPS",
|
||||
StandardOutput = StandardOut,
|
||||
ErrorOutput = "WARNING: The command execution froze and was forced to return before finishing. " +
|
||||
@ -134,7 +134,7 @@ namespace Remotely.Agent.Services
|
||||
return new GenericCommandResult()
|
||||
{
|
||||
CommandContextID = LastInputID,
|
||||
DeviceID = Utilities.GetConnectionInfo().DeviceID,
|
||||
DeviceID = ConfigService.GetConnectionInfo().DeviceID,
|
||||
CommandType = "WinPS",
|
||||
StandardOutput = StandardOut,
|
||||
ErrorOutput = ErrorOut
|
||||
|
||||
@ -392,17 +392,6 @@ namespace Remotely.Server.Data
|
||||
.UserOptions;
|
||||
}
|
||||
|
||||
public List<RemotelyUser> GetUsersWithAccessToDevice(IEnumerable<string> userIDs, Device device)
|
||||
{
|
||||
var targetDevice = RemotelyContext.Devices
|
||||
.FirstOrDefault(x => x.ID == device.ID && x.OrganizationID == device.OrganizationID);
|
||||
|
||||
var targetUsers = RemotelyContext.Users.Where(x =>
|
||||
x.OrganizationID == device.OrganizationID &&
|
||||
userIDs.Contains(x.Id)).ToList();
|
||||
|
||||
return targetUsers.ToList();
|
||||
}
|
||||
public bool JoinViaInvitation(string userName, string inviteID)
|
||||
{
|
||||
var invite = RemotelyContext.InviteLinks
|
||||
|
||||
38
Server/Services/DeviceAlertService.cs
Normal file
38
Server/Services/DeviceAlertService.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using Remotely.Server.Data;
|
||||
using Remotely.Shared.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Remotely.Server.Services
|
||||
{
|
||||
public class DeviceAlertService
|
||||
{
|
||||
public DeviceAlertService(DataService dataService, ApplicationConfig appConfig)
|
||||
{
|
||||
DataService = dataService;
|
||||
AppConfig = appConfig;
|
||||
}
|
||||
|
||||
public DataService DataService { get; }
|
||||
public ApplicationConfig AppConfig { get; }
|
||||
|
||||
public bool ShouldSendAlert(Device device, out DeviceAlert alert)
|
||||
{
|
||||
if (true) // Check
|
||||
{
|
||||
//DataService.AddDeviceAlert(alert);
|
||||
//TrySendAlertEmail(alert);
|
||||
//TrySendAlertWebRequest(alert);
|
||||
alert = new DeviceAlert();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
alert = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -14,14 +14,19 @@ namespace Remotely.Server.Services
|
||||
{
|
||||
public class DeviceSocketHub : Hub
|
||||
{
|
||||
public DeviceSocketHub(DataService dataService, IHubContext<BrowserSocketHub> browserHub, IHubContext<RCBrowserSocketHub> rcBrowserHub)
|
||||
public DeviceSocketHub(DataService dataService,
|
||||
IHubContext<BrowserSocketHub> browserHub,
|
||||
IHubContext<RCBrowserSocketHub> rcBrowserHub,
|
||||
DeviceAlertService deviceAlertService)
|
||||
{
|
||||
DataService = dataService;
|
||||
BrowserHub = browserHub;
|
||||
RCBrowserHub = rcBrowserHub;
|
||||
DeviceAlertService = deviceAlertService;
|
||||
}
|
||||
|
||||
public static ConcurrentDictionary<string, Device> ServiceConnections { get; } = new ConcurrentDictionary<string, Device>();
|
||||
public DeviceAlertService DeviceAlertService { get; }
|
||||
public IHubContext<RCBrowserSocketHub> RCBrowserHub { get; }
|
||||
private IHubContext<BrowserSocketHub> BrowserHub { get; }
|
||||
private DataService DataService { get; }
|
||||
@ -79,14 +84,10 @@ namespace Remotely.Server.Services
|
||||
Device = updatedDevice;
|
||||
ServiceConnections.AddOrUpdate(Context.ConnectionId, Device, (id, d) => Device);
|
||||
|
||||
var onlineOrganizationUsers = BrowserSocketHub.ConnectionIdToUserLookup
|
||||
.Where(x => x.Value.OrganizationID == Device.OrganizationID);
|
||||
|
||||
var authorizedUsers = DataService.GetUsersWithAccessToDevice(onlineOrganizationUsers.Select(x => x.Value.Id), Device);
|
||||
var connectionIds = onlineOrganizationUsers
|
||||
.Where(onlineUser => authorizedUsers.Any(authorizedUser => authorizedUser.Id == onlineUser.Value.Id))
|
||||
.Select(x => x.Key)
|
||||
.ToList();
|
||||
var connectionIds = BrowserSocketHub.ConnectionIdToUserLookup
|
||||
.Where(x => x.Value.OrganizationID == Device.OrganizationID)
|
||||
.Select(x => x.Key)
|
||||
.ToList();
|
||||
|
||||
await BrowserHub.Clients.Clients(connectionIds).SendAsync("DeviceCameOnline", Device);
|
||||
}
|
||||
@ -107,16 +108,17 @@ namespace Remotely.Server.Services
|
||||
{
|
||||
DataService.AddOrUpdateDevice(device, out var updatedDevice);
|
||||
Device = updatedDevice;
|
||||
var onlineOrganizationUsers = BrowserSocketHub.ConnectionIdToUserLookup
|
||||
.Where(x => x.Value.OrganizationID == Device.OrganizationID);
|
||||
|
||||
var authorizedUsers = DataService.GetUsersWithAccessToDevice(onlineOrganizationUsers.Select(x=>x.Value.Id), Device);
|
||||
var connectionIds = onlineOrganizationUsers
|
||||
.Where(onlineUser => authorizedUsers.Any(authorizedUser => authorizedUser.Id == onlineUser.Value.Id))
|
||||
.Select(x => x.Key)
|
||||
.ToList();
|
||||
var connectionIds = BrowserSocketHub.ConnectionIdToUserLookup
|
||||
.Where(x => x.Value.OrganizationID == Device.OrganizationID)
|
||||
.Select(x => x.Key)
|
||||
.ToList();
|
||||
|
||||
await BrowserHub.Clients.Clients(connectionIds).SendAsync("DeviceHeartbeat", Device);
|
||||
|
||||
if (DeviceAlertService.ShouldSendAlert(Device, out var alert))
|
||||
{
|
||||
await BrowserHub.Clients.Clients(connectionIds).SendAsync("DeviceAlert", alert);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DisplayMessage(string consoleMessage, string popupMessage, string requesterID)
|
||||
@ -135,18 +137,19 @@ namespace Remotely.Server.Services
|
||||
|
||||
Device.IsOnline = false;
|
||||
|
||||
var onlineOrganizationUsers = BrowserSocketHub.ConnectionIdToUserLookup
|
||||
.Where(x => x.Value.OrganizationID == Device.OrganizationID);
|
||||
|
||||
var authorizedUsers = DataService.GetUsersWithAccessToDevice(onlineOrganizationUsers.Select(x => x.Value.Id), Device);
|
||||
var connectionIds = onlineOrganizationUsers
|
||||
.Where(onlineUser => authorizedUsers.Any(authorizedUser => authorizedUser.Id == onlineUser.Value.Id))
|
||||
.Select(x => x.Key)
|
||||
.ToList();
|
||||
var connectionIds = BrowserSocketHub.ConnectionIdToUserLookup
|
||||
.Where(x => x.Value.OrganizationID == Device.OrganizationID)
|
||||
.Select(x => x.Key)
|
||||
.ToList();
|
||||
|
||||
await BrowserHub.Clients.Clients(connectionIds).SendAsync("DeviceWentOffline", Device);
|
||||
|
||||
ServiceConnections.Remove(Context.ConnectionId, out _);
|
||||
|
||||
if (DeviceAlertService.ShouldSendAlert(Device, out var alert))
|
||||
{
|
||||
await BrowserHub.Clients.Clients(connectionIds).SendAsync("DeviceAlert", alert);
|
||||
}
|
||||
}
|
||||
|
||||
await base.OnDisconnectedAsync(exception);
|
||||
|
||||
@ -25,5 +25,6 @@ namespace Remotely.Shared.Models
|
||||
}
|
||||
public string OrganizationID { get; set; }
|
||||
public string ServerVerificationToken { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
10
Shared/Models/DeviceAlert.cs
Normal file
10
Shared/Models/DeviceAlert.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Remotely.Shared.Models
|
||||
{
|
||||
public class DeviceAlert
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -10,15 +10,10 @@ namespace Remotely.Shared.Models
|
||||
{
|
||||
public class RemotelyUser : IdentityUser
|
||||
{
|
||||
public RemotelyUser()
|
||||
{
|
||||
UserOptions = new RemotelyUserOptions();
|
||||
Organization = new Organization();
|
||||
}
|
||||
public RemotelyUserOptions UserOptions { get; set; }
|
||||
public RemotelyUserOptions UserOptions { get; set; } = new RemotelyUserOptions();
|
||||
|
||||
[JsonIgnore]
|
||||
public virtual Organization Organization { get; set; }
|
||||
public virtual Organization Organization { get; set; } = new Organization();
|
||||
public string OrganizationID { get; set; }
|
||||
|
||||
public bool IsAdministrator { get; set; } = true;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user