Skip to content

Commit

Permalink
Create new convention for transferring DTOs to entities.
Browse files Browse the repository at this point in the history
  • Loading branch information
bitbound committed Jul 26, 2023
1 parent c8d1e9c commit 6e1c231
Show file tree
Hide file tree
Showing 11 changed files with 126 additions and 83 deletions.
13 changes: 7 additions & 6 deletions Agent/Services/ExternalScriptingShell.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Immense.RemoteControl.Shared.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Remotely.Shared.Dtos;
using Remotely.Shared.Enums;
using Remotely.Shared.Models;
using System;
Expand All @@ -17,7 +18,7 @@ public interface IExternalScriptingShell
{
Process? ShellProcess { get; }
Task Init(ScriptingShell shell, string shellProcessName, string lineEnding, string connectionId);
Task<ScriptResult> WriteInput(string input, TimeSpan timeout);
Task<ScriptResultDto> WriteInput(string input, TimeSpan timeout);
}

public class ExternalScriptingShell : IExternalScriptingShell
Expand Down Expand Up @@ -129,7 +130,7 @@ public async Task Init(ScriptingShell shell, string shellProcessName, string lin
}
}

public async Task<ScriptResult> WriteInput(string input, TimeSpan timeout)
public async Task<ScriptResultDto> WriteInput(string input, TimeSpan timeout)
{
await _writeLock.WaitAsync();
var sw = Stopwatch.StartNew();
Expand Down Expand Up @@ -186,9 +187,9 @@ public async Task<ScriptResult> WriteInput(string input, TimeSpan timeout)
return GeneratePartialResult(input, sw.Elapsed);
}

private ScriptResult GenerateCompletedResult(string input, TimeSpan runtime)
private ScriptResultDto GenerateCompletedResult(string input, TimeSpan runtime)
{
return new ScriptResult()
return new ScriptResultDto()
{
Shell = _shell,
RunTime = runtime,
Expand All @@ -202,9 +203,9 @@ private ScriptResult GenerateCompletedResult(string input, TimeSpan runtime)
};
}

