Merge pull request #370 from sbwalker/master

added defensive coding to deal with scenarios where files are deleted but still references from other entities
This commit is contained in:
Shaun Walker 2020-04-14 12:17:44 -04:00 committed by GitHub
commit 4bb906a316
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 92 additions and 38 deletions

View File

@ -37,6 +37,8 @@ else
} }
} }
<!-- The content below is for informational purposes only and can be safely removed -->
<hr /> <hr />
[Module] Module Created Successfully. Use Edit Mode To Add A [Module]. You Can Access The Files At The Following Locations:<br /><br /> [Module] Module Created Successfully. Use Edit Mode To Add A [Module]. You Can Access The Files At The Following Locations:<br /><br />
[RootPath]Client\<br /> [RootPath]Client\<br />
@ -65,6 +67,8 @@ else
- [Owner].[Module]s.Module.Shared.csproj - shared project<br /> - [Owner].[Module]s.Module.Shared.csproj - shared project<br />
- Models\[Module].cs - model definition<br /><br /> - Models\[Module].cs - model definition<br /><br />
<!-- The content above is for informational purposes only and can be safely removed -->
@code { @code {
I[Module]Service [Module]Service; I[Module]Service [Module]Service;
List<[Module]> _[Module]s; List<[Module]> _[Module]s;

View File

@ -37,6 +37,8 @@ else
} }
} }
<!-- The content below is for informational purposes only and can be safely removed -->
<hr /> <hr />
[Module] Module Created Successfully. Use Edit Mode To Add A [Module]. You Can Access The Files At The Following Locations:<br /><br /> [Module] Module Created Successfully. Use Edit Mode To Add A [Module]. You Can Access The Files At The Following Locations:<br /><br />
[RootPath]Oqtane.Client\Modules\[Module]\<br /> [RootPath]Oqtane.Client\Modules\[Module]\<br />
@ -56,6 +58,8 @@ else
[RootPath]Oqtane.Shared\Modules\[Module]\<br /> [RootPath]Oqtane.Shared\Modules\[Module]\<br />
- Models\[Module].cs - model definition<br /><br /> - Models\[Module].cs - model definition<br /><br />
<!-- The content above is for informational purposes only and can be safely removed -->
@code { @code {
I[Module]Service [Module]Service; I[Module]Service [Module]Service;
List<[Module]> _[Module]s; List<[Module]> _[Module]s;

View File

@ -6,7 +6,7 @@
@if (_folders != null) @if (_folders != null)
{ {
<div class="container-fluid px-0"> <div id="@Id" class="container-fluid px-0">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div> <div>
@ -95,6 +95,10 @@
private bool _haseditpermission = false; private bool _haseditpermission = false;
private string _message = string.Empty; private string _message = string.Empty;
private string _image = string.Empty; private string _image = string.Empty;
private string _guid;
[Parameter]
public string Id { get; set; } // optional - for setting the id of the FileManager component for accessibility
[Parameter] [Parameter]
public string Folder { get; set; } // optional - for setting a specific folder by default public string Folder { get; set; } // optional - for setting a specific folder by default
@ -116,6 +120,11 @@
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
if (!string.IsNullOrEmpty(Id))
{
_id = Id;
}
if (!string.IsNullOrEmpty(Folder)) if (!string.IsNullOrEmpty(Folder))
{ {
_folders = new List<Folder> {new Folder {FolderId = -1, Name = Folder}}; _folders = new List<Folder> {new Folder {FolderId = -1, Name = Folder}};
@ -133,7 +142,6 @@
if (!string.IsNullOrEmpty(FileId)) if (!string.IsNullOrEmpty(FileId))
{ {
_fileid = int.Parse(FileId); _fileid = int.Parse(FileId);
await SetImage();
if (_fileid != -1) if (_fileid != -1)
{ {
File file = await FileService.GetFileAsync(int.Parse(FileId)); File file = await FileService.GetFileAsync(int.Parse(FileId));
@ -141,7 +149,12 @@
{ {
_folderid = file.FolderId; _folderid = file.FolderId;
} }
else
{
_fileid = -1; // file does not exist
}
} }
await SetImage();
} }
if (!string.IsNullOrEmpty(ShowFiles)) if (!string.IsNullOrEmpty(ShowFiles))
{ {
@ -156,10 +169,10 @@
await GetFiles(); await GetFiles();
// create unique id for component // create unique id for component
_id = Guid.NewGuid().ToString("N"); _guid = Guid.NewGuid().ToString("N");
_fileinputid = _id + "FileInput"; _fileinputid = _guid + "FileInput";
_progressinfoid = _id + "ProgressInfo"; _progressinfoid = _guid + "ProgressInfo";
_progressbarid = _id + "ProgressBar"; _progressbarid = _guid + "ProgressBar";
if (!string.IsNullOrEmpty(UploadMultiple)) if (!string.IsNullOrEmpty(UploadMultiple))
{ {
@ -236,7 +249,7 @@
if (_fileid != -1) if (_fileid != -1)
{ {
File file = await FileService.GetFileAsync(_fileid); File file = await FileService.GetFileAsync(_fileid);
if (file.ImageHeight != 0 && file.ImageWidth != 0) if (file != null && file.ImageHeight != 0 && file.ImageWidth != 0)
{ {
var maxwidth = 200; var maxwidth = 200;
var maxheight = 200; var maxheight = 200;
@ -263,11 +276,11 @@
string result; string result;
if (!string.IsNullOrEmpty(Folder)) if (!string.IsNullOrEmpty(Folder))
{ {
result = await FileService.UploadFilesAsync(Folder, upload, _id); result = await FileService.UploadFilesAsync(Folder, upload, _guid);
} }
else else
{ {
result = await FileService.UploadFilesAsync(_folderid, upload, _id); result = await FileService.UploadFilesAsync(_folderid, upload, _guid);
} }
if (result == string.Empty) if (result == string.Empty)

View File

@ -56,7 +56,14 @@ namespace Oqtane.Services
public async Task<File> GetFileAsync(int fileId) public async Task<File> GetFileAsync(int fileId)
{ {
return await _http.GetJsonAsync<File>($"{Apiurl}/{fileId.ToString()}"); try
{
return await _http.GetJsonAsync<File>($"{Apiurl}/{fileId.ToString()}");
}
catch
{
return null;
}
} }
public async Task<File> AddFileAsync(File file) public async Task<File> AddFileAsync(File file)

View File

@ -81,22 +81,22 @@ namespace Oqtane.Controllers
Folder folder = _folders.GetFolder(siteId, folderPath); Folder folder = _folders.GetFolder(siteId, folderPath);
List<Models.File> files; List<Models.File> files;
if (folder != null) if (folder != null)
{
if (_userPermissions.IsAuthorized(User, PermissionNames.Browse, folder.Permissions)) if (_userPermissions.IsAuthorized(User, PermissionNames.Browse, folder.Permissions))
{ {
files = _files.GetFiles(folder.FolderId).ToList(); files = _files.GetFiles(folder.FolderId).ToList();
} }
else else
{ {
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Folder {folder}", _logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Folder {folder}", folder);
folder);
HttpContext.Response.StatusCode = 401; HttpContext.Response.StatusCode = 401;
return null; return null;
} }
}
else else
{ {
_logger.Log(LogLevel.Error, this, LogFunction.Read, "Folder not found {path}", _logger.Log(LogLevel.Error, this, LogFunction.Read, "Folder Not Found {SiteId} {Path}", siteId, path);
path); HttpContext.Response.StatusCode = 404;
HttpContext.Response.StatusCode = 401;
return null; return null;
} }
@ -108,14 +108,23 @@ namespace Oqtane.Controllers
public Models.File Get(int id) public Models.File Get(int id)
{ {
Models.File file = _files.GetFile(id); Models.File file = _files.GetFile(id);
if (_userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions)) if (file != null)
{ {
return file; if (_userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions))
{
return file;
}
else
{
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access File {File}", file);
HttpContext.Response.StatusCode = 401;
return null;
}
} }
else else
{ {
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access File {File}", file); _logger.Log(LogLevel.Error, this, LogFunction.Read, "File Not Found {FileId}", id);
HttpContext.Response.StatusCode = 401; HttpContext.Response.StatusCode = 404;
return null; return null;
} }
} }
@ -146,22 +155,30 @@ namespace Oqtane.Controllers
public void Delete(int id) public void Delete(int id)
{ {
Models.File file = _files.GetFile(id); Models.File file = _files.GetFile(id);
if (_userPermissions.IsAuthorized(User, EntityNames.Folder, file.Folder.FolderId, PermissionNames.Edit)) if (file != null)
{ {
_files.DeleteFile(id); if (_userPermissions.IsAuthorized(User, EntityNames.Folder, file.Folder.FolderId, PermissionNames.Edit))
string filepath = Path.Combine(GetFolderPath(file.Folder) + file.Name);
if (System.IO.File.Exists(filepath))
{ {
System.IO.File.Delete(filepath); _files.DeleteFile(id);
}
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "File Deleted {File}", file); string filepath = Path.Combine(GetFolderPath(file.Folder) + file.Name);
if (System.IO.File.Exists(filepath))
{
System.IO.File.Delete(filepath);
}
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "File Deleted {File}", file);
}
else
{
_logger.Log(LogLevel.Error, this, LogFunction.Delete, "User Not Authorized To Delete File {FileId}", id);
HttpContext.Response.StatusCode = 401;
}
} }
else else
{ {
_logger.Log(LogLevel.Error, this, LogFunction.Delete, "User Not Authorized To Delete File {FileId}", id); _logger.Log(LogLevel.Error, this, LogFunction.Delete, "File Not Found {FileId}", id);
HttpContext.Response.StatusCode = 401; HttpContext.Response.StatusCode = 404;
} }
} }
@ -379,25 +396,34 @@ namespace Oqtane.Controllers
public IActionResult Download(int id) public IActionResult Download(int id)
{ {
Models.File file = _files.GetFile(id); Models.File file = _files.GetFile(id);
if (file != null && _userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions)) if (file != null)
{ {
string filepath = GetFolderPath(file.Folder) + file.Name; if (_userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions))
if (System.IO.File.Exists(filepath))
{ {
byte[] filebytes = System.IO.File.ReadAllBytes(filepath); string filepath = GetFolderPath(file.Folder) + file.Name;
return File(filebytes, "application/octet-stream", file.Name); if (System.IO.File.Exists(filepath))
{
byte[] filebytes = System.IO.File.ReadAllBytes(filepath);
return File(filebytes, "application/octet-stream", file.Name);
}
else
{
_logger.Log(LogLevel.Error, this, LogFunction.Read, "File Does Not Exist {FileId} {FilePath}", id, filepath);
HttpContext.Response.StatusCode = 404;
return null;
}
} }
else else
{ {
_logger.Log(LogLevel.Error, this, LogFunction.Read, "File Does Not Exist {File}", file); _logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access File {FileId}", id);
HttpContext.Response.StatusCode = 404; HttpContext.Response.StatusCode = 401;
return null; return null;
} }
} }
else else
{ {
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access File {FileId}", id); _logger.Log(LogLevel.Error, this, LogFunction.Read, "File Not Found {FileId}", id);
HttpContext.Response.StatusCode = 401; HttpContext.Response.StatusCode = 404;
return null; return null;
} }
} }