mirror of
https://github.com/immense/Remotely.git
synced 2025-10-26 11:27:15 +00:00
Create AlertsController and DataService methods.
This commit is contained in:
parent
bbfceeeb6b
commit
68a0cc0d7e
@ -1,9 +1,15 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Remotely.Server.Auth;
|
||||
using Remotely.Server.Services;
|
||||
using Remotely.Shared.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Remotely.Server.API
|
||||
@ -13,27 +19,103 @@ namespace Remotely.Server.API
|
||||
[ServiceFilter(typeof(ApiAuthorizationFilter))]
|
||||
public class AlertsController : ControllerBase
|
||||
{
|
||||
public AlertsController(DataService dataService, IEmailSenderEx emailSender)
|
||||
{
|
||||
DataService = dataService;
|
||||
EmailSender = emailSender;
|
||||
}
|
||||
|
||||
private DataService DataService { get; }
|
||||
private IEmailSenderEx EmailSender { get; }
|
||||
|
||||
[HttpPost("Create")]
|
||||
[ServiceFilter(typeof(ApiAuthorizationFilter))]
|
||||
public async Task<IActionResult> Create(AlertOptions alertOptions)
|
||||
{
|
||||
Request.Headers.TryGetValue("OrganizationID", out var orgID);
|
||||
|
||||
DataService.WriteEvent("Alert created. Alert Options: " + JsonSerializer.Serialize(alertOptions), orgID);
|
||||
|
||||
if (alertOptions.ShouldAlert)
|
||||
{
|
||||
var alert = new Alert()
|
||||
try
|
||||
{
|
||||
CreatedOn = DateTimeOffset.Now,
|
||||
DeviceID = alertOptions.AlertDeviceID,
|
||||
Message = alertOptions.AlertMessage
|
||||
};
|
||||
// TODO: Add alert.
|
||||
var alert = new Alert()
|
||||
{
|
||||
CreatedOn = DateTimeOffset.Now,
|
||||
DeviceID = alertOptions.AlertDeviceID,
|
||||
Message = alertOptions.AlertMessage,
|
||||
OrganizationID = orgID
|
||||
};
|
||||
await DataService.AddAlert(alert);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DataService.WriteEvent(ex, orgID);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Email.
|
||||
if (alertOptions.ShouldEmail)
|
||||
{
|
||||
try
|
||||
{
|
||||
await EmailSender.SendEmailAsync(alertOptions.EmailTo,
|
||||
alertOptions.EmailSubject,
|
||||
alertOptions.EmailBody,
|
||||
orgID);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DataService.WriteEvent(ex, orgID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO: API request.
|
||||
if (alertOptions.ShouldSendApiRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
var httpRequest = WebRequest.CreateHttp(alertOptions.ApiRequestUrl);
|
||||
httpRequest.Method = alertOptions.ApiRequestMethod;
|
||||
httpRequest.ContentType = "application/json";
|
||||
foreach (var header in alertOptions.ApiRequestHeaders)
|
||||
{
|
||||
httpRequest.Headers.Add(header.Key, header.Value);
|
||||
}
|
||||
using (var rs = httpRequest.GetRequestStream())
|
||||
using (var sw = new StreamWriter(rs))
|
||||
{
|
||||
sw.Write(alertOptions.ApiRequestBody);
|
||||
}
|
||||
var response = (HttpWebResponse)httpRequest.GetResponse();
|
||||
DataService.WriteEvent($"Alert API Response Status: {response.StatusCode}.", orgID);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DataService.WriteEvent(ex, orgID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPost("Delete/{alertID}")]
|
||||
[ServiceFilter(typeof(ApiAuthorizationFilter))]
|
||||
public async Task<IActionResult> Delete(string alertID)
|
||||
{
|
||||
Request.Headers.TryGetValue("OrganizationID", out var orgID);
|
||||
|
||||
var alert = await DataService.GetAlert(alertID);
|
||||
|
||||
if (alert?.OrganizationID == orgID)
|
||||
{
|
||||
await DataService.DeleteAlert(alert);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
return Unauthorized();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,8 @@ namespace Remotely.Server.Data
|
||||
{
|
||||
}
|
||||
|
||||
public DbSet<Alert> Alerts { get; set; }
|
||||
|
||||
public DbSet<ApiToken> ApiTokens { get; set; }
|
||||
|
||||
public DbSet<CommandResult> CommandResults { get; set; }
|
||||
@ -74,6 +76,9 @@ namespace Remotely.Server.Data
|
||||
builder.Entity<Organization>()
|
||||
.HasMany(x => x.ApiTokens)
|
||||
.WithOne(x => x.Organization);
|
||||
builder.Entity<Organization>()
|
||||
.HasMany(x => x.Alerts)
|
||||
.WithOne(x => x.Organization);
|
||||
|
||||
|
||||
builder.Entity<CommandResult>()
|
||||
@ -122,6 +127,9 @@ namespace Remotely.Server.Data
|
||||
|
||||
builder.Entity<Device>()
|
||||
.HasIndex(x => x.DeviceName);
|
||||
builder.Entity<Device>()
|
||||
.HasMany(x => x.Alerts)
|
||||
.WithOne(x => x.Device);
|
||||
|
||||
builder.Entity<ApiToken>()
|
||||
.HasIndex(x => x.Token);
|
||||
|
||||
@ -34,6 +34,12 @@ namespace Remotely.Server.Services
|
||||
private ApplicationDbContext RemotelyContext { get; }
|
||||
private UserManager<RemotelyUser> UserManager { get; }
|
||||
|
||||
public async Task AddAlert(Alert alert)
|
||||
{
|
||||
RemotelyContext.Alerts.Add(alert);
|
||||
await RemotelyContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public bool AddDeviceGroup(string orgID, DeviceGroup deviceGroup, out string deviceGroupID, out string errorMessage)
|
||||
{
|
||||
deviceGroupID = null;
|
||||
@ -64,12 +70,9 @@ namespace Remotely.Server.Services
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<string> GetServerAdmins()
|
||||
public async Task<Alert> GetAlert(string alertID)
|
||||
{
|
||||
return RemotelyContext.Users
|
||||
.Where(x => x.IsServerAdmin)
|
||||
.Select(x => x.UserName)
|
||||
.ToList();
|
||||
return await RemotelyContext.Alerts.FirstOrDefaultAsync(x => x.ID == alertID);
|
||||
}
|
||||
|
||||
public InviteLink AddInvite(string orgID, Invite invite)
|
||||
@ -109,7 +112,6 @@ namespace Remotely.Server.Services
|
||||
RemotelyContext.SaveChanges();
|
||||
}
|
||||
|
||||
|
||||
public bool AddOrUpdateDevice(Device device, out Device updatedDevice)
|
||||
{
|
||||
var existingDevice = RemotelyContext.Devices.Find(device.ID);
|
||||
@ -161,31 +163,6 @@ namespace Remotely.Server.Services
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task UpdateServerAdmins(List<string> serverAdmins, string callerUserName)
|
||||
{
|
||||
var currentAdmins = RemotelyContext.Users.Where(x => x.IsServerAdmin).ToList();
|
||||
|
||||
var removeAdmins = currentAdmins.Where(currentAdmin =>
|
||||
!serverAdmins.Contains(currentAdmin.UserName.Trim().ToLower()) &&
|
||||
currentAdmin.UserName.Trim().ToLower() != callerUserName.Trim().ToLower());
|
||||
|
||||
foreach (var removeAdmin in removeAdmins)
|
||||
{
|
||||
removeAdmin.IsServerAdmin = false;
|
||||
}
|
||||
|
||||
var newAdmins = RemotelyContext.Users.Where(user =>
|
||||
serverAdmins.Contains(user.UserName.Trim().ToLower()) &&
|
||||
!user.IsServerAdmin);
|
||||
|
||||
foreach (var newAdmin in newAdmins)
|
||||
{
|
||||
newAdmin.IsServerAdmin = true;
|
||||
}
|
||||
|
||||
await RemotelyContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public string AddSharedFile(IFormFile file, string organizationID)
|
||||
{
|
||||
var expirationDate = DateTimeOffset.Now.AddDays(-AppConfig.DataRetentionInDays);
|
||||
@ -212,6 +189,60 @@ namespace Remotely.Server.Services
|
||||
return newEntity.Entity.ID;
|
||||
}
|
||||
|
||||
public bool AddUserToDeviceGroup(string orgID, string groupID, string userName, out string resultMessage)
|
||||
{
|
||||
resultMessage = string.Empty;
|
||||
|
||||
var deviceGroup = RemotelyContext.DeviceGroups
|
||||
.Include(x => x.PermissionLinks)
|
||||
.FirstOrDefault(x =>
|
||||
x.ID == groupID &&
|
||||
x.OrganizationID == orgID);
|
||||
|
||||
if (deviceGroup == null)
|
||||
{
|
||||
resultMessage = "Device group not found.";
|
||||
return false;
|
||||
}
|
||||
|
||||
userName = userName.Trim().ToLower();
|
||||
|
||||
var user = RemotelyContext.Users
|
||||
.Include(x => x.PermissionLinks)
|
||||
.FirstOrDefault(x =>
|
||||
x.UserName.ToLower() == userName &&
|
||||
x.OrganizationID == orgID);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
resultMessage = "User not found.";
|
||||
return false;
|
||||
}
|
||||
|
||||
deviceGroup.PermissionLinks = deviceGroup.PermissionLinks ?? new List<UserDevicePermission>();
|
||||
user.PermissionLinks = user.PermissionLinks ?? new List<UserDevicePermission>();
|
||||
|
||||
if (deviceGroup.PermissionLinks.Any(x => x.UserID == user.Id))
|
||||
{
|
||||
resultMessage = "User already in group.";
|
||||
return false;
|
||||
}
|
||||
|
||||
var link = new UserDevicePermission()
|
||||
{
|
||||
DeviceGroup = deviceGroup,
|
||||
DeviceGroupID = deviceGroup.ID,
|
||||
User = user,
|
||||
UserID = user.Id
|
||||
};
|
||||
|
||||
deviceGroup.PermissionLinks.Add(link);
|
||||
user.PermissionLinks.Add(link);
|
||||
RemotelyContext.SaveChanges();
|
||||
resultMessage = user.Id;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ChangeUserIsAdmin(string organizationID, string targetUserID, bool isAdmin)
|
||||
{
|
||||
var targetUser = RemotelyContext.Users.FirstOrDefault(x =>
|
||||
@ -267,7 +298,6 @@ namespace Remotely.Server.Services
|
||||
return newToken;
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool> CreateUser(string userEmail, bool isAdmin, string organizationID)
|
||||
{
|
||||
try
|
||||
@ -280,8 +310,8 @@ namespace Remotely.Server.Services
|
||||
OrganizationID = organizationID
|
||||
};
|
||||
var org = RemotelyContext.Organizations
|
||||
.Include(x=>x.RemotelyUsers)
|
||||
.FirstOrDefault(x=>x.ID == organizationID);
|
||||
.Include(x => x.RemotelyUsers)
|
||||
.FirstOrDefault(x => x.ID == organizationID);
|
||||
org.RemotelyUsers.Add(user);
|
||||
await RemotelyContext.SaveChangesAsync();
|
||||
return true;
|
||||
@ -294,6 +324,11 @@ namespace Remotely.Server.Services
|
||||
|
||||
}
|
||||
|
||||
public async Task DeleteAlert(Alert alert)
|
||||
{
|
||||
RemotelyContext.Alerts.Remove(alert);
|
||||
await RemotelyContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task DeleteApiToken(string userName, string tokenId)
|
||||
{
|
||||
@ -401,7 +436,7 @@ namespace Remotely.Server.Services
|
||||
return RemotelyContext.Devices
|
||||
.Include(x => x.DeviceGroup)
|
||||
.ThenInclude(x => x.PermissionLinks)
|
||||
.Where(device =>
|
||||
.Where(device =>
|
||||
device.OrganizationID == remotelyUser.OrganizationID &&
|
||||
deviceIDs.Contains(device.ID) &&
|
||||
(
|
||||
@ -437,7 +472,6 @@ namespace Remotely.Server.Services
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
|
||||
public IEnumerable<ApiToken> GetAllApiTokens(string userID)
|
||||
{
|
||||
var user = RemotelyContext.Users.FirstOrDefault(x => x.Id == userID);
|
||||
@ -540,12 +574,12 @@ namespace Remotely.Server.Services
|
||||
return RemotelyContext.DeviceGroups
|
||||
.Include(x => x.PermissionLinks)
|
||||
.ThenInclude(x => x.User)
|
||||
.Where(x =>
|
||||
x.OrganizationID == user.OrganizationID &&
|
||||
.Where(x =>
|
||||
x.OrganizationID == user.OrganizationID &&
|
||||
(
|
||||
user.IsAdministrator ||
|
||||
x.PermissionLinks.Count == 0 ||
|
||||
x.PermissionLinks.Any(x=>x.UserID == user.Id)
|
||||
x.PermissionLinks.Any(x => x.UserID == user.Id)
|
||||
)
|
||||
) ?? Enumerable.Empty<DeviceGroup>();
|
||||
}
|
||||
@ -558,7 +592,7 @@ namespace Remotely.Server.Services
|
||||
return RemotelyContext.Devices
|
||||
.Include(x => x.DeviceGroup)
|
||||
.ThenInclude(x => x.PermissionLinks)
|
||||
.Where(x =>
|
||||
.Where(x =>
|
||||
x.OrganizationID == user.OrganizationID &&
|
||||
(
|
||||
user.IsAdministrator ||
|
||||
@ -599,6 +633,14 @@ namespace Remotely.Server.Services
|
||||
{
|
||||
return RemotelyContext.Organizations.FirstOrDefault(x => x.ID == organizationID)?.OrganizationName;
|
||||
}
|
||||
|
||||
public List<string> GetServerAdmins()
|
||||
{
|
||||
return RemotelyContext.Users
|
||||
.Where(x => x.IsServerAdmin)
|
||||
.Select(x => x.UserName)
|
||||
.ToList();
|
||||
}
|
||||
public SharedFile GetSharedFiled(string fileID)
|
||||
{
|
||||
return RemotelyContext.SharedFiles.Find(fileID);
|
||||
@ -692,60 +734,6 @@ namespace Remotely.Server.Services
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool AddUserToDeviceGroup(string orgID, string groupID, string userName, out string resultMessage)
|
||||
{
|
||||
resultMessage = string.Empty;
|
||||
|
||||
var deviceGroup = RemotelyContext.DeviceGroups
|
||||
.Include(x => x.PermissionLinks)
|
||||
.FirstOrDefault(x =>
|
||||
x.ID == groupID &&
|
||||
x.OrganizationID == orgID);
|
||||
|
||||
if (deviceGroup == null)
|
||||
{
|
||||
resultMessage = "Device group not found.";
|
||||
return false;
|
||||
}
|
||||
|
||||
userName = userName.Trim().ToLower();
|
||||
|
||||
var user = RemotelyContext.Users
|
||||
.Include(x => x.PermissionLinks)
|
||||
.FirstOrDefault(x =>
|
||||
x.UserName.ToLower() == userName &&
|
||||
x.OrganizationID == orgID);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
resultMessage = "User not found.";
|
||||
return false;
|
||||
}
|
||||
|
||||
deviceGroup.PermissionLinks = deviceGroup.PermissionLinks ?? new List<UserDevicePermission>();
|
||||
user.PermissionLinks = user.PermissionLinks ?? new List<UserDevicePermission>();
|
||||
|
||||
if (deviceGroup.PermissionLinks.Any(x => x.UserID == user.Id))
|
||||
{
|
||||
resultMessage = "User already in group.";
|
||||
return false;
|
||||
}
|
||||
|
||||
var link = new UserDevicePermission()
|
||||
{
|
||||
DeviceGroup = deviceGroup,
|
||||
DeviceGroupID = deviceGroup.ID,
|
||||
User = user,
|
||||
UserID = user.Id
|
||||
};
|
||||
|
||||
deviceGroup.PermissionLinks.Add(link);
|
||||
user.PermissionLinks.Add(link);
|
||||
RemotelyContext.SaveChanges();
|
||||
resultMessage = user.Id;
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task RemoveUserFromOrganization(string orgID, string targetUserID)
|
||||
{
|
||||
var target = RemotelyContext.Users
|
||||
@ -845,6 +833,30 @@ namespace Remotely.Server.Services
|
||||
RemotelyContext.SaveChanges();
|
||||
}
|
||||
|
||||
public async Task UpdateServerAdmins(List<string> serverAdmins, string callerUserName)
|
||||
{
|
||||
var currentAdmins = RemotelyContext.Users.Where(x => x.IsServerAdmin).ToList();
|
||||
|
||||
var removeAdmins = currentAdmins.Where(currentAdmin =>
|
||||
!serverAdmins.Contains(currentAdmin.UserName.Trim().ToLower()) &&
|
||||
currentAdmin.UserName.Trim().ToLower() != callerUserName.Trim().ToLower());
|
||||
|
||||
foreach (var removeAdmin in removeAdmins)
|
||||
{
|
||||
removeAdmin.IsServerAdmin = false;
|
||||
}
|
||||
|
||||
var newAdmins = RemotelyContext.Users.Where(user =>
|
||||
serverAdmins.Contains(user.UserName.Trim().ToLower()) &&
|
||||
!user.IsServerAdmin);
|
||||
|
||||
foreach (var newAdmin in newAdmins)
|
||||
{
|
||||
newAdmin.IsServerAdmin = true;
|
||||
}
|
||||
|
||||
await RemotelyContext.SaveChangesAsync();
|
||||
}
|
||||
public void UpdateTags(string deviceID, string tags)
|
||||
{
|
||||
var device = RemotelyContext.Devices.Find(deviceID);
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Remotely.Shared.Models
|
||||
{
|
||||
@ -10,9 +11,17 @@ namespace Remotely.Shared.Models
|
||||
[Key]
|
||||
public string ID { get; set; } = Guid.NewGuid().ToString();
|
||||
public DateTimeOffset CreatedOn { get; set; } = DateTimeOffset.Now;
|
||||
|
||||
[JsonIgnore]
|
||||
public Device Device { get; set; }
|
||||
public string DeviceID { get; set; }
|
||||
public string Message { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Organization Organization { get; set; }
|
||||
|
||||
public string OrganizationID { get; set; }
|
||||
|
||||
public ICollection<RemotelyUser> SeenBy { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ namespace Remotely.Shared.Models
|
||||
public class Device
|
||||
{
|
||||
public string AgentVersion { get; set; }
|
||||
public ICollection<Alert> Alerts { get; set; }
|
||||
[StringLength(100)]
|
||||
public string Alias { get; set; }
|
||||
public double CpuUtilization { get; set; }
|
||||
|
||||
@ -7,6 +7,8 @@ namespace Remotely.Shared.Models
|
||||
{
|
||||
public class Organization
|
||||
{
|
||||
public ICollection<Alert> Alerts { get; set; }
|
||||
|
||||
public ICollection<ApiToken> ApiTokens { get; set; }
|
||||
|
||||
public ICollection<CommandResult> CommandResults { get; set; }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user