validate folder names, handle missing files more gracefully
This commit is contained in:
parent
c83496d814
commit
6f3fe8d933
@ -149,12 +149,18 @@
|
|||||||
{
|
{
|
||||||
folder = await FolderService.AddFolderAsync(folder);
|
folder = await FolderService.AddFolderAsync(folder);
|
||||||
}
|
}
|
||||||
|
if (folder != null)
|
||||||
|
{
|
||||||
await FolderService.UpdateFolderOrderAsync(folder.SiteId, folder.FolderId, folder.ParentId);
|
await FolderService.UpdateFolderOrderAsync(folder.SiteId, folder.FolderId, folder.ParentId);
|
||||||
await logger.LogInformation("Folder Saved {Folder}", folder);
|
await logger.LogInformation("Folder Saved {Folder}", folder);
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage("An Error Was Encountered Saving The Folder", MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage("Folders Must Have A Parent And A Name", MessageType.Warning);
|
AddModuleMessage("Folders Must Have A Parent And A Name", MessageType.Warning);
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ using System.Net;
|
|||||||
using Oqtane.Enums;
|
using Oqtane.Enums;
|
||||||
using Oqtane.Infrastructure;
|
using Oqtane.Infrastructure;
|
||||||
using Oqtane.Repository;
|
using Oqtane.Repository;
|
||||||
|
using Microsoft.AspNetCore.Routing.Constraints;
|
||||||
|
|
||||||
// ReSharper disable StringIndexOfIsCultureSpecific.1
|
// ReSharper disable StringIndexOfIsCultureSpecific.1
|
||||||
|
|
||||||
@ -396,12 +397,13 @@ namespace Oqtane.Controllers
|
|||||||
[HttpGet("download/{id}")]
|
[HttpGet("download/{id}")]
|
||||||
public IActionResult Download(int id)
|
public IActionResult Download(int id)
|
||||||
{
|
{
|
||||||
|
string errorpath = Path.Combine(GetFolderPath("images"), "error.png");
|
||||||
Models.File file = _files.GetFile(id);
|
Models.File file = _files.GetFile(id);
|
||||||
if (file != null)
|
if (file != null)
|
||||||
{
|
{
|
||||||
if (_userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions))
|
if (_userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions))
|
||||||
{
|
{
|
||||||
string filepath = Path.Combine(GetFolderPath(file.Folder) , file.Name);
|
string filepath = Path.Combine(GetFolderPath(file.Folder), file.Name);
|
||||||
if (System.IO.File.Exists(filepath))
|
if (System.IO.File.Exists(filepath))
|
||||||
{
|
{
|
||||||
byte[] filebytes = System.IO.File.ReadAllBytes(filepath);
|
byte[] filebytes = System.IO.File.ReadAllBytes(filepath);
|
||||||
@ -411,21 +413,24 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Read, "File Does Not Exist {FileId} {FilePath}", id, filepath);
|
_logger.Log(LogLevel.Error, this, LogFunction.Read, "File Does Not Exist {FileId} {FilePath}", id, filepath);
|
||||||
HttpContext.Response.StatusCode = 404;
|
HttpContext.Response.StatusCode = 404;
|
||||||
return null;
|
byte[] filebytes = System.IO.File.ReadAllBytes(errorpath);
|
||||||
|
return File(filebytes, "application/octet-stream", file.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access File {FileId}", id);
|
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access File {FileId}", id);
|
||||||
HttpContext.Response.StatusCode = 401;
|
HttpContext.Response.StatusCode = 401;
|
||||||
return null;
|
byte[] filebytes = System.IO.File.ReadAllBytes(errorpath);
|
||||||
|
return File(filebytes, "application/octet-stream", file.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Read, "File Not Found {FileId}", id);
|
_logger.Log(LogLevel.Error, this, LogFunction.Read, "File Not Found {FileId}", id);
|
||||||
HttpContext.Response.StatusCode = 404;
|
HttpContext.Response.StatusCode = 404;
|
||||||
return null;
|
byte[] filebytes = System.IO.File.ReadAllBytes(errorpath);
|
||||||
|
return File(filebytes, "application/octet-stream", "error.png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ using Oqtane.Extensions;
|
|||||||
using Oqtane.Infrastructure;
|
using Oqtane.Infrastructure;
|
||||||
using Oqtane.Repository;
|
using Oqtane.Repository;
|
||||||
using Oqtane.Security;
|
using Oqtane.Security;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Oqtane.Controllers
|
namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
@ -105,16 +104,26 @@ namespace Oqtane.Controllers
|
|||||||
}.EncodePermissions();
|
}.EncodePermissions();
|
||||||
}
|
}
|
||||||
if (_userPermissions.IsAuthorized(User,PermissionNames.Edit, permissions))
|
if (_userPermissions.IsAuthorized(User,PermissionNames.Edit, permissions))
|
||||||
|
{
|
||||||
|
if (FolderPathValid(folder))
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(folder.Path) && folder.ParentId != null)
|
if (string.IsNullOrEmpty(folder.Path) && folder.ParentId != null)
|
||||||
{
|
{
|
||||||
Folder parent = _folders.GetFolder(folder.ParentId.Value);
|
Folder parent = _folders.GetFolder(folder.ParentId.Value);
|
||||||
folder.Path = Utilities.PathCombine(parent.Path, folder.Name,"\\");
|
folder.Path = Utilities.PathCombine(parent.Path, folder.Name);
|
||||||
}
|
}
|
||||||
|
folder.Path = Utilities.PathCombine(folder.Path, "\\");
|
||||||
folder = _folders.AddFolder(folder);
|
folder = _folders.AddFolder(folder);
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Folder Added {Folder}", folder);
|
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Folder Added {Folder}", folder);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Folder Name Not Valid {Folder}", folder);
|
||||||
|
HttpContext.Response.StatusCode = 401;
|
||||||
|
folder = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Create, "User Not Authorized To Add Folder {Folder}", folder);
|
_logger.Log(LogLevel.Error, this, LogFunction.Create, "User Not Authorized To Add Folder {Folder}", folder);
|
||||||
HttpContext.Response.StatusCode = 401;
|
HttpContext.Response.StatusCode = 401;
|
||||||
@ -130,16 +139,26 @@ namespace Oqtane.Controllers
|
|||||||
public Folder Put(int id, [FromBody] Folder folder)
|
public Folder Put(int id, [FromBody] Folder folder)
|
||||||
{
|
{
|
||||||
if (ModelState.IsValid && _userPermissions.IsAuthorized(User, EntityNames.Folder, folder.FolderId, PermissionNames.Edit))
|
if (ModelState.IsValid && _userPermissions.IsAuthorized(User, EntityNames.Folder, folder.FolderId, PermissionNames.Edit))
|
||||||
|
{
|
||||||
|
if (FolderPathValid(folder))
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(folder.Path) && folder.ParentId != null)
|
if (string.IsNullOrEmpty(folder.Path) && folder.ParentId != null)
|
||||||
{
|
{
|
||||||
Folder parent = _folders.GetFolder(folder.ParentId.Value);
|
Folder parent = _folders.GetFolder(folder.ParentId.Value);
|
||||||
folder.Path = Utilities.PathCombine(parent.Path, folder.Name,"\\");
|
folder.Path = Utilities.PathCombine(parent.Path, folder.Name);
|
||||||
}
|
}
|
||||||
|
folder.Path = Utilities.PathCombine(folder.Path, "\\");
|
||||||
folder = _folders.UpdateFolder(folder);
|
folder = _folders.UpdateFolder(folder);
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Folder Updated {Folder}", folder);
|
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Folder Updated {Folder}", folder);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Folder Name Not Valid {Folder}", folder);
|
||||||
|
HttpContext.Response.StatusCode = 401;
|
||||||
|
folder = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Update, "User Not Authorized To Update Folder {Folder}", folder);
|
_logger.Log(LogLevel.Error, this, LogFunction.Update, "User Not Authorized To Update Folder {Folder}", folder);
|
||||||
HttpContext.Response.StatusCode = 401;
|
HttpContext.Response.StatusCode = 401;
|
||||||
@ -191,5 +210,11 @@ namespace Oqtane.Controllers
|
|||||||
HttpContext.Response.StatusCode = 401;
|
HttpContext.Response.StatusCode = 401;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool FolderPathValid(Folder folder)
|
||||||
|
{
|
||||||
|
// prevent folder path traversal and reserved devices
|
||||||
|
return (!folder.Name.Contains("\\") && !folder.Name.Contains("/") && !Constants.ReservedDevices.Split(',').Contains(folder.Name.ToUpper()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,12 @@
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-logo {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.breadcrumbs {
|
.breadcrumbs {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
left: 275px;
|
left: 275px;
|
||||||
@ -164,6 +170,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
@media (max-width: 767px) {
|
||||||
|
.app-logo {
|
||||||
|
height: 80px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.breadcrumbs {
|
.breadcrumbs {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 150px;
|
top: 150px;
|
||||||
|
BIN
Oqtane.Server/wwwroot/images/error.png
Normal file
BIN
Oqtane.Server/wwwroot/images/error.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
@ -81,15 +81,27 @@ window.interop = {
|
|||||||
if (link.href !== url) {
|
if (link.href !== url) {
|
||||||
link.setAttribute('href', url);
|
link.setAttribute('href', url);
|
||||||
}
|
}
|
||||||
if (type !== "" && link.type !== type) {
|
if (type !== "") {
|
||||||
|
if (link.type !== type) {
|
||||||
link.setAttribute('type', type);
|
link.setAttribute('type', type);
|
||||||
}
|
}
|
||||||
if (integrity !== "" && link.integrity !== integrity) {
|
} else {
|
||||||
|
link.removeAttribute('type');
|
||||||
|
}
|
||||||
|
if (integrity !== "") {
|
||||||
|
if (link.integrity !== integrity) {
|
||||||
link.setAttribute('integrity', integrity);
|
link.setAttribute('integrity', integrity);
|
||||||
}
|
}
|
||||||
if (crossorigin !== "" && link.crossOrigin !== crossorigin) {
|
} else {
|
||||||
|
link.removeAttribute('integrity');
|
||||||
|
}
|
||||||
|
if (crossorigin !== "") {
|
||||||
|
if (link.crossOrigin !== crossorigin) {
|
||||||
link.setAttribute('crossorigin', crossorigin);
|
link.setAttribute('crossorigin', crossorigin);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
link.removeAttribute('crossorigin');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
includeScript: function (id, src, content, location, integrity, crossorigin) {
|
includeScript: function (id, src, content, location, integrity, crossorigin) {
|
||||||
@ -126,12 +138,20 @@ window.interop = {
|
|||||||
if (script.src !== src) {
|
if (script.src !== src) {
|
||||||
script.src = src;
|
script.src = src;
|
||||||
}
|
}
|
||||||
if (integrity !== "" && script.integrity !== integrity) {
|
if (integrity !== "") {
|
||||||
|
if (script.integrity !== integrity) {
|
||||||
script.setAttribute('integrity', integrity);
|
script.setAttribute('integrity', integrity);
|
||||||
}
|
}
|
||||||
if (crossorigin !== "" && script.crossorigin !== crossorigin) {
|
} else {
|
||||||
|
script.removeAttribute('integrity');
|
||||||
|
}
|
||||||
|
if (crossorigin !== "") {
|
||||||
|
if (script.crossOrigin !== crossorigin) {
|
||||||
script.setAttribute('crossorigin', crossorigin);
|
script.setAttribute('crossorigin', crossorigin);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
script.removeAttribute('crossorigin');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (script.innerHTML !== content) {
|
if (script.innerHTML !== content) {
|
||||||
|
@ -43,5 +43,6 @@
|
|||||||
|
|
||||||
public const string ImageFiles = "jpg,jpeg,jpe,gif,bmp,png";
|
public const string ImageFiles = "jpg,jpeg,jpe,gif,bmp,png";
|
||||||
public const string UploadableFiles = "jpg,jpeg,jpe,gif,bmp,png,mov,wmv,avi,mp4,mp3,doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,nupkg";
|
public const string UploadableFiles = "jpg,jpeg,jpe,gif,bmp,png,mov,wmv,avi,mp4,mp3,doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,nupkg";
|
||||||
|
public const string ReservedDevices = "CON,NUL,PRN,COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8,COM9,LPT1,LPT2,LPT3,LPT4,LPT5,LPT6,LPT7,LPT8,LPT9";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user