From 9e455f9325fad7e1b853bf19e6951d7e3e2a4252 Mon Sep 17 00:00:00 2001 From: Sven Geusens Date: Wed, 6 Mar 2024 08:21:33 +0100 Subject: [PATCH] Check for duplicate keys on media if we know it's a fresh entity (#15838) Co-authored-by: Sven Geusens --- .../Controllers/Content/ContentControllerBase.cs | 4 ++++ src/Umbraco.Core/Services/MediaEditingService.cs | 1 + src/Umbraco.Core/Services/MediaService.cs | 7 +++++++ src/Umbraco.Core/Services/OperationResultType.cs | 5 +++++ .../OperationStatus/ContentEditingOperationStatus.cs | 3 ++- 5 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Content/ContentControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/Content/ContentControllerBase.cs index ca62e8738d..42398145bd 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Content/ContentControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Content/ContentControllerBase.cs @@ -64,6 +64,10 @@ public class ContentControllerBase : ManagementApiControllerBase .WithTitle("Invalid culture") .WithDetail("One or more of the supplied culture codes did not match the configured languages.") .Build()), + ContentEditingOperationStatus.DuplicateKey => BadRequest(problemDetailsBuilder + .WithTitle("Invalid Id") + .WithDetail("The supplied id is already in use.") + .Build()), ContentEditingOperationStatus.Unknown => StatusCode( StatusCodes.Status500InternalServerError, problemDetailsBuilder diff --git a/src/Umbraco.Core/Services/MediaEditingService.cs b/src/Umbraco.Core/Services/MediaEditingService.cs index 90eddcef22..f771dd3460 100644 --- a/src/Umbraco.Core/Services/MediaEditingService.cs +++ b/src/Umbraco.Core/Services/MediaEditingService.cs @@ -144,6 +144,7 @@ internal sealed class MediaEditingService // these are the only result states currently expected from Save OperationResultType.Success => ContentEditingOperationStatus.Success, OperationResultType.FailedCancelledByEvent => ContentEditingOperationStatus.CancelledByNotification, + OperationResultType.FailedDuplicateKey => ContentEditingOperationStatus.DuplicateKey, // for any other state we'll return "unknown" so we know that we need to amend this _ => ContentEditingOperationStatus.Unknown diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs index 63aace15d4..755b36ae82 100644 --- a/src/Umbraco.Core/Services/MediaService.cs +++ b/src/Umbraco.Core/Services/MediaService.cs @@ -756,6 +756,13 @@ namespace Umbraco.Cms.Core.Services scope.WriteLock(Constants.Locks.MediaTree); if (media.HasIdentity == false) { + if (_entityRepository.Get(media.Key, UmbracoObjectTypes.Media.GetGuid()) is not null) + { + scope.Complete(); + return Attempt.Fail( + new OperationResult(OperationResultType.FailedDuplicateKey, eventMessages)); + } + media.CreatorId = userId; } diff --git a/src/Umbraco.Core/Services/OperationResultType.cs b/src/Umbraco.Core/Services/OperationResultType.cs index c87b70c2a2..8db80fe61c 100644 --- a/src/Umbraco.Core/Services/OperationResultType.cs +++ b/src/Umbraco.Core/Services/OperationResultType.cs @@ -40,5 +40,10 @@ public enum OperationResultType : byte /// NoOperation = Failed | 6, // TODO: shouldn't it be a success? + /// + /// The operation could not complete due to duplicate key detection + /// + FailedDuplicateKey = Failed | 7 + // TODO: In the future, we might need to add more operations statuses, potentially like 'FailedByPermissions', etc... } diff --git a/src/Umbraco.Core/Services/OperationStatus/ContentEditingOperationStatus.cs b/src/Umbraco.Core/Services/OperationStatus/ContentEditingOperationStatus.cs index 1585207eef..6288104af5 100644 --- a/src/Umbraco.Core/Services/OperationStatus/ContentEditingOperationStatus.cs +++ b/src/Umbraco.Core/Services/OperationStatus/ContentEditingOperationStatus.cs @@ -18,5 +18,6 @@ public enum ContentEditingOperationStatus SortingInvalid, PropertyValidationError, InvalidCulture, - Unknown + DuplicateKey, + Unknown, }