Merge pull request #3528 from leigh-pointer/FileExtentions

File Extension management - site wide. Fix for #3493
This commit is contained in:
Shaun Walker 2023-12-04 15:16:42 -05:00 committed by GitHub
commit 7550a19951
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 125 additions and 44 deletions

View File

@ -4,6 +4,7 @@
@inject NavigationManager NavigationManager
@inject IFileService FileService
@inject IFolderService FolderService
@inject ISettingService SettingService
@inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@ -80,6 +81,7 @@
{
validated = true;
var interop = new Interop(JSRuntime);
if (await interop.FormValid(form))
{
if (_url == string.Empty || _folderId == -1)
@ -93,7 +95,7 @@
_name = _url.Substring(_url.LastIndexOf("/", StringComparison.Ordinal) + 1);
}
if (!Constants.UploadableFiles.Split(',').Contains(Path.GetExtension(_name).ToLower().Replace(".", "")))
if (!PageState.Site.UploadableFiles.Split(',').Contains(Path.GetExtension(_name).ToLower().Replace(".", "")))
{
AddModuleMessage(Localizer["Message.Download.InvalidExtension"], MessageType.Warning);
return;

View File

@ -74,7 +74,7 @@
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label>
<div class="col-sm-9">
<FileManager FileId="@_logofileid" Filter="@Constants.ImageFiles" @ref="_logofilemanager" />
<FileManager FileId="@_logofileid" Filter="@_ImageFiles" @ref="_logofilemanager" />
</div>
</div>
<div class="row mb-1 align-items-center">
@ -119,6 +119,22 @@
</div>
</div>
</Section>
<Section Name="FileExtensions" Heading="File Extensions" ResourceKey="FileExtensions">
<div class="container">
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="imageExt" HelpText="Enter a comma separated list of image file extensions" ResourceKey="ImageExtensions">Image Extensions: </Label>
<div class="col-sm-9">
<input id="imageExt" spellcheck="false" class="form-control" @bind="@_ImageFiles" />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="uploadableFileExt" HelpText="Enter a comma separated list of uploadable file extensions" ResourceKey="UploadableFileExtensions">Uploadable File Extensions: </Label>
<div class="col-sm-9">
<input id="uploadableFileExt" spellcheck="false" class="form-control" @bind="@_UploadableFiles" />
</div>
</div>
</div>
</Section>
<Section Name="PageContent" Heading="Page Content" ResourceKey="PageContent">
<div class="container">
<div class="row mb-1 align-items-center">
@ -377,6 +393,8 @@
private string _smtpsender = string.Empty;
private string _smtprelay = "False";
private string _smtpenabled = "True";
private string _ImageFiles = string.Empty;
private string _UploadableFiles = string.Empty;
private int _retention = 30;
private string _pwaisenabled;
private int _pwaappiconfileid = -1;
@ -462,6 +480,10 @@
_smtpenabled = SettingService.GetSetting(settings, "SMTPEnabled", "True");
_retention = int.Parse(SettingService.GetSetting(settings, "NotificationRetention", "30"));
//File Extensions
_ImageFiles = SettingService.GetSetting(settings, "ImageFiles", Constants.ImageFiles);
_UploadableFiles = SettingService.GetSetting(settings, "UploadableFiles", Constants.UploadableFiles);
// aliases
await GetAliases();
@ -622,6 +644,11 @@
settings = SettingService.SetSetting(settings, "SMTPEnabled", _smtpenabled, true);
settings = SettingService.SetSetting(settings, "SiteGuid", _siteguid, true);
settings = SettingService.SetSetting(settings, "NotificationRetention", _retention.ToString(), true);
//File Extensions
settings = SettingService.SetSetting(settings, "ImageFiles", _ImageFiles, false);
settings = SettingService.SetSetting(settings, "UploadableFiles", _UploadableFiles, false);
await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId);
await logger.LogInformation("Site Settings Saved {Site}", site);

View File

@ -77,7 +77,7 @@
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="@photofileid.ToString()" HelpText="A photo of yourself" ResourceKey="Photo"></Label>
<div class="col-sm-9">
<FileManager FileId="@photofileid" Filter="@Constants.ImageFiles" ShowFolders="false" ShowFiles="true" UploadMultiple="false" FolderId="@folderid" @ref="filemanager" />
<FileManager FileId="@photofileid" Filter="@PageState.Site.ImageFiles" ShowFolders="false" ShowFiles="true" UploadMultiple="false" FolderId="@folderid" @ref="filemanager" />
</div>
</div>
</div>
@ -311,7 +311,7 @@
private int folderid = -1;
private int photofileid = -1;
private File photo = null;
private string _ImageFiles = string.Empty;
private List<Profile> profiles;
private Dictionary<string, string> settings;
private string category = string.Empty;
@ -360,6 +360,8 @@
photofileid = -1;
photo = null;
}
var sitesettings = await SettingService.GetSiteSettingsAsync(SiteState.Alias.SiteId);
_ImageFiles = SettingService.GetSetting(settings, "ImageFiles", Constants.ImageFiles);
settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);

