Headless CMS and Content Managment Hub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

178 lines
6.1 KiB

// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Security.Claims;
using System.Threading.Tasks;
using NodaTime;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Entities.Contents.Commands;
using Squidex.Domain.Apps.Entities.Contents.Repositories;
using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Translations;
using Squidex.Infrastructure.Validation;
namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
{
public static class GuardContent
{
public static async Task CanCreate(CreateContent command, IContentWorkflow contentWorkflow, ISchemaEntity schema)
{
Guard.NotNull(command, nameof(command));
if (schema.SchemaDef.IsSingleton && command.ContentId != schema.Id)
{
throw new DomainException(T.Get("contents.singletonNotCreatable"));
}
if (command.Publish && !await contentWorkflow.CanPublishOnCreateAsync(schema, command.Data, command.User))
{
throw new DomainException(T.Get("contents.workflowErorPublishing"));
}
Validate.It(e =>
{
ValidateData(command, e);
});
}
public static async Task CanUpdate(UpdateContent command,
IContentEntity content,
IContentWorkflow contentWorkflow)
{
Guard.NotNull(command, nameof(command));
Validate.It(e =>
{
ValidateData(command, e);
});
await ValidateCanUpdate(content, contentWorkflow, command.User);
}
public static async Task CanPatch(PatchContent command,
IContentEntity content,
IContentWorkflow contentWorkflow)
{
Guard.NotNull(command, nameof(command));
Validate.It(e =>
{
ValidateData(command, e);
});
await ValidateCanUpdate(content, contentWorkflow, command.User);
}
public static void CanDeleteDraft(DeleteContentDraft command, IContentEntity content)
{
Guard.NotNull(command, nameof(command));
if (content.NewStatus == null)
{
throw new DomainException(T.Get("contents.draftToDeleteNotFound"));
}
}
public static void CanCreateDraft(CreateContentDraft command, IContentEntity content)
{
Guard.NotNull(command, nameof(command));
if (content.Status != Status.Published)
{
throw new DomainException(T.Get("contents.draftNotCreateForUnpublished"));
}
}
public static Task CanChangeStatus(ChangeContentStatus command,
IContentEntity content,
IContentWorkflow contentWorkflow,
IContentRepository contentRepository,
ISchemaEntity schema)
{
Guard.NotNull(command, nameof(command));
if (schema.SchemaDef.IsSingleton)
{
if (content.NewStatus == null || command.Status != Status.Published)
{
throw new DomainException(T.Get("contents.singletonNotChangeable"));
}
return Task.CompletedTask;
}
return Validate.It(async e =>
{
var status = content.NewStatus ?? content.Status;
if (!await contentWorkflow.CanMoveToAsync(content, status, command.Status, command.User))
{
var values = new { oldStatus = status, newStatus = command.Status };
e(T.Get("contents.statusTransitionNotAllowed", values), nameof(command.Status));
}
if (content.Status == Status.Published && command.CheckReferrers)
{
var hasReferrer = await contentRepository.HasReferrersAsync(content.AppId.Id, command.ContentId, SearchScope.Published);
if (hasReferrer)
{
throw new DomainException(T.Get("contents.referenced"));
}
}
if (command.DueTime.HasValue && command.DueTime.Value < SystemClock.Instance.GetCurrentInstant())
{
e(T.Get("contents.statusSchedulingNotInFuture"), nameof(command.DueTime));
}
});
}
public static async Task CanDelete(DeleteContent command,
IContentEntity content,
IContentRepository contentRepository,
ISchemaEntity schema)
{
Guard.NotNull(command, nameof(command));
if (schema.SchemaDef.IsSingleton)
{
throw new DomainException(T.Get("contents.singletonNotDeletable"));
}
if (command.CheckReferrers)
{
var hasReferrer = await contentRepository.HasReferrersAsync(content.AppId.Id, command.ContentId, SearchScope.All);
if (hasReferrer)
{
throw new DomainException(T.Get("contents.referenced"));
}
}
}
private static void ValidateData(ContentDataCommand command, AddValidation e)
{
if (command.Data == null)
{
e(Not.Defined(nameof(command.Data)), nameof(command.Data));
}
}
private static async Task ValidateCanUpdate(IContentEntity content, IContentWorkflow contentWorkflow, ClaimsPrincipal user)
{
var status = content.NewStatus ?? content.Status;
if (!await contentWorkflow.CanUpdateAsync(content, status, user))
{
throw new DomainException(T.Get("contents.workflowErrorUpdate", new { status }));
}
}
}
}