From 39641804f1c93814cd7a19aa3dd8538d81158dee Mon Sep 17 00:00:00 2001 From: Jim Spillane Date: Thu, 14 May 2020 22:02:57 -0400 Subject: [PATCH] Move Path and File validation to Shared Utilities Created extension methods: IsPathValid(Folder) IsFileValid(File) IsPathOrFileValid(string) Added client side validation check for Folders. --- Oqtane.Client/Modules/Admin/Files/Edit.razor | 98 ++++++++++--------- Oqtane.Server/Controllers/FolderController.cs | 12 +-- Oqtane.Shared/Shared/Utilities.cs | 19 ++++ 3 files changed, 73 insertions(+), 56 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Files/Edit.razor b/Oqtane.Client/Modules/Admin/Files/Edit.razor index 1d7ddc81..5d42485b 100644 --- a/Oqtane.Client/Modules/Admin/Files/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Files/Edit.razor @@ -25,7 +25,7 @@ - + @@ -112,57 +112,63 @@ 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 { - if (_name != string.Empty && _parentId != -1) + Folder folder; + if (_folderId != -1) { - Folder folder; - 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); - } + folder = await FolderService.GetFolderAsync(_folderId); } 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) diff --git a/Oqtane.Server/Controllers/FolderController.cs b/Oqtane.Server/Controllers/FolderController.cs index fb824641..ebaaa590 100644 --- a/Oqtane.Server/Controllers/FolderController.cs +++ b/Oqtane.Server/Controllers/FolderController.cs @@ -105,7 +105,7 @@ namespace Oqtane.Controllers } if (_userPermissions.IsAuthorized(User, PermissionNames.Edit, permissions)) { - if (FolderPathValid(folder)) + if (folder.IsPathValid()) { 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 (FolderPathValid(folder)) + if (folder.IsPathValid()) { if (string.IsNullOrEmpty(folder.Path) && folder.ParentId != null) { @@ -210,13 +210,5 @@ namespace Oqtane.Controllers 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])); - } } } diff --git a/Oqtane.Shared/Shared/Utilities.cs b/Oqtane.Shared/Shared/Utilities.cs index 11bef4dd..de81561b 100644 --- a/Oqtane.Shared/Shared/Utilities.cs +++ b/Oqtane.Shared/Shared/Utilities.cs @@ -2,8 +2,10 @@ using System; using System.Globalization; using System.IO; +using System.Linq; using System.Text; using System.Text.RegularExpressions; +using File = Oqtane.Models.File; namespace Oqtane.Shared { @@ -254,5 +256,22 @@ namespace Oqtane.Shared 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])); + } } }