From 9e6947f62c1c8db5f192bd2e43418da7c3c740fd Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 8 Aug 2018 11:49:05 +1000 Subject: [PATCH] Fixes issue of moving/deleting media along with other issues of us returning plain text responses with incorrect mime type results and an issue with our interceptors --- .../Services/Implement/MediaService.cs | 12 ++++---- .../Services/ContentServiceTests.cs | 2 +- .../Services/MediaServiceTests.cs | 29 +++++++++++++++++++ .../interceptors/security.interceptor.js | 13 +++++---- .../src/common/resources/content.resource.js | 7 +++-- .../common/resources/contenttype.resource.js | 4 +-- .../src/common/resources/datatype.resource.js | 2 +- .../src/common/resources/media.resource.js | 2 +- .../common/resources/mediatype.resource.js | 4 +-- .../services/umbrequesthelper.service.js | 7 +++++ src/Umbraco.Web/Editors/ContentController.cs | 8 ++--- .../Editors/ContentTypeControllerBase.cs | 4 +-- src/Umbraco.Web/Editors/DataTypeController.cs | 2 +- src/Umbraco.Web/Editors/MediaController.cs | 2 +- 14 files changed, 69 insertions(+), 29 deletions(-) diff --git a/src/Umbraco.Core/Services/Implement/MediaService.cs b/src/Umbraco.Core/Services/Implement/MediaService.cs index f2d873f2ca..d29875d68b 100644 --- a/src/Umbraco.Core/Services/Implement/MediaService.cs +++ b/src/Umbraco.Core/Services/Implement/MediaService.cs @@ -1010,7 +1010,7 @@ namespace Umbraco.Core.Services.Implement var originalPath = media.Path; - if (scope.Events.DispatchCancelable(Trashing, this, new MoveEventArgs(new MoveEventInfo(media, originalPath, Constants.System.RecycleBinMedia)))) + if (scope.Events.DispatchCancelable(Trashing, this, new MoveEventArgs(new MoveEventInfo(media, originalPath, Constants.System.RecycleBinMedia)), nameof(Trashing))) { scope.Complete(); return OperationResult.Attempt.Cancel(evtMsgs); @@ -1022,7 +1022,7 @@ namespace Umbraco.Core.Services.Implement var moveInfo = moves.Select(x => new MoveEventInfo(x.Item1, x.Item2, x.Item1.ParentId)) .ToArray(); - scope.Events.Dispatch(Trashed, this, new MoveEventArgs(false, evtMsgs, moveInfo)); + scope.Events.Dispatch(Trashed, this, new MoveEventArgs(false, evtMsgs, moveInfo), nameof(Trashed)); Audit(AuditType.Move, "Move Media to Recycle Bin performed by user", userId, media.Id); scope.Complete(); @@ -1058,7 +1058,7 @@ namespace Umbraco.Core.Services.Implement var moveEventInfo = new MoveEventInfo(media, media.Path, parentId); var moveEventArgs = new MoveEventArgs(moveEventInfo); - if (scope.Events.DispatchCancelable(Moving, this, moveEventArgs)) + if (scope.Events.DispatchCancelable(Moving, this, moveEventArgs, nameof(Moving))) { scope.Complete(); return; @@ -1082,7 +1082,7 @@ namespace Umbraco.Core.Services.Implement .ToArray(); moveEventArgs.MoveInfoCollection = moveInfo; moveEventArgs.CanCancel = false; - scope.Events.Dispatch(Moved, this, moveEventArgs); + scope.Events.Dispatch(Moved, this, moveEventArgs, nameof(Moved)); Audit(AuditType.Move, "Move Media performed by user", userId, media.Id); scope.Complete(); } @@ -1382,7 +1382,7 @@ namespace Umbraco.Core.Services.Implement /// Deletes media items of the specified type, and only that type. Does *not* handle content types /// inheritance and compositions, which need to be managed outside of this method. /// - /// Id of the + /// Id of the /// Optional id of the user deleting the media public void DeleteMediaOfTypes(IEnumerable mediaTypeIds, int userId = 0) { @@ -1434,7 +1434,7 @@ namespace Umbraco.Core.Services.Implement var moveInfos = moves.Select(x => new MoveEventInfo(x.Item1, x.Item2, x.Item1.ParentId)) .ToArray(); if (moveInfos.Length > 0) - scope.Events.Dispatch(Trashed, this, new MoveEventArgs(false, moveInfos), "Trashed"); + scope.Events.Dispatch(Trashed, this, new MoveEventArgs(false, moveInfos), nameof(Trashed)); scope.Events.Dispatch(TreeChanged, this, changes.ToEventArgs()); Audit(AuditType.Delete, $"Delete Media of types {string.Join(",", mediaTypeIdsA)} performed by user", userId, Constants.System.Root); diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index 0fcbb4b22c..22e1617389 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -63,7 +63,7 @@ namespace Umbraco.Tests.Services /// /// Used to list out all ambiguous events that will require dispatching with a name /// - [Test] + [Test, Explicit] public void List_Ambiguous_Events() { var events = ServiceContext.ContentService.GetType().GetEvents(BindingFlags.Static | BindingFlags.Public); diff --git a/src/Umbraco.Tests/Services/MediaServiceTests.cs b/src/Umbraco.Tests/Services/MediaServiceTests.cs index 02e8e3673e..68fd2c3e11 100644 --- a/src/Umbraco.Tests/Services/MediaServiceTests.cs +++ b/src/Umbraco.Tests/Services/MediaServiceTests.cs @@ -1,16 +1,19 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Events; using Umbraco.Core.Models; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Services; +using Umbraco.Core.Services.Implement; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Tests.Testing; @@ -22,6 +25,32 @@ namespace Umbraco.Tests.Services [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, PublishedRepositoryEvents = true)] public class MediaServiceTests : TestWithSomeContentBase { + /// + /// Used to list out all ambiguous events that will require dispatching with a name + /// + [Test, Explicit] + public void List_Ambiguous_Events() + { + var events = ServiceContext.MediaService.GetType().GetEvents(BindingFlags.Static | BindingFlags.Public); + var typedEventHandler = typeof(TypedEventHandler<,>); + foreach (var e in events) + { + //only continue if this is a TypedEventHandler + if (!e.EventHandlerType.IsGenericType) continue; + var typeDef = e.EventHandlerType.GetGenericTypeDefinition(); + if (typedEventHandler != typeDef) continue; + + //get the event arg type + var eventArgType = e.EventHandlerType.GenericTypeArguments[1]; + + var found = EventNameExtractor.FindEvent(typeof(MediaService), eventArgType, EventNameExtractor.MatchIngNames); + if (!found.Success && found.Result.Error == EventNameExtractorError.Ambiguous) + { + Console.WriteLine($"Ambiguous event, source: {typeof(MediaService)}, args: {eventArgType}"); + } + } + } + [Test] public void Get_Paged_Children_With_Media_Type_Filter() { diff --git a/src/Umbraco.Web.UI.Client/src/common/interceptors/security.interceptor.js b/src/Umbraco.Web.UI.Client/src/common/interceptors/security.interceptor.js index 221e71eb8c..b636a0a51c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/interceptors/security.interceptor.js +++ b/src/Umbraco.Web.UI.Client/src/common/interceptors/security.interceptor.js @@ -48,11 +48,14 @@ //exit/ignore return $q.reject(rejection); } - var filtered = _.find(requestInterceptorFilter(), function (val) { - return config.url.indexOf(val) > 0; - }); - if (filtered) { - return $q.reject(rejection); + + if (config.url) { + var filtered = _.find(requestInterceptorFilter(), function (val) { + return config.url.indexOf(val) > 0; + }); + if (filtered) { + return $q.reject(rejection); + } } //A 401 means that the user is not logged in diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js index bfe64923c3..3423bd92bd 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js @@ -157,7 +157,7 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { { parentId: args.parentId, id: args.id - }), + }, { responseType: 'text' }), 'Failed to move content'); }, @@ -198,7 +198,7 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { return umbRequestHelper.resourcePromise( $http.post(umbRequestHelper.getApiUrl("contentApiBaseUrl", "PostCopy"), - args), + args, { responseType: 'text' }), 'Failed to copy content'); }, @@ -467,7 +467,8 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { $http.get( umbRequestHelper.getApiUrl( "contentApiBaseUrl", - "GetNiceUrl", [{ id: id }])), + "GetNiceUrl", { id: id }), + { responseType: 'text' }), 'Failed to retrieve url for id:' + id); }, diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js index c6842513b2..cd095845f4 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js @@ -266,7 +266,7 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter, loca { parentId: args.parentId, id: args.id - }), + }, { responseType: 'text' }), 'Failed to move content'); }, @@ -286,7 +286,7 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter, loca { parentId: args.parentId, id: args.id - }), + }, { responseType: 'text' }), 'Failed to copy content'); }, diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/datatype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/datatype.resource.js index 118cda1a4c..7c4daedd38 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/datatype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/datatype.resource.js @@ -344,7 +344,7 @@ function dataTypeResource($q, $http, umbDataFormatter, umbRequestHelper) { { parentId: args.parentId, id: args.id - }), + }, { responseType: 'text' }), 'Failed to move content'); }, diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/media.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/media.resource.js index 74c2718bad..5d2ac1e8b9 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/media.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/media.resource.js @@ -112,7 +112,7 @@ function mediaResource($q, $http, umbDataFormatter, umbRequestHelper) { { parentId: args.parentId, id: args.id - }), + }, {responseType: 'text'}), 'Failed to move media'); }, diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js index 3fd0bdd1fd..8dc64e4cac 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js @@ -213,7 +213,7 @@ function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { { parentId: args.parentId, id: args.id - }), + }, { responseType: 'text' }), 'Failed to move content'); }, @@ -233,7 +233,7 @@ function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { { parentId: args.parentId, id: args.id - }), + }, { responseType: 'text' }), 'Failed to copy content'); }, diff --git a/src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js index 69fe6a6818..dbd92e4323 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js @@ -152,6 +152,13 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ }, function (response) { + if (!response.status && response.message && response.stack) { + //this is a JS/angular error that we should deal with + return $q.reject({ + errorMsg: response.message + }) + } + //invoke the callback var result = callbacks.error.apply(this, [response.data, response.status, response.headers, response.config]); diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index ae33e3c261..2df9a69df7 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -396,7 +396,7 @@ namespace Umbraco.Web.Editors { var url = Umbraco.Url(id); var response = Request.CreateResponse(HttpStatusCode.OK); - response.Content = new StringContent(url, Encoding.UTF8, "application/json"); + response.Content = new StringContent(url, Encoding.UTF8, "text/plain"); return response; } @@ -409,7 +409,7 @@ namespace Umbraco.Web.Editors { var url = Umbraco.UrlProvider.GetUrl(id); var response = Request.CreateResponse(HttpStatusCode.OK); - response.Content = new StringContent(url, Encoding.UTF8, "application/json"); + response.Content = new StringContent(url, Encoding.UTF8, "text/plain"); return response; } @@ -1005,7 +1005,7 @@ namespace Umbraco.Web.Editors Services.ContentService.Move(toMove, move.ParentId, Security.GetUserId().ResultOr(0)); var response = Request.CreateResponse(HttpStatusCode.OK); - response.Content = new StringContent(toMove.Path, Encoding.UTF8, "application/json"); + response.Content = new StringContent(toMove.Path, Encoding.UTF8, "text/plain"); return response; } @@ -1022,7 +1022,7 @@ namespace Umbraco.Web.Editors var c = Services.ContentService.Copy(toCopy, copy.ParentId, copy.RelateToOriginal, copy.Recursive, Security.GetUserId().ResultOr(0)); var response = Request.CreateResponse(HttpStatusCode.OK); - response.Content = new StringContent(c.Path, Encoding.UTF8, "application/json"); + response.Content = new StringContent(c.Path, Encoding.UTF8, "text/plain"); return response; } diff --git a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs index 1be2976834..ca7cc54bd9 100644 --- a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs +++ b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs @@ -321,7 +321,7 @@ namespace Umbraco.Web.Editors if (result.Success) { var response = Request.CreateResponse(HttpStatusCode.OK); - response.Content = new StringContent(toMove.Path, Encoding.UTF8, "application/json"); + response.Content = new StringContent(toMove.Path, Encoding.UTF8, "text/plain"); return response; } @@ -365,7 +365,7 @@ namespace Umbraco.Web.Editors { var copy = result.Result.Entity; var response = Request.CreateResponse(HttpStatusCode.OK); - response.Content = new StringContent(copy.Path, Encoding.UTF8, "application/json"); + response.Content = new StringContent(copy.Path, Encoding.UTF8, "text/plain"); return response; } diff --git a/src/Umbraco.Web/Editors/DataTypeController.cs b/src/Umbraco.Web/Editors/DataTypeController.cs index d618473277..7f95fdde54 100644 --- a/src/Umbraco.Web/Editors/DataTypeController.cs +++ b/src/Umbraco.Web/Editors/DataTypeController.cs @@ -250,7 +250,7 @@ namespace Umbraco.Web.Editors if (result.Success) { var response = Request.CreateResponse(HttpStatusCode.OK); - response.Content = new StringContent(toMove.Path, Encoding.UTF8, "application/json"); + response.Content = new StringContent(toMove.Path, Encoding.UTF8, "text/plain"); return response; } diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index e48444067d..7b4054deec 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -422,7 +422,7 @@ namespace Umbraco.Web.Editors Services.MediaService.Move(toMove, move.ParentId); var response = Request.CreateResponse(HttpStatusCode.OK); - response.Content = new StringContent(toMove.Path, Encoding.UTF8, "application/json"); + response.Content = new StringContent(toMove.Path, Encoding.UTF8, "text/plain"); return response; }