From 23cf5b544a1a313cce40de9fd197e06b1e9808de Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 5 Dec 2013 19:06:55 +1100 Subject: [PATCH] Moved image handling to diff controller since it doesn't support the csrf header, need to test more in an hour (WIP) --- .../html/umbphotofolder.directive.js | 2 +- .../fileupload/fileupload.controller.js | 2 +- .../Editors/BackOfficeController.cs | 4 + src/Umbraco.Web/Editors/ImagesController.cs | 145 ++++++++++++++++++ src/Umbraco.Web/Editors/MediaController.cs | 130 +--------------- .../UmbracoAuthorizedJsonController.cs | 6 +- src/Umbraco.Web/Umbraco.Web.csproj | 1 + 7 files changed, 158 insertions(+), 132 deletions(-) create mode 100644 src/Umbraco.Web/Editors/ImagesController.cs diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/html/umbphotofolder.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/html/umbphotofolder.directive.js index 9422bba925..b8987a5367 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/html/umbphotofolder.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/html/umbphotofolder.directive.js @@ -86,7 +86,7 @@ angular.module("umbraco.directives.html") //get the proxy url for big thumbnails (this ensures one is always generated) var thumbnailUrl = umbRequestHelper.getApiUrl( - "mediaApiBaseUrl", + "imagesApiBaseUrl", "GetBigThumbnail", [{ mediaId: photo.id }]); photo.thumbnail = thumbnailUrl; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js index f1049f2a41..bc802bdc46 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js @@ -57,7 +57,7 @@ function fileUploadController($scope, $element, $compile, imageHelper, fileManag _.each($scope.persistedFiles, function (file) { var thumbnailUrl = umbRequestHelper.getApiUrl( - "mediaApiBaseUrl", + "imagesApiBaseUrl", "GetBigThumbnail", [{ originalImagePath: file.file }]); diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index 3d24d81d09..255ef8b5d3 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -84,6 +84,10 @@ namespace Umbraco.Web.Editors "mediaApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( controller => controller.GetRootMedia()) }, + { + "imagesApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( + controller => controller.GetBigThumbnail(0)) + }, { "sectionApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( controller => controller.GetSections()) diff --git a/src/Umbraco.Web/Editors/ImagesController.cs b/src/Umbraco.Web/Editors/ImagesController.cs new file mode 100644 index 0000000000..080219f943 --- /dev/null +++ b/src/Umbraco.Web/Editors/ImagesController.cs @@ -0,0 +1,145 @@ +using System; +using System.Drawing; +using System.IO; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using Umbraco.Core; +using Umbraco.Core.IO; +using Umbraco.Core.Media; +using Umbraco.Web.Mvc; +using Umbraco.Web.WebApi; +using Umbraco.Web.WebApi.Filters; +using Constants = Umbraco.Core.Constants; + +namespace Umbraco.Web.Editors +{ + /// + /// A controller used to return images for media + /// + [PluginController("UmbracoApi")] + public class ImagesController : UmbracoAuthorizedApiController + { + /// + /// Gets the big thumbnail image for the media id + /// + /// + /// + /// + /// If there is no media, image property or image file is found then this will return not found. + /// + public HttpResponseMessage GetBigThumbnail(int mediaId) + { + var media = Services.MediaService.GetById(mediaId); + if (media == null) + { + return Request.CreateResponse(HttpStatusCode.NotFound); + } + var imageProp = media.Properties[Constants.Conventions.Media.File]; + if (imageProp == null) + { + return Request.CreateResponse(HttpStatusCode.NotFound); + } + + var imagePath = imageProp.Value.ToString(); + + return GetBigThumbnail(imagePath); + } + + /// + /// Gets the big thumbnail image for the original image path + /// + /// + /// + /// + /// If there is no original image is found then this will return not found. + /// + public HttpResponseMessage GetBigThumbnail(string originalImagePath) + { + return GetResized(originalImagePath, 500, "big-thumb"); + } + + /// + /// Gets a resized image for the media id + /// + /// + /// + /// + /// + /// If there is no media, image property or image file is found then this will return not found. + /// + public HttpResponseMessage GetResized(int mediaId, int width) + { + var media = Services.MediaService.GetById(mediaId); + if (media == null) + { + return new HttpResponseMessage(HttpStatusCode.NotFound); + } + var imageProp = media.Properties[Constants.Conventions.Media.File]; + if (imageProp == null) + { + return new HttpResponseMessage(HttpStatusCode.NotFound); + } + + var imagePath = imageProp.Value.ToString(); + + return GetResized(imagePath, width); + } + + /// + /// Gets a resized image for the image at the given path + /// + /// + /// + /// + /// + /// If there is no media, image property or image file is found then this will return not found. + /// + public HttpResponseMessage GetResized(string imagePath, int width) + { + return GetResized(imagePath, width, Convert.ToString(width)); + } + + private HttpResponseMessage GetResized(string imagePath, int width, string suffix) + { + var mediaFileSystem = FileSystemProviderManager.Current.GetFileSystemProvider(); + var ext = Path.GetExtension(imagePath); + var thumbFilePath = imagePath.TrimEnd(ext) + "_" + suffix + ".jpg"; + var fullOrgPath = mediaFileSystem.GetFullPath(mediaFileSystem.GetRelativePath(imagePath)); + var fullNewPath = mediaFileSystem.GetFullPath(mediaFileSystem.GetRelativePath(thumbFilePath)); + var thumbIsNew = mediaFileSystem.FileExists(fullNewPath) == false; + if (thumbIsNew) + { + //we need to generate it + if (mediaFileSystem.FileExists(fullOrgPath) == false) + { + return Request.CreateResponse(HttpStatusCode.NotFound); + } + + using (var fileStream = mediaFileSystem.OpenFile(fullOrgPath)) + { + if (fileStream.CanSeek) fileStream.Seek(0, 0); + using (var originalImage = Image.FromStream(fileStream)) + { + ImageHelper.GenerateThumbnail( + originalImage, + width, + fullNewPath, + "jpg", + mediaFileSystem); + } + } + } + + var result = Request.CreateResponse(HttpStatusCode.OK); + //NOTE: That we are not closing this stream as the framework will do that for us, if we try it will + // fail. See http://stackoverflow.com/questions/9541351/returning-binary-file-from-controller-in-asp-net-web-api + var stream = mediaFileSystem.OpenFile(fullNewPath); + if (stream.CanSeek) stream.Seek(0, 0); + result.Content = new StreamContent(stream); + result.Headers.Date = mediaFileSystem.GetLastModified(imagePath); + result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); + return result; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index 096bfd9f1f..3816b8a57f 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -1,11 +1,9 @@ using System; using System.Collections.Generic; -using System.Drawing; using System.IO; using System.Net; using System.Net.Http; using System.Net.Http.Formatting; -using System.Net.Http.Headers; using System.Security.AccessControl; using System.Text; using System.Threading.Tasks; @@ -17,7 +15,6 @@ using Umbraco.Core; using Umbraco.Core.Dynamics; using Umbraco.Core.IO; using Umbraco.Core.Logging; -using Umbraco.Core.Media; using Umbraco.Core.Models; using Umbraco.Core.Models.Editors; using Umbraco.Core.Models.Membership; @@ -38,8 +35,6 @@ using Umbraco.Core.Configuration; namespace Umbraco.Web.Editors { - - /// /// This controller is decorated with the UmbracoApplicationAuthorizeAttribute which means that any user requesting /// access to ALL of the methods on this controller will need access to the media application. @@ -64,130 +59,7 @@ namespace Umbraco.Web.Editors : base(umbracoContext) { } - - /// - /// Gets the big thumbnail image for the media id - /// - /// - /// - /// - /// If there is no media, image property or image file is found then this will return not found. - /// - public HttpResponseMessage GetBigThumbnail(int mediaId) - { - var media = Services.MediaService.GetById(mediaId); - if (media == null) - { - return Request.CreateResponse(HttpStatusCode.NotFound); - } - var imageProp = media.Properties[Constants.Conventions.Media.File]; - if (imageProp == null) - { - return Request.CreateResponse(HttpStatusCode.NotFound); - } - - var imagePath = imageProp.Value.ToString(); - - return GetBigThumbnail(imagePath); - } - - /// - /// Gets the big thumbnail image for the original image path - /// - /// - /// - /// - /// If there is no original image is found then this will return not found. - /// - public HttpResponseMessage GetBigThumbnail(string originalImagePath) - { - return GetResized(originalImagePath, 500, "big-thumb"); - } - - /// - /// Gets a resized image for the media id - /// - /// - /// - /// - /// - /// If there is no media, image property or image file is found then this will return not found. - /// - public HttpResponseMessage GetResized(int mediaId, int width) - { - var media = Services.MediaService.GetById(mediaId); - if (media == null) - { - return new HttpResponseMessage(HttpStatusCode.NotFound); - } - var imageProp = media.Properties[Constants.Conventions.Media.File]; - if (imageProp == null) - { - return new HttpResponseMessage(HttpStatusCode.NotFound); - } - - var imagePath = imageProp.Value.ToString(); - - return GetResized(imagePath, width); - } - - /// - /// Gets a resized image for the image at the given path - /// - /// - /// - /// - /// - /// If there is no media, image property or image file is found then this will return not found. - /// - public HttpResponseMessage GetResized(string imagePath, int width) - { - return GetResized(imagePath, width, Convert.ToString(width)); - } - - private HttpResponseMessage GetResized(string imagePath, int width, string suffix) - { - var mediaFileSystem = FileSystemProviderManager.Current.GetFileSystemProvider(); - var ext = Path.GetExtension(imagePath); - var thumbFilePath = imagePath.TrimEnd(ext) + "_" + suffix + ".jpg"; - var fullOrgPath = mediaFileSystem.GetFullPath(mediaFileSystem.GetRelativePath(imagePath)); - var fullNewPath = mediaFileSystem.GetFullPath(mediaFileSystem.GetRelativePath(thumbFilePath)); - var thumbIsNew = mediaFileSystem.FileExists(fullNewPath) == false; - if (thumbIsNew) - { - //we need to generate it - if (mediaFileSystem.FileExists(fullOrgPath) == false) - { - return Request.CreateResponse(HttpStatusCode.NotFound); - } - - using (var fileStream = mediaFileSystem.OpenFile(fullOrgPath)) - { - if (fileStream.CanSeek) fileStream.Seek(0, 0); - using (var originalImage = Image.FromStream(fileStream)) - { - ImageHelper.GenerateThumbnail( - originalImage, - width, - fullNewPath, - "jpg", - mediaFileSystem); - } - } - } - - var result = Request.CreateResponse(HttpStatusCode.OK); - //NOTE: That we are not closing this stream as the framework will do that for us, if we try it will - // fail. See http://stackoverflow.com/questions/9541351/returning-binary-file-from-controller-in-asp-net-web-api - var stream = mediaFileSystem.OpenFile(fullNewPath); - if (stream.CanSeek) stream.Seek(0, 0); - result.Content = new StreamContent(stream); - result.Headers.Date = mediaFileSystem.GetLastModified(imagePath); - result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); - return result; - } - - + /// /// Gets an empty content item for the /// diff --git a/src/Umbraco.Web/Editors/UmbracoAuthorizedJsonController.cs b/src/Umbraco.Web/Editors/UmbracoAuthorizedJsonController.cs index d4e5a56c6a..cd8b9f6084 100644 --- a/src/Umbraco.Web/Editors/UmbracoAuthorizedJsonController.cs +++ b/src/Umbraco.Web/Editors/UmbracoAuthorizedJsonController.cs @@ -5,8 +5,12 @@ using Umbraco.Web.WebApi.Filters; namespace Umbraco.Web.Editors { /// - /// An abstract API controller that only supports JSON + /// An abstract API controller that only supports JSON and all requests must contain the correct csrf header /// + /// + /// Inheriting from this controller means that ALL of your methods are JSON methods that are called by Angular, + /// methods that are not called by Angular or don't contain a valid csrf header will NOT work. + /// [ValidateAngularAntiForgeryToken] public abstract class UmbracoAuthorizedJsonController : UmbracoAuthorizedApiController { diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index a7d38ad2f6..f14159f141 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -300,6 +300,7 @@ +