Property level validation for Management API (#15644)
* Property level validation for content - initial implementation * Always succeed create/update regardless of property level validation errors * Move old complex editor validation classes to Web.BackOffice so they will be deleted * Include operation status and property validation errors in ProblemDetails * Refactor property validation to its own service(s) * Make the problem details builder a little more generic towards extensions * Validation for item and branch publish * Moved malplaced test * Get rid of a TODO * Integration tests for content validation service * Simplify validation service * Add missing response types to create and update for document and media * Remove test that no longer applies * Use "errors" for model validation errors (property validation errors) * Split create/update and validation into their own endpoints * Fix forward merge * Correct wrong assumption for missing properties * Remove localization from validation error messages - decreases dependencies, adds a lot of obsolete constructors * Reuse existing validation service + support custom error messages * Fix merge errors * Review comments
This commit is contained in:
@@ -3,24 +3,18 @@ using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.Security.Authorization.Content;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Document;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
public class UpdateDocumentController : DocumentControllerBase
|
||||
public class UpdateDocumentController : UpdateDocumentControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IContentEditingService _contentEditingService;
|
||||
private readonly IDocumentEditingPresentationFactory _documentEditingPresentationFactory;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
@@ -30,8 +24,8 @@ public class UpdateDocumentController : DocumentControllerBase
|
||||
IContentEditingService contentEditingService,
|
||||
IDocumentEditingPresentationFactory documentEditingPresentationFactory,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
: base(authorizationService, contentEditingService)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_contentEditingService = contentEditingService;
|
||||
_documentEditingPresentationFactory = documentEditingPresentationFactory;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
@@ -40,35 +34,17 @@ public class UpdateDocumentController : DocumentControllerBase
|
||||
[HttpPut("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> Update(Guid id, UpdateDocumentRequestModel requestModel)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ContentPermissionResource.WithKeys(
|
||||
ActionUpdate.ActionLetter,
|
||||
id,
|
||||
requestModel.Variants
|
||||
.Where(v => v.Culture is not null)
|
||||
.Select(v => v.Culture!)),
|
||||
AuthorizationPolicies.ContentPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
=> await HandleRequest(id, requestModel, async content =>
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
ContentUpdateModel model = _documentEditingPresentationFactory.MapUpdateModel(requestModel);
|
||||
Attempt<ContentUpdateResult, ContentEditingOperationStatus> result =
|
||||
await _contentEditingService.UpdateAsync(content, model, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
IContent? content = await _contentEditingService.GetAsync(id);
|
||||
if (content == null)
|
||||
{
|
||||
return DocumentNotFound();
|
||||
}
|
||||
|
||||
ContentUpdateModel model = _documentEditingPresentationFactory.MapUpdateModel(requestModel);
|
||||
Attempt<IContent, ContentEditingOperationStatus> result = await _contentEditingService.UpdateAsync(content, model, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return result.Success
|
||||
? Ok()
|
||||
: ContentEditingOperationStatusResult(result.Status);
|
||||
}
|
||||
return result.Success
|
||||
? Ok()
|
||||
: ContentEditingOperationStatusResult(result.Status);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user