mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-18 06:24:24 +01:00
Enhance files actions to accept arrays of fileids (#2735)
* Enhanced Files action by modifying it to accept a list of SelectedFileIds * Added checks to verify all files passed to the files action exist, Updated tests * Enhanced Files action to accept an array of fileIds * Removed redundant fileId list
This commit is contained in:
@@ -13,6 +13,7 @@ using BTCPayServer.Tests.Logging;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
@@ -185,22 +186,23 @@ namespace BTCPayServer.Tests
|
||||
fileList.Add(TestUtils.GetFormFile("uploadtestfile1.txt", fileContent));
|
||||
|
||||
var uploadFormFileResult = Assert.IsType<RedirectToActionResult>(await controller.CreateFiles(fileList));
|
||||
Assert.True(uploadFormFileResult.RouteValues.ContainsKey("fileId"));
|
||||
var fileId = uploadFormFileResult.RouteValues["fileId"].ToString();
|
||||
Assert.True(uploadFormFileResult.RouteValues.ContainsKey("fileIds"));
|
||||
string[] uploadFileList = (string[])uploadFormFileResult.RouteValues["fileIds"];
|
||||
var fileId = uploadFileList[0];
|
||||
Assert.Equal("Files", uploadFormFileResult.ActionName);
|
||||
|
||||
//check if file was uploaded and saved in db
|
||||
var viewFilesViewModel =
|
||||
Assert.IsType<ViewFilesViewModel>(Assert.IsType<ViewResult>(await controller.Files(fileId)).Model);
|
||||
Assert.IsType<ViewFilesViewModel>(Assert.IsType<ViewResult>(await controller.Files(new string[] { fileId })).Model);
|
||||
|
||||
Assert.NotEmpty(viewFilesViewModel.Files);
|
||||
Assert.Equal(fileId, viewFilesViewModel.SelectedFileId);
|
||||
Assert.NotEmpty(viewFilesViewModel.DirectFileUrl);
|
||||
Assert.True(viewFilesViewModel.DirectUrlByFiles.ContainsKey(fileId));
|
||||
Assert.NotEmpty(viewFilesViewModel.DirectUrlByFiles[fileId]);
|
||||
|
||||
|
||||
//verify file is available and the same
|
||||
var net = new System.Net.WebClient();
|
||||
var data = await net.DownloadStringTaskAsync(new Uri(viewFilesViewModel.DirectFileUrl));
|
||||
var data = await net.DownloadStringTaskAsync(new Uri(viewFilesViewModel.DirectUrlByFiles[fileId]));
|
||||
Assert.Equal(fileContent, data);
|
||||
|
||||
//create a temporary link to file
|
||||
@@ -232,10 +234,8 @@ namespace BTCPayServer.Tests
|
||||
|
||||
//attempt to fetch deleted file
|
||||
viewFilesViewModel =
|
||||
Assert.IsType<ViewFilesViewModel>(Assert.IsType<ViewResult>(await controller.Files(fileId)).Model);
|
||||
|
||||
Assert.Null(viewFilesViewModel.DirectFileUrl);
|
||||
Assert.Null(viewFilesViewModel.SelectedFileId);
|
||||
Assert.IsType<ViewFilesViewModel>(Assert.IsType<ViewResult>(await controller.Files(new string[] { fileId })).Model);
|
||||
Assert.Null(viewFilesViewModel.DirectUrlByFiles);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,24 +22,51 @@ using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace BTCPayServer.Controllers
|
||||
{
|
||||
public partial class ServerController
|
||||
{
|
||||
[HttpGet("server/files/{fileId?}")]
|
||||
public async Task<IActionResult> Files(string fileId = null)
|
||||
[HttpGet("server/files")]
|
||||
public async Task<IActionResult> Files([FromQuery] string[] fileIds = null)
|
||||
{
|
||||
var fileUrl = string.IsNullOrEmpty(fileId) ? null : await _FileService.GetFileUrl(Request.GetAbsoluteRootUri(), fileId);
|
||||
|
||||
var model = new ViewFilesViewModel()
|
||||
{
|
||||
Files = await _StoredFileRepository.GetFiles(),
|
||||
SelectedFileId = string.IsNullOrEmpty(fileUrl) ? null : fileId,
|
||||
DirectFileUrl = fileUrl,
|
||||
DirectUrlByFiles = null,
|
||||
StorageConfigured = (await _SettingsRepository.GetSettingAsync<StorageSettings>()) != null
|
||||
};
|
||||
|
||||
if (fileIds != null && fileIds.Length > 0)
|
||||
{
|
||||
bool allFilesExist = true;
|
||||
Dictionary<string, string> directUrlByFiles = new Dictionary<string, string>();
|
||||
foreach (string filename in fileIds)
|
||||
{
|
||||
string fileUrl = await _FileService.GetFileUrl(Request.GetAbsoluteRootUri(), filename);
|
||||
if (fileUrl == null)
|
||||
{
|
||||
allFilesExist = false;
|
||||
break;
|
||||
}
|
||||
directUrlByFiles.Add(filename, fileUrl);
|
||||
}
|
||||
|
||||
if (!allFilesExist)
|
||||
{
|
||||
this.TempData.SetStatusMessageModel(new StatusMessageModel()
|
||||
{
|
||||
Message = "Some of the files were not found",
|
||||
Severity = StatusMessageModel.StatusSeverity.Warning,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
model.DirectUrlByFiles = directUrlByFiles;
|
||||
}
|
||||
}
|
||||
return View(model);
|
||||
}
|
||||
|
||||
@@ -51,7 +78,7 @@ namespace BTCPayServer.Controllers
|
||||
await _FileService.RemoveFile(fileId, null);
|
||||
return RedirectToAction(nameof(Files), new
|
||||
{
|
||||
fileId = "",
|
||||
fileIds = Array.Empty<string>(),
|
||||
statusMessage = "File removed"
|
||||
});
|
||||
}
|
||||
@@ -127,7 +154,7 @@ namespace BTCPayServer.Controllers
|
||||
});
|
||||
return RedirectToAction(nameof(Files), new
|
||||
{
|
||||
fileId
|
||||
fileIds = new string[] { fileId }
|
||||
});
|
||||
|
||||
}
|
||||
@@ -190,12 +217,9 @@ namespace BTCPayServer.Controllers
|
||||
Severity = statusMessageSeverity
|
||||
});
|
||||
|
||||
if (fileIds.Count == 1)
|
||||
{
|
||||
return RedirectToAction(nameof(Files), new
|
||||
{
|
||||
statusMessage = "File added!",
|
||||
fileId = fileIds[0]
|
||||
fileIds = fileIds.ToArray(),
|
||||
});
|
||||
}
|
||||
else
|
||||
@@ -203,11 +227,6 @@ namespace BTCPayServer.Controllers
|
||||
return RedirectToAction(nameof(Files));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return RedirectToAction(nameof(Files));
|
||||
}
|
||||
}
|
||||
|
||||
private string GetUserId()
|
||||
{
|
||||
|
||||
@@ -6,8 +6,7 @@ namespace BTCPayServer.Models.ServerViewModels
|
||||
public class ViewFilesViewModel
|
||||
{
|
||||
public List<StoredFile> Files { get; set; }
|
||||
public string DirectFileUrl { get; set; }
|
||||
public string SelectedFileId { get; set; }
|
||||
public Dictionary<string, string> DirectUrlByFiles { get; set; }
|
||||
public bool StorageConfigured { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ else
|
||||
<td>@file.Timestamp.ToBrowserDate()</td>
|
||||
<td>@file.ApplicationUser.UserName</td>
|
||||
<td class="text-end">
|
||||
<a asp-action="Files" asp-route-fileId="@file.Id">Get Link</a>
|
||||
<a href="@Url.Action("Files", "Server", new { fileIds = new string[] { file.Id} })">Get Link</a>
|
||||
- <a asp-action="CreateTemporaryFileUrl" asp-route-fileId="@file.Id">Get Temp Link</a>
|
||||
- <a asp-action="DeleteFile" asp-route-fileId="@file.Id">Remove</a>
|
||||
</td>
|
||||
@@ -63,9 +63,15 @@ else
|
||||
}
|
||||
|
||||
|
||||
@if (!string.IsNullOrEmpty(Model.SelectedFileId))
|
||||
@if(Model.DirectUrlByFiles!=null && Model.DirectUrlByFiles.Count > 0)
|
||||
{
|
||||
var file = Model.Files.Single(storedFile => storedFile.Id.Equals(Model.SelectedFileId, StringComparison.InvariantCultureIgnoreCase));
|
||||
foreach (KeyValuePair<string, string> fileUrlPair in Model.DirectUrlByFiles)
|
||||
{
|
||||
var fileId = fileUrlPair.Key;
|
||||
var fileUrl = fileUrlPair.Value;
|
||||
var file = Model.Files.Single(storedFile => storedFile.Id.Equals(fileId, StringComparison.InvariantCultureIgnoreCase));
|
||||
|
||||
|
||||
<div class="card mb-2">
|
||||
<div class="card-text">
|
||||
<ul class="list-group list-group-flush">
|
||||
@@ -74,21 +80,22 @@ else
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<strong>URL:</strong>
|
||||
<a asp-action="GetFile" asp-controller="Storage" asp-route-fileId="@Model.SelectedFileId" target="_blank">
|
||||
<a asp-action="GetFile" asp-controller="Storage" asp-route-fileId="@fileId" target="_blank">
|
||||
@Url.Action("GetFile", "Storage", new
|
||||
{
|
||||
fileId = Model.SelectedFileId
|
||||
fileId = fileId
|
||||
}, Context.Request.Scheme, Context.Request.Host.ToString())
|
||||
</a>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<strong>Direct URL:</strong>
|
||||
<a href="@Model.DirectFileUrl" target="_blank" rel="noreferrer noopener">@Model.DirectFileUrl</a>
|
||||
<a href="@fileUrl" target="_blank" rel="noreferrer noopener">@fileUrl</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@if (Model.StorageConfigured)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user