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."));
            }
        }
Beispiel #2
0
        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));
            }
        }