View File

@ -3,6 +3,7 @@
@inherits ModuleControlBase
@inject IFolderService FolderService
@inject IFileService FileService
@inject ISettingService SettingService
@inject IStringLocalizer<FileManager> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@ -343,6 +344,7 @@
_message = string.Empty;
var interop = new Interop(JSRuntime);
var uploads = await interop.GetFiles(_fileinputid);
if (uploads.Length > 0)
{
string restricted = "";
@ -350,7 +352,7 @@
{
var filename = upload.Split(':')[0];
var extension = (filename.LastIndexOf(".") != -1) ? filename.Substring(filename.LastIndexOf(".") + 1) : "";
if (!Constants.UploadableFiles.Split(',').Contains(extension.ToLower()))
if (!PageState.Site.UploadableFiles.Split(',').Contains(extension.ToLower()))
{
restricted += (restricted == "" ? "" : ",") + extension;
}

View File

@ -1,5 +1,6 @@
@namespace Oqtane.Modules.Controls
@inherits ModuleControlBase
@inject ISettingService SettingService
@inject IStringLocalizer<RichTextEditor> Localizer
<div class="row" style="margin-bottom: 50px;">
@ -8,7 +9,7 @@
<TabPanel Name="Rich" Heading="Rich Text Editor" ResourceKey="RichTextEditor">
@if (_richfilemanager)
{
<FileManager @ref="_fileManager" Filter="@Constants.ImageFiles" />
<FileManager @ref="_fileManager" Filter="@PageState.Site.ImageFiles" />
<ModuleMessage Message="@_message" Type="MessageType.Warning"></ModuleMessage>
<br />
}
@ -73,7 +74,7 @@
<TabPanel Name="Raw" Heading="Raw HTML Editor" ResourceKey="HtmlEditor">
@if (_rawfilemanager)
{
<FileManager @ref="_fileManager" Filter="@Constants.ImageFiles" />
<FileManager @ref="_fileManager" Filter="@PageState.Site.ImageFiles" />
<ModuleMessage Message="@_message" Type="MessageType.Warning"></ModuleMessage>
<br />
}
@ -104,51 +105,51 @@
</div>
@code {
private ElementReference _editorElement;
private ElementReference _toolBar;
private bool _richfilemanager = false;
private FileManager _fileManager;
private string _richhtml = string.Empty;
private string _originalrichhtml = string.Empty;
private bool _rawfilemanager = false;
private string _rawhtml = string.Empty;
private string _originalrawhtml = string.Empty;
private string _message = string.Empty;
private ElementReference _editorElement;
private ElementReference _toolBar;
private bool _richfilemanager = false;
private FileManager _fileManager;
private string _richhtml = string.Empty;
private string _originalrichhtml = string.Empty;
private bool _rawfilemanager = false;
private string _rawhtml = string.Empty;
private string _originalrawhtml = string.Empty;
private string _message = string.Empty;
[Parameter]
public string Content { get; set; }
[Parameter]
public string Content { get; set; }
[Parameter]
public bool ReadOnly { get; set; } = false;
[Parameter]
public bool ReadOnly { get; set; } = false;
[Parameter]
public string Placeholder { get; set; } = "Enter Your Content...";
[Parameter]
public string Placeholder { get; set; } = "Enter Your Content...";
[Parameter]
public bool AllowFileManagement { get; set; } = true;
[Parameter]
public bool AllowFileManagement { get; set; } = true;
[Parameter]
public bool AllowRawHtml { get; set; } = true;
// parameters only applicable to rich text editor
[Parameter]
public RenderFragment ToolbarContent { get; set; }
[Parameter]
public bool AllowRawHtml { get; set; } = true;
[Parameter]
public string Theme { get; set; } = "snow";
// parameters only applicable to rich text editor
[Parameter]
public RenderFragment ToolbarContent { get; set; }
[Parameter]
public string DebugLevel { get; set; } = "info";
[Parameter]
public string Theme { get; set; } = "snow";
public override List<Resource> Resources => new List<Resource>()
[Parameter]
public string DebugLevel { get; set; } = "info";
public override List<Resource> Resources => new List<Resource>()
{
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill.min.js" },
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-blot-formatter.min.js" },
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-interop.js" }
};
protected override void OnParametersSet()
{
protected override void OnParametersSet()
{
_richhtml = Content;
_rawhtml = Content;
_originalrawhtml = _rawhtml; // preserve for comparison later

View File

@ -402,4 +402,19 @@
<data name="Retention.Text" xml:space="preserve">
<value>Retention (Days):</value>
</data>
<data name="FileExtensions.Heading" xml:space="preserve">
<value>File Extensions</value>
</data>
<data name="ImageExtensions.HelpText" xml:space="preserve">
<value>Enter a comma separated list of image file extensions</value>
</data>
<data name="ImageExtensions.Text" xml:space="preserve">
<value>Image Extensions:</value>
</data>
<data name="UploadableFileExtensions.HelpText" xml:space="preserve">
<value>Enter a comma separated list of uploadable file extensions</value>
</data>
<data name="UploadableFileExtensions.Text" xml:space="preserve">
<value>Uploadable File Extensions:</value>
</data>
</root>

View File

@ -35,8 +35,8 @@ namespace Oqtane.Controllers
private readonly ISyncManager _syncManager;
private readonly ILogManager _logger;
private readonly Alias _alias;
public FileController(IWebHostEnvironment environment, IFileRepository files, IFolderRepository folders, IUserPermissions userPermissions, ISyncManager syncManager, ILogManager logger, ITenantManager tenantManager)
private readonly ISettingRepository _settingRepository;
public FileController(IWebHostEnvironment environment, IFileRepository files, IFolderRepository folders, IUserPermissions userPermissions, ISettingRepository settingRepository, ISyncManager syncManager, ILogManager logger, ITenantManager tenantManager)
{
_environment = environment;
_files = files;
@ -45,6 +45,7 @@ namespace Oqtane.Controllers
_syncManager = syncManager;
_logger = logger;
_alias = tenantManager.GetAlias();
_settingRepository = settingRepository;
}
// GET: api/<controller>?folder=x
@ -287,6 +288,8 @@ namespace Oqtane.Controllers
folder = _folders.GetFolder(FolderId);
}
var _UploadableFiles = (_settingRepository.GetSetting(EntityNames.Site, _alias.SiteId, "UploadableFiles")?.SettingValue ?? Constants.UploadableFiles) ?? Constants.UploadableFiles;
if (folder != null && folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.Edit, folder.PermissionList))
{
string folderPath = _folders.GetFolderPath(folder);
@ -297,7 +300,7 @@ namespace Oqtane.Controllers
name = url.Substring(url.LastIndexOf("/", StringComparison.Ordinal) + 1);
}
// check for allowable file extensions
if (!Constants.UploadableFiles.Split(',').Contains(Path.GetExtension(name).ToLower().Replace(".", "")))
if (!_UploadableFiles.Split(',').Contains(Path.GetExtension(name).ToLower().Replace(".", "")))
{
_logger.Log(LogLevel.Error, this, LogFunction.Create, "File Could Not Be Downloaded From Url Due To Its File Extension {Url}", url);
HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
@ -362,6 +365,10 @@ namespace Oqtane.Controllers
return;
}
// Get the UploadableFiles extensions
string uploadfilesSetting = _settingRepository.GetSetting(EntityNames.Site, _alias.SiteId, "UploadableFiles")?.SettingValue;
string _UploadableFiles = uploadfilesSetting ?? Constants.UploadableFiles;
// ensure filename is valid
string token = ".part_";
if (!formfile.FileName.IsPathOrFileValid() || !formfile.FileName.Contains(token))
@ -371,7 +378,7 @@ namespace Oqtane.Controllers
// check for allowable file extensions (ignore token)
var extension = Path.GetExtension(formfile.FileName.Substring(0, formfile.FileName.IndexOf(token))).Replace(".", "");
if (!Constants.UploadableFiles.Split(',').Contains(extension.ToLower()))
if (!_UploadableFiles.Split(',').Contains(extension.ToLower()))
{
return;
}
@ -604,9 +611,11 @@ namespace Oqtane.Controllers
public IActionResult GetImage(int id, int width, int height, string mode, string position, string background, string rotate, string recreate)
{
var file = _files.GetFile(id);
var _ImageFiles = (_settingRepository.GetSetting(EntityNames.Site, _alias.SiteId, "ImageFiles")?.SettingValue ?? Constants.ImageFiles) ?? Constants.ImageFiles;
if (file != null && file.Folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.PermissionList))
{
if (Constants.ImageFiles.Split(',').Contains(file.Extension.ToLower()))
if (_ImageFiles.Split(',').Contains(file.Extension.ToLower()))
{
var filepath = _files.GetFilePath(file);
if (System.IO.File.Exists(filepath))
@ -770,6 +779,7 @@ namespace Oqtane.Controllers
private Models.File CreateFile(string filename, int folderid, string filepath)
{
var file = _files.GetFile(folderid, filename);
var _ImageFiles = (_settingRepository.GetSetting(EntityNames.Site, _alias.SiteId, "ImageFiles")?.SettingValue ?? Constants.ImageFiles) ?? Constants.ImageFiles;
int size = 0;
var folder = _folders.GetFolder(folderid, false);
@ -796,7 +806,7 @@ namespace Oqtane.Controllers
file.ImageHeight = 0;
file.ImageWidth = 0;
if (Constants.ImageFiles.Split(',').Contains(file.Extension.ToLower()))
if (_ImageFiles.Split(',').Contains(file.Extension.ToLower()))
{
try
{

View File

@ -86,6 +86,16 @@ namespace Oqtane.Controllers
.Where(item => !item.IsPrivate || User.IsInRole(RoleNames.Admin))
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
// Populate ImageFile extentions with setting or constant value
site.ImageFiles = site.Settings.ContainsKey("ImageFiles")
? site.Settings["ImageFiles"]?.ToString() ?? Constants.ImageFiles
: Constants.ImageFiles;
// Populate UploadableFile extensions with setting or constant value
site.UploadableFiles = site.Settings.ContainsKey("UploadableFiles")
? site.Settings["UploadableFiles"]?.ToString() ?? Constants.UploadableFiles
: Constants.UploadableFiles;
// pages
List<Setting> settings = _settings.GetSettings(EntityNames.Page).ToList();
site.Pages = new List<Page>();

View File

@ -98,6 +98,18 @@ namespace Oqtane.Models
/// </summary>
public string BodyContent { get; set; }
/// <summary>
/// The ImageFile extensions
/// </summary>
[NotMapped]
public string ImageFiles { get; set; }
/// <summary>
/// The UploadableFile extensions
/// </summary>
[NotMapped]
public string UploadableFiles { get; set; }
[NotMapped]
public Dictionary<string, string> Settings { get; set; }