From 3d21448f894d6749c68f2e48fcad9f4d2accb022 Mon Sep 17 00:00:00 2001 From: AndyButland Date: Tue, 9 May 2017 18:12:51 +0200 Subject: [PATCH 1/5] Validated file uploads using white list if provided, before falling back to blacklist --- .../Configuration/UmbracoSettings/ContentElement.cs | 11 +++++++++++ .../Configuration/UmbracoSettings/IContentSection.cs | 4 +++- .../UmbracoSettings/ContentElementTests.cs | 6 ++++++ .../UmbracoSettings/umbracoSettings.config | 3 +++ .../PropertyEditors/UploadFileTypeValidator.cs | 6 +++++- src/umbraco.businesslogic/UmbracoSettings.cs | 8 ++++++++ src/umbraco.editorControls/uploadfield/uploadField.cs | 7 +++++-- 7 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/ContentElement.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/ContentElement.cs index 51a39e15df..2bab497b2b 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings/ContentElement.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings/ContentElement.cs @@ -139,6 +139,12 @@ namespace Umbraco.Core.Configuration.UmbracoSettings internal CommaDelimitedConfigurationElement DisallowedUploadFiles { get { return GetOptionalDelimitedElement("disallowedUploadFiles", new[] {"ashx", "aspx", "ascx", "config", "cshtml", "vbhtml", "asmx", "air", "axd"}); } + } + + [ConfigurationProperty("allowedUploadFiles")] + internal CommaDelimitedConfigurationElement AllowedUploadFiles + { + get { return GetOptionalDelimitedElement("allowedUploadFiles", new string[0]); } } [ConfigurationProperty("cloneXmlContent")] @@ -307,6 +313,11 @@ namespace Umbraco.Core.Configuration.UmbracoSettings IEnumerable IContentSection.DisallowedUploadFiles { get { return DisallowedUploadFiles; } + } + + IEnumerable IContentSection.AllowedUploadFiles + { + get { return AllowedUploadFiles; } } bool IContentSection.CloneXmlContent diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/IContentSection.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/IContentSection.cs index d73b3b9e41..7e874c9582 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings/IContentSection.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings/IContentSection.cs @@ -52,7 +52,9 @@ namespace Umbraco.Core.Configuration.UmbracoSettings MacroErrorBehaviour MacroErrorBehaviour { get; } - IEnumerable DisallowedUploadFiles { get; } + IEnumerable DisallowedUploadFiles { get; } + + IEnumerable AllowedUploadFiles { get; } bool CloneXmlContent { get; } diff --git a/src/Umbraco.Tests/Configurations/UmbracoSettings/ContentElementTests.cs b/src/Umbraco.Tests/Configurations/UmbracoSettings/ContentElementTests.cs index 06dab42556..cb30b1f782 100644 --- a/src/Umbraco.Tests/Configurations/UmbracoSettings/ContentElementTests.cs +++ b/src/Umbraco.Tests/Configurations/UmbracoSettings/ContentElementTests.cs @@ -177,6 +177,12 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings public void DisallowedUploadFiles() { Assert.IsTrue(SettingsSection.Content.DisallowedUploadFiles.All(x => "ashx,aspx,ascx,config,cshtml,vbhtml,asmx,air,axd".Split(',').Contains(x))); + } + + [Test] + public void AllowedUploadFiles() + { + Assert.IsTrue(SettingsSection.Content.AllowedUploadFiles.All(x => "jpg,gif,png".Split(',').Contains(x))); } } } diff --git a/src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.config b/src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.config index 80eaee77d3..a6f9826492 100644 --- a/src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.config +++ b/src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.config @@ -100,6 +100,9 @@ ashx,aspx,ascx,config,cshtml,vbhtml,asmx,air,axd + + jpg,png,gif + Textstring diff --git a/src/Umbraco.Web/PropertyEditors/UploadFileTypeValidator.cs b/src/Umbraco.Web/PropertyEditors/UploadFileTypeValidator.cs index 96a1211589..5bc1df6bc4 100644 --- a/src/Umbraco.Web/PropertyEditors/UploadFileTypeValidator.cs +++ b/src/Umbraco.Web/PropertyEditors/UploadFileTypeValidator.cs @@ -42,7 +42,11 @@ namespace Umbraco.Web.PropertyEditors { if (fileName.IndexOf('.') <= 0) return false; var extension = Path.GetExtension(fileName).TrimStart("."); - return UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Any(x => StringExtensions.InvariantEquals(x, extension)) == false; + + // Is valid if extension is whitelisted OR if there is no whitelist and extension is NOT blacklisted + return UmbracoConfig.For.UmbracoSettings().Content.AllowedUploadFiles.Any(x => x.InvariantEquals(extension)) || + (UmbracoConfig.For.UmbracoSettings().Content.AllowedUploadFiles.Any() == false && + UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Any(x => x.InvariantEquals(extension)) == false); } } diff --git a/src/umbraco.businesslogic/UmbracoSettings.cs b/src/umbraco.businesslogic/UmbracoSettings.cs index d73ea22844..dea58ab3ae 100644 --- a/src/umbraco.businesslogic/UmbracoSettings.cs +++ b/src/umbraco.businesslogic/UmbracoSettings.cs @@ -270,6 +270,14 @@ namespace umbraco public static IEnumerable DisallowedUploadFiles { get { return UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles; } + } + + /// + /// File types that will be allowed to be uploaded via the content/media upload control + /// + public static IEnumerable AllowedUploadFiles + { + get { return UmbracoConfig.For.UmbracoSettings().Content.AllowedUploadFiles; } } /// diff --git a/src/umbraco.editorControls/uploadfield/uploadField.cs b/src/umbraco.editorControls/uploadfield/uploadField.cs index 6f795e1ad9..9c2d26bbd4 100644 --- a/src/umbraco.editorControls/uploadfield/uploadField.cs +++ b/src/umbraco.editorControls/uploadfield/uploadField.cs @@ -90,8 +90,11 @@ namespace umbraco.editorControls //now check the file type var extension = Path.GetExtension(postedFile.FileName).TrimStart("."); - - return UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Any(x => x.InvariantEquals(extension)) == false; + + // allow if extension is whitelisted OR if there is no whitelist and extension is NOT blacklisted + return UmbracoConfig.For.UmbracoSettings().Content.AllowedUploadFiles.Any(x => x.InvariantEquals(extension)) || + (UmbracoConfig.For.UmbracoSettings().Content.AllowedUploadFiles.Any() == false && + UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Any(x => x.InvariantEquals(extension)) == false); } public string Text From 712cd29fea600771ada594cfd8928988671ab64c Mon Sep 17 00:00:00 2001 From: AndyButland Date: Tue, 9 May 2017 23:29:30 +0200 Subject: [PATCH 2/5] Upload checks to utilise whitelist. Refactored check on white and black list to common extension method. --- .../ContentSectionExtensions.cs | 19 ++ src/Umbraco.Core/Umbraco.Core.csproj | 1 + .../UmbracoSettings/ContentElementTests.cs | 8 + .../mediaPicker/mediapicker.controller.js | 36 +++- .../grid/grid.listviewlayout.controller.js | 166 +++++++++--------- .../list/list.listviewlayout.controller.js | 149 ++++++++-------- .../config/umbracoSettings.config | 3 + .../Editors/BackOfficeController.cs | 4 + src/Umbraco.Web/Editors/MediaController.cs | 5 +- .../UploadFileTypeValidator.cs | 12 +- .../uploadfield/uploadField.cs | 8 +- 11 files changed, 237 insertions(+), 174 deletions(-) create mode 100644 src/Umbraco.Core/Configuration/UmbracoSettings/ContentSectionExtensions.cs diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/ContentSectionExtensions.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/ContentSectionExtensions.cs new file mode 100644 index 0000000000..a4f182b373 --- /dev/null +++ b/src/Umbraco.Core/Configuration/UmbracoSettings/ContentSectionExtensions.cs @@ -0,0 +1,19 @@ +using System.Linq; + +namespace Umbraco.Core.Configuration.UmbracoSettings +{ + public static class ContentSectionExtensions + { + /// + /// Determines if file extension is allowed for upload based on (optional) white list and black list + /// held in settings. + /// Allow upload if extension is whitelisted OR if there is no whitelist and extension is NOT blacklisted. + /// + public static bool IsFileAllowedForUpload(this IContentSection contentSection, string extension) + { + return contentSection.AllowedUploadFiles.Any(x => x.InvariantEquals(extension)) || + (contentSection.AllowedUploadFiles.Any() == false && + contentSection.DisallowedUploadFiles.Any(x => x.InvariantEquals(extension)) == false); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index a8d1cc55bd..e55eab43e2 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -237,6 +237,7 @@ + diff --git a/src/Umbraco.Tests/Configurations/UmbracoSettings/ContentElementTests.cs b/src/Umbraco.Tests/Configurations/UmbracoSettings/ContentElementTests.cs index cb30b1f782..61aadaf4bf 100644 --- a/src/Umbraco.Tests/Configurations/UmbracoSettings/ContentElementTests.cs +++ b/src/Umbraco.Tests/Configurations/UmbracoSettings/ContentElementTests.cs @@ -183,6 +183,14 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings public void AllowedUploadFiles() { Assert.IsTrue(SettingsSection.Content.AllowedUploadFiles.All(x => "jpg,gif,png".Split(',').Contains(x))); + } + + [Test] + public void IsFileAllowedForUpload_WithWhitelist() + { + Assert.IsTrue(SettingsSection.Content.IsFileAllowedForUpload("png")); + Assert.IsFalse(SettingsSection.Content.IsFileAllowedForUpload("bmp")); + Assert.IsFalse(SettingsSection.Content.IsFileAllowedForUpload("php")); } } } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js index 7010a0db9d..94472b1f36 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js @@ -15,15 +15,33 @@ angular.module("umbraco") $scope.multiPicker = (dialogOptions.multiPicker && dialogOptions.multiPicker !== "0") ? true : false; $scope.startNodeId = dialogOptions.startNodeId ? dialogOptions.startNodeId : -1; $scope.cropSize = dialogOptions.cropSize; - $scope.lastOpenedNode = localStorageService.get("umbLastOpenedMediaNodeId"); - if ($scope.onlyImages) { - $scope.acceptedFileTypes = mediaHelper - .formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.imageFileTypes); - } else { - $scope.acceptedFileTypes = !mediaHelper - .formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.disallowedUploadFiles); - } - $scope.maxFileSize = Umbraco.Sys.ServerVariables.umbracoSettings.maxFileSize + "KB"; + $scope.lastOpenedNode = localStorageService.get("umbLastOpenedMediaNodeId"); + + var umbracoSettings = Umbraco.Sys.ServerVariables.umbracoSettings; + var allowedUploadFiles = mediaHelper.formatFileTypes(umbracoSettings.allowedUploadFiles); + if ($scope.onlyImages) { + // If whitelist provided, use just images from that + if (allowedUploadFiles !== '') { + var allowedUploadFilesArray = allowedUploadFiles.Split(','); + var allowedImageFiles = umbracoSettings.imageFileTypes.split(',').filter(function (n) { + return allowedUploadFilesArray.indexOf(n) > -1; + }); + $scope.acceptedFileTypes = allowedImageFiles; + } else { + // If no whitelist, allow all images + $scope.acceptedFileTypes = mediaHelper.formatFileTypes(umbracoSettings.imageFileTypes); + } + } else { + // Use whitelist of allowed file types if provided + if (allowedUploadFiles !== '') { + $scope.acceptedFileTypes = allowedUploadFiles; + } else { + // If no whitelist, we pass in a blacklist by adding ! to the file extensions, allowing everything EXCEPT for disallowedUploadFiles + $scope.acceptedFileTypes = !mediaHelper.formatFileTypes(umbracoSettings.disallowedUploadFiles); + } + } + + $scope.maxFileSize = umbracoSettings.maxFileSize + "KB"; $scope.model.selectedImages = []; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.listviewlayout.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.listviewlayout.controller.js index b8ba4f880b..9a28627aa1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.listviewlayout.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.listviewlayout.controller.js @@ -6,118 +6,124 @@ * @description * The controller for the content type editor */ -(function() { - "use strict"; +(function () { + "use strict"; - function ListViewGridLayoutController($scope, $routeParams, mediaHelper, mediaResource, $location, listViewHelper, mediaTypeHelper) { + function ListViewGridLayoutController($scope, $routeParams, mediaHelper, mediaResource, $location, listViewHelper, mediaTypeHelper) { - var vm = this; + var vm = this; + var umbracoSettings = Umbraco.Sys.ServerVariables.umbracoSettings; - vm.nodeId = $scope.contentId; - //we pass in a blacklist by adding ! to the file extensions, allowing everything EXCEPT for disallowedUploadFiles - vm.acceptedFileTypes = !mediaHelper.formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.disallowedUploadFiles); - vm.maxFileSize = Umbraco.Sys.ServerVariables.umbracoSettings.maxFileSize + "KB"; - vm.activeDrag = false; - vm.mediaDetailsTooltip = {}; - vm.itemsWithoutFolders = []; - vm.isRecycleBin = $scope.contentId === '-21' || $scope.contentId === '-20'; - vm.acceptedMediatypes = []; + vm.nodeId = $scope.contentId; + // Use whitelist of allowed file types if provided + vm.acceptedFileTypes = mediaHelper.formatFileTypes(umbracoSettings.allowedUploadFiles); + if (vm.acceptedFileTypes === '') { + // If not provided, we pass in a blacklist by adding ! to the file extensions, allowing everything EXCEPT for disallowedUploadFiles + vm.acceptedFileTypes = !mediaHelper.formatFileTypes(umbracoSettings.disallowedUploadFiles); + } - vm.dragEnter = dragEnter; - vm.dragLeave = dragLeave; - vm.onFilesQueue = onFilesQueue; - vm.onUploadComplete = onUploadComplete; + vm.maxFileSize = umbracoSettings.maxFileSize + "KB"; + vm.activeDrag = false; + vm.mediaDetailsTooltip = {}; + vm.itemsWithoutFolders = []; + vm.isRecycleBin = $scope.contentId === '-21' || $scope.contentId === '-20'; + vm.acceptedMediatypes = []; - vm.hoverMediaItemDetails = hoverMediaItemDetails; - vm.selectContentItem = selectContentItem; - vm.selectItem = selectItem; - vm.selectFolder = selectFolder; - vm.goToItem = goToItem; + vm.dragEnter = dragEnter; + vm.dragLeave = dragLeave; + vm.onFilesQueue = onFilesQueue; + vm.onUploadComplete = onUploadComplete; - function activate() { - vm.itemsWithoutFolders = filterOutFolders($scope.items); + vm.hoverMediaItemDetails = hoverMediaItemDetails; + vm.selectContentItem = selectContentItem; + vm.selectItem = selectItem; + vm.selectFolder = selectFolder; + vm.goToItem = goToItem; - //no need to make another REST/DB call if this data is not used when we are browsing the bin - if ($scope.entityType === 'media' && !vm.isRecycleBin) { - mediaTypeHelper.getAllowedImagetypes(vm.nodeId).then(function (types) { - vm.acceptedMediatypes = types; - }); - } + function activate() { + vm.itemsWithoutFolders = filterOutFolders($scope.items); - } + //no need to make another REST/DB call if this data is not used when we are browsing the bin + if ($scope.entityType === 'media' && !vm.isRecycleBin) { + mediaTypeHelper.getAllowedImagetypes(vm.nodeId).then(function (types) { + vm.acceptedMediatypes = types; + }); + } - function filterOutFolders(items) { + } - var newArray = []; + function filterOutFolders(items) { - if(items && items.length ) { + var newArray = []; - for (var i = 0; items.length > i; i++) { - var item = items[i]; - var isFolder = !mediaHelper.hasFilePropertyType(item); + if (items && items.length) { - if (!isFolder) { - newArray.push(item); - } - } + for (var i = 0; items.length > i; i++) { + var item = items[i]; + var isFolder = !mediaHelper.hasFilePropertyType(item); - } + if (!isFolder) { + newArray.push(item); + } + } - return newArray; - } + } - function dragEnter(el, event) { - vm.activeDrag = true; - } + return newArray; + } - function dragLeave(el, event) { - vm.activeDrag = false; - } + function dragEnter(el, event) { + vm.activeDrag = true; + } - function onFilesQueue() { - vm.activeDrag = false; - } + function dragLeave(el, event) { + vm.activeDrag = false; + } - function onUploadComplete() { - $scope.getContent($scope.contentId); - } + function onFilesQueue() { + vm.activeDrag = false; + } - function hoverMediaItemDetails(item, event, hover) { + function onUploadComplete() { + $scope.getContent($scope.contentId); + } - if (hover && !vm.mediaDetailsTooltip.show) { + function hoverMediaItemDetails(item, event, hover) { - vm.mediaDetailsTooltip.event = event; - vm.mediaDetailsTooltip.item = item; - vm.mediaDetailsTooltip.show = true; + if (hover && !vm.mediaDetailsTooltip.show) { - } else if (!hover && vm.mediaDetailsTooltip.show) { + vm.mediaDetailsTooltip.event = event; + vm.mediaDetailsTooltip.item = item; + vm.mediaDetailsTooltip.show = true; - vm.mediaDetailsTooltip.show = false; + } else if (!hover && vm.mediaDetailsTooltip.show) { - } + vm.mediaDetailsTooltip.show = false; - } + } - function selectContentItem(item, $event, $index) { - listViewHelper.selectHandler(item, $index, $scope.items, $scope.selection, $event); - } + } - function selectItem(item, $event, $index) { - listViewHelper.selectHandler(item, $index, vm.itemsWithoutFolders, $scope.selection, $event); - } + function selectContentItem(item, $event, $index) { + listViewHelper.selectHandler(item, $index, $scope.items, $scope.selection, $event); + } - function selectFolder(folder, $event, $index) { - listViewHelper.selectHandler(folder, $index, $scope.folders, $scope.selection, $event); - } + function selectItem(item, $event, $index) { + listViewHelper.selectHandler(item, $index, vm.itemsWithoutFolders, $scope.selection, $event); + } - function goToItem(item, $event, $index) { - $location.path($scope.entityType + '/' + $scope.entityType + '/edit/' + item.id); - } + function selectFolder(folder, $event, $index) { + listViewHelper.selectHandler(folder, $index, $scope.folders, $scope.selection, $event); + } - activate(); + function goToItem(item, $event, $index) { + $location.path($scope.entityType + '/' + $scope.entityType + '/edit/' + item.id); + } - } + activate(); - angular.module("umbraco").controller("Umbraco.PropertyEditors.ListView.GridLayoutController", ListViewGridLayoutController); + } + + angular.module("umbraco").controller("Umbraco.PropertyEditors.ListView.GridLayoutController", ListViewGridLayoutController); })(); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/list/list.listviewlayout.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/list/list.listviewlayout.controller.js index 15c2042477..799cc5894c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/list/list.listviewlayout.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/list/list.listviewlayout.controller.js @@ -1,89 +1,96 @@ (function () { - "use strict"; + "use strict"; - function ListViewListLayoutController($scope, listViewHelper, $location, mediaHelper, mediaTypeHelper) { + function ListViewListLayoutController($scope, listViewHelper, $location, mediaHelper, mediaTypeHelper) { - var vm = this; + var vm = this; + var umbracoSettings = Umbraco.Sys.ServerVariables.umbracoSettings; - vm.nodeId = $scope.contentId; - //we pass in a blacklist by adding ! to the file extensions, allowing everything EXCEPT for disallowedUploadFiles - vm.acceptedFileTypes = !mediaHelper.formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.disallowedUploadFiles); - vm.maxFileSize = Umbraco.Sys.ServerVariables.umbracoSettings.maxFileSize + "KB"; - vm.activeDrag = false; - vm.isRecycleBin = $scope.contentId === '-21' || $scope.contentId === '-20'; - vm.acceptedMediatypes = []; + vm.nodeId = $scope.contentId; - vm.selectItem = selectItem; - vm.clickItem = clickItem; - vm.selectAll = selectAll; - vm.isSelectedAll = isSelectedAll; - vm.isSortDirection = isSortDirection; - vm.sort = sort; - vm.dragEnter = dragEnter; - vm.dragLeave = dragLeave; - vm.onFilesQueue = onFilesQueue; - vm.onUploadComplete = onUploadComplete; - - function activate() { - - if ($scope.entityType === 'media') { - mediaTypeHelper.getAllowedImagetypes(vm.nodeId).then(function (types) { - vm.acceptedMediatypes = types; - }); + // Use whitelist of allowed file types if provided + vm.acceptedFileTypes = mediaHelper.formatFileTypes(umbracoSettings.allowedUploadFiles); + if (vm.acceptedFileTypes === '') { + // If not provided, we pass in a blacklist by adding ! to the file extensions, allowing everything EXCEPT for disallowedUploadFiles + vm.acceptedFileTypes = !mediaHelper.formatFileTypes(umbracoSettings.disallowedUploadFiles); } - } + vm.maxFileSize = umbracoSettings.maxFileSize + "KB"; + vm.activeDrag = false; + vm.isRecycleBin = $scope.contentId === '-21' || $scope.contentId === '-20'; + vm.acceptedMediatypes = []; - function selectAll($event) { - listViewHelper.selectAllItems($scope.items, $scope.selection, $event); - } + vm.selectItem = selectItem; + vm.clickItem = clickItem; + vm.selectAll = selectAll; + vm.isSelectedAll = isSelectedAll; + vm.isSortDirection = isSortDirection; + vm.sort = sort; + vm.dragEnter = dragEnter; + vm.dragLeave = dragLeave; + vm.onFilesQueue = onFilesQueue; + vm.onUploadComplete = onUploadComplete; - function isSelectedAll() { - return listViewHelper.isSelectedAll($scope.items, $scope.selection); - } + function activate() { - function selectItem(selectedItem, $index, $event) { - listViewHelper.selectHandler(selectedItem, $index, $scope.items, $scope.selection, $event); - } + if ($scope.entityType === 'media') { + mediaTypeHelper.getAllowedImagetypes(vm.nodeId).then(function (types) { + vm.acceptedMediatypes = types; + }); + } - function clickItem(item) { - // if item.id is 2147483647 (int.MaxValue) use item.key - $location.path($scope.entityType + '/' +$scope.entityType + '/edit/' + (item.id === 2147483647 ? item.key : item.id)); - } + } - function isSortDirection(col, direction) { - return listViewHelper.setSortingDirection(col, direction, $scope.options); - } + function selectAll($event) { + listViewHelper.selectAllItems($scope.items, $scope.selection, $event); + } - function sort(field, allow, isSystem) { - if (allow) { - $scope.options.orderBySystemField = isSystem; - listViewHelper.setSorting(field, allow, $scope.options); + function isSelectedAll() { + return listViewHelper.isSelectedAll($scope.items, $scope.selection); + } + + function selectItem(selectedItem, $index, $event) { + listViewHelper.selectHandler(selectedItem, $index, $scope.items, $scope.selection, $event); + } + + function clickItem(item) { + // if item.id is 2147483647 (int.MaxValue) use item.key + $location.path($scope.entityType + '/' + $scope.entityType + '/edit/' + (item.id === 2147483647 ? item.key : item.id)); + } + + function isSortDirection(col, direction) { + return listViewHelper.setSortingDirection(col, direction, $scope.options); + } + + function sort(field, allow, isSystem) { + if (allow) { + $scope.options.orderBySystemField = isSystem; + listViewHelper.setSorting(field, allow, $scope.options); + $scope.getContent($scope.contentId); + } + } + + // Dropzone upload functions + function dragEnter(el, event) { + vm.activeDrag = true; + } + + function dragLeave(el, event) { + vm.activeDrag = false; + } + + function onFilesQueue() { + vm.activeDrag = false; + } + + function onUploadComplete() { $scope.getContent($scope.contentId); - } - } + } - // Dropzone upload functions - function dragEnter(el, event) { - vm.activeDrag = true; - } + activate(); - function dragLeave(el, event) { - vm.activeDrag = false; - } + } - function onFilesQueue() { - vm.activeDrag = false; - } + angular.module("umbraco").controller("Umbraco.PropertyEditors.ListView.ListLayoutController", ListViewListLayoutController); - function onUploadComplete() { - $scope.getContent($scope.contentId); - } - - activate(); - - } - -angular.module("umbraco").controller("Umbraco.PropertyEditors.ListView.ListLayoutController", ListViewListLayoutController); - -}) (); +})(); diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.config b/src/Umbraco.Web.UI/config/umbracoSettings.config index 78d13ab600..08eb440f1c 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.config @@ -102,6 +102,9 @@ ashx,aspx,ascx,config,cshtml,vbhtml,asmx,air,axd,swf,xml,xhtml,html,htm,svg,php,htaccess + + jpg,txt,pdf + Textstring diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index 901189e28a..a72b9ac85e 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -391,6 +391,10 @@ namespace Umbraco.Web.Editors { "disallowedUploadFiles", string.Join(",", UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles) + }, + { + "allowedUploadFiles", + string.Join(",", UmbracoConfig.For.UmbracoSettings().Content.AllowedUploadFiles) }, { "maxFileSize", diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index 4980605374..3ca4195a26 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -33,7 +33,8 @@ using Umbraco.Core.Configuration; using Umbraco.Web.UI; using Notification = Umbraco.Web.Models.ContentEditing.Notification; using Umbraco.Core.Persistence; - +using Umbraco.Core.Configuration.UmbracoSettings; + namespace Umbraco.Web.Editors { /// @@ -723,7 +724,7 @@ namespace Umbraco.Web.Editors var safeFileName = fileName.ToSafeFileName(); var ext = safeFileName.Substring(safeFileName.LastIndexOf('.') + 1).ToLower(); - if (UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Contains(ext) == false) + if (UmbracoConfig.For.UmbracoSettings().Content.IsFileAllowedForUpload(ext)) { var mediaType = Constants.Conventions.MediaTypes.File; diff --git a/src/Umbraco.Web/PropertyEditors/UploadFileTypeValidator.cs b/src/Umbraco.Web/PropertyEditors/UploadFileTypeValidator.cs index 5bc1df6bc4..8a96c7ac3e 100644 --- a/src/Umbraco.Web/PropertyEditors/UploadFileTypeValidator.cs +++ b/src/Umbraco.Web/PropertyEditors/UploadFileTypeValidator.cs @@ -9,7 +9,8 @@ using Umbraco.Core.Configuration; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using umbraco; - +using Umbraco.Core.Configuration.UmbracoSettings; + namespace Umbraco.Web.PropertyEditors { internal class UploadFileTypeValidator : IPropertyValidator @@ -41,12 +42,9 @@ namespace Umbraco.Web.PropertyEditors internal static bool ValidateFileExtension(string fileName) { if (fileName.IndexOf('.') <= 0) return false; - var extension = Path.GetExtension(fileName).TrimStart("."); - - // Is valid if extension is whitelisted OR if there is no whitelist and extension is NOT blacklisted - return UmbracoConfig.For.UmbracoSettings().Content.AllowedUploadFiles.Any(x => x.InvariantEquals(extension)) || - (UmbracoConfig.For.UmbracoSettings().Content.AllowedUploadFiles.Any() == false && - UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Any(x => x.InvariantEquals(extension)) == false); + var extension = Path.GetExtension(fileName).TrimStart("."); + + return UmbracoConfig.For.UmbracoSettings().Content.IsFileAllowedForUpload(extension); } } diff --git a/src/umbraco.editorControls/uploadfield/uploadField.cs b/src/umbraco.editorControls/uploadfield/uploadField.cs index 9c2d26bbd4..8a62fb3073 100644 --- a/src/umbraco.editorControls/uploadfield/uploadField.cs +++ b/src/umbraco.editorControls/uploadfield/uploadField.cs @@ -9,7 +9,8 @@ using System.Web.UI.WebControls; using Umbraco.Core.Configuration; using Umbraco.Core.IO; using umbraco.interfaces; -using Umbraco.Core; +using Umbraco.Core; +using Umbraco.Core.Configuration.UmbracoSettings; using Content = umbraco.cms.businesslogic.Content; using Umbraco.Core; @@ -91,10 +92,7 @@ namespace umbraco.editorControls //now check the file type var extension = Path.GetExtension(postedFile.FileName).TrimStart("."); - // allow if extension is whitelisted OR if there is no whitelist and extension is NOT blacklisted - return UmbracoConfig.For.UmbracoSettings().Content.AllowedUploadFiles.Any(x => x.InvariantEquals(extension)) || - (UmbracoConfig.For.UmbracoSettings().Content.AllowedUploadFiles.Any() == false && - UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Any(x => x.InvariantEquals(extension)) == false); + return UmbracoConfig.For.UmbracoSettings().Content.IsFileAllowedForUpload(extension); } public string Text From 3cc0df0273bc6d8c0cf5261c645d4a04d0a46b63 Mon Sep 17 00:00:00 2001 From: AndyButland Date: Tue, 9 May 2017 23:44:31 +0200 Subject: [PATCH 3/5] Fixed media picker calculation of intersection of allowed whitelist and images list --- .../views/common/overlays/mediaPicker/mediapicker.controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js index 94472b1f36..1dae7f303d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js @@ -26,7 +26,7 @@ angular.module("umbraco") var allowedImageFiles = umbracoSettings.imageFileTypes.split(',').filter(function (n) { return allowedUploadFilesArray.indexOf(n) > -1; }); - $scope.acceptedFileTypes = allowedImageFiles; + $scope.acceptedFileTypes = allowedImageFiles.join(','); } else { // If no whitelist, allow all images $scope.acceptedFileTypes = mediaHelper.formatFileTypes(umbracoSettings.imageFileTypes); From 4a593a0814c5b576f62a629d18e206e2cd83f5ed Mon Sep 17 00:00:00 2001 From: AndyButland Date: Tue, 9 May 2017 23:59:43 +0200 Subject: [PATCH 4/5] Reverted to empty whitelist for default. --- src/Umbraco.Web.UI/config/umbracoSettings.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.config b/src/Umbraco.Web.UI/config/umbracoSettings.config index 08eb440f1c..f208ab649e 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.config @@ -103,7 +103,7 @@ ashx,aspx,ascx,config,cshtml,vbhtml,asmx,air,axd,swf,xml,xhtml,html,htm,svg,php,htaccess - jpg,txt,pdf + Textstring From eb357910031af1ed2c02c6b537645026d20ac179 Mon Sep 17 00:00:00 2001 From: AndyButland Date: Tue, 16 May 2017 21:16:11 +0100 Subject: [PATCH 5/5] Reverted media picker behaviour when selecting images to use just configured image types --- .../overlays/mediaPicker/mediapicker.controller.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js index 1dae7f303d..d5e4301335 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js @@ -20,17 +20,7 @@ angular.module("umbraco") var umbracoSettings = Umbraco.Sys.ServerVariables.umbracoSettings; var allowedUploadFiles = mediaHelper.formatFileTypes(umbracoSettings.allowedUploadFiles); if ($scope.onlyImages) { - // If whitelist provided, use just images from that - if (allowedUploadFiles !== '') { - var allowedUploadFilesArray = allowedUploadFiles.Split(','); - var allowedImageFiles = umbracoSettings.imageFileTypes.split(',').filter(function (n) { - return allowedUploadFilesArray.indexOf(n) > -1; - }); - $scope.acceptedFileTypes = allowedImageFiles.join(','); - } else { - // If no whitelist, allow all images - $scope.acceptedFileTypes = mediaHelper.formatFileTypes(umbracoSettings.imageFileTypes); - } + $scope.acceptedFileTypes = mediaHelper.formatFileTypes(umbracoSettings.imageFileTypes); } else { // Use whitelist of allowed file types if provided if (allowedUploadFiles !== '') {