From 8fc3963acbd4091b8f4f6b1ff1a0f801c7b14fa2 Mon Sep 17 00:00:00 2001 From: GiuseppeMusso-Laser Date: Thu, 22 Jun 2017 21:27:29 +0200 Subject: [PATCH] Media Library: added global media permissions (#7622) Fixes #7620 --- .../Controllers/AdminController.cs | 6 +- .../Modules/Orchard.MediaLibrary/AdminMenu.cs | 3 +- .../Controllers/AdminController.cs | 83 +++++++++++++------ .../Controllers/ClientStorageController.cs | 11 +-- .../Controllers/FolderController.cs | 49 ++++++++--- .../Controllers/OEmbedController.cs | 11 +-- .../Controllers/WebSearchController.cs | 11 +-- .../MediaFileName/MediaFileNameDriver.cs | 2 +- .../Orchard.MediaLibrary/Permissions.cs | 10 ++- .../Providers/ClientStorageMenu.cs | 3 +- .../Providers/OEmbedMenu.cs | 3 +- .../Providers/WebSearchMenu.cs | 3 +- .../Scripts/media-library.js | 5 +- .../MediaAuthorizationEventHandler.cs | 9 +- .../Services/IMediaLibraryService.cs | 4 +- .../Services/MediaLibraryService.cs | 35 +++++++- .../Services/XmlRpcHandler.cs | 5 +- .../Views/Admin/Index.cshtml | 1 + .../Views/Parts/Media.Actions.cshtml | 4 +- 19 files changed, 182 insertions(+), 76 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.ImageEditor/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.ImageEditor/Controllers/AdminController.cs index 2ae820faa..c4fe4be8f 100644 --- a/src/Orchard.Web/Modules/Orchard.ImageEditor/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.ImageEditor/Controllers/AdminController.cs @@ -45,12 +45,12 @@ namespace Orchard.ImageEditor.Controllers { [Themed(false)] public ActionResult Edit(string folderPath, string filename) { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.EditMediaContent, folderPath)) return new HttpUnauthorizedResult(); // Check permission. var rootMediaFolder = _mediaLibraryService.GetRootMediaFolder(); - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) { + if (!_mediaLibraryService.CanManageMediaFolder(folderPath)) { return new HttpUnauthorizedResult(); } @@ -84,7 +84,7 @@ namespace Orchard.ImageEditor.Controllers { // Check permission. var rootMediaFolder = _mediaLibraryService.GetRootMediaFolder(); - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(media.FolderPath)) { + if (!Services.Authorizer.Authorize(Permissions.ImportMediaContent) && !_mediaLibraryService.CanManageMediaFolder(media.FolderPath)) { return new HttpUnauthorizedResult(); } diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/AdminMenu.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/AdminMenu.cs index 8d3d5f48d..1e28ed316 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/AdminMenu.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/AdminMenu.cs @@ -15,7 +15,8 @@ namespace Orchard.MediaLibrary { builder.AddImageSet("media-library") .Add(T("Media"), "6", menu => menu.Add(T("Media"), "0", item => item.Action("Index", "Admin", new { area = "Orchard.MediaLibrary" }) - .Permission(Permissions.ManageOwnMedia))); + .Permission(Permissions.ManageOwnMedia) + .Permission(Permissions.SelectMediaContent))); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/AdminController.cs index 0d0fbaef4..b3e46c1ac 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/AdminController.cs @@ -1,9 +1,11 @@ using System; -using System.IO; +using System.Collections.Generic; using System.Linq; using System.Web.Mvc; using Orchard.ContentManagement; +using Orchard.ContentManagement.MetaData; using Orchard.Core.Title.Models; +using Orchard.FileSystems.Media; using Orchard.Localization; using Orchard.Logging; using Orchard.MediaLibrary.Models; @@ -12,9 +14,7 @@ using Orchard.MediaLibrary.ViewModels; using Orchard.Mvc; using Orchard.Themes; using Orchard.UI.Navigation; -using Orchard.ContentManagement.MetaData; using Orchard.Validation; -using System.Collections.Generic; namespace Orchard.MediaLibrary.Controllers { [ValidateInput(false)] @@ -22,15 +22,18 @@ namespace Orchard.MediaLibrary.Controllers { private readonly IMediaLibraryService _mediaLibraryService; private readonly INavigationManager _navigationManager; private readonly IContentDefinitionManager _contentDefinitionManager; + private readonly IStorageProvider _storageProvider; public AdminController( IOrchardServices services, IMediaLibraryService mediaLibraryService, INavigationManager navigationManager, - IContentDefinitionManager contentDefinitionManager) { + IContentDefinitionManager contentDefinitionManager, + IStorageProvider storageProvider) { _mediaLibraryService = mediaLibraryService; _navigationManager = navigationManager; _contentDefinitionManager = contentDefinitionManager; + _storageProvider = storageProvider; Services = services; T = NullLocalizer.Instance; @@ -42,12 +45,18 @@ namespace Orchard.MediaLibrary.Controllers { public ILogger Logger { get; set; } public ActionResult Index(string folderPath = "", bool dialog = false) { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, T("Cannot view media"))) + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.SelectMediaContent, folderPath)) { + Services.Notifier.Add(UI.Notify.NotifyType.Error, T("Cannot select media")); return new HttpUnauthorizedResult(); + } + + var userMediaFolder = _mediaLibraryService.GetUserMediaFolder(); + if (Services.Authorizer.Authorize(Permissions.ManageOwnMedia) && !Services.Authorizer.Authorize(Permissions.ManageMediaContent)) + _storageProvider.TryCreateFolder(userMediaFolder.MediaPath); // If the user is trying to access a folder above his boundaries, redirect him to his home folder var rootMediaFolder = _mediaLibraryService.GetRootMediaFolder(); - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) { + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.SelectMediaContent, folderPath) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) { return RedirectToAction("Index", new { folderPath = rootMediaFolder.MediaPath, dialog }); } @@ -80,8 +89,10 @@ namespace Orchard.MediaLibrary.Controllers { } public ActionResult Import(string folderPath, int? replaceId = null) { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, T("Cannot import media"))) - return new HttpUnauthorizedResult(); + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, folderPath)) { + Services.Notifier.Add(UI.Notify.NotifyType.Error, T("Cannot import media")); + return RedirectToAction("Index", new { folderPath = folderPath }); + } var mediaProviderMenu = _navigationManager.BuildMenu("mediaproviders"); var imageSets = _navigationManager.BuildImageSets("mediaproviders"); @@ -99,7 +110,7 @@ namespace Orchard.MediaLibrary.Controllers { return HttpNotFound(); // Check permission - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(replaceMedia.FolderPath)) { + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, folderPath) && !_mediaLibraryService.CanManageMediaFolder(replaceMedia.FolderPath)) { return new HttpUnauthorizedResult(); } @@ -107,7 +118,7 @@ namespace Orchard.MediaLibrary.Controllers { viewModel.FolderPath = replaceMedia.FolderPath; } else { // Check permission - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) { + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, folderPath) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) { return new HttpUnauthorizedResult(); } } @@ -117,11 +128,19 @@ namespace Orchard.MediaLibrary.Controllers { [Themed(false)] public ActionResult MediaItems(string folderPath, int skip = 0, int count = 0, string order = "created", string mediaType = "") { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, T("Cannot view media"))) - return new HttpUnauthorizedResult(); + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.SelectMediaContent, folderPath)) { + Services.Notifier.Add(UI.Notify.NotifyType.Error, T("Cannot select media")); + var model = new MediaManagerMediaItemsViewModel { + MediaItems = new List(), + MediaItemsCount = 0, + FolderPath = folderPath + }; + + return View(model); + } // Check permission - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) { + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.SelectMediaContent, folderPath) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) { var model = new MediaManagerMediaItemsViewModel { MediaItems = new List(), MediaItemsCount = 0, @@ -150,12 +169,18 @@ namespace Orchard.MediaLibrary.Controllers { [Themed(false)] public ActionResult ChildFolders(string folderPath = null) { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, T("Cannot get child folder listing"))) - return new HttpUnauthorizedResult(); + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.SelectMediaContent, folderPath)) { + Services.Notifier.Add(UI.Notify.NotifyType.Error, T("Cannot get child folder listing")); + var model = new MediaManagerChildFoldersViewModel { + Children = new IMediaFolder[0] + }; + + return View(model); + } // Check permission var rootMediaFolder = _mediaLibraryService.GetRootMediaFolder(); - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) { + if (!_mediaLibraryService.CanManageMediaFolder(folderPath)) { var model = new MediaManagerChildFoldersViewModel { Children = new IMediaFolder[0] }; @@ -174,8 +199,10 @@ namespace Orchard.MediaLibrary.Controllers { [Themed(false)] public ActionResult RecentMediaItems(int skip = 0, int count = 0, string order = "created", string mediaType = "") { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, T("Cannot view media"))) + if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) { + Services.Notifier.Add(UI.Notify.NotifyType.Error, T("Cannot view media")); return new HttpUnauthorizedResult(); + } var rootMediaFolder = _mediaLibraryService.GetRootMediaFolder(); var rootMediaFolderPath = rootMediaFolder == null ? null : rootMediaFolder.MediaPath; @@ -203,9 +230,10 @@ namespace Orchard.MediaLibrary.Controllers { if (contentItem == null) return HttpNotFound(); - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, contentItem, T("Cannot view media")) - || !_mediaLibraryService.CanManageMediaFolder(contentItem.FolderPath)) + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.SelectMediaContent, contentItem.FolderPath)) { + Services.Notifier.Add(UI.Notify.NotifyType.Error, T("Cannot select media")); return new HttpUnauthorizedResult(); + } dynamic model = Services.ContentManager.BuildDisplay(contentItem, displayType); @@ -214,8 +242,10 @@ namespace Orchard.MediaLibrary.Controllers { [HttpPost] public ActionResult Delete(int[] mediaItemIds) { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, T("Couldn't delete media items"))) + if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) { + Services.Notifier.Add(UI.Notify.NotifyType.Error, T("Couldn't delete media items")); return new HttpUnauthorizedResult(); + } var mediaItems = Services.ContentManager .Query(VersionOptions.Latest) @@ -226,9 +256,10 @@ namespace Orchard.MediaLibrary.Controllers { try { foreach (var media in mediaItems) { - if (_mediaLibraryService.CanManageMediaFolder(media.FolderPath)) { - Services.ContentManager.Remove(media.ContentItem); + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.DeleteMediaContent, media.FolderPath)) { + return Json(false); } + Services.ContentManager.Remove(media.ContentItem); } return Json(true); @@ -241,14 +272,16 @@ namespace Orchard.MediaLibrary.Controllers { [HttpPost] public ActionResult Clone(int mediaItemId) { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, T("Couldn't clone media items"))) + if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) { + Services.Notifier.Add(UI.Notify.NotifyType.Error, T("Couldn't clone media items")); return new HttpUnauthorizedResult(); + } try { var media = Services.ContentManager.Get(mediaItemId).As(); - if (!_mediaLibraryService.CanManageMediaFolder(media.FolderPath)) { - return new HttpUnauthorizedResult(); + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, media.FolderPath)) { + return Json(false); } var newFileName = _mediaLibraryService.GetUniqueFilename(media.FolderPath, media.FileName); diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/ClientStorageController.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/ClientStorageController.cs index be3035e33..ee8d8fc0a 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/ClientStorageController.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/ClientStorageController.cs @@ -35,12 +35,12 @@ namespace Orchard.MediaLibrary.Controllers { public ILogger Logger { get; set; } public ActionResult Index(string folderPath, string type, int? replaceId = null) { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) { + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.SelectMediaContent, folderPath)) { return new HttpUnauthorizedResult(); } // Check permission - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) { + if (!_mediaLibraryService.CanManageMediaFolder(folderPath)) { return new HttpUnauthorizedResult(); } @@ -62,12 +62,12 @@ namespace Orchard.MediaLibrary.Controllers { [HttpPost] public ActionResult Upload(string folderPath, string type) { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) { + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, folderPath)) { return new HttpUnauthorizedResult(); } // Check permission - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) { + if (!_mediaLibraryService.CanManageMediaFolder(folderPath)) { return new HttpUnauthorizedResult(); } @@ -135,7 +135,8 @@ namespace Orchard.MediaLibrary.Controllers { return HttpNotFound(); // Check permission - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(replaceMedia.FolderPath)) { + if (!(_mediaLibraryService.CheckMediaFolderPermission(Permissions.EditMediaContent, replaceMedia.FolderPath) && _mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, replaceMedia.FolderPath)) + && !_mediaLibraryService.CanManageMediaFolder(replaceMedia.FolderPath)) { return new HttpUnauthorizedResult(); } diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/FolderController.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/FolderController.cs index 936d59c58..903c11d1d 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/FolderController.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/FolderController.cs @@ -32,12 +32,14 @@ namespace Orchard.MediaLibrary.Controllers { public Localizer T { get; set; } public ActionResult Create(string folderPath) { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, T("Couldn't create media folder"))) - return new HttpUnauthorizedResult(); + if (!(_mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, folderPath) || _mediaLibraryService.CheckMediaFolderPermission(Permissions.EditMediaContent, folderPath))) { + Services.Notifier.Error(T("Couldn't create media folder")); + return RedirectToAction("Index", "Admin", new { area = "Orchard.MediaLibrary", folderPath = folderPath }); + } // If the user is trying to access a folder above his boundaries, redirect him to his home folder var rootMediaFolder = _mediaLibraryService.GetRootMediaFolder(); - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) { + if (!_mediaLibraryService.CanManageMediaFolder(folderPath)) { return RedirectToAction("Create", new { folderPath = rootMediaFolder.MediaPath }); } @@ -51,13 +53,16 @@ namespace Orchard.MediaLibrary.Controllers { [HttpPost, ActionName("Create")] public ActionResult Create() { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, T("Couldn't create media folder"))) + if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) { + Services.Notifier.Error(T("Couldn't create media folder")); return new HttpUnauthorizedResult(); + } var viewModel = new MediaManagerFolderCreateViewModel(); UpdateModel(viewModel); - if (!_mediaLibraryService.CanManageMediaFolder(viewModel.FolderPath)) { + if (!(_mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, viewModel.FolderPath) + || _mediaLibraryService.CheckMediaFolderPermission(Permissions.EditMediaContent, viewModel.FolderPath))) { return new HttpUnauthorizedResult(); } @@ -76,8 +81,10 @@ namespace Orchard.MediaLibrary.Controllers { } public ActionResult Edit(string folderPath) { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, T("Couldn't edit media folder"))) - return new HttpUnauthorizedResult(); + if (!(_mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, folderPath) || _mediaLibraryService.CheckMediaFolderPermission(Permissions.EditMediaContent, folderPath))) { + Services.Notifier.Error(T("Couldn't edit media folder")); + return RedirectToAction("Index", "Admin", new { area = "Orchard.MediaLibrary", folderPath = folderPath }); + } if (!_mediaLibraryService.CanManageMediaFolder(folderPath)) { return new HttpUnauthorizedResult(); @@ -88,6 +95,10 @@ namespace Orchard.MediaLibrary.Controllers { return new HttpUnauthorizedResult(); } + // Shouldn't be able to rename Users folder + if (folderPath == "Users") { + return new HttpUnauthorizedResult(); + } var viewModel = new MediaManagerFolderEditViewModel { FolderPath = folderPath, @@ -100,13 +111,16 @@ namespace Orchard.MediaLibrary.Controllers { [HttpPost, ActionName("Edit")] [FormValueRequired("submit.Save")] public ActionResult Edit() { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, T("Couldn't edit media folder"))) + if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) { + Services.Notifier.Error(T("Couldn't edit media folder")); return new HttpUnauthorizedResult(); + } var viewModel = new MediaManagerFolderEditViewModel(); UpdateModel(viewModel); - if (!_mediaLibraryService.CanManageMediaFolder(viewModel.FolderPath)) { + if (!(_mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, viewModel.FolderPath) + || _mediaLibraryService.CheckMediaFolderPermission(Permissions.EditMediaContent, viewModel.FolderPath))) { return new HttpUnauthorizedResult(); } @@ -130,16 +144,18 @@ namespace Orchard.MediaLibrary.Controllers { [HttpPost, ActionName("Edit")] [FormValueRequired("submit.Delete")] public ActionResult Delete() { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, T("Couldn't delete media folder"))) + if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) { + Services.Notifier.Error(T("Couldn't delete media folder")); return new HttpUnauthorizedResult(); + } var viewModel = new MediaManagerFolderEditViewModel(); UpdateModel(viewModel); - if (!_mediaLibraryService.CanManageMediaFolder(viewModel.FolderPath)) { + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.DeleteMediaContent, viewModel.FolderPath)) { return new HttpUnauthorizedResult(); - } + try { _mediaLibraryService.DeleteFolder(viewModel.FolderPath); Services.Notifier.Information(T("Media folder deleted")); @@ -155,8 +171,11 @@ namespace Orchard.MediaLibrary.Controllers { [HttpPost] public ActionResult Move(string folderPath, int[] mediaItemIds) { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, T("Couldn't move media items"))) + // check permission on destination folder + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, folderPath)) { + Services.Notifier.Error(T("Couldn't move media items")); return new HttpUnauthorizedResult(); + } if (!_mediaLibraryService.CanManageMediaFolder(folderPath)) { return new HttpUnauthorizedResult(); @@ -166,6 +185,10 @@ namespace Orchard.MediaLibrary.Controllers { // don't try to rename the file if there is no associated media file if (!string.IsNullOrEmpty(media.FileName)) { + // check permission on source folder + if(!_mediaLibraryService.CheckMediaFolderPermission(Permissions.DeleteMediaContent, media.FolderPath)) { + return new HttpUnauthorizedResult(); + } var uniqueFilename = _mediaLibraryService.GetUniqueFilename(folderPath, media.FileName); _mediaLibraryService.MoveFile(media.FolderPath, media.FileName, folderPath, uniqueFilename); media.FileName = uniqueFilename; diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/OEmbedController.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/OEmbedController.cs index e1b1c3241..2d42832ef 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/OEmbedController.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/OEmbedController.cs @@ -30,11 +30,11 @@ namespace Orchard.MediaLibrary.Controllers { public Localizer T { get; set; } public ActionResult Index(string folderPath, string type, int? replaceId) { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.SelectMediaContent, folderPath)) return new HttpUnauthorizedResult(); // Check permission - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) { + if (!_mediaLibraryService.CanManageMediaFolder(folderPath)) { return new HttpUnauthorizedResult(); } @@ -147,12 +147,12 @@ namespace Orchard.MediaLibrary.Controllers { [HttpPost, ValidateInput(false)] public ActionResult Import(string folderPath, string url, string document) { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) { + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, folderPath)) { return new HttpUnauthorizedResult(); } // Check permission - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) { + if (!_mediaLibraryService.CanManageMediaFolder(folderPath)) { return new HttpUnauthorizedResult(); } @@ -203,7 +203,8 @@ namespace Orchard.MediaLibrary.Controllers { return HttpNotFound(); // Check permission - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(replaceMedia.FolderPath)) { + if (!(_mediaLibraryService.CheckMediaFolderPermission(Permissions.EditMediaContent, replaceMedia.FolderPath) && _mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, replaceMedia.FolderPath)) + && !_mediaLibraryService.CanManageMediaFolder(replaceMedia.FolderPath)) { return new HttpUnauthorizedResult(); } diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/WebSearchController.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/WebSearchController.cs index 4cce84264..93d531298 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/WebSearchController.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/WebSearchController.cs @@ -35,12 +35,12 @@ namespace Orchard.MediaLibrary.Controllers { public Localizer T { get; set; } public ActionResult Index(string folderPath, string type, int? replaceId = null) { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) { + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.SelectMediaContent, folderPath)) { return new HttpUnauthorizedResult(); } // Check permission - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) { + if (!_mediaLibraryService.CanManageMediaFolder(folderPath)) { return new HttpUnauthorizedResult(); } @@ -62,11 +62,11 @@ namespace Orchard.MediaLibrary.Controllers { [HttpPost] public ActionResult Import(string folderPath, string type, string url) { - if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) + if (!_mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, folderPath)) return new HttpUnauthorizedResult(); // Check permission - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) { + if (!_mediaLibraryService.CanManageMediaFolder(folderPath)) { return new HttpUnauthorizedResult(); } @@ -109,7 +109,8 @@ namespace Orchard.MediaLibrary.Controllers { return HttpNotFound(); // Check permission - if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(replaceMedia.FolderPath)) { + if (!(_mediaLibraryService.CheckMediaFolderPermission(Permissions.EditMediaContent, replaceMedia.FolderPath) && _mediaLibraryService.CheckMediaFolderPermission(Permissions.ImportMediaContent, replaceMedia.FolderPath)) + && !_mediaLibraryService.CanManageMediaFolder(replaceMedia.FolderPath)) { return new HttpUnauthorizedResult(); } diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/MediaFileName/MediaFileNameDriver.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/MediaFileName/MediaFileNameDriver.cs index ee345abbf..330a28e65 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/MediaFileName/MediaFileNameDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/MediaFileName/MediaFileNameDriver.cs @@ -39,7 +39,7 @@ namespace Orchard.MediaLibrary.MediaFileName "Parts_Media_Edit_FileName", () => { var currentUser = _authenticationService.GetAuthenticatedUser(); - if (!_authorizationService.TryCheckAccess(Permissions.ManageMediaContent, currentUser, part)) { + if (!_authorizationService.TryCheckAccess(Permissions.EditMediaContent, currentUser, part)) { return null; } diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Permissions.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Permissions.cs index c308153ec..a2f7a2e6b 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Permissions.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Permissions.cs @@ -5,13 +5,21 @@ using Orchard.Security.Permissions; namespace Orchard.MediaLibrary { public class Permissions : IPermissionProvider { public static readonly Permission ManageMediaContent = new Permission { Description = "Manage Media", Name = "ManageMediaContent" }; - public static readonly Permission ManageOwnMedia = new Permission { Description = "Manage Own Media", Name = "ManageOwnMedia", ImpliedBy = new[] { ManageMediaContent } }; + public static readonly Permission ImportMediaContent = new Permission { Description = "Import All Media", Name = "ImportMedia", ImpliedBy = new[] { ManageMediaContent } }; + public static readonly Permission EditMediaContent = new Permission { Description = "Edit All Media", Name = "EditMedia", ImpliedBy = new[] { ManageMediaContent } }; + public static readonly Permission DeleteMediaContent = new Permission { Description = "Delete All Media", Name = "DeleteMedia", ImpliedBy = new[] { ManageMediaContent } }; + public static readonly Permission SelectMediaContent = new Permission { Description = "Select All Media", Name = "SelectMedia", ImpliedBy = new[] { ManageMediaContent, ImportMediaContent, EditMediaContent, DeleteMediaContent } }; + public static readonly Permission ManageOwnMedia = new Permission { Description = "Manage Own Media", Name = "ManageOwnMedia", ImpliedBy = new[] { ManageMediaContent, SelectMediaContent, ImportMediaContent, EditMediaContent, DeleteMediaContent } }; public virtual Feature Feature { get; set; } public IEnumerable GetPermissions() { return new[] { ManageMediaContent, + ImportMediaContent, + EditMediaContent, + DeleteMediaContent, + SelectMediaContent, ManageOwnMedia, }; } diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Providers/ClientStorageMenu.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Providers/ClientStorageMenu.cs index e648903ac..935708332 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Providers/ClientStorageMenu.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Providers/ClientStorageMenu.cs @@ -15,7 +15,8 @@ namespace Orchard.MediaLibrary.Providers { builder.AddImageSet("clientstorage") .Add(T("My Computer"), "5", menu => menu.Action("Index", "ClientStorage", new { area = "Orchard.MediaLibrary" }) - .Permission(Permissions.ManageOwnMedia)); + .Permission(Permissions.ManageOwnMedia) + .Permission(Permissions.ImportMediaContent)); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Providers/OEmbedMenu.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Providers/OEmbedMenu.cs index 8be665eaa..495699673 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Providers/OEmbedMenu.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Providers/OEmbedMenu.cs @@ -15,7 +15,8 @@ namespace Orchard.MediaLibrary.Providers { builder.AddImageSet("oembed") .Add(T("Media Url"), "10", menu => menu.Action("Index", "OEmbed", new { area = "Orchard.MediaLibrary" }) - .Permission(Permissions.ManageOwnMedia)); + .Permission(Permissions.ManageOwnMedia) + .Permission(Permissions.ImportMediaContent)); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Providers/WebSearchMenu.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Providers/WebSearchMenu.cs index e1adc3c07..ab0b04cf8 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Providers/WebSearchMenu.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Providers/WebSearchMenu.cs @@ -15,7 +15,8 @@ namespace Orchard.MediaLibrary.Providers { builder.AddImageSet("websearch") .Add(T("Web Search"), "7", menu => menu.Action("Index", "WebSearch", new { area = "Orchard.MediaLibrary" }) - .Permission(Permissions.ManageOwnMedia)); + .Permission(Permissions.ManageOwnMedia) + .Permission(Permissions.ImportMediaContent)); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library.js b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library.js index fb1d5f342..d72741fa8 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library.js +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library.js @@ -383,7 +383,8 @@ $(function () { $.ajax({ type: "GET", url: url, - cache: false + cache: false, + dataType: 'json' }).done(function (data) { var newChildFolders = data.childFolders; @@ -586,6 +587,7 @@ $(function () { viewModel.clearSelection(); } else { console.log('failed to delete media items'); + alert(settings.unauthorizedMessage); } return false; }); @@ -620,6 +622,7 @@ $(function () { viewModel.getMediaItems(viewModel.pageCount); } else { console.log('failed to clone media items'); + alert(settings.unauthorizedMessage); } return false; }); diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Security/MediaAuthorizationEventHandler.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Security/MediaAuthorizationEventHandler.cs index 14bb48916..ba07735a0 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Security/MediaAuthorizationEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Security/MediaAuthorizationEventHandler.cs @@ -21,14 +21,7 @@ namespace Orchard.MediaLibrary.Security { public void Adjust(CheckAccessContext context) { var mediaPart = context.Content.As(); if (mediaPart != null) { - if(_authorizer.Authorize(Permissions.ManageMediaContent)) { - context.Granted = true; - return; - } - - if(_authorizer.Authorize(Permissions.ManageOwnMedia)) { - context.Granted = _mediaLibraryService.CanManageMediaFolder(mediaPart.FolderPath); - } + context.Granted = _mediaLibraryService.CheckMediaFolderPermission(context.Permission, mediaPart.FolderPath); } } } diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/IMediaLibraryService.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/IMediaLibraryService.cs index 092876cf6..cc0aad2d1 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/IMediaLibraryService.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/IMediaLibraryService.cs @@ -22,7 +22,7 @@ namespace Orchard.MediaLibrary.Services { MediaPart ImportMedia(Stream stream, string relativePath, string filename); MediaPart ImportMedia(Stream stream, string relativePath, string filename, string contentType); IMediaFactory GetMediaFactory(Stream stream, string mimeType, string contentType); - + bool CheckMediaFolderPermission(Orchard.Security.Permissions.Permission permission, string folderPath); /// /// Creates a unique filename to prevent filename collisions. /// @@ -41,6 +41,8 @@ namespace Orchard.MediaLibrary.Services { IMediaFolder GetRootMediaFolder(); + IMediaFolder GetUserMediaFolder(); + /// /// Retrieves the media folders within a given relative path. /// diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/MediaLibraryService.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/MediaLibraryService.cs index f6eca979e..5d888bdc9 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/MediaLibraryService.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/MediaLibraryService.cs @@ -226,7 +226,7 @@ namespace Orchard.MediaLibrary.Services { } public IMediaFolder GetRootMediaFolder() { - if (_orchardServices.Authorizer.Authorize(Permissions.ManageMediaContent)) { + if (_orchardServices.Authorizer.Authorize(Permissions.SelectMediaContent)) { return null; } @@ -242,6 +242,39 @@ namespace Orchard.MediaLibrary.Services { return null; } + public IMediaFolder GetUserMediaFolder() { + var currentUser = _orchardServices.WorkContext.CurrentUser; + var userPath = _storageProvider.Combine("Users", _mediaFolderProvider.GetFolderName(currentUser)); + return new MediaFolder() { + Name = currentUser.UserName, + MediaPath = userPath + }; + } + + public bool CheckMediaFolderPermission(Orchard.Security.Permissions.Permission permission, string folderPath) { + if (_orchardServices.Authorizer.Authorize(Permissions.ManageMediaContent)) { + return true; + } + if (_orchardServices.WorkContext.CurrentUser==null) + return _orchardServices.Authorizer.Authorize(permission); + // determines the folder type: public, user own folder (my), folder of another user (private) + var rootedFolderPath = this.GetRootedFolderPath(folderPath) ?? ""; + var userFolderPath = GetUserMediaFolder().MediaPath; + bool isMyfolder = false; + + if (rootedFolderPath.StartsWith(userFolderPath)) { + // the folder is the user's private path or one of its subfolders + isMyfolder = true; + } + + if(isMyfolder) { + return _orchardServices.Authorizer.Authorize(Permissions.ManageOwnMedia); + } + else { // other + return _orchardServices.Authorizer.Authorize(permission); + } + } + /// /// Retrieves the media folders within a given relative path. /// diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/XmlRpcHandler.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/XmlRpcHandler.cs index 14a35ab00..42410aa90 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/XmlRpcHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Services/XmlRpcHandler.cs @@ -60,7 +60,8 @@ namespace Orchard.MediaLibrary.Services { UrlHelper url) { var user = _membershipService.ValidateUser(userName, password); - if (!_authorizationService.TryCheckAccess(Permissions.ManageOwnMedia, user, null)) { + if (!_authorizationService.TryCheckAccess(Permissions.ManageOwnMedia, user, null) + && !_authorizationService.TryCheckAccess(Permissions.EditMediaContent, user, null)) { throw new OrchardCoreException(T("Access denied")); } @@ -73,7 +74,7 @@ namespace Orchard.MediaLibrary.Services { } // If the user only has access to his own folder, rewrite the folder name - if (!_authorizationService.TryCheckAccess(Permissions.ManageMediaContent, user, null)) { + if (!_authorizationService.TryCheckAccess(Permissions.EditMediaContent, user, null)) { directoryName = Path.Combine(_mediaLibraryService.GetRootedFolderPath(directoryName)); } diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/Admin/Index.cshtml index 159d6c119..4c3d56d4f 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/Admin/Index.cshtml @@ -105,6 +105,7 @@ var mediaLibrarySettings = { cloneConfirmationMessage: '@HttpUtility.JavaScriptStringEncode(T("Are you sure you want to clone this media item ?").Text)', replaceConfirmationMessage: '@HttpUtility.JavaScriptStringEncode(T("Are you sure you want to replace this media item ?").Text)', errorMessage: '@HttpUtility.JavaScriptStringEncode(T("An unexpected error occured, please refresh the page and try again.").Text)', + unauthorizedMessage: '@HttpUtility.JavaScriptStringEncode(T("Access denied").Text)', antiForgeryToken: '@Html.AntiForgeryTokenValueOrchard()', childFolders: (@Display.Partial(TemplateName: "ChildFolders", Model: viewModel.ChildFoldersViewModel))['childFolders'] }; diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/Parts/Media.Actions.cshtml b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/Parts/Media.Actions.cshtml index e65370b4d..1bdc0f1e6 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/Parts/Media.Actions.cshtml +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Views/Parts/Media.Actions.cshtml @@ -4,10 +4,12 @@ @{ ContentItem contentItem = Model.ContentItem; var draftable = contentItem.TypeDefinition.Settings.GetModel().Draftable; + var media = contentItem.As(); + var mediaService = WorkContext.Resolve(); }
- @if (Authorizer.Authorize(Permissions.EditContent, contentItem)) { + @if (mediaService.CheckMediaFolderPermission(Orchard.MediaLibrary.Permissions.EditMediaContent, media.FolderPath)) { @Html.Link(T("Edit").Text, Url.ItemEditUrl(contentItem), new { @class = "button", id = "edit-media-link" }) } @if (Authorizer.Authorize(Permissions.PublishContent, contentItem) && draftable) {