Move Path and File validation to Shared Utilities

Created extension methods:
IsPathValid(Folder)
IsFileValid(File)
IsPathOrFileValid(string)

Added client side validation check for Folders.
This commit is contained in:
Jim Spillane 2020-05-14 22:02:57 -04:00
parent def12489e6
commit 39641804f1
3 changed files with 73 additions and 56 deletions

View File

@ -25,7 +25,7 @@
</tr> </tr>
<tr> <tr>
<td> <td>
<Label for="name" HelpText="Enter the file name">Name: </Label> <Label for="name" HelpText="Enter the folder name">Name: </Label>
</td> </td>
<td> <td>
<input id="name" class="form-control" @bind="@_name" /> <input id="name" class="form-control" @bind="@_name" />
@ -112,57 +112,63 @@
private async Task SaveFolder() private async Task SaveFolder()
{ {
if (_name == string.Empty || _parentId == -1)
{
AddModuleMessage("Folders Must Have A Parent And A Name", MessageType.Warning);
return;
}
if (!_name.IsPathOrFileValid())
{
AddModuleMessage("Folder Name Not Valid.", MessageType.Warning);
return;
}
try try
{ {
if (_name != string.Empty && _parentId != -1) Folder folder;
if (_folderId != -1)
{ {
Folder folder; folder = await FolderService.GetFolderAsync(_folderId);
if (_folderId != -1)
{
folder = await FolderService.GetFolderAsync(_folderId);
}
else
{
folder = new Folder();
}
folder.SiteId = PageState.Site.SiteId;
if (_parentId == -1)
{
folder.ParentId = null;
}
else
{
folder.ParentId = _parentId;
}
folder.Name = _name;
folder.IsSystem = _isSystem;
folder.Permissions = _permissionGrid.GetPermissions();
if (_folderId != -1)
{
folder = await FolderService.UpdateFolderAsync(folder);
}
else
{
folder = await FolderService.AddFolderAsync(folder);
}
if (folder != null)
{
await FolderService.UpdateFolderOrderAsync(folder.SiteId, folder.FolderId, folder.ParentId);
await logger.LogInformation("Folder Saved {Folder}", folder);
NavigationManager.NavigateTo(NavigateUrl());
}
else
{
AddModuleMessage("An Error Was Encountered Saving The Folder", MessageType.Error);
}
} }
else else
{ {
AddModuleMessage("Folders Must Have A Parent And A Name", MessageType.Warning); folder = new Folder();
}
folder.SiteId = PageState.Site.SiteId;
if (_parentId == -1)
{
folder.ParentId = null;
}
else
{
folder.ParentId = _parentId;
}
folder.Name = _name;
folder.IsSystem = _isSystem;
folder.Permissions = _permissionGrid.GetPermissions();
if (_folderId != -1)
{
folder = await FolderService.UpdateFolderAsync(folder);
}
else
{
folder = await FolderService.AddFolderAsync(folder);
}
if (folder != null)
{
await FolderService.UpdateFolderOrderAsync(folder.SiteId, folder.FolderId, folder.ParentId);
await logger.LogInformation("Folder Saved {Folder}", folder);
NavigationManager.NavigateTo(NavigateUrl());
}
else
{
AddModuleMessage("An Error Was Encountered Saving The Folder", MessageType.Error);
} }
} }
catch (Exception ex) catch (Exception ex)

View File

@ -105,7 +105,7 @@ namespace Oqtane.Controllers
} }
if (_userPermissions.IsAuthorized(User, PermissionNames.Edit, permissions)) if (_userPermissions.IsAuthorized(User, PermissionNames.Edit, permissions))
{ {
if (FolderPathValid(folder)) if (folder.IsPathValid())
{ {
if (string.IsNullOrEmpty(folder.Path) && folder.ParentId != null) if (string.IsNullOrEmpty(folder.Path) && folder.ParentId != null)
{ {
@ -140,7 +140,7 @@ namespace Oqtane.Controllers
{ {
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 (folder.IsPathValid())
{ {
if (string.IsNullOrEmpty(folder.Path) && folder.ParentId != null) if (string.IsNullOrEmpty(folder.Path) && folder.ParentId != null)
{ {
@ -210,13 +210,5 @@ 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.IndexOfAny(Constants.InvalidFileNameChars) == -1 &&
!Constants.InvalidFileNameEndingChars.Any(x => folder.Name.EndsWith(x)) &&
!Constants.ReservedDevices.Split(',').Contains(folder.Name.ToUpper().Split('.')[0]));
}
} }
} }

View File

@ -2,8 +2,10 @@
using System; using System;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using File = Oqtane.Models.File;
namespace Oqtane.Shared namespace Oqtane.Shared
{ {
@ -254,5 +256,22 @@ namespace Oqtane.Shared
return Path.Combine(segments).TrimEnd(); return Path.Combine(segments).TrimEnd();
} }
public static bool IsPathValid(this Folder folder)
{
return IsPathOrFileValid(folder.Name);
}
public static bool IsFileValid(this File file)
{
return IsPathOrFileValid(file.Name);
}
public static bool IsPathOrFileValid(this string name)
{
return (name.IndexOfAny(Constants.InvalidFileNameChars) == -1 &&
!Constants.InvalidFileNameEndingChars.Any(name.EndsWith) &&
!Constants.ReservedDevices.Split(',').Contains(name.ToUpper().Split('.')[0]));
}
} }
} }