diff --git a/Server/Pages/EditDevice.cshtml.cs b/Server/Pages/EditDevice.cshtml.cs
index fb3fe226..24a1aec3 100644
--- a/Server/Pages/EditDevice.cshtml.cs
+++ b/Server/Pages/EditDevice.cshtml.cs
@@ -31,10 +31,21 @@ namespace Remotely.Server.Pages
private DataService DataService { get; }
- public void OnGet(string deviceID, bool success)
+ public IActionResult OnGet(string deviceID, bool success)
{
+ var user = DataService.GetUserByName(User.Identity.Name);
+ if (!DataService.DoesUserHaveAccessToDevice(deviceID, user))
+ {
+ var targetDevice = DataService.GetDevice(deviceID);
+ DataService.WriteEvent($"Edit device attempted by unauthorized user. Device ID: {deviceID}. User Name: {user.UserName}.",
+ Remotely.Shared.Models.EventType.Warning,
+ targetDevice.OrganizationID);
+ return Unauthorized();
+ }
SaveSucessful = success;
PopulateViewModel(deviceID);
+
+ return Page();
}
public IActionResult OnPost(string deviceID)
diff --git a/Server/Services/BrowserSocketHub.cs b/Server/Services/BrowserSocketHub.cs
index 17684a7f..093b6ce0 100644
--- a/Server/Services/BrowserSocketHub.cs
+++ b/Server/Services/BrowserSocketHub.cs
@@ -134,9 +134,9 @@ namespace Remotely.Server.Services
public Task RemoteControl(string deviceID)
{
- if (DataService.DoesUserHaveAccessToDevice(deviceID, RemotelyUser))
+ var targetDevice = DeviceSocketHub.ServiceConnections.FirstOrDefault(x => x.Value.ID == deviceID);
+ if (DataService.DoesUserHaveAccessToDevice(deviceID, RemotelyUser))
{
- var targetDevice = DeviceSocketHub.ServiceConnections.FirstOrDefault(x => x.Value.ID == deviceID);
var currentUsers = RCDeviceSocketHub.SessionInfoList.Count(x => x.Value.OrganizationID == RemotelyUser.OrganizationID);
if (currentUsers >= AppConfig.RemoteControlSessionLimit)
{
@@ -145,6 +145,10 @@ namespace Remotely.Server.Services
Clients.Caller.SendAsync("ServiceID", targetDevice.Key);
return DeviceHub.Clients.Client(targetDevice.Key).SendAsync("RemoteControl", Context.ConnectionId, targetDevice.Key);
}
+ else
+ {
+ DataService.WriteEvent($"Remote control attempted by unauthorized user. Device ID: {deviceID}. User Name: {RemotelyUser.UserName}.", EventType.Warning, targetDevice.Value.OrganizationID);
+ }
return Task.CompletedTask;
}
diff --git a/Server/Services/DataService.cs b/Server/Services/DataService.cs
index 2c02c812..0b52bb7d 100644
--- a/Server/Services/DataService.cs
+++ b/Server/Services/DataService.cs
@@ -380,12 +380,12 @@ namespace Remotely.Server.Services
return RemotelyContext.Devices
.Include(x => x.DeviceGroup)
.ThenInclude(x => x.PermissionLinks)
- .Any(x => x.OrganizationID == remotelyUser.OrganizationID &&
- x.ID == deviceID &&
+ .Any(device => device.OrganizationID == remotelyUser.OrganizationID &&
+ device.ID == deviceID &&
(
remotelyUser.IsAdministrator ||
- x.DeviceGroup.PermissionLinks.Count == 0 ||
- x.DeviceGroup.PermissionLinks.Any(x => x.UserID == remotelyUser.Id
+ device.DeviceGroup.PermissionLinks.Count == 0 ||
+ device.DeviceGroup.PermissionLinks.Any(permission => permission.UserID == remotelyUser.Id
)));
}
@@ -401,18 +401,42 @@ namespace Remotely.Server.Services
return RemotelyContext.Devices
.Include(x => x.DeviceGroup)
.ThenInclude(x => x.PermissionLinks)
- .Where(x =>
- x.OrganizationID == remotelyUser.OrganizationID &&
- deviceIDs.Contains(x.ID) &&
+ .Where(device =>
+ device.OrganizationID == remotelyUser.OrganizationID &&
+ deviceIDs.Contains(device.ID) &&
(
remotelyUser.IsAdministrator ||
- x.DeviceGroup.PermissionLinks.Count == 0 ||
- x.DeviceGroup.PermissionLinks.Any(x => x.UserID == remotelyUser.Id
+ device.DeviceGroup.PermissionLinks.Count == 0 ||
+ device.DeviceGroup.PermissionLinks.Any(permission => permission.UserID == remotelyUser.Id
)))
.Select(x => x.ID)
.ToArray();
}
+ public IEnumerable FilterUsersByDevicePermission(IEnumerable userIDs, string deviceID)
+ {
+ var device = RemotelyContext.Devices
+ .Include(x => x.DeviceGroup)
+ .ThenInclude(x => x.PermissionLinks)
+ .FirstOrDefault(x => x.ID == deviceID);
+
+ var allowedUsers = device.DeviceGroup.PermissionLinks.Select(x => x.UserID);
+
+ return RemotelyContext.Users
+ .Include(x => x.PermissionLinks)
+ .Where(user =>
+ user.OrganizationID == device.OrganizationID &&
+ userIDs.Contains(user.Id) &&
+ (
+ user.IsAdministrator ||
+ device.DeviceGroup.PermissionLinks.Count == 0 ||
+ allowedUsers.Contains(user.Id)
+ )
+ )
+ .Select(x => x.Id);
+ }
+
+
public IEnumerable GetAllApiTokens(string userID)
{
var user = RemotelyContext.Users.FirstOrDefault(x => x.Id == userID);
@@ -493,6 +517,11 @@ namespace Remotely.Server.Services
x.ID == deviceID);
}
+ public Device GetDevice(string deviceID)
+ {
+ return RemotelyContext.Devices.FirstOrDefault(x => x.ID == deviceID);
+ }
+
public int GetDeviceCount()
{
return RemotelyContext.Devices.Count();
@@ -533,7 +562,7 @@ namespace Remotely.Server.Services
(
user.IsAdministrator ||
x.DeviceGroup.PermissionLinks.Count == 0 ||
- x.DeviceGroup.PermissionLinks.Any(x => x.UserID == userID
+ x.DeviceGroup.PermissionLinks.Any(permission => permission.UserID == userID
)));
}
diff --git a/Server/Services/DeviceSocketHub.cs b/Server/Services/DeviceSocketHub.cs
index 67d9d9a0..56f94b8b 100644
--- a/Server/Services/DeviceSocketHub.cs
+++ b/Server/Services/DeviceSocketHub.cs
@@ -92,11 +92,16 @@ namespace Remotely.Server.Services
{
Device = updatedDevice;
ServiceConnections.AddOrUpdate(Context.ConnectionId, Device, (id, d) => Device);
+
+ var userIDs = BrowserSocketHub.ConnectionIdToUserLookup.Values.Select(x => x.Id);
+
+ var filteredUserIDs = DataService.FilterUsersByDevicePermission(userIDs, Device.ID);
var connectionIds = BrowserSocketHub.ConnectionIdToUserLookup
- .Where(x => x.Value.OrganizationID == Device.OrganizationID)
- .Select(x => x.Key)
- .ToList();
+ .Where(x => x.Value.OrganizationID == Device.OrganizationID &&
+ filteredUserIDs.Contains(x.Value.Id))
+ .Select(x => x.Key)
+ .ToList();
BrowserHub.Clients.Clients(connectionIds).SendAsync("DeviceCameOnline", Device);
return Task.FromResult(true);
@@ -120,10 +125,16 @@ namespace Remotely.Server.Services
{
DataService.AddOrUpdateDevice(device, out var updatedDevice);
Device = updatedDevice;
+
+ var userIDs = BrowserSocketHub.ConnectionIdToUserLookup.Values.Select(x => x.Id);
+
+ var filteredUserIDs = DataService.FilterUsersByDevicePermission(userIDs, Device.ID);
+
var connectionIds = BrowserSocketHub.ConnectionIdToUserLookup
- .Where(x => x.Value.OrganizationID == Device.OrganizationID)
- .Select(x => x.Key)
- .ToList();
+ .Where(x => x.Value.OrganizationID == Device.OrganizationID &&
+ filteredUserIDs.Contains(x.Value.Id))
+ .Select(x => x.Key)
+ .ToList();
return BrowserHub.Clients.Clients(connectionIds).SendAsync("DeviceHeartbeat", Device);
}