private async Task <IActionResult> InitiateRemoteControl(string deviceID, string orgID) { var targetDevice = AgentHub.ServiceConnections.FirstOrDefault(x => x.Value.OrganizationID == orgID && x.Value.ID.ToLower() == deviceID.ToLower()); if (targetDevice.Value != null) { if (User.Identity.IsAuthenticated && !DataService.DoesUserHaveAccessToDevice(targetDevice.Value.ID, DataService.GetUserByNameWithOrg(User.Identity.Name))) { return(Unauthorized()); } var currentUsers = CasterHub.SessionInfoList.Count(x => x.Value.OrganizationID == orgID); if (currentUsers >= AppConfig.RemoteControlSessionLimit) { return(BadRequest("There are already the maximum amount of active remote control sessions for your organization.")); } var existingSessions = CasterHub.SessionInfoList .Where(x => x.Value.DeviceID == targetDevice.Value.ID) .Select(x => x.Key) .ToList(); await AgentHubContext.Clients.Client(targetDevice.Key).SendAsync("RemoteControl", Request.HttpContext.Connection.Id, targetDevice.Key); bool remoteControlStarted() { return(!CasterHub.SessionInfoList.Values .Where(x => x.DeviceID == targetDevice.Value.ID) .All(x => existingSessions.Contains(x.CasterSocketID))); }; if (!await TaskHelper.DelayUntilAsync(remoteControlStarted, TimeSpan.FromSeconds(30))) { return(StatusCode(408, "The remote control process failed to start in time on the remote device.")); } else { var rcSession = CasterHub.SessionInfoList.Values.LastOrDefault(x => x.DeviceID == targetDevice.Value.ID && !existingSessions.Contains(x.CasterSocketID)); var otp = RemoteControlFilterAttribute.GetOtp(targetDevice.Value.ID); return(Ok($"{HttpContext.Request.Scheme}://{Request.Host}/RemoteControl?casterID={rcSession.CasterSocketID}&serviceID={targetDevice.Key}&fromApi=true&otp={Uri.EscapeDataString(otp)}")); } } else { return(BadRequest("The target device couldn't be found.")); } }
public async Task <Task> SendScreenCastRequestToDevice(string screenCasterID, string requesterName, int remoteControlMode, string otp) { if ((RemoteControlMode)remoteControlMode == RemoteControlMode.Normal) { if (!CasterHub.SessionInfoList.Any(x => x.Value.AttendedSessionID == screenCasterID)) { return(Clients.Caller.SendAsync("SessionIDNotFound")); } screenCasterID = CasterHub.SessionInfoList.First(x => x.Value.AttendedSessionID == screenCasterID).Value.CasterSocketID; } if (!CasterHub.SessionInfoList.TryGetValue(screenCasterID, out var sessionInfo)) { return(Clients.Caller.SendAsync("SessionIDNotFound")); } SessionInfo = sessionInfo; ScreenCasterID = screenCasterID; RequesterName = requesterName; Mode = (RemoteControlMode)remoteControlMode; string orgId = null; if (Context?.User?.Identity?.IsAuthenticated == true) { orgId = DataService.GetUserByID(Context.UserIdentifier).OrganizationID; var currentUsers = CasterHub.SessionInfoList.Count(x => x.Key != screenCasterID && x.Value.OrganizationID == orgId); if (currentUsers >= AppConfig.RemoteControlSessionLimit) { await Clients.Caller.SendAsync("ShowMessage", "Max number of concurrent sessions reached."); Context.Abort(); return(Task.CompletedTask); } SessionInfo.OrganizationID = orgId; SessionInfo.RequesterUserName = Context.User.Identity.Name; SessionInfo.RequesterSocketID = Context.ConnectionId; } DataService.WriteEvent(new EventLog() { EventType = EventType.Info, TimeStamp = DateTimeOffset.Now, Message = $"Remote control session requested. " + $"Login ID (if logged in): {Context?.User?.Identity?.Name}. " + $"Machine Name: {SessionInfo.MachineName}. " + $"Requester Name (if specified): {requesterName}. " + $"Connection ID: {Context.ConnectionId}. User ID: {Context.UserIdentifier}. " + $"Screen Caster ID: {screenCasterID}. " + $"Mode: {(RemoteControlMode)remoteControlMode}. " + $"Requester IP Address: " + Context?.GetHttpContext()?.Connection?.RemoteIpAddress?.ToString(), OrganizationID = orgId }); if (Mode == RemoteControlMode.Unattended) { SessionInfo.Mode = RemoteControlMode.Unattended; var deviceID = AgentHub.ServiceConnections[SessionInfo.ServiceID].ID; if ((!string.IsNullOrWhiteSpace(otp) && RemoteControlFilterAttribute.OtpMatchesDevice(otp, deviceID)) || (Context.User.Identity.IsAuthenticated && DataService.DoesUserHaveAccessToDevice(deviceID, Context.UserIdentifier))) { return(CasterHubContext.Clients.Client(screenCasterID).SendAsync("GetScreenCast", Context.ConnectionId, requesterName, AppConfig.RemoteControlNotifyUser)); } else { return(Clients.Caller.SendAsync("Unauthorized")); } } else { SessionInfo.Mode = RemoteControlMode.Normal; _ = Clients.Caller.SendAsync("RequestingScreenCast"); return(CasterHubContext.Clients.Client(screenCasterID).SendAsync("RequestScreenCast", Context.ConnectionId, requesterName, AppConfig.RemoteControlNotifyUser)); } }