private ScriptResult GeneratePartialResult(string input, TimeSpan runtime)
private ScriptResultDto GeneratePartialResult(string input, TimeSpan runtime)
{
var partialResult = new ScriptResult()
var partialResult = new ScriptResultDto()
{
Shell = _shell,
RunTime = runtime,
Expand Down
9 changes: 5 additions & 4 deletions Agent/Services/PsCoreShell.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Remotely.Shared.Dtos;
using Remotely.Shared.Models;
using System;
using System.Collections.Concurrent;
Expand All @@ -15,7 +16,7 @@ public interface IPsCoreShell
string? SenderConnectionId { get; set; }

CommandCompletion GetCompletions(string inputText, int currentIndex, bool? forward);
Task<ScriptResult> WriteInput(string input);
Task<ScriptResultDto> WriteInput(string input);
}

public class PsCoreShell : IPsCoreShell
Expand Down Expand Up @@ -83,7 +84,7 @@ public CommandCompletion GetCompletions(string inputText, int currentIndex, bool
return _lastCompletion;
}

public async Task<ScriptResult> WriteInput(string input)
public async Task<ScriptResultDto> WriteInput(string input)
{
var deviceId = _configService.GetConnectionInfo().DeviceID;
var sw = Stopwatch.StartNew();
Expand Down Expand Up @@ -121,7 +122,7 @@ public async Task<ScriptResult> WriteInput(string input)
var errorAndWarningOut = errorOut.Concat(warningOut).ToArray();


return new ScriptResult()
return new ScriptResultDto()
{
DeviceID = _configService.GetConnectionInfo().DeviceID,
SenderConnectionID = SenderConnectionId,
Expand All @@ -136,7 +137,7 @@ public async Task<ScriptResult> WriteInput(string input)
catch (Exception ex)
{
_logger.LogError(ex, "Error while writing input to PSCore.");
return new ScriptResult()
return new ScriptResultDto()
{
DeviceID = deviceId,
SenderConnectionID = SenderConnectionId,
Expand Down
5 changes: 3 additions & 2 deletions Agent/Services/ScriptExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Remotely.Shared;
using Remotely.Shared.Dtos;
using Remotely.Shared.Enums;
using Remotely.Shared.Models;
using Remotely.Shared.Utilities;
Expand Down Expand Up @@ -151,7 +152,7 @@ public async Task RunScript(Guid savedScriptId,
}
}

private async Task<ScriptResult> ExecuteScriptContent(
private async Task<ScriptResultDto> ExecuteScriptContent(
ScriptingShell shell,
string terminalSessionId,
string command,
Expand Down Expand Up @@ -196,7 +197,7 @@ private async Task<ScriptResult> ExecuteScriptContent(
}
throw new InvalidOperationException($"Unknown shell type: {shell}");
}
private async Task<ScriptResultResponse?> SendResultsToApi(ScriptResult result, string expiringToken)
private async Task<ScriptResultResponse?> SendResultsToApi(ScriptResultDto result, string expiringToken)
{
var targetURL = _configService.GetConnectionInfo().Host + $"/API/ScriptResults";

Expand Down
29 changes: 22 additions & 7 deletions Server/API/ScriptResultsController.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
using Microsoft.AspNetCore.Mvc;
using Immense.RemoteControl.Shared.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Build.Framework;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Remotely.Server.Auth;
using Remotely.Server.Extensions;
using Remotely.Server.Services;
using Remotely.Shared.Dtos;
using Remotely.Shared.Models;
using System;
using System.Text;
Expand All @@ -16,11 +20,16 @@ public class ScriptResultsController : ControllerBase
{
private readonly IDataService _dataService;
private readonly IEmailSenderEx _emailSender;
private readonly ILogger<ScriptResultsController> _logger;

public ScriptResultsController(IDataService dataService, IEmailSenderEx emailSenderEx)
public ScriptResultsController(
IDataService dataService,
IEmailSenderEx emailSenderEx,
ILogger<ScriptResultsController> logger)
{
_dataService = dataService;
_emailSender = emailSenderEx;
_logger = logger;
}

[HttpGet]
Expand Down Expand Up @@ -54,9 +63,15 @@ public ActionResult<FileResult> DownloadResults(string scriptId)

[HttpPost]
[ServiceFilter(typeof(ExpiringTokenFilter))]
public async Task<ActionResult<ScriptResultResponse>> Post([FromBody] ScriptResult result)
public async Task<ActionResult<ScriptResultResponse>> Post([FromBody] ScriptResultDto result)
{
_dataService.AddOrUpdateScriptResult(result);
var scriptResult = await _dataService.AddScriptResult(result);

if (!scriptResult.IsSuccess)
{
_logger.LogResult(scriptResult);
return BadRequest();
}

var errorOut = result.ErrorOutput ?? Array.Empty<string>();

Expand All @@ -72,7 +87,7 @@ public async Task<ActionResult<ScriptResultResponse>> Post([FromBody] ScriptResu
if (savedScript.GenerateAlertOnError)
{
await _dataService.AddAlert(result.DeviceID,
result.OrganizationID,
savedScript.OrganizationID,
$"Alert triggered while running script {savedScript.Name}.",
string.Join("\n", errorOut));
}
Expand Down Expand Up @@ -108,12 +123,12 @@ await _emailSender.SendEmailAsync(savedScript.SendErrorEmailTo,

if (result.ScriptRunId.HasValue)
{
await _dataService.AddScriptResultToScriptRun(result.ID, result.ScriptRunId.Value);
await _dataService.AddScriptResultToScriptRun(scriptResult.Value.ID, result.ScriptRunId.Value);
}

return new ScriptResultResponse()
{
Id = result.ID
Id = scriptResult.Value.ID
};
}
}
2 changes: 2 additions & 0 deletions Server/Components/AuthComponentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ protected override async Task OnInitializedAsync()

public bool IsAuthenticated { get; private set; }

public bool IsUserSet => _user is not null;

public RemotelyUser User
{
get => _user ?? throw new InvalidOperationException("User has not been resolved yet.");
Expand Down
6 changes: 3 additions & 3 deletions Server/Components/AuthorizedIndex.razor
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
<DevicesFrame />
<ChatFrame />

@code {
@code {

protected override void OnAfterRender(bool firstRender)
{
if (AppConfig.Require2FA && !User.TwoFactorEnabled)
if (AppConfig.Require2FA && IsUserSet && !User.TwoFactorEnabled)
{
NavManager.NavigateTo("/TwoFactorRequired");
}
Expand All @@ -31,7 +31,7 @@
{
await base.OnInitializedAsync();

if (IsAuthenticated == true && User is null)
if (IsAuthenticated == true && !IsUserSet)
{
await SignInManager.SignOutAsync();
NavManager.NavigateTo("/");
Expand Down
57 changes: 27 additions & 30 deletions Server/Services/DataService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,9 @@ public interface IDataService

Task<Result> AddOrUpdateSavedScript(SavedScript script, string userId);

void AddOrUpdateScriptResult(ScriptResult scriptResult);

Task AddOrUpdateScriptSchedule(ScriptSchedule schedule);

Task<Result<ScriptResult>> AddScriptResult(ScriptResultDto dto);
Task<Result> AddScriptResultToScriptRun(string scriptResultId, int scriptRunId);

Task AddScriptRun(ScriptRun scriptRun);
Expand Down Expand Up @@ -228,8 +227,8 @@ Task UpdateBrandingInfo(
public class DataService : IDataService
{
private readonly IApplicationConfig _appConfig;
private readonly IHostEnvironment _hostEnvironment;
private readonly IAppDbFactory _appDbFactory;
private readonly IHostEnvironment _hostEnvironment;
private readonly ILogger<DataService> _logger;

public DataService(
Expand Down Expand Up @@ -446,33 +445,6 @@ public async Task<Result> AddOrUpdateSavedScript(SavedScript script, string user
return Result.Ok();
}

public void AddOrUpdateScriptResult(ScriptResult result)
{
using var dbContext = _appDbFactory.GetContext();

var device = dbContext.Devices.Find(result.DeviceID);

if (device is null)
{
return;
}

result.OrganizationID = device.OrganizationID;

var existingResult = dbContext.ScriptResults.Find(result.ID);
if (existingResult is not null)
{
var entry = dbContext.Entry(existingResult);
entry.CurrentValues.SetValues(result);
entry.State = EntityState.Modified;
}
else
{
dbContext.ScriptResults.Add(result);
}
dbContext.SaveChanges();
}

public async Task AddOrUpdateScriptSchedule(ScriptSchedule schedule)
{
using var dbContext = _appDbFactory.GetContext();
Expand Down Expand Up @@ -516,6 +488,31 @@ public async Task AddOrUpdateScriptSchedule(ScriptSchedule schedule)
await dbContext.SaveChangesAsync();
}

public async Task<Result<ScriptResult>> AddScriptResult(ScriptResultDto dto)
{
using var dbContext = _appDbFactory.GetContext();

var device = dbContext.Devices.Find(dto.DeviceID);

if (device is null)
{
return Result.Fail<ScriptResult>("Device not found.");
}

var scriptResult = new ScriptResult
{
DeviceID = dto.DeviceID,
OrganizationID = device.OrganizationID
};

var entry = dbContext.Attach(scriptResult);
entry.CurrentValues.SetValues(dto);
entry.State = EntityState.Added;
await dbContext.ScriptResults.AddAsync(scriptResult);
await dbContext.SaveChangesAsync();
return Result.Ok(scriptResult);
}

public async Task<Result> AddScriptResultToScriptRun(string scriptResultId, int scriptRunId)
{
using var dbContext = _appDbFactory.GetContext();
Expand Down
37 changes: 37 additions & 0 deletions Shared/DtoEntityBases/ScriptResultBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Remotely.Shared.Enums;
using Remotely.Shared.Models;
using Remotely.Shared.Utilities;
using System;
using System.Text.Json.Serialization;

namespace Remotely.Shared.DtoEntityBases;

public abstract class ScriptResultBase
{
public virtual required string DeviceID { get; set; }

public virtual string[]? ErrorOutput { get; set; }

public virtual bool HadErrors { get; set; }

public virtual ScriptInputType InputType { get; set; }

[JsonConverter(typeof(TimeSpanJsonConverter))]
public virtual TimeSpan RunTime { get; set; }

public virtual string ScriptInput { get; set; } = string.Empty;

public virtual int? ScheduleId { get; set; }
public virtual Guid? SavedScriptId { get; set; }

public virtual int? ScriptRunId { get; set; }


public virtual string? SenderConnectionID { get; set; }
public virtual string? SenderUserName { get; set; } = null!;
public virtual ScriptingShell Shell { get; set; }
public virtual string[]? StandardOutput { get; set; }

public virtual DateTimeOffset TimeStamp { get; set; } = DateTimeOffset.Now;

}
13 changes: 13 additions & 0 deletions Shared/Dtos/ScriptResultDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Remotely.Shared.DtoEntityBases;
using Remotely.Shared.Enums;
using Remotely.Shared.Models;
using Remotely.Shared.Utilities;
using System;
using System.Text.Json.Serialization;

namespace Remotely.Shared.Dtos;

public class ScriptResultDto : ScriptResultBase
{

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Text;
using System.Threading.Tasks;

namespace Remotely.Shared.Models;
namespace Remotely.Shared.Dtos;
public class ScriptResultResponse
{
public required string Id { get; init; }
Expand Down
Loading

0 comments on commit 6e1c231

Please sign in to comment.