Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c497fd19f | ||
|
|
ae3add6f7b | ||
|
|
7cf691888b | ||
|
|
4638406fc9 | ||
|
|
704ee94101 | ||
|
|
6c96ad1f93 | ||
|
|
8cebbd23d8 | ||
|
|
4a4437b500 | ||
|
|
bd83df28bc | ||
|
|
010ceab910 | ||
|
|
c6f1cfdd4a | ||
|
|
e09cf2aaf8 | ||
|
|
85680bd36d | ||
|
|
36f3bf6b9c | ||
|
|
8df1c3f152 | ||
|
|
ee44dbd677 | ||
|
|
05112b559f | ||
|
|
0fa669db94 | ||
|
|
e5d44cd9c3 | ||
|
|
5d682f69a8 | ||
|
|
df3724c830 | ||
|
|
e093ca5f49 | ||
|
|
b972d1db5a | ||
|
|
015d17db3f | ||
|
|
617f2441fc | ||
|
|
c18f28d22d | ||
|
|
f550eeec28 | ||
|
|
22907e01ef | ||
|
|
59a7d99e3c | ||
|
|
f4b3a0f4ac | ||
|
|
68d9e02417 | ||
|
|
6e85871595 | ||
|
|
6853f2c910 | ||
|
|
9d94b26cc2 | ||
|
|
58cbc9790f | ||
|
|
8311bae2ab | ||
|
|
2bfb83d6f7 | ||
|
|
f1a7c6bbc1 | ||
|
|
4d993a6dd1 | ||
|
|
950470aade | ||
|
|
7f1255b5e7 | ||
|
|
6e27ab2e0a | ||
|
|
da614e7d2c | ||
|
|
858c450223 | ||
|
|
e8f5b98cb0 | ||
|
|
339da5e19e | ||
|
|
9ef7c5b955 | ||
|
|
ad8db9c567 | ||
|
|
0210dd00a0 | ||
|
|
41f62ae03b | ||
|
|
b19f8a2eb1 | ||
|
|
1a86c9f45c | ||
|
|
5968bae002 | ||
|
|
7014f9a125 | ||
|
|
7536d6b95f | ||
|
|
6036b13e94 | ||
|
|
d2e7fc1863 | ||
|
|
27b7f220a3 | ||
|
|
9e360e8dc0 | ||
|
|
a2acb7a53f | ||
|
|
d9db6b02ce | ||
|
|
ae80d921c0 | ||
|
|
14a2ca89ea | ||
|
|
b2517e3302 | ||
|
|
f83949c508 | ||
|
|
af439c6a66 | ||
|
|
71d700ea28 | ||
|
|
90b2062d85 | ||
|
|
e6a91e5f6c | ||
|
|
421d616682 | ||
|
|
fb5030010c | ||
|
|
421ad35034 | ||
|
|
a17aef5af8 | ||
|
|
6544c5cbcc | ||
|
|
a0518a0636 | ||
|
|
5e669bb8c7 | ||
|
|
29ef442e99 | ||
|
|
2ae5582a9e | ||
|
|
0ec334e252 | ||
|
|
db9cbcb457 | ||
|
|
d04f8d9029 | ||
|
|
c4d09893cd | ||
|
|
040735b1c1 | ||
|
|
d92502b212 | ||
|
|
6b00925a6a | ||
|
|
b9142ad728 | ||
|
|
b71c2e53b7 | ||
|
|
598a2186d7 | ||
|
|
fcdfb9e588 | ||
|
|
b00840e147 | ||
|
|
f2473f7f74 | ||
|
|
673d97c19b | ||
|
|
32acc62cde | ||
|
|
c568db2704 | ||
|
|
fa6c5d0537 | ||
|
|
62d9a002f7 | ||
|
|
8b59e8eb3b | ||
|
|
eec6a27cca | ||
|
|
3b68fef220 | ||
|
|
92ec78086d | ||
|
|
cf9c2908b4 | ||
|
|
765a3b2968 | ||
|
|
89c7bb356b | ||
|
|
023c08fcdb | ||
|
|
29233a3455 | ||
|
|
7b97bdd0ef | ||
|
|
21597fa2f8 | ||
|
|
336039f963 | ||
|
|
c7125967c9 | ||
|
|
3e0a3ff1ea | ||
|
|
fa95f956a0 | ||
|
|
ba83cc1006 | ||
|
|
17dd0757d3 | ||
|
|
e02a3d452c | ||
|
|
33a30c38dc | ||
|
|
9a0309ac62 | ||
|
|
31ffc9ff02 | ||
|
|
8e911d728d | ||
|
|
7a12f056e4 | ||
|
|
391e8a0867 | ||
|
|
0ca1a861e9 | ||
|
|
e3135685da | ||
|
|
6f0fd8f6ec | ||
|
|
ebcb996431 | ||
|
|
8cbf68223a | ||
|
|
39f19bf3ab | ||
|
|
e8c0dd897b | ||
|
|
66fbade194 | ||
|
|
ae2761f204 | ||
|
|
a49981b6c5 | ||
|
|
d21d1453f5 | ||
|
|
11e19466f8 | ||
|
|
d51de53804 | ||
|
|
8b5448adcd | ||
|
|
cf70d7ff13 | ||
|
|
f0dc972bf2 | ||
|
|
81276fc048 | ||
|
|
58f300a20d | ||
|
|
f530772b80 | ||
|
|
8cea6cb6b5 | ||
|
|
7cf4c7857f | ||
|
|
5fe5a0febf | ||
|
|
d4ee843a01 | ||
|
|
c48ef57a84 | ||
|
|
0c3d1d7058 | ||
|
|
eda9857200 | ||
|
|
46b96f3811 | ||
|
|
7d73588c99 | ||
|
|
40c91262e6 | ||
|
|
31f23204f3 | ||
|
|
e53b8bcc52 | ||
|
|
25d3013949 | ||
|
|
8ac46e99b7 | ||
|
|
59cc153b84 | ||
|
|
29ecae7010 | ||
|
|
409f5072af | ||
|
|
58a0b160b2 | ||
|
|
c8ba79b2d1 | ||
|
|
ef1b48c992 | ||
|
|
e9819d6e57 | ||
|
|
480a208655 | ||
|
|
179f2e709d | ||
|
|
90c09b1bf1 | ||
|
|
e7719c2458 | ||
|
|
fbce5882c6 |
@@ -40,8 +40,8 @@
|
||||
<!-- Package Validation -->
|
||||
<PropertyGroup>
|
||||
<GenerateCompatibilitySuppressionFile>false</GenerateCompatibilitySuppressionFile>
|
||||
<EnablePackageValidation>true</EnablePackageValidation>
|
||||
<PackageValidationBaselineVersion>17.0.0</PackageValidationBaselineVersion>
|
||||
<EnablePackageValidation>false</EnablePackageValidation> <!-- TODO (V18): Set to true once this version is released. -->
|
||||
<PackageValidationBaselineVersion>18.0.0</PackageValidationBaselineVersion>
|
||||
<EnableStrictModeForCompatibleFrameworksInPackage>true</EnableStrictModeForCompatibleFrameworksInPackage>
|
||||
<EnableStrictModeForCompatibleTfms>true</EnableStrictModeForCompatibleTfms>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -8,13 +8,15 @@
|
||||
<ItemGroup>
|
||||
<GlobalPackageReference Include="Nerdbank.GitVersioning" Version="3.9.50" />
|
||||
<GlobalPackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
|
||||
<GlobalPackageReference Include="Umbraco.Code" Version="2.4.0" />
|
||||
<!-- TODO (V18): Bump Umbraco.Code to 3.0.0 stable before release of 18.0.0 -->
|
||||
<GlobalPackageReference Include="Umbraco.Code" Version="3.0.0-beta" />
|
||||
<GlobalPackageReference Include="Umbraco.GitVersioning.Extensions" Version="0.2.0" />
|
||||
</ItemGroup>
|
||||
<!-- Microsoft packages -->
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="10.0.4" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="5.0.0" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="10.0.4" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.4" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.4" />
|
||||
@@ -51,7 +53,7 @@
|
||||
<PackageVersion Include="JsonPatch.Net" Version="3.3.0" />
|
||||
<PackageVersion Include="K4os.Compression.LZ4" Version="1.3.8" />
|
||||
<PackageVersion Include="MailKit" Version="4.15.1" />
|
||||
<PackageVersion Include="Markdig" Version="0.45.0" />
|
||||
<PackageVersion Include="Markdig" Version="1.1.1" />
|
||||
<PackageVersion Include="Markdown" Version="2.2.1" />
|
||||
<PackageVersion Include="MessagePack" Version="3.1.4" />
|
||||
<PackageVersion Include="MiniProfiler.AspNetCore.Mvc" Version="4.5.4" />
|
||||
@@ -63,14 +65,14 @@
|
||||
<PackageVersion Include="OpenIddict.AspNetCore" Version="7.2.0" />
|
||||
<PackageVersion Include="OpenIddict.EntityFrameworkCore" Version="7.2.0" />
|
||||
<PackageVersion Include="Serilog" Version="4.3.1" />
|
||||
<PackageVersion Include="Serilog.AspNetCore" Version="9.0.0" />
|
||||
<PackageVersion Include="Serilog.AspNetCore" Version="10.0.0" />
|
||||
<PackageVersion Include="Serilog.Enrichers.Process" Version="3.0.0" />
|
||||
<PackageVersion Include="Serilog.Enrichers.Thread" Version="4.0.0" />
|
||||
<PackageVersion Include="Serilog.Expressions" Version="5.0.0" />
|
||||
<PackageVersion Include="Serilog.Extensions.Hosting" Version="9.0.0" />
|
||||
<PackageVersion Include="Serilog.Extensions.Hosting" Version="10.0.0" />
|
||||
<PackageVersion Include="Serilog.Formatting.Compact" Version="3.0.0" />
|
||||
<PackageVersion Include="Serilog.Formatting.Compact.Reader" Version="4.0.0" />
|
||||
<PackageVersion Include="Serilog.Settings.Configuration" Version="9.0.0" />
|
||||
<PackageVersion Include="Serilog.Settings.Configuration" Version="10.0.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.Async" Version="2.1.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.Map" Version="2.0.0" />
|
||||
|
||||
@@ -4,11 +4,11 @@ pr: none
|
||||
trigger: none
|
||||
|
||||
schedules:
|
||||
- cron: '0 3 * * *'
|
||||
displayName: Daily 3AM build (main)
|
||||
- cron: '0 6 * * *'
|
||||
displayName: Daily 6AM build (v18/dev)
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
- v18/dev
|
||||
|
||||
parameters:
|
||||
- name: skipIntegrationTests
|
||||
|
||||
@@ -10,15 +10,6 @@ public class OperationIdSelector : IOperationIdSelector
|
||||
{
|
||||
private readonly IEnumerable<IOperationIdHandler> _operationIdHandlers;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OperationIdSelector"/> class.
|
||||
/// </summary>
|
||||
[Obsolete("Use non-obsolete constructor. Scheduled for removal in Umbraco 18.")]
|
||||
public OperationIdSelector()
|
||||
: this(Enumerable.Empty<IOperationIdHandler>())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OperationIdSelector"/> class.
|
||||
/// </summary>
|
||||
|
||||
+3
-2
@@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Options;
|
||||
using OpenIddict.Server;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Extensions;
|
||||
@@ -32,12 +33,12 @@ public class ExposeBackOfficeAuthenticationOpenIddictServerEventsHandler : IOpen
|
||||
|
||||
// These are the type identifiers for the claims required by the principal
|
||||
// for the custom authentication scheme.
|
||||
// We make available the ID, user name and allowed applications (sections) claims.
|
||||
// We make available the ID and user name claims, plus the claim necessary for parsing the user key.
|
||||
_claimTypes =
|
||||
[
|
||||
backOfficeIdentityOptions.Value.ClaimsIdentity.UserIdClaimType,
|
||||
backOfficeIdentityOptions.Value.ClaimsIdentity.UserNameClaimType,
|
||||
Core.Constants.Security.AllowedApplicationsClaimType,
|
||||
Constants.Security.OpenIdDictSubClaimType
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,6 @@ public static class UmbracoBuilderExtensions
|
||||
ServiceLifetime.Scoped);
|
||||
|
||||
builder.Services.AddSingleton<IRequestCultureService, RequestCultureService>();
|
||||
builder.Services.AddSingleton<IRequestSegmmentService, RequestSegmentService>();
|
||||
builder.Services.AddSingleton<IRequestSegmentService, RequestSegmentService>();
|
||||
builder.Services.AddSingleton<IRequestRoutingService, RequestRoutingService>();
|
||||
builder.Services.AddSingleton<IRequestRedirectService, RequestRedirectService>();
|
||||
|
||||
@@ -3,7 +3,7 @@ using Umbraco.Cms.Core.DeliveryApi;
|
||||
|
||||
namespace Umbraco.Cms.Api.Delivery.Services;
|
||||
|
||||
internal sealed class RequestSegmentService : RequestHeaderHandler, IRequestSegmentService, IRequestSegmmentService
|
||||
internal sealed class RequestSegmentService : RequestHeaderHandler, IRequestSegmentService
|
||||
{
|
||||
public RequestSegmentService(IHttpContextAccessor httpContextAccessor)
|
||||
: base(httpContextAccessor)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Document;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing.Validation;
|
||||
using Umbraco.Cms.Core.Models.ContentPublishing;
|
||||
using Umbraco.Cms.Core.PropertyEditors.Validation;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
using Umbraco.Extensions;
|
||||
@@ -13,6 +15,8 @@ namespace Umbraco.Cms.Api.Management.Controllers.Content;
|
||||
/// </summary>
|
||||
public abstract class ContentControllerBase : ManagementApiControllerBase
|
||||
{
|
||||
protected abstract string EntityName { get; }
|
||||
|
||||
protected IActionResult ContentEditingOperationStatusResult(ContentEditingOperationStatus status)
|
||||
=> OperationStatusResult(status, problemDetailsBuilder => status switch
|
||||
{
|
||||
@@ -90,12 +94,12 @@ public abstract class ContentControllerBase : ManagementApiControllerBase
|
||||
.WithDetail("The supplied name is already in use for the same content type.")
|
||||
.Build()),
|
||||
ContentEditingOperationStatus.CannotDeleteWhenReferenced => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Cannot delete a referenced content item")
|
||||
.WithDetail("Cannot delete a referenced content item, while the setting ContentSettings.DisableDeleteWhenReferenced is enabled.")
|
||||
.WithTitle($"Cannot delete a referenced {EntityName}")
|
||||
.WithDetail($"Cannot delete a referenced {EntityName}, while the setting ContentSettings.DisableDeleteWhenReferenced is enabled.")
|
||||
.Build()),
|
||||
ContentEditingOperationStatus.CannotMoveToRecycleBinWhenReferenced => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Cannot move a referenced content item to the recycle bin")
|
||||
.WithDetail("Cannot move a referenced content item to the recycle bin, while the setting ContentSettings.DisableDeleteWhenReferenced is enabled.")
|
||||
.WithTitle($"Cannot move a referenced {EntityName} to the recycle bin")
|
||||
.WithDetail($"Cannot move a referenced {EntityName} to the recycle bin, while the setting ContentSettings.DisableUnpublishWhenReferenced is enabled.")
|
||||
.Build()),
|
||||
ContentEditingOperationStatus.Unknown => StatusCode(
|
||||
StatusCodes.Status500InternalServerError,
|
||||
@@ -118,6 +122,122 @@ public abstract class ContentControllerBase : ManagementApiControllerBase
|
||||
.Build()),
|
||||
});
|
||||
|
||||
protected IActionResult ContentPublishingOperationStatusResult(
|
||||
ContentPublishingOperationStatus status,
|
||||
IEnumerable<string>? invalidPropertyAliases = null,
|
||||
IEnumerable<ContentPublishingBranchItemResult>? failedBranchItems = null)
|
||||
=> OperationStatusResult(
|
||||
status,
|
||||
problemDetailsBuilder => status switch
|
||||
{
|
||||
ContentPublishingOperationStatus.ContentNotFound => NotFound(problemDetailsBuilder
|
||||
.WithTitle($"The requested {EntityName} could not be found")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.CancelledByEvent => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Publish cancelled by event")
|
||||
.WithDetail("The publish operation was cancelled by an event.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.ContentInvalid => BadRequest(problemDetailsBuilder
|
||||
.WithTitle($"Invalid {EntityName}")
|
||||
.WithDetail($"The specified {EntityName} had an invalid configuration.")
|
||||
.WithExtension("invalidProperties", invalidPropertyAliases ?? Enumerable.Empty<string>())
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.NothingToPublish => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Nothing to publish")
|
||||
.WithDetail("None of the specified cultures needed publishing.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.MandatoryCultureMissing => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Mandatory culture missing")
|
||||
.WithDetail("Must include all mandatory cultures when publishing.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.HasExpired => BadRequest(problemDetailsBuilder
|
||||
.WithTitle($"{EntityName.ToFirstUpperInvariant()} expired")
|
||||
.WithDetail($"Could not publish the {EntityName} because it was expired.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.CultureHasExpired => BadRequest(problemDetailsBuilder
|
||||
.WithTitle($"{EntityName.ToFirstUpperInvariant()} culture expired")
|
||||
.WithDetail($"Could not publish the {EntityName} because some of the specified cultures were expired.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.AwaitingRelease => BadRequest(problemDetailsBuilder
|
||||
.WithTitle($"{EntityName.ToFirstUpperInvariant()} awaiting release")
|
||||
.WithDetail($"Could not publish the {EntityName} because it was awaiting release.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.CultureAwaitingRelease => BadRequest(problemDetailsBuilder
|
||||
.WithTitle($"{EntityName.ToFirstUpperInvariant()} culture awaiting release")
|
||||
.WithDetail(
|
||||
$"Could not publish the {EntityName} because some of the specified cultures were awaiting release.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.InTrash => BadRequest(problemDetailsBuilder
|
||||
.WithTitle($"{EntityName.ToFirstUpperInvariant()} in the recycle bin")
|
||||
.WithDetail($"Could not publish the {EntityName} because it was in the recycle bin.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.PathNotPublished => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Parent not published")
|
||||
.WithDetail($"Could not publish the {EntityName} because its parent was not published.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.InvalidCulture => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Invalid cultures specified")
|
||||
.WithDetail("A specified culture is not valid for the operation.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.CultureMissing => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Culture missing")
|
||||
.WithDetail("A culture needs to be specified to execute the operation.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.CannotPublishInvariantWhenVariant => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Cannot publish invariant when variant")
|
||||
.WithDetail($"Cannot publish invariant culture when the {EntityName} varies by culture.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.CannotPublishVariantWhenNotVariant => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Cannot publish variant when not variant.")
|
||||
.WithDetail($"Cannot publish a given culture when the {EntityName} is invariant.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.ConcurrencyViolation => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Concurrency violation detected")
|
||||
.WithDetail("An attempt was made to publish a version older than the latest version.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.UnsavedChanges => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Unsaved changes")
|
||||
.WithDetail(
|
||||
$"Could not publish the {EntityName} because it had unsaved changes. Make sure to save all changes before attempting a publish.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.UnpublishTimeNeedsToBeAfterPublishTime => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Unpublish time needs to be after the publish time")
|
||||
.WithDetail(
|
||||
"Cannot handle an unpublish time that is not after the specified publish time.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.PublishTimeNeedsToBeInFuture => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Publish time needs to be higher than the current time")
|
||||
.WithDetail(
|
||||
"Cannot handle a publish time that is not after the current server time.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.UpublishTimeNeedsToBeInFuture => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Unpublish time needs to be higher than the current time")
|
||||
.WithDetail(
|
||||
"Cannot handle an unpublish time that is not after the current server time.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.CannotUnpublishWhenReferenced => BadRequest(problemDetailsBuilder
|
||||
.WithTitle($"Cannot unpublish {EntityName} when it's referenced somewhere else.")
|
||||
.WithDetail(
|
||||
$"Cannot unpublish a referenced {EntityName}, while the setting ContentSettings.DisableUnpublishWhenReferenced is enabled.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.FailedBranch => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Failed branch operation")
|
||||
.WithDetail("One or more items in the branch could not complete the operation.")
|
||||
.WithExtension("failedBranchItems", failedBranchItems?.Select(item => new DocumentPublishBranchItemResult { Id = item.Key, OperationStatus = item.OperationStatus }) ?? [])
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.Failed => BadRequest(
|
||||
problemDetailsBuilder
|
||||
.WithTitle("Publish or unpublish failed")
|
||||
.WithDetail(
|
||||
"An unspecified error occurred while (un)publishing. Please check the logs for additional information.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.TaskResultNotFound => NotFound(problemDetailsBuilder
|
||||
.WithTitle("The result of the submitted task could not be found")
|
||||
.Build()),
|
||||
|
||||
_ => StatusCode(StatusCodes.Status500InternalServerError, "Unknown content operation status."),
|
||||
});
|
||||
|
||||
protected IActionResult ContentEditingOperationStatusResult<TContentModelBase, TValueModel, TVariantModel>(
|
||||
ContentEditingOperationStatus status,
|
||||
TContentModelBase requestModel,
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute(Constants.UdiEntityType.DataType)]
|
||||
[ApiExplorerSettings(GroupName = "Data Type")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentsOrMediaOrMembersOrContentTypes)]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentsOrElementsOrMediaOrMembersOrContentTypes)]
|
||||
public abstract class DataTypeControllerBase : ManagementApiControllerBase
|
||||
{
|
||||
protected IActionResult DataTypeOperationStatusResult(DataTypeOperationStatus status) =>
|
||||
|
||||
-18
@@ -14,24 +14,6 @@ namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree;
|
||||
[ApiVersion("1.0")]
|
||||
public class AncestorsDataTypeTreeController : DataTypeTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AncestorsDataTypeTreeController"/> class, which provides API endpoints for retrieving ancestor data types in the tree structure.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the API.</param>
|
||||
/// <param name="dataTypeService">Service used for data type management and retrieval.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public AncestorsDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService)
|
||||
: base(entityService, dataTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AncestorsDataTypeTreeController"/> class, which manages operations related to ancestor data type trees in the Umbraco CMS.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity-related operations.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flags for tree nodes.</param>
|
||||
/// <param name="dataTypeService">Service used for data type management operations.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public AncestorsDataTypeTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDataTypeService dataTypeService)
|
||||
: base(entityService, flagProviders, dataTypeService)
|
||||
{
|
||||
|
||||
-18
@@ -15,24 +15,6 @@ namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree;
|
||||
[ApiVersion("1.0")]
|
||||
public class ChildrenDataTypeTreeController : DataTypeTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChildrenDataTypeTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for managing and retrieving entities within the system.</param>
|
||||
/// <param name="dataTypeService">Service used for managing and retrieving data types.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public ChildrenDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService)
|
||||
: base(entityService, dataTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChildrenDataTypeTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for managing and retrieving entities within the system.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply additional flags or metadata for entities.</param>
|
||||
/// <param name="dataTypeService">Service responsible for operations related to data types.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public ChildrenDataTypeTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDataTypeService dataTypeService)
|
||||
: base(entityService, flagProviders, dataTypeService)
|
||||
{
|
||||
|
||||
+8
-26
@@ -25,26 +25,6 @@ public class DataTypeTreeControllerBase : FolderTreeControllerBase<DataTypeTreeI
|
||||
{
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DataTypeTreeControllerBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for managing Umbraco entities.</param>
|
||||
/// <param name="dataTypeService">Service for managing data types within Umbraco.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public DataTypeTreeControllerBase(IEntityService entityService, IDataTypeService dataTypeService)
|
||||
: this(
|
||||
entityService,
|
||||
StaticServiceProvider.Instance.GetRequiredService<FlagProviderCollection>(),
|
||||
dataTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DataTypeTreeControllerBase"/> class with the specified services.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the data type tree.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flags for entities.</param>
|
||||
/// <param name="dataTypeService">Service used for managing data types.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 19.")]
|
||||
public DataTypeTreeControllerBase(IEntityService entityService, FlagProviderCollection flagProviders, IDataTypeService dataTypeService)
|
||||
: this(
|
||||
@@ -80,17 +60,17 @@ public class DataTypeTreeControllerBase : FolderTreeControllerBase<DataTypeTreeI
|
||||
}
|
||||
}
|
||||
|
||||
protected override DataTypeTreeItemResponseModel[] MapTreeItemViewModels(Guid? parentId, IEntitySlim[] entities)
|
||||
protected override async Task<DataTypeTreeItemResponseModel[]> MapTreeItemViewModelsAsync(Guid? parentId, IEntitySlim[] entities)
|
||||
{
|
||||
Dictionary<int, IDataType> dataTypes = entities.Any()
|
||||
? _dataTypeService
|
||||
.GetAllAsync(entities.Select(entity => entity.Key).ToArray()).GetAwaiter().GetResult()
|
||||
? (await _dataTypeService
|
||||
.GetAllAsync(entities.Select(entity => entity.Key).ToArray()))
|
||||
.ToDictionary(contentType => contentType.Id)
|
||||
: new Dictionary<int, IDataType>();
|
||||
|
||||
return entities.Select(entity =>
|
||||
IEnumerable<Task<DataTypeTreeItemResponseModel>> tasks = entities.Select(async entity =>
|
||||
{
|
||||
DataTypeTreeItemResponseModel responseModel = MapTreeItemViewModel(parentId, entity);
|
||||
DataTypeTreeItemResponseModel responseModel = await MapTreeItemViewModelAsync(parentId, entity);
|
||||
if (dataTypes.TryGetValue(entity.Id, out IDataType? dataType))
|
||||
{
|
||||
responseModel.EditorUiAlias = dataType.EditorUiAlias;
|
||||
@@ -98,6 +78,8 @@ public class DataTypeTreeControllerBase : FolderTreeControllerBase<DataTypeTreeI
|
||||
}
|
||||
|
||||
return responseModel;
|
||||
}).ToArray();
|
||||
});
|
||||
|
||||
return await Task.WhenAll(tasks);
|
||||
}
|
||||
}
|
||||
|
||||
-18
@@ -15,24 +15,6 @@ namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree;
|
||||
[ApiVersion("1.0")]
|
||||
public class RootDataTypeTreeController : DataTypeTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RootDataTypeTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for managing and retrieving entities within Umbraco.</param>
|
||||
/// <param name="dataTypeService">Service used for managing data types in Umbraco.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public RootDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService)
|
||||
: base(entityService, dataTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RootDataTypeTreeController"/> class, which manages the root of the data type tree in the Umbraco management API.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the tree.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flags for tree nodes.</param>
|
||||
/// <param name="dataTypeService">Service used for data type management and retrieval.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public RootDataTypeTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDataTypeService dataTypeService)
|
||||
: base(entityService, flagProviders, dataTypeService)
|
||||
{
|
||||
|
||||
-18
@@ -13,24 +13,6 @@ namespace Umbraco.Cms.Api.Management.Controllers.DataType.Tree;
|
||||
/// </summary>
|
||||
public class SiblingsDataTypeTreeController : DataTypeTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SiblingsDataTypeTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for managing and retrieving entities within Umbraco.</param>
|
||||
/// <param name="dataTypeService">Service used for managing data types in Umbraco.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public SiblingsDataTypeTreeController(IEntityService entityService, IDataTypeService dataTypeService)
|
||||
: base(entityService, dataTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SiblingsDataTypeTreeController"/> class, which manages operations related to sibling data type trees in the Umbraco CMS.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the CMS.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flags for tree nodes.</param>
|
||||
/// <param name="dataTypeService">Service used for managing data types.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public SiblingsDataTypeTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDataTypeService dataTypeService)
|
||||
: base(entityService, flagProviders, dataTypeService)
|
||||
{
|
||||
|
||||
-18
@@ -14,24 +14,6 @@ namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree;
|
||||
[ApiVersion("1.0")]
|
||||
public class AncestorsDictionaryTreeController : DictionaryTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AncestorsDictionaryTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for managing and retrieving entities within Umbraco.</param>
|
||||
/// <param name="dictionaryItemService">Service used for managing dictionary items in the Umbraco dictionary tree.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public AncestorsDictionaryTreeController(IEntityService entityService, IDictionaryItemService dictionaryItemService)
|
||||
: base(entityService, dictionaryItemService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AncestorsDictionaryTreeController"/> class, which handles operations related to retrieving ancestor dictionary tree items.
|
||||
/// </summary>
|
||||
/// <param name="entityService">The service used for entity operations.</param>
|
||||
/// <param name="flagProviders">A collection of providers for entity flags.</param>
|
||||
/// <param name="dictionaryItemService">The service used for dictionary item operations.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public AncestorsDictionaryTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDictionaryItemService dictionaryItemService)
|
||||
: base(entityService, flagProviders, dictionaryItemService)
|
||||
{
|
||||
|
||||
-18
@@ -16,24 +16,6 @@ namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree;
|
||||
[ApiVersion("1.0")]
|
||||
public class ChildrenDictionaryTreeController : DictionaryTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChildrenDictionaryTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for managing and retrieving entities within the system.</param>
|
||||
/// <param name="dictionaryItemService">Service used for managing dictionary items.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public ChildrenDictionaryTreeController(IEntityService entityService, IDictionaryItemService dictionaryItemService)
|
||||
: base(entityService, dictionaryItemService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChildrenDictionaryTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for managing and retrieving entities within Umbraco.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply additional flags or metadata for entities.</param>
|
||||
/// <param name="dictionaryItemService">Service for managing dictionary items used for localization.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public ChildrenDictionaryTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDictionaryItemService dictionaryItemService)
|
||||
: base(entityService, flagProviders, dictionaryItemService)
|
||||
{
|
||||
|
||||
-22
@@ -1,13 +1,11 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Tree;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
using Umbraco.Cms.Api.Management.ViewModels;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
@@ -25,26 +23,6 @@ namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree;
|
||||
// tree controller base. We'll keep it though, in the hope that we can mend EntityService.
|
||||
public class DictionaryTreeControllerBase : NamedEntityTreeControllerBase<NamedEntityTreeItemResponseModel>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DictionaryTreeControllerBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for managing and retrieving entities within the Umbraco system.</param>
|
||||
/// <param name="dictionaryItemService">Service used for managing and retrieving dictionary items for localization.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public DictionaryTreeControllerBase(IEntityService entityService, IDictionaryItemService dictionaryItemService)
|
||||
: this(
|
||||
entityService,
|
||||
StaticServiceProvider.Instance.GetRequiredService<FlagProviderCollection>(),
|
||||
dictionaryItemService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DictionaryTreeControllerBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for managing entities within the system.</param>
|
||||
/// <param name="flagProviders">A collection of providers for entity flags.</param>
|
||||
/// <param name="dictionaryItemService">Service for managing dictionary items.</param>
|
||||
public DictionaryTreeControllerBase(
|
||||
IEntityService entityService,
|
||||
FlagProviderCollection flagProviders,
|
||||
|
||||
+6
-6
@@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
@@ -16,13 +17,12 @@ namespace Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree;
|
||||
[ApiVersion("1.0")]
|
||||
public class RootDictionaryTreeController : DictionaryTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RootDictionaryTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the dictionary tree.</param>
|
||||
/// <param name="dictionaryItemService">Service used for managing dictionary items.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 20.")]
|
||||
public RootDictionaryTreeController(IEntityService entityService, IDictionaryItemService dictionaryItemService)
|
||||
: base(entityService, dictionaryItemService)
|
||||
: this(
|
||||
entityService,
|
||||
StaticServiceProvider.Instance.GetRequiredService<FlagProviderCollection>(),
|
||||
dictionaryItemService)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
-34
@@ -1,13 +1,11 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Document.Collection;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Mapping;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
@@ -26,16 +24,6 @@ public class ByKeyDocumentCollectionController : DocumentCollectionControllerBas
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
private readonly IDocumentCollectionPresentationFactory _documentCollectionPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Umbraco.Cms.Api.Management.Controllers.Document.Collection.ByKeyDocumentCollectionController"/> class,
|
||||
/// which handles document collection operations by document key.
|
||||
/// </summary>
|
||||
/// <param name="contentListViewService">Service for retrieving and managing content list views.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="mapper">The Umbraco object mapper used for mapping between models.</param>
|
||||
/// <param name="documentCollectionPresentationFactory">Factory for creating document collection presentation models.</param>
|
||||
/// <param name="flagProviders">A collection of providers for document collection flags.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public ByKeyDocumentCollectionController(
|
||||
IContentListViewService contentListViewService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
@@ -49,28 +37,6 @@ public class ByKeyDocumentCollectionController : DocumentCollectionControllerBas
|
||||
_documentCollectionPresentationFactory = documentCollectionPresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Umbraco.Cms.Api.Management.Controllers.Document.Collection.ByKeyDocumentCollectionController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="contentListViewService">Service for managing content list views.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security operations.</param>
|
||||
/// <param name="mapper">Maps Umbraco objects to API models.</param>
|
||||
/// <param name="documentCollectionPresentationFactory">Factory for creating document collection presentation models.</param>
|
||||
[Obsolete("Please use the constructor with all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public ByKeyDocumentCollectionController(
|
||||
IContentListViewService contentListViewService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IUmbracoMapper mapper,
|
||||
IDocumentCollectionPresentationFactory documentCollectionPresentationFactory)
|
||||
: this(
|
||||
contentListViewService,
|
||||
backOfficeSecurityAccessor,
|
||||
mapper,
|
||||
documentCollectionPresentationFactory,
|
||||
StaticServiceProvider.Instance.GetRequiredService<FlagProviderCollection>())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a paged collection of documents identified by the provided unique identifier.
|
||||
/// </summary>
|
||||
|
||||
@@ -21,6 +21,8 @@ namespace Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocuments)]
|
||||
public abstract class DocumentControllerBase : ContentControllerBase
|
||||
{
|
||||
protected override string EntityName => "document";
|
||||
|
||||
protected IActionResult DocumentNotFound()
|
||||
=> OperationStatusResult(ContentEditingOperationStatus.NotFound, problemDetailsBuilder
|
||||
=> NotFound(problemDetailsBuilder
|
||||
@@ -38,118 +40,7 @@ public abstract class DocumentControllerBase : ContentControllerBase
|
||||
ContentPublishingOperationStatus status,
|
||||
IEnumerable<string>? invalidPropertyAliases = null,
|
||||
IEnumerable<ContentPublishingBranchItemResult>? failedBranchItems = null)
|
||||
=> OperationStatusResult(status, problemDetailsBuilder => status switch
|
||||
{
|
||||
ContentPublishingOperationStatus.ContentNotFound => NotFound(problemDetailsBuilder
|
||||
.WithTitle("The requested document could not be found")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.CancelledByEvent => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Publish cancelled by event")
|
||||
.WithDetail("The publish operation was cancelled by an event.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.ContentInvalid => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Invalid document")
|
||||
.WithDetail("The specified document had an invalid configuration.")
|
||||
.WithExtension("invalidProperties", invalidPropertyAliases ?? Enumerable.Empty<string>())
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.NothingToPublish => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Nothing to publish")
|
||||
.WithDetail("None of the specified cultures needed publishing.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.MandatoryCultureMissing => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Mandatory culture missing")
|
||||
.WithDetail("Must include all mandatory cultures when publishing.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.HasExpired => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Document expired")
|
||||
.WithDetail("Could not publish the document because it was expired.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.CultureHasExpired => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Document culture expired")
|
||||
.WithDetail("Could not publish the document because some of the specified cultures were expired.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.AwaitingRelease => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Document awaiting release")
|
||||
.WithDetail("Could not publish the document because it was awaiting release.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.CultureAwaitingRelease => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Document culture awaiting release")
|
||||
.WithDetail(
|
||||
"Could not publish the document because some of the specified cultures were awaiting release.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.InTrash => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Document in the recycle bin")
|
||||
.WithDetail("Could not publish the document because it was in the recycle bin.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.PathNotPublished => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Parent not published")
|
||||
.WithDetail("Could not publish the document because its parent was not published.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.InvalidCulture => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Invalid cultures specified")
|
||||
.WithDetail("A specified culture is not valid for the operation.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.CultureMissing => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Culture missing")
|
||||
.WithDetail("A culture needs to be specified to execute the operation.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.CannotPublishInvariantWhenVariant => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Cannot publish invariant when variant")
|
||||
.WithDetail("Cannot publish invariant culture when the document varies by culture.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.CannotPublishVariantWhenNotVariant => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Cannot publish variant when not variant.")
|
||||
.WithDetail("Cannot publish a given culture when the document is invariant.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.ConcurrencyViolation => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Concurrency violation detected")
|
||||
.WithDetail("An attempt was made to publish a version older than the latest version.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.UnsavedChanges => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Unsaved changes")
|
||||
.WithDetail(
|
||||
"Could not publish the document because it had unsaved changes. Make sure to save all changes before attempting a publish.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.UnpublishTimeNeedsToBeAfterPublishTime => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Unpublish time needs to be after the publish time")
|
||||
.WithDetail(
|
||||
"Cannot handle an unpublish time that is not after the specified publish time.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.PublishTimeNeedsToBeInFuture => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Publish time needs to be higher than the current time")
|
||||
.WithDetail(
|
||||
"Cannot handle a publish time that is not after the current server time.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.UpublishTimeNeedsToBeInFuture => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Unpublish time needs to be higher than the current time")
|
||||
.WithDetail(
|
||||
"Cannot handle an unpublish time that is not after the current server time.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.CannotUnpublishWhenReferenced => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Cannot unpublish document when it's referenced somewhere else.")
|
||||
.WithDetail(
|
||||
"Cannot unpublish a referenced document, while the setting ContentSettings.DisableUnpublishWhenReferenced is enabled.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.FailedBranch => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Failed branch operation")
|
||||
.WithDetail("One or more items in the branch could not complete the operation.")
|
||||
.WithExtension("failedBranchItems", failedBranchItems?.Select(item => new DocumentPublishBranchItemResult
|
||||
{
|
||||
Id = item.Key,
|
||||
OperationStatus = item.OperationStatus
|
||||
}) ?? Enumerable.Empty<DocumentPublishBranchItemResult>())
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.Failed => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Publish or unpublish failed")
|
||||
.WithDetail(
|
||||
"An unspecified error occurred while (un)publishing. Please check the logs for additional information.")
|
||||
.Build()),
|
||||
ContentPublishingOperationStatus.TaskResultNotFound => NotFound(problemDetailsBuilder
|
||||
.WithTitle("The result of the submitted task could not be found")
|
||||
.Build()),
|
||||
|
||||
_ => StatusCode(StatusCodes.Status500InternalServerError, "Unknown content operation status."),
|
||||
});
|
||||
=> ContentPublishingOperationStatusResult(status, invalidPropertyAliases, failedBranchItems);
|
||||
|
||||
protected IActionResult PublicAccessOperationStatusResult(PublicAccessOperationStatus status)
|
||||
=> OperationStatusResult(status, problemDetailsBuilder => status switch
|
||||
|
||||
@@ -38,15 +38,6 @@ public class DomainsController : DocumentControllerBase
|
||||
_umbracoMapper = umbracoMapper;
|
||||
}
|
||||
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public DomainsController(IDomainService domainService, IUmbracoMapper umbracoMapper)
|
||||
: this(
|
||||
StaticServiceProvider.Instance.GetRequiredService<IAuthorizationService>(),
|
||||
domainService,
|
||||
umbracoMapper)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the list of domains and their associated culture settings assigned to the specified document.
|
||||
/// </summary>
|
||||
|
||||
+2
-3
@@ -1,7 +1,6 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Document.Item;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
@@ -26,7 +25,6 @@ public class ItemDocumentItemController : DocumentItemControllerBase
|
||||
/// </summary>
|
||||
/// <param name="entityService">The service used to manage and retrieve entities within the CMS.</param>
|
||||
/// <param name="documentPresentationFactory">The factory responsible for creating document presentation models.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public ItemDocumentItemController(
|
||||
IEntityService entityService,
|
||||
IDocumentPresentationFactory documentPresentationFactory)
|
||||
@@ -59,7 +57,8 @@ public class ItemDocumentItemController : DocumentItemControllerBase
|
||||
.GetAll(UmbracoObjectTypes.Document, ids.ToArray())
|
||||
.OfType<IDocumentEntitySlim>();
|
||||
|
||||
IEnumerable<DocumentItemResponseModel> responseModels = documents.Select(_documentPresentationFactory.CreateItemResponseModel);
|
||||
IEnumerable<Task<DocumentItemResponseModel>> tasks = documents.Select(_documentPresentationFactory.CreateItemResponseModelAsync);
|
||||
DocumentItemResponseModel[] responseModels = await Task.WhenAll(tasks);
|
||||
return Ok(responseModels);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-53
@@ -4,7 +4,6 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Document.Item;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.Entities;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
@@ -28,7 +27,6 @@ public class SearchDocumentItemController : DocumentItemControllerBase
|
||||
/// <param name="indexedEntitySearchService">Service for searching indexed entities.</param>
|
||||
/// <param name="documentPresentationFactory">Factory for creating document presentation models.</param>
|
||||
/// <param name="dataTypeService">Service for managing data types.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public SearchDocumentItemController(
|
||||
IIndexedEntitySearchService indexedEntitySearchService,
|
||||
IDocumentPresentationFactory documentPresentationFactory,
|
||||
@@ -39,56 +37,6 @@ public class SearchDocumentItemController : DocumentItemControllerBase
|
||||
_dataTypeService = dataTypeService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SearchDocumentItemController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="indexedEntitySearchService">The service used to perform searches on indexed entities. This dependency is injected.</param>
|
||||
/// <param name="documentPresentationFactory">The factory responsible for creating document presentation models. This dependency is injected.</param>
|
||||
[Obsolete("Use the non-obsolete constructor instead. Scheduled for removal in Umbraco 18.")]
|
||||
public SearchDocumentItemController(
|
||||
IIndexedEntitySearchService indexedEntitySearchService,
|
||||
IDocumentPresentationFactory documentPresentationFactory)
|
||||
: this(
|
||||
indexedEntitySearchService,
|
||||
documentPresentationFactory,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IDataTypeService>())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for document items, including those in the recycle bin, using the specified query and filters.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="query">The search query string.</param>
|
||||
/// <param name="trashed">If set, filters results to include only trashed items, only non-trashed items, or both (when null).</param>
|
||||
/// <param name="culture">An optional culture code to filter search results.</param>
|
||||
/// <param name="skip">The number of items to skip (for pagination).</param>
|
||||
/// <param name="take">The maximum number of items to return (for pagination).</param>
|
||||
/// <param name="parentId">An optional parent ID to filter results by parent.</param>
|
||||
/// <param name="allowedDocumentTypes">An optional list of allowed document type IDs to filter results.</param>
|
||||
/// <returns>A task representing the asynchronous operation, with an action result containing the search results.</returns>
|
||||
[Obsolete("Please use the overload taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public async Task<IActionResult> SearchWithTrashed(
|
||||
CancellationToken cancellationToken,
|
||||
string query,
|
||||
bool? trashed = null,
|
||||
string? culture = null,
|
||||
int skip = 0,
|
||||
int take = 100,
|
||||
Guid? parentId = null,
|
||||
[FromQuery] IEnumerable<Guid>? allowedDocumentTypes = null)
|
||||
=> await SearchWithTrashed(
|
||||
cancellationToken,
|
||||
query,
|
||||
trashed,
|
||||
culture,
|
||||
skip,
|
||||
take,
|
||||
parentId,
|
||||
allowedDocumentTypes,
|
||||
null);
|
||||
|
||||
/// <summary>
|
||||
/// Searches for document items, including those in the recycle bin, based on the specified query and filters.
|
||||
/// </summary>
|
||||
@@ -130,9 +78,12 @@ public class SearchDocumentItemController : DocumentItemControllerBase
|
||||
take,
|
||||
ignoreUserStartNodes);
|
||||
|
||||
IEnumerable<Task<DocumentItemResponseModel>> tasks = searchResult.Items.OfType<IDocumentEntitySlim>().Select(_documentPresentationFactory.CreateItemResponseModelAsync);
|
||||
DocumentItemResponseModel[] items = await Task.WhenAll(tasks);
|
||||
|
||||
var result = new PagedModel<DocumentItemResponseModel>
|
||||
{
|
||||
Items = searchResult.Items.OfType<IDocumentEntitySlim>().Select(_documentPresentationFactory.CreateItemResponseModel),
|
||||
Items = items,
|
||||
Total = searchResult.Total,
|
||||
};
|
||||
|
||||
|
||||
+5
-3
@@ -22,6 +22,8 @@ namespace Umbraco.Cms.Api.Management.Controllers.Document.RecycleBin;
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocuments)]
|
||||
public class DocumentRecycleBinControllerBase : RecycleBinControllerBase<DocumentRecycleBinItemResponseModel>
|
||||
{
|
||||
protected override string EntityName => "document";
|
||||
|
||||
private readonly IDocumentPresentationFactory _documentPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
@@ -37,13 +39,13 @@ public class DocumentRecycleBinControllerBase : RecycleBinControllerBase<Documen
|
||||
|
||||
protected override Guid RecycleBinRootKey => Constants.System.RecycleBinContentKey;
|
||||
|
||||
protected override DocumentRecycleBinItemResponseModel MapRecycleBinViewModel(Guid? parentId, IEntitySlim entity)
|
||||
protected override async Task<DocumentRecycleBinItemResponseModel> MapRecycleBinViewModelAsync(Guid? parentId, IEntitySlim entity)
|
||||
{
|
||||
DocumentRecycleBinItemResponseModel responseModel = base.MapRecycleBinViewModel(parentId, entity);
|
||||
DocumentRecycleBinItemResponseModel responseModel = await base.MapRecycleBinViewModelAsync(parentId, entity);
|
||||
|
||||
if (entity is IDocumentEntitySlim documentEntitySlim)
|
||||
{
|
||||
responseModel.Variants = _documentPresentationFactory.CreateVariantsItemResponseModels(documentEntitySlim);
|
||||
responseModel.Variants = await _documentPresentationFactory.CreateVariantsItemResponseModelsAsync(documentEntitySlim);
|
||||
responseModel.DocumentType = _documentPresentationFactory.CreateDocumentTypeReferenceResponseModel(documentEntitySlim);
|
||||
}
|
||||
|
||||
|
||||
-41
@@ -19,47 +19,6 @@ namespace Umbraco.Cms.Api.Management.Controllers.Document.Tree;
|
||||
[ApiVersion("1.0")]
|
||||
public class AncestorsDocumentTreeController : DocumentTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Umbraco.Cms.Api.Management.Controllers.Document.Tree.AncestorsDocumentTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the Umbraco CMS.</param>
|
||||
/// <param name="userStartNodeEntitiesService">Service for resolving user start nodes for entities.</param>
|
||||
/// <param name="dataTypeService">Service for managing data types in the CMS.</param>
|
||||
/// <param name="publicAccessService">Service for handling public access permissions on content.</param>
|
||||
/// <param name="appCaches">Provides access to application-level caches.</param>
|
||||
/// <param name="backofficeSecurityAccessor">Accessor for backoffice security context and operations.</param>
|
||||
/// <param name="documentPresentationFactory">Factory for creating document presentation models.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public AncestorsDocumentTreeController(
|
||||
IEntityService entityService,
|
||||
IUserStartNodeEntitiesService userStartNodeEntitiesService,
|
||||
IDataTypeService dataTypeService,
|
||||
IPublicAccessService publicAccessService,
|
||||
AppCaches appCaches,
|
||||
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
|
||||
IDocumentPresentationFactory documentPresentationFactory)
|
||||
: base(
|
||||
entityService,
|
||||
userStartNodeEntitiesService,
|
||||
dataTypeService,
|
||||
publicAccessService,
|
||||
appCaches,
|
||||
backofficeSecurityAccessor,
|
||||
documentPresentationFactory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AncestorsDocumentTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for managing and retrieving entities within Umbraco.</param>
|
||||
/// <param name="flagProviders">A collection of providers for handling entity flags.</param>
|
||||
/// <param name="userStartNodeEntitiesService">Service for resolving user start node entities.</param>
|
||||
/// <param name="dataTypeService">Service for managing data types in Umbraco.</param>
|
||||
/// <param name="publicAccessService">Service for handling public access permissions.</param>
|
||||
/// <param name="appCaches">Provides access to application-level caches.</param>
|
||||
/// <param name="backofficeSecurityAccessor">Accessor for backoffice security context and operations.</param>
|
||||
/// <param name="documentPresentationFactory">Factory for creating document presentation models.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 19.")]
|
||||
public AncestorsDocumentTreeController(
|
||||
IEntityService entityService,
|
||||
|
||||
-41
@@ -20,47 +20,6 @@ namespace Umbraco.Cms.Api.Management.Controllers.Document.Tree;
|
||||
[ApiVersion("1.0")]
|
||||
public class ChildrenDocumentTreeController : DocumentTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChildrenDocumentTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for managing and retrieving entities in the system.</param>
|
||||
/// <param name="userStartNodeEntitiesService">Service for resolving user start nodes for entities.</param>
|
||||
/// <param name="dataTypeService">Service for accessing and managing data types.</param>
|
||||
/// <param name="publicAccessService">Service for handling public access permissions and restrictions.</param>
|
||||
/// <param name="appCaches">Provides application-level caching mechanisms.</param>
|
||||
/// <param name="backofficeSecurityAccessor">Accessor for back office security context and operations.</param>
|
||||
/// <param name="documentPresentationFactory">Factory for creating document presentation models.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public ChildrenDocumentTreeController(
|
||||
IEntityService entityService,
|
||||
IUserStartNodeEntitiesService userStartNodeEntitiesService,
|
||||
IDataTypeService dataTypeService,
|
||||
IPublicAccessService publicAccessService,
|
||||
AppCaches appCaches,
|
||||
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
|
||||
IDocumentPresentationFactory documentPresentationFactory)
|
||||
: base(
|
||||
entityService,
|
||||
userStartNodeEntitiesService,
|
||||
dataTypeService,
|
||||
publicAccessService,
|
||||
appCaches,
|
||||
backofficeSecurityAccessor,
|
||||
documentPresentationFactory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChildrenDocumentTreeController"/> class, responsible for managing child document tree operations in the Umbraco backoffice API.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for accessing and managing entities within Umbraco.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flags for document tree nodes.</param>
|
||||
/// <param name="userStartNodeEntitiesService">Service for resolving user-specific start nodes in the content tree.</param>
|
||||
/// <param name="dataTypeService">Service for managing data types in Umbraco.</param>
|
||||
/// <param name="publicAccessService">Service for handling public access permissions on documents.</param>
|
||||
/// <param name="appCaches">Provides application-level caching functionality.</param>
|
||||
/// <param name="backofficeSecurityAccessor">Accessor for backoffice security context and authentication.</param>
|
||||
/// <param name="documentPresentationFactory">Factory for creating document presentation models for the API.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 19.")]
|
||||
public ChildrenDocumentTreeController(
|
||||
IEntityService entityService,
|
||||
|
||||
+3
-24
@@ -34,27 +34,6 @@ public abstract class DocumentTreeControllerBase : UserStartNodeTreeControllerBa
|
||||
private readonly IDocumentPresentationFactory _documentPresentationFactory;
|
||||
private readonly IDocumentPermissionFilterService _documentPermissionFilterService;
|
||||
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
protected DocumentTreeControllerBase(
|
||||
IEntityService entityService,
|
||||
IUserStartNodeEntitiesService userStartNodeEntitiesService,
|
||||
IDataTypeService dataTypeService,
|
||||
IPublicAccessService publicAccessService,
|
||||
AppCaches appCaches,
|
||||
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
|
||||
IDocumentPresentationFactory documentPresentationFactory)
|
||||
: this(
|
||||
entityService,
|
||||
StaticServiceProvider.Instance.GetRequiredService<FlagProviderCollection>(),
|
||||
userStartNodeEntitiesService,
|
||||
dataTypeService,
|
||||
publicAccessService,
|
||||
appCaches,
|
||||
backofficeSecurityAccessor,
|
||||
documentPresentationFactory)
|
||||
{
|
||||
}
|
||||
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 19.")]
|
||||
protected DocumentTreeControllerBase(
|
||||
IEntityService entityService,
|
||||
@@ -102,9 +81,9 @@ public abstract class DocumentTreeControllerBase : UserStartNodeTreeControllerBa
|
||||
|
||||
protected override Ordering ItemOrdering => Ordering.By(Infrastructure.Persistence.Dtos.NodeDto.SortOrderColumnName);
|
||||
|
||||
protected override DocumentTreeItemResponseModel MapTreeItemViewModel(Guid? parentId, IEntitySlim entity)
|
||||
protected override async Task<DocumentTreeItemResponseModel> MapTreeItemViewModelAsync(Guid? parentId, IEntitySlim entity)
|
||||
{
|
||||
DocumentTreeItemResponseModel responseModel = base.MapTreeItemViewModel(parentId, entity);
|
||||
DocumentTreeItemResponseModel responseModel = await base.MapTreeItemViewModelAsync(parentId, entity);
|
||||
|
||||
if (entity is IDocumentEntitySlim documentEntitySlim)
|
||||
{
|
||||
@@ -115,7 +94,7 @@ public abstract class DocumentTreeControllerBase : UserStartNodeTreeControllerBa
|
||||
responseModel.Id = entity.Key;
|
||||
responseModel.CreateDate = entity.CreateDate;
|
||||
|
||||
responseModel.Variants = _documentPresentationFactory.CreateVariantsItemResponseModels(documentEntitySlim);
|
||||
responseModel.Variants = await _documentPresentationFactory.CreateVariantsItemResponseModelsAsync(documentEntitySlim);
|
||||
responseModel.DocumentType = _documentPresentationFactory.CreateDocumentTypeReferenceResponseModel(documentEntitySlim);
|
||||
}
|
||||
|
||||
|
||||
-41
@@ -20,47 +20,6 @@ namespace Umbraco.Cms.Api.Management.Controllers.Document.Tree;
|
||||
[ApiVersion("1.0")]
|
||||
public class RootDocumentTreeController : DocumentTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RootDocumentTreeController"/> class, which manages the root nodes of the document tree in the Umbraco backoffice.
|
||||
/// </summary>
|
||||
/// <param name="entityService">The service used for entity operations.</param>
|
||||
/// <param name="userStartNodeEntitiesService">The service for resolving user start node entities.</param>
|
||||
/// <param name="dataTypeService">The service for managing data types.</param>
|
||||
/// <param name="publicAccessService">The service for handling public access permissions.</param>
|
||||
/// <param name="appCaches">The application-level caches.</param>
|
||||
/// <param name="backofficeSecurityAccessor">Accessor for backoffice security context.</param>
|
||||
/// <param name="documentPresentationFactory">Factory for creating document presentation models.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public RootDocumentTreeController(
|
||||
IEntityService entityService,
|
||||
IUserStartNodeEntitiesService userStartNodeEntitiesService,
|
||||
IDataTypeService dataTypeService,
|
||||
IPublicAccessService publicAccessService,
|
||||
AppCaches appCaches,
|
||||
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
|
||||
IDocumentPresentationFactory documentPresentationFactory)
|
||||
: base(
|
||||
entityService,
|
||||
userStartNodeEntitiesService,
|
||||
dataTypeService,
|
||||
publicAccessService,
|
||||
appCaches,
|
||||
backofficeSecurityAccessor,
|
||||
documentPresentationFactory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Umbraco.Cms.Api.Management.Controllers.Document.Tree.RootDocumentTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for managing and retrieving entities within Umbraco.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flags for document tree nodes.</param>
|
||||
/// <param name="userStartNodeEntitiesService">Service for resolving user-specific start nodes in the content tree.</param>
|
||||
/// <param name="dataTypeService">Service for accessing and managing data types.</param>
|
||||
/// <param name="publicAccessService">Service for handling public access permissions on documents.</param>
|
||||
/// <param name="appCaches">Provides application-level caching mechanisms.</param>
|
||||
/// <param name="backofficeSecurityAccessor">Accessor for backoffice security context and operations.</param>
|
||||
/// <param name="documentPresentationFactory">Factory for creating document presentation models.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 19.")]
|
||||
public RootDocumentTreeController(
|
||||
IEntityService entityService,
|
||||
|
||||
-41
@@ -20,47 +20,6 @@ namespace Umbraco.Cms.Api.Management.Controllers.Document.Tree;
|
||||
[ApiVersion("1.0")]
|
||||
public class SiblingsDocumentTreeController : DocumentTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SiblingsDocumentTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for managing and retrieving entities in the system.</param>
|
||||
/// <param name="userStartNodeEntitiesService">Service for resolving user start nodes for entities.</param>
|
||||
/// <param name="dataTypeService">Service for accessing and managing data types.</param>
|
||||
/// <param name="publicAccessService">Service for handling public access permissions.</param>
|
||||
/// <param name="appCaches">Provides application-level caching functionality.</param>
|
||||
/// <param name="backofficeSecurityAccessor">Accessor for backoffice security context and operations.</param>
|
||||
/// <param name="documentPresentationFactory">Factory for creating document presentation models.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public SiblingsDocumentTreeController(
|
||||
IEntityService entityService,
|
||||
IUserStartNodeEntitiesService userStartNodeEntitiesService,
|
||||
IDataTypeService dataTypeService,
|
||||
IPublicAccessService publicAccessService,
|
||||
AppCaches appCaches,
|
||||
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
|
||||
IDocumentPresentationFactory documentPresentationFactory)
|
||||
: base(
|
||||
entityService,
|
||||
userStartNodeEntitiesService,
|
||||
dataTypeService,
|
||||
publicAccessService,
|
||||
appCaches,
|
||||
backofficeSecurityAccessor,
|
||||
documentPresentationFactory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SiblingsDocumentTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the Umbraco CMS.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flag information for entities.</param>
|
||||
/// <param name="userStartNodeEntitiesService">Service for resolving user start node entities.</param>
|
||||
/// <param name="dataTypeService">Service for managing data types in the CMS.</param>
|
||||
/// <param name="publicAccessService">Service for handling public access permissions.</param>
|
||||
/// <param name="appCaches">Provides access to application-level caches.</param>
|
||||
/// <param name="backofficeSecurityAccessor">Accessor for backoffice security context and operations.</param>
|
||||
/// <param name="documentPresentationFactory">Factory for creating document presentation models.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 19.")]
|
||||
public SiblingsDocumentTreeController(
|
||||
IEntityService entityService,
|
||||
|
||||
@@ -44,16 +44,6 @@ public class UpdateDomainsController : DocumentControllerBase
|
||||
_domainPresentationFactory = domainPresentationFactory;
|
||||
}
|
||||
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public UpdateDomainsController(IDomainService domainService, IUmbracoMapper umbracoMapper, IDomainPresentationFactory domainPresentationFactory)
|
||||
: this(
|
||||
StaticServiceProvider.Instance.GetRequiredService<IAuthorizationService>(),
|
||||
domainService,
|
||||
umbracoMapper,
|
||||
domainPresentationFactory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the domains assigned to the specified document.
|
||||
/// </summary>
|
||||
|
||||
@@ -41,16 +41,6 @@ public class UpdateNotificationsController : DocumentControllerBase
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public UpdateNotificationsController(IContentEditingService contentEditingService, INotificationService notificationService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
: this(
|
||||
StaticServiceProvider.Instance.GetRequiredService<IAuthorizationService>(),
|
||||
contentEditingService,
|
||||
notificationService,
|
||||
backOfficeSecurityAccessor)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the notification subscriptions for the current user on the specified document.
|
||||
/// </summary>
|
||||
|
||||
+2
@@ -14,6 +14,8 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentBlueprint;
|
||||
[ApiExplorerSettings(GroupName = "Document Blueprint")]
|
||||
public abstract class DocumentBlueprintControllerBase : ContentControllerBase
|
||||
{
|
||||
protected override string EntityName => "document blueprint";
|
||||
|
||||
protected IActionResult DocumentBlueprintNotFound()
|
||||
=> OperationStatusResult(ContentEditingOperationStatus.NotFound, problemDetailsBuilder
|
||||
=> NotFound(problemDetailsBuilder
|
||||
|
||||
-13
@@ -1,7 +1,6 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
@@ -15,24 +14,12 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentBlueprint.Tree;
|
||||
[ApiVersion("1.0")]
|
||||
public class AncestorsDocumentBlueprintTreeController : DocumentBlueprintTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AncestorsDocumentBlueprintTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the controller.</param>
|
||||
/// <param name="documentPresentationFactory">Factory responsible for creating document presentation models.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public AncestorsDocumentBlueprintTreeController(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory)
|
||||
: base(entityService, documentPresentationFactory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AncestorsDocumentBlueprintTreeController"/> class, which manages the retrieval of ancestor document blueprint tree nodes.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the document blueprint tree.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flags for tree nodes.</param>
|
||||
/// <param name="documentPresentationFactory">Factory responsible for creating document presentation models.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public AncestorsDocumentBlueprintTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDocumentPresentationFactory documentPresentationFactory)
|
||||
: base(entityService, flagProviders, documentPresentationFactory)
|
||||
{
|
||||
|
||||
-13
@@ -1,7 +1,6 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
@@ -16,24 +15,12 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentBlueprint.Tree;
|
||||
[ApiVersion("1.0")]
|
||||
public class ChildrenDocumentBlueprintTreeController : DocumentBlueprintTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChildrenDocumentBlueprintTreeController"/> class, which manages the retrieval of child document blueprint nodes in the tree structure.
|
||||
/// </summary>
|
||||
/// <param name="entityService">The service used to interact with and retrieve entity data.</param>
|
||||
/// <param name="documentPresentationFactory">The factory responsible for creating document presentation models.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public ChildrenDocumentBlueprintTreeController(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory)
|
||||
: base(entityService, documentPresentationFactory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChildrenDocumentBlueprintTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used to manage and retrieve entities within the Umbraco CMS.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flags for document blueprints.</param>
|
||||
/// <param name="documentPresentationFactory">Factory responsible for creating document presentation models.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public ChildrenDocumentBlueprintTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDocumentPresentationFactory documentPresentationFactory)
|
||||
: base(entityService, flagProviders, documentPresentationFactory)
|
||||
{
|
||||
|
||||
+8
-18
@@ -25,20 +25,6 @@ public class DocumentBlueprintTreeControllerBase : FolderTreeControllerBase<Docu
|
||||
{
|
||||
private readonly IDocumentPresentationFactory _documentPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DocumentBlueprintTreeControllerBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the document blueprint tree.</param>
|
||||
/// <param name="documentPresentationFactory">Factory responsible for creating document presentation models.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public DocumentBlueprintTreeControllerBase(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory)
|
||||
: this(
|
||||
entityService,
|
||||
StaticServiceProvider.Instance.GetRequiredService<FlagProviderCollection>(),
|
||||
documentPresentationFactory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DocumentBlueprintTreeControllerBase"/> class, providing required services for managing document blueprint trees.
|
||||
/// </summary>
|
||||
@@ -80,15 +66,19 @@ public class DocumentBlueprintTreeControllerBase : FolderTreeControllerBase<Docu
|
||||
}
|
||||
}
|
||||
|
||||
protected override DocumentBlueprintTreeItemResponseModel[] MapTreeItemViewModels(Guid? parentId, IEntitySlim[] entities)
|
||||
=> entities.Select(entity =>
|
||||
protected override async Task<DocumentBlueprintTreeItemResponseModel[]> MapTreeItemViewModelsAsync(Guid? parentId, IEntitySlim[] entities)
|
||||
{
|
||||
IEnumerable<Task<DocumentBlueprintTreeItemResponseModel>> tasks = entities.Select(async entity =>
|
||||
{
|
||||
DocumentBlueprintTreeItemResponseModel responseModel = MapTreeItemViewModel(parentId, entity);
|
||||
DocumentBlueprintTreeItemResponseModel responseModel = await MapTreeItemViewModelAsync(parentId, entity);
|
||||
if (entity is IDocumentEntitySlim documentEntitySlim)
|
||||
{
|
||||
responseModel.HasChildren = false;
|
||||
responseModel.DocumentType = _documentPresentationFactory.CreateDocumentTypeReferenceResponseModel(documentEntitySlim);
|
||||
}
|
||||
return responseModel;
|
||||
}).ToArray();
|
||||
});
|
||||
|
||||
return await Task.WhenAll(tasks);
|
||||
}
|
||||
}
|
||||
|
||||
-13
@@ -1,7 +1,6 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
@@ -17,24 +16,12 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentBlueprint.Tree;
|
||||
[ApiVersion("1.0")]
|
||||
public class RootDocumentBlueprintTreeController : DocumentBlueprintTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RootDocumentBlueprintTreeController"/> class, which manages the tree structure for root document blueprints.
|
||||
/// </summary>
|
||||
/// <param name="entityService">The service used to manage and retrieve entities within the system.</param>
|
||||
/// <param name="documentPresentationFactory">The factory responsible for creating document presentation models.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public RootDocumentBlueprintTreeController(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory)
|
||||
: base(entityService, documentPresentationFactory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RootDocumentBlueprintTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the document blueprint tree.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flags for document blueprints.</param>
|
||||
/// <param name="documentPresentationFactory">Factory responsible for creating document presentation models.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public RootDocumentBlueprintTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDocumentPresentationFactory documentPresentationFactory)
|
||||
: base(entityService, flagProviders, documentPresentationFactory)
|
||||
{
|
||||
|
||||
-8
@@ -1,6 +1,5 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
@@ -14,19 +13,12 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentBlueprint.Tree;
|
||||
/// </summary>
|
||||
public class SiblingsDocumentBlueprintTreeController : DocumentBlueprintTreeControllerBase
|
||||
{
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public SiblingsDocumentBlueprintTreeController(IEntityService entityService, IDocumentPresentationFactory documentPresentationFactory)
|
||||
: base(entityService, documentPresentationFactory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SiblingsDocumentBlueprintTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the Umbraco CMS.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flags for document blueprints.</param>
|
||||
/// <param name="documentPresentationFactory">Factory responsible for creating document presentation models.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public SiblingsDocumentBlueprintTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IDocumentPresentationFactory documentPresentationFactory)
|
||||
: base(entityService, flagProviders, documentPresentationFactory)
|
||||
{
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.DocumentType;
|
||||
using Umbraco.Cms.Core.Mapping;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.DocumentType;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
public class AllowedInLibraryDocumentTypeController : DocumentTypeControllerBase
|
||||
{
|
||||
private readonly IContentTypeService _contentTypeService;
|
||||
private readonly IUmbracoMapper _umbracoMapper;
|
||||
|
||||
public AllowedInLibraryDocumentTypeController(IContentTypeService contentTypeService, IUmbracoMapper umbracoMapper)
|
||||
{
|
||||
_contentTypeService = contentTypeService;
|
||||
_umbracoMapper = umbracoMapper;
|
||||
}
|
||||
|
||||
[HttpGet("allowed-in-library")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<AllowedDocumentType>), StatusCodes.Status200OK)]
|
||||
[EndpointSummary("Gets document types allowed in library.")]
|
||||
[EndpointDescription("Gets a collection of document types that are allowed in the library.")]
|
||||
public async Task<IActionResult> AllowedInLibrary(CancellationToken cancellationToken, int skip = 0, int take = 100)
|
||||
{
|
||||
PagedModel<IContentType> result = await _contentTypeService.GetAllAllowedInLibraryAsync(skip, take);
|
||||
|
||||
List<AllowedDocumentType> viewModels = _umbracoMapper.MapEnumerable<IContentType, AllowedDocumentType>(result.Items);
|
||||
|
||||
var pagedViewModel = new PagedViewModel<AllowedDocumentType>
|
||||
{
|
||||
Total = result.Total,
|
||||
Items = viewModels,
|
||||
};
|
||||
|
||||
return Ok(pagedViewModel);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -15,7 +15,7 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentType;
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute(Constants.UdiEntityType.DocumentType)]
|
||||
[ApiExplorerSettings(GroupName = "Document Type")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentsOrDocumentTypes)]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentsOrElementsOrDocumentTypes)]
|
||||
public abstract class DocumentTypeControllerBase : ManagementApiControllerBase
|
||||
{
|
||||
protected IActionResult OperationStatusResult(ContentTypeOperationStatus status)
|
||||
|
||||
-13
@@ -1,7 +1,6 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
@@ -14,24 +13,12 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentType.Tree;
|
||||
[ApiVersion("1.0")]
|
||||
public class AncestorsDocumentTypeTreeController : DocumentTypeTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AncestorsDocumentTypeTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for managing and retrieving entities within Umbraco.</param>
|
||||
/// <param name="contentTypeService">Service used for managing and retrieving content types in Umbraco.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public AncestorsDocumentTypeTreeController(IEntityService entityService, IContentTypeService contentTypeService)
|
||||
: base(entityService, contentTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AncestorsDocumentTypeTreeController"/> class, which manages operations related to ancestor document types in the tree structure.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the Umbraco CMS.</param>
|
||||
/// <param name="flagProviders">A collection of flag providers used to determine additional metadata or state for entities.</param>
|
||||
/// <param name="contentTypeService">Service used for managing content types in the CMS.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public AncestorsDocumentTypeTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IContentTypeService contentTypeService)
|
||||
: base(entityService, flagProviders, contentTypeService)
|
||||
{
|
||||
|
||||
-13
@@ -1,7 +1,6 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
@@ -15,24 +14,12 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentType.Tree;
|
||||
[ApiVersion("1.0")]
|
||||
public class ChildrenDocumentTypeTreeController : DocumentTypeTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChildrenDocumentTypeTreeController"/> class, which manages the retrieval of child document types in the tree structure.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the Umbraco CMS.</param>
|
||||
/// <param name="contentTypeService">Service used for managing content types in the Umbraco CMS.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public ChildrenDocumentTypeTreeController(IEntityService entityService, IContentTypeService contentTypeService)
|
||||
: base(entityService, contentTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChildrenDocumentTypeTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">The <see cref="IEntityService"/> used to manage entities.</param>
|
||||
/// <param name="flagProviders">The <see cref="FlagProviderCollection"/> containing flag providers for the tree.</param>
|
||||
/// <param name="contentTypeService">The <see cref="IContentTypeService"/> used to manage content types.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public ChildrenDocumentTypeTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IContentTypeService contentTypeService)
|
||||
: base(entityService, flagProviders, contentTypeService)
|
||||
{
|
||||
|
||||
+6
-18
@@ -25,20 +25,6 @@ public class DocumentTypeTreeControllerBase : FolderTreeControllerBase<DocumentT
|
||||
{
|
||||
private readonly IContentTypeService _contentTypeService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DocumentTypeTreeControllerBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for managing and retrieving entities within the Umbraco CMS.</param>
|
||||
/// <param name="contentTypeService">Service used for managing and retrieving content types (document types) within the Umbraco CMS.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public DocumentTypeTreeControllerBase(IEntityService entityService, IContentTypeService contentTypeService)
|
||||
: this(
|
||||
entityService,
|
||||
StaticServiceProvider.Instance.GetRequiredService<FlagProviderCollection>(),
|
||||
contentTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DocumentTypeTreeControllerBase"/> class.
|
||||
/// </summary>
|
||||
@@ -69,15 +55,15 @@ public class DocumentTypeTreeControllerBase : FolderTreeControllerBase<DocumentT
|
||||
|
||||
protected override UmbracoObjectTypes FolderObjectType => UmbracoObjectTypes.DocumentTypeContainer;
|
||||
|
||||
protected override DocumentTypeTreeItemResponseModel[] MapTreeItemViewModels(Guid? parentKey, IEntitySlim[] entities)
|
||||
protected override async Task<DocumentTypeTreeItemResponseModel[]> MapTreeItemViewModelsAsync(Guid? parentKey, IEntitySlim[] entities)
|
||||
{
|
||||
var contentTypes = _contentTypeService
|
||||
.GetMany(entities.Select(entity => entity.Id).ToArray())
|
||||
.ToDictionary(contentType => contentType.Id);
|
||||
|
||||
return entities.Select(entity =>
|
||||
IEnumerable<Task<DocumentTypeTreeItemResponseModel>> tasks = entities.Select(async entity =>
|
||||
{
|
||||
DocumentTypeTreeItemResponseModel responseModel = MapTreeItemViewModel(parentKey, entity);
|
||||
DocumentTypeTreeItemResponseModel responseModel = await MapTreeItemViewModelAsync(parentKey, entity);
|
||||
if (contentTypes.TryGetValue(entity.Id, out IContentType? contentType))
|
||||
{
|
||||
responseModel.Icon = contentType.Icon ?? responseModel.Icon;
|
||||
@@ -85,6 +71,8 @@ public class DocumentTypeTreeControllerBase : FolderTreeControllerBase<DocumentT
|
||||
}
|
||||
|
||||
return responseModel;
|
||||
}).ToArray();
|
||||
});
|
||||
|
||||
return await Task.WhenAll(tasks);
|
||||
}
|
||||
}
|
||||
|
||||
-13
@@ -1,7 +1,6 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
@@ -16,24 +15,12 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentType.Tree;
|
||||
[ApiVersion("1.0")]
|
||||
public class RootDocumentTypeTreeController : DocumentTypeTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RootDocumentTypeTreeController"/> class, which manages the root nodes of the document type tree in the Umbraco management API.
|
||||
/// </summary>
|
||||
/// <param name="entityService">The service used to manage and retrieve entities.</param>
|
||||
/// <param name="contentTypeService">The service used to manage and retrieve content types.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public RootDocumentTypeTreeController(IEntityService entityService, IContentTypeService contentTypeService)
|
||||
: base(entityService, contentTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RootDocumentTypeTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">An <see cref="IEntityService"/> instance used for managing entities within the system.</param>
|
||||
/// <param name="flagProviders">A <see cref="FlagProviderCollection"/> containing providers for entity flags.</param>
|
||||
/// <param name="contentTypeService">An <see cref="IContentTypeService"/> instance used for managing content types.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public RootDocumentTypeTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IContentTypeService contentTypeService)
|
||||
: base(entityService, flagProviders, contentTypeService)
|
||||
{
|
||||
|
||||
-13
@@ -1,6 +1,5 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
@@ -13,24 +12,12 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentType.Tree;
|
||||
/// </summary>
|
||||
public class SiblingsDocumentTypeTreeController : DocumentTypeTreeControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SiblingsDocumentTypeTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the Umbraco CMS.</param>
|
||||
/// <param name="contentTypeService">Service used for managing content types in the Umbraco CMS.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public SiblingsDocumentTypeTreeController(IEntityService entityService, IContentTypeService contentTypeService)
|
||||
: base(entityService, contentTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SiblingsDocumentTypeTreeController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service used for entity operations within the controller.</param>
|
||||
/// <param name="flagProviders">A collection of providers that supply flags for document type tree nodes.</param>
|
||||
/// <param name="contentTypeService">Service used for managing content types.</param>
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public SiblingsDocumentTypeTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IContentTypeService contentTypeService)
|
||||
: base(entityService, flagProviders, contentTypeService)
|
||||
{
|
||||
|
||||
+6
-3
@@ -62,14 +62,17 @@ public class AllDocumentVersionController : DocumentVersionControllerBase
|
||||
Attempt<PagedModel<ContentVersionMeta>?, ContentVersionOperationStatus> attempt =
|
||||
await _contentVersionService.GetPagedContentVersionsAsync(documentId, culture, skip, take);
|
||||
|
||||
if (attempt.Success is false)
|
||||
{
|
||||
return MapFailure(attempt.Status);
|
||||
}
|
||||
|
||||
var pagedViewModel = new PagedViewModel<DocumentVersionItemResponseModel>
|
||||
{
|
||||
Total = attempt.Result!.Total,
|
||||
Items = await _documentVersionPresentationFactory.CreateMultipleAsync(attempt.Result!.Items),
|
||||
};
|
||||
|
||||
return attempt.Success
|
||||
? Ok(pagedViewModel)
|
||||
: MapFailure(attempt.Status);
|
||||
return Ok(pagedViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-8
@@ -16,25 +16,26 @@ namespace Umbraco.Cms.Api.Management.Controllers.DocumentVersion;
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocuments)]
|
||||
public abstract class DocumentVersionControllerBase : ManagementApiControllerBase
|
||||
{
|
||||
protected IActionResult MapFailure(ContentVersionOperationStatus status)
|
||||
internal static IActionResult MapFailure(ContentVersionOperationStatus status)
|
||||
=> OperationStatusResult(status, problemDetailsBuilder => status switch
|
||||
{
|
||||
ContentVersionOperationStatus.NotFound => NotFound(problemDetailsBuilder
|
||||
ContentVersionOperationStatus.NotFound => new NotFoundObjectResult(problemDetailsBuilder
|
||||
.WithTitle("The requested version could not be found")
|
||||
.Build()),
|
||||
ContentVersionOperationStatus.ContentNotFound => NotFound(problemDetailsBuilder
|
||||
ContentVersionOperationStatus.ContentNotFound => new NotFoundObjectResult(problemDetailsBuilder
|
||||
.WithTitle("The requested document could not be found")
|
||||
.Build()),
|
||||
ContentVersionOperationStatus.InvalidSkipTake => SkipTakeToPagingProblem(),
|
||||
ContentVersionOperationStatus.RollBackFailed => BadRequest(problemDetailsBuilder
|
||||
ContentVersionOperationStatus.RollBackFailed => new BadRequestObjectResult(problemDetailsBuilder
|
||||
.WithTitle("Rollback failed")
|
||||
.WithDetail("An unspecified error occurred while rolling back the requested version. Please check the logs for additional information.")),
|
||||
ContentVersionOperationStatus.RollBackCanceled => BadRequest(problemDetailsBuilder
|
||||
.WithDetail(
|
||||
"An unspecified error occurred while rolling back the requested version. Please check the logs for additional information.")),
|
||||
ContentVersionOperationStatus.RollBackCanceled => new BadRequestObjectResult(problemDetailsBuilder
|
||||
.WithTitle("Request cancelled by notification")
|
||||
.WithDetail("The request to roll back was cancelled by a notification handler.")
|
||||
.Build()),
|
||||
_ => StatusCode(StatusCodes.Status500InternalServerError, problemDetailsBuilder
|
||||
_ => new ObjectResult(problemDetailsBuilder
|
||||
.WithTitle("Unknown content version operation status.")
|
||||
.Build()),
|
||||
.Build()) { StatusCode = StatusCodes.Status500InternalServerError },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
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.Element;
|
||||
|
||||
/// <summary>
|
||||
/// Controller for managing elements in Umbraco that are identified by their unique key.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ByKeyElementController : ElementControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IElementService _elementService;
|
||||
private readonly IElementPresentationFactory _elementPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ByKeyElementController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize access to element resources.</param>
|
||||
/// <param name="elementService">Service for retrieving element data within the CMS.</param>
|
||||
/// <param name="elementPresentationFactory">Factory responsible for creating element presentation models.</param>
|
||||
public ByKeyElementController(
|
||||
IAuthorizationService authorizationService,
|
||||
IElementService elementService,
|
||||
IElementPresentationFactory elementPresentationFactory)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_elementService = elementService;
|
||||
_elementPresentationFactory = elementPresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves an element by its unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique <see cref="Guid"/> of the element to retrieve.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IActionResult"/> containing an <see cref="ElementResponseModel"/> if the element is found;
|
||||
/// otherwise, a 404 Not Found or 403 Forbidden error response.
|
||||
/// </returns>
|
||||
[HttpGet("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(ElementResponseModel), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Gets an element.")]
|
||||
[EndpointDescription("Gets an element identified by the provided Id.")]
|
||||
public async Task<IActionResult> ByKey(CancellationToken cancellationToken, Guid id)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementBrowse.ActionLetter, id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
IElement? element = _elementService.GetById(id);
|
||||
if (element is null)
|
||||
{
|
||||
return ContentEditingOperationStatusResult(ContentEditingOperationStatus.NotFound);
|
||||
}
|
||||
|
||||
ContentScheduleCollection contentScheduleCollection = _elementService.GetContentScheduleByContentId(id);
|
||||
|
||||
ElementResponseModel model = _elementPresentationFactory.CreateResponseModel(element, contentScheduleCollection);
|
||||
return Ok(model);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling operations related to configuration elements within the Umbraco CMS management area.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ConfigurationElementController : ElementControllerBase
|
||||
{
|
||||
private readonly IConfigurationPresentationFactory _configurationPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConfigurationElementController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="configurationPresentationFactory">Factory used to create configuration presentation models for elements.</param>
|
||||
public ConfigurationElementController(IConfigurationPresentationFactory configurationPresentationFactory)
|
||||
=> _configurationPresentationFactory = configurationPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the configuration settings for elements.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the operation.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> containing an <see cref="ElementConfigurationResponseModel"/> with the element configuration settings.</returns>
|
||||
[HttpGet("configuration")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(ElementConfigurationResponseModel), StatusCodes.Status200OK)]
|
||||
[EndpointSummary("Gets the element configuration.")]
|
||||
[EndpointDescription("Gets the configuration settings for elements.")]
|
||||
public Task<IActionResult> Configuration(CancellationToken cancellationToken)
|
||||
{
|
||||
ElementConfigurationResponseModel responseModel = _configurationPresentationFactory.CreateElementConfigurationResponseModel();
|
||||
return Task.FromResult<IActionResult>(Ok(responseModel));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
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.Element;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling copy operations on elements in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class CopyElementController : ElementControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IElementEditingService _elementEditingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CopyElementController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize element copy operations.</param>
|
||||
/// <param name="elementEditingService">Service responsible for element editing operations.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
public CopyElementController(
|
||||
IAuthorizationService authorizationService,
|
||||
IElementEditingService elementEditingService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_elementEditingService = elementEditingService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of an element identified by the specified unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element to copy.</param>
|
||||
/// <param name="copyElementRequestModel">The model containing the target location for the copy.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the result of the copy operation.</returns>
|
||||
[HttpPost("{id:guid}/copy")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Copies an element.")]
|
||||
[EndpointDescription("Creates a duplicate of an existing element identified by the provided Id.")]
|
||||
public async Task<IActionResult> Copy(CancellationToken cancellationToken, Guid id, CopyElementRequestModel copyElementRequestModel)
|
||||
{
|
||||
// Check Copy permission on source element
|
||||
AuthorizationResult sourceAuthorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementCopy.ActionLetter, id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!sourceAuthorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
// Check Create permission on target (where we're copying to)
|
||||
AuthorizationResult targetAuthorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementNew.ActionLetter, copyElementRequestModel.Target?.Id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!targetAuthorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
Attempt<IElement?, ContentEditingOperationStatus> result = await _elementEditingService.CopyAsync(
|
||||
id,
|
||||
copyElementRequestModel.Target?.Id,
|
||||
CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return result.Success
|
||||
? CreatedAtId<ByKeyElementController>(controller => nameof(controller.ByKey), result.Result!.Key)
|
||||
: ContentEditingOperationStatusResult(result.Status);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling operations related to the creation of elements in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class CreateElementController : CreateElementControllerBase
|
||||
{
|
||||
private readonly IElementEditingPresentationFactory _elementEditingPresentationFactory;
|
||||
private readonly IElementEditingService _elementEditingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CreateElementController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize access to element creation operations.</param>
|
||||
/// <param name="elementEditingPresentationFactory">Factory for creating element editing presentation models.</param>
|
||||
/// <param name="elementEditingService">Service responsible for element editing functionality.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
public CreateElementController(
|
||||
IAuthorizationService authorizationService,
|
||||
IElementEditingPresentationFactory elementEditingPresentationFactory,
|
||||
IElementEditingService elementEditingService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
: base(authorizationService)
|
||||
{
|
||||
_elementEditingPresentationFactory = elementEditingPresentationFactory;
|
||||
_elementEditingService = elementEditingService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new element using the specified request model.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Token to monitor for cancellation requests.</param>
|
||||
/// <param name="requestModel">The details of the element to create.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the result of the operation.</returns>
|
||||
[HttpPost]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Creates a new element.")]
|
||||
[EndpointDescription("Creates a new element with the configuration specified in the request model.")]
|
||||
public async Task<IActionResult> Create(CancellationToken cancellationToken, CreateElementRequestModel requestModel)
|
||||
=> await HandleRequest(requestModel, async () =>
|
||||
{
|
||||
ElementCreateModel model = _elementEditingPresentationFactory.MapCreateModel(requestModel);
|
||||
Attempt<ElementCreateResult, ContentEditingOperationStatus> result =
|
||||
await _elementEditingService.CreateAsync(model, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return result.Success
|
||||
? CreatedAtId<ByKeyElementController>(controller => nameof(controller.ByKey), result.Result.Content!.Key)
|
||||
: ContentEditingOperationStatusResult(result.Status);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for element creation endpoints in the Umbraco CMS Management API.
|
||||
/// Provides shared functionality for creating elements.
|
||||
/// </summary>
|
||||
public abstract class CreateElementControllerBase : ElementControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CreateElementControllerBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize access to element creation operations.</param>
|
||||
protected CreateElementControllerBase(IAuthorizationService authorizationService)
|
||||
=> _authorizationService = authorizationService;
|
||||
|
||||
protected async Task<IActionResult> HandleRequest(CreateElementRequestModel requestModel, Func<Task<IActionResult>> authorizedHandler)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementNew.ActionLetter, requestModel.Parent?.Id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (authorizationResult.Succeeded is false)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
return await authorizedHandler();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
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.Element;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling requests to delete elements in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class DeleteElementController : ElementControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IElementEditingService _elementEditingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeleteElementController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">An <see cref="IAuthorizationService"/> used to authorize element deletion requests.</param>
|
||||
/// <param name="elementEditingService">An <see cref="IElementEditingService"/> used to perform element editing operations.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">An <see cref="IBackOfficeSecurityAccessor"/> providing access to back office security information.</param>
|
||||
public DeleteElementController(
|
||||
IAuthorizationService authorizationService,
|
||||
IElementEditingService elementEditingService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_elementEditingService = elementEditingService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the element with the specified unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier (GUID) of the element to delete.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> indicating the outcome of the delete operation.</returns>
|
||||
[HttpDelete("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Deletes an element.")]
|
||||
[EndpointDescription("Deletes an element identified by the provided Id.")]
|
||||
public async Task<IActionResult> Delete(CancellationToken cancellationToken, Guid id)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementDelete.ActionLetter, id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
Attempt<IElement?, ContentEditingOperationStatus> result = await _elementEditingService.DeleteAsync(id, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return result.Success
|
||||
? Ok()
|
||||
: ContentEditingOperationStatusResult(result.Status);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Content;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Models.ContentPublishing;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for implementing element management operations within the Umbraco CMS Management API.
|
||||
/// Provides shared functionality for derived element controllers.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute(Constants.UdiEntityType.Element)]
|
||||
[ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Element))]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessElements)]
|
||||
public class ElementControllerBase : ContentControllerBase
|
||||
{
|
||||
protected override string EntityName => "element";
|
||||
|
||||
protected IActionResult ElementEditingOperationStatusResult<TContentModelBase>(
|
||||
ContentEditingOperationStatus status,
|
||||
TContentModelBase requestModel,
|
||||
ContentValidationResult validationResult)
|
||||
where TContentModelBase : ContentModelBase<ElementValueModel, ElementVariantRequestModel>
|
||||
=> ContentEditingOperationStatusResult<TContentModelBase, ElementValueModel, ElementVariantRequestModel>(status, requestModel, validationResult);
|
||||
|
||||
protected IActionResult ElementPublishingOperationStatusResult(
|
||||
ContentPublishingOperationStatus status,
|
||||
IEnumerable<string>? invalidPropertyAliases = null,
|
||||
IEnumerable<ContentPublishingBranchItemResult>? failedBranchItems = null)
|
||||
=> ContentPublishingOperationStatusResult(status, invalidPropertyAliases, failedBranchItems);
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Folder;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.Folder;
|
||||
|
||||
/// <summary>
|
||||
/// Controller for retrieving element folders by their unique key.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ByKeyElementFolderController : ElementFolderControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ByKeyElementFolderController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize access to element folder resources.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="elementContainerService">Service for managing element containers.</param>
|
||||
public ByKeyElementFolderController(
|
||||
IAuthorizationService authorizationService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IElementContainerService elementContainerService)
|
||||
: base(backOfficeSecurityAccessor, elementContainerService) =>
|
||||
_authorizationService = authorizationService;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves an element folder by its unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element folder to retrieve.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> containing the element folder if found.</returns>
|
||||
[HttpGet("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(FolderResponseModel), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Gets an element folder.")]
|
||||
[EndpointDescription("Gets an element folder identified by the provided Id.")]
|
||||
public async Task<IActionResult> ByKey(CancellationToken cancellationToken, Guid id)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementBrowse.ActionLetter, id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
return await GetFolderAsync(id);
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Folder;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.Folder;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for creating element folders in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class CreateElementFolderController : ElementFolderControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CreateElementFolderController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize element folder creation operations.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="elementContainerService">Service for managing element containers.</param>
|
||||
public CreateElementFolderController(
|
||||
IAuthorizationService authorizationService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IElementContainerService elementContainerService)
|
||||
: base(backOfficeSecurityAccessor, elementContainerService) =>
|
||||
_authorizationService = authorizationService;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new element folder.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="createFolderRequestModel">The model containing the folder details.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the result of the creation operation.</returns>
|
||||
[HttpPost]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Creates an element folder.")]
|
||||
[EndpointDescription("Creates a new element folder with the provided name and parent location.")]
|
||||
public async Task<IActionResult> Create(CancellationToken cancellationToken, CreateFolderRequestModel createFolderRequestModel)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementNew.ActionLetter, createFolderRequestModel.Parent?.Id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
return await CreateFolderAsync<ByKeyElementFolderController>(
|
||||
createFolderRequestModel,
|
||||
controller => nameof(controller.ByKey));
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.Folder;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for deleting element folders in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class DeleteElementFolderController : ElementFolderControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeleteElementFolderController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize element folder deletion operations.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="elementContainerService">Service for managing element containers.</param>
|
||||
public DeleteElementFolderController(
|
||||
IAuthorizationService authorizationService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IElementContainerService elementContainerService)
|
||||
: base(backOfficeSecurityAccessor, elementContainerService) =>
|
||||
_authorizationService = authorizationService;
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the element folder with the specified unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element folder to delete.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> indicating the outcome of the delete operation.</returns>
|
||||
[HttpDelete("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Deletes an element folder.")]
|
||||
[EndpointDescription("Deletes an element folder identified by the provided Id.")]
|
||||
public async Task<IActionResult> Delete(CancellationToken cancellationToken, Guid id)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementDelete.ActionLetter, id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
return await DeleteFolderAsync(id);
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.Folder;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for element folder management operations within the Umbraco CMS Management API.
|
||||
/// Provides shared functionality for derived element folder controllers.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.Element}/folder")]
|
||||
[ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Element))]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessElements)]
|
||||
public abstract class ElementFolderControllerBase : FolderManagementControllerBase<IElement>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ElementFolderControllerBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="elementContainerService">Service for managing element containers.</param>
|
||||
protected ElementFolderControllerBase(
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IElementContainerService elementContainerService)
|
||||
: base(backOfficeSecurityAccessor, elementContainerService)
|
||||
{
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Core;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.Folder.Item;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for element folder item operations within the Umbraco CMS Management API.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.Element}/folder")]
|
||||
[ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Element))]
|
||||
public class FolderItemControllerBase : ManagementApiControllerBase;
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Folder.Item;
|
||||
using Umbraco.Cms.Core.Mapping;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.Entities;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.Folder.Item;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving element folder items by their identifiers.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ItemFolderItemController : FolderItemControllerBase
|
||||
{
|
||||
private readonly IEntityService _entityService;
|
||||
private readonly IUmbracoMapper _umbracoMapper;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ItemFolderItemController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for retrieving entity data.</param>
|
||||
/// <param name="umbracoMapper">Mapper for converting domain models to view models.</param>
|
||||
public ItemFolderItemController(
|
||||
IEntityService entityService,
|
||||
IUmbracoMapper umbracoMapper)
|
||||
{
|
||||
_entityService = entityService;
|
||||
_umbracoMapper = umbracoMapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of element folder items identified by the provided identifiers.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="ids">The set of unique identifiers of the element folder items to retrieve.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> containing the collection of element folder items.</returns>
|
||||
[HttpGet]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(IEnumerable<FolderItemResponseModel>), StatusCodes.Status200OK)]
|
||||
[EndpointSummary("Gets a collection of element folder items.")]
|
||||
[EndpointDescription("Gets a collection of element folder items identified by the provided Ids.")]
|
||||
public Task<IActionResult> Item(
|
||||
CancellationToken cancellationToken,
|
||||
[FromQuery(Name = "id")] HashSet<Guid> ids)
|
||||
{
|
||||
if (ids.Count is 0)
|
||||
{
|
||||
return Task.FromResult<IActionResult>(Ok(Enumerable.Empty<FolderItemResponseModel>()));
|
||||
}
|
||||
|
||||
IEnumerable<IEntitySlim> elements = _entityService
|
||||
.GetAll([UmbracoObjectTypes.ElementContainer], ids.ToArray());
|
||||
|
||||
List<FolderItemResponseModel> responseModels = _umbracoMapper.MapEnumerable<IEntitySlim, FolderItemResponseModel>(elements);
|
||||
return Task.FromResult<IActionResult>(Ok(responseModels));
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Folder;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
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.Element.Folder;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling move operations on element folders in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class MoveElementFolderController : ElementFolderControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
private readonly IElementContainerService _elementContainerService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MoveElementFolderController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize element folder move operations.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="elementContainerService">Service for managing element containers.</param>
|
||||
public MoveElementFolderController(
|
||||
IAuthorizationService authorizationService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IElementContainerService elementContainerService)
|
||||
: base(backOfficeSecurityAccessor, elementContainerService)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
_elementContainerService = elementContainerService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves an element folder identified by the specified unique identifier to a different location.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element folder to move.</param>
|
||||
/// <param name="moveFolderRequestModel">The model containing the target location for the move.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the outcome of the move operation.</returns>
|
||||
[HttpPut("{id:guid}/move")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Moves an element folder.")]
|
||||
[EndpointDescription("Moves an element folder identified by the provided Id to a different location.")]
|
||||
public async Task<IActionResult> Move(CancellationToken cancellationToken, Guid id, MoveFolderRequestModel moveFolderRequestModel)
|
||||
{
|
||||
// Check Move permission on source folder
|
||||
AuthorizationResult sourceAuthorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementMove.ActionLetter, id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!sourceAuthorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
// Check Create permission on target (where we're moving to)
|
||||
AuthorizationResult targetAuthorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementNew.ActionLetter, moveFolderRequestModel.Target?.Id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!targetAuthorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
Attempt<EntityContainerOperationStatus> result = await _elementContainerService
|
||||
.MoveAsync(id, moveFolderRequestModel.Target?.Id, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return result.Success
|
||||
? Ok()
|
||||
: OperationStatusResult(result.Result);
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
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.Element.Folder;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for moving element folders to the recycle bin in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class MoveToRecycleBinElementFolderController : ElementFolderControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
private readonly IElementContainerService _elementContainerService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MoveToRecycleBinElementFolderController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize recycle bin operations.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="elementContainerService">Service for managing element containers.</param>
|
||||
public MoveToRecycleBinElementFolderController(
|
||||
IAuthorizationService authorizationService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IElementContainerService elementContainerService)
|
||||
: base(backOfficeSecurityAccessor, elementContainerService)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
_elementContainerService = elementContainerService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves an element folder identified by the specified unique identifier to the recycle bin.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element folder to move to the recycle bin.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the outcome of the operation.</returns>
|
||||
[HttpPut("{id:guid}/move-to-recycle-bin")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Moves an element folder to the recycle bin.")]
|
||||
[EndpointDescription("Moves an element folder identified by the provided Id to the recycle bin.")]
|
||||
public async Task<IActionResult> Move(CancellationToken cancellationToken, Guid id)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementDelete.ActionLetter, id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
Attempt<EntityContainerOperationStatus> result = await _elementContainerService
|
||||
.MoveToRecycleBinAsync(id, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return result.Success
|
||||
? Ok()
|
||||
: OperationStatusResult(result.Result);
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Folder;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.Folder;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for updating element folders in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class UpdateElementFolderController : ElementFolderControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UpdateElementFolderController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize element folder update operations.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="elementContainerService">Service for managing element containers.</param>
|
||||
public UpdateElementFolderController(
|
||||
IAuthorizationService authorizationService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IElementContainerService elementContainerService)
|
||||
: base(backOfficeSecurityAccessor, elementContainerService) =>
|
||||
_authorizationService = authorizationService;
|
||||
|
||||
/// <summary>
|
||||
/// Updates the element folder with the specified unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element folder to update.</param>
|
||||
/// <param name="updateFolderResponseModel">The model containing the updated folder details.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the outcome of the update operation.</returns>
|
||||
[HttpPut("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Updates an element folder.")]
|
||||
[EndpointDescription("Updates an element folder identified by the provided Id with the details provided in the request model.")]
|
||||
public async Task<IActionResult> Update(CancellationToken cancellationToken, Guid id, UpdateFolderResponseModel updateFolderResponseModel)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementUpdate.ActionLetter, id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
return await UpdateFolderAsync(id, updateFolderResponseModel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.AuditLog;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving audit log entries for elements in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class GetAuditLogElementController : ElementControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IAuditService _auditService;
|
||||
private readonly IAuditLogPresentationFactory _auditLogPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GetAuditLogElementController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize access to audit log data.</param>
|
||||
/// <param name="auditService">Service for retrieving audit log entries.</param>
|
||||
/// <param name="auditLogPresentationFactory">Factory for creating audit log presentation models.</param>
|
||||
public GetAuditLogElementController(
|
||||
IAuthorizationService authorizationService,
|
||||
IAuditService auditService,
|
||||
IAuditLogPresentationFactory auditLogPresentationFactory)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_auditService = auditService;
|
||||
_auditLogPresentationFactory = auditLogPresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a paginated collection of audit log entries for the specified element.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element to retrieve audit logs for.</param>
|
||||
/// <param name="orderDirection">The sort order direction for the results.</param>
|
||||
/// <param name="sinceDate">Optional date filter to retrieve entries since a specific date.</param>
|
||||
/// <param name="skip">The number of entries to skip for pagination.</param>
|
||||
/// <param name="take">The number of entries to return for pagination.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> containing a paginated collection of audit log entries.</returns>
|
||||
[MapToApiVersion("1.0")]
|
||||
[HttpGet("{id:guid}/audit-log")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<AuditLogResponseModel>), StatusCodes.Status200OK)]
|
||||
[EndpointSummary("Gets the audit log for an element.")]
|
||||
[EndpointDescription("Gets a paginated collection of audit log entries for the element identified by the provided Id.")]
|
||||
public async Task<IActionResult> GetAuditLog(CancellationToken cancellationToken, Guid id, Direction orderDirection = Direction.Descending, DateTimeOffset? sinceDate = null, int skip = 0, int take = 100)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementBrowse.ActionLetter, id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
PagedModel<IAuditItem> result = await _auditService.GetItemsByKeyAsync(id, UmbracoObjectTypes.Element, skip, take, orderDirection, sinceDate);
|
||||
IEnumerable<AuditLogResponseModel> mapped = _auditLogPresentationFactory.CreateAuditLogViewModel(result.Items);
|
||||
var viewModel = new PagedViewModel<AuditLogResponseModel>
|
||||
{
|
||||
Total = result.Total,
|
||||
Items = mapped,
|
||||
};
|
||||
|
||||
return Ok(viewModel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Core;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.Item;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for element item operations within the Umbraco CMS Management API.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Item}/{Constants.UdiEntityType.Element}")]
|
||||
[ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Element))]
|
||||
public class ElementItemControllerBase : ManagementApiControllerBase;
|
||||
@@ -0,0 +1,62 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element.Item;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.Entities;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.Item;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving element items by their identifiers.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ItemElementItemController : ElementItemControllerBase
|
||||
{
|
||||
private readonly IEntityService _entityService;
|
||||
private readonly IElementPresentationFactory _elementPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ItemElementItemController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for retrieving entity data.</param>
|
||||
/// <param name="elementPresentationFactory">Factory responsible for creating element presentation models.</param>
|
||||
public ItemElementItemController(
|
||||
IEntityService entityService,
|
||||
IElementPresentationFactory elementPresentationFactory)
|
||||
{
|
||||
_entityService = entityService;
|
||||
_elementPresentationFactory = elementPresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of element items identified by the provided identifiers.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="ids">The set of unique identifiers of the element items to retrieve.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> containing the collection of element items.</returns>
|
||||
[HttpGet]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(IEnumerable<ElementItemResponseModel>), StatusCodes.Status200OK)]
|
||||
[EndpointSummary("Gets a collection of element items.")]
|
||||
[EndpointDescription("Gets a collection of element items identified by the provided Ids.")]
|
||||
public async Task<IActionResult> Item(
|
||||
CancellationToken cancellationToken,
|
||||
[FromQuery(Name = "id")] HashSet<Guid> ids)
|
||||
{
|
||||
if (ids.Count is 0)
|
||||
{
|
||||
return Ok(Enumerable.Empty<ElementItemResponseModel>());
|
||||
}
|
||||
|
||||
IEnumerable<IElementEntitySlim> elements = _entityService
|
||||
.GetAll(UmbracoObjectTypes.Element, ids.ToArray())
|
||||
.OfType<IElementEntitySlim>();
|
||||
|
||||
IEnumerable<Task<ElementItemResponseModel>> tasks = elements.Select(_elementPresentationFactory.CreateItemResponseModelAsync);
|
||||
ElementItemResponseModel[] responseModels = await Task.WhenAll(tasks);
|
||||
return Ok(responseModels);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
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.Element;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling move operations on elements in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class MoveElementController : ElementControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IElementEditingService _elementEditingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MoveElementController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize element move operations.</param>
|
||||
/// <param name="elementEditingService">Service responsible for element editing operations.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
public MoveElementController(
|
||||
IAuthorizationService authorizationService,
|
||||
IElementEditingService elementEditingService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_elementEditingService = elementEditingService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves an element identified by the specified unique identifier to a different location.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element to move.</param>
|
||||
/// <param name="moveElementRequestModel">The model containing the target location for the move.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the outcome of the move operation.</returns>
|
||||
[HttpPut("{id:guid}/move")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Moves an element.")]
|
||||
[EndpointDescription("Moves an element identified by the provided Id to a different location.")]
|
||||
public async Task<IActionResult> Move(CancellationToken cancellationToken, Guid id, MoveElementRequestModel moveElementRequestModel)
|
||||
{
|
||||
// Check Move permission on source element
|
||||
AuthorizationResult sourceAuthorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementMove.ActionLetter, id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!sourceAuthorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
// Check Create permission on target (where we're moving to)
|
||||
AuthorizationResult targetAuthorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementNew.ActionLetter, moveElementRequestModel.Target?.Id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!targetAuthorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
Attempt<ContentEditingOperationStatus> result = await _elementEditingService.MoveAsync(
|
||||
id,
|
||||
moveElementRequestModel.Target?.Id,
|
||||
CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return result.Success
|
||||
? Ok()
|
||||
: ContentEditingOperationStatusResult(result.Result);
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
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.Element;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling move-to-recycle-bin operations on elements in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class MoveToRecycleBinElementController : ElementControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IElementEditingService _elementEditingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MoveToRecycleBinElementController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize recycle bin operations.</param>
|
||||
/// <param name="elementEditingService">Service responsible for element editing operations.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
public MoveToRecycleBinElementController(
|
||||
IAuthorizationService authorizationService,
|
||||
IElementEditingService elementEditingService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_elementEditingService = elementEditingService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves an element identified by the specified unique identifier to the recycle bin.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element to move to the recycle bin.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the outcome of the operation.</returns>
|
||||
[HttpPut("{id:guid}/move-to-recycle-bin")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Moves an element to the recycle bin.")]
|
||||
[EndpointDescription("Moves an element identified by the provided Id to the recycle bin.")]
|
||||
public async Task<IActionResult> MoveToRecycleBin(CancellationToken cancellationToken, Guid id)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementDelete.ActionLetter, id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
Attempt<ContentEditingOperationStatus> result = await _elementEditingService.MoveToRecycleBinAsync(id, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
return result.Success
|
||||
? Ok()
|
||||
: ContentEditingOperationStatusResult(result.Result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Document;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Models.ContentPublishing;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
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.Element;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling publish operations on elements in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class PublishElementController : ElementControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IElementPublishingService _elementPublishingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
private readonly IElementPresentationFactory _elementPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishElementController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize element publish operations.</param>
|
||||
/// <param name="elementPublishingService">Service responsible for publishing elements.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="elementPresentationFactory">Factory used for creating culture publish schedule models.</param>
|
||||
public PublishElementController(
|
||||
IAuthorizationService authorizationService,
|
||||
IElementPublishingService elementPublishingService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IElementPresentationFactory elementPresentationFactory)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_elementPublishingService = elementPublishingService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
_elementPresentationFactory = elementPresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Publishes an element identified by the specified unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element to publish.</param>
|
||||
/// <param name="requestModel">The model containing the publish schedule configuration.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the outcome of the publish operation.</returns>
|
||||
[HttpPut("{id:guid}/publish")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Publishes an element.")]
|
||||
[EndpointDescription("Publishes an element identified by the provided Id.")]
|
||||
public async Task<IActionResult> Publish(CancellationToken cancellationToken, Guid id, PublishElementRequestModel requestModel)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(
|
||||
ActionElementPublish.ActionLetter,
|
||||
id,
|
||||
requestModel.PublishSchedules
|
||||
.Where(x => x.Culture is not null)
|
||||
.Select(x => x.Culture!)),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
Attempt<List<CulturePublishScheduleModel>, ContentPublishingOperationStatus> modelResult = _elementPresentationFactory.CreateCulturePublishScheduleModels(requestModel);
|
||||
|
||||
if (modelResult.Success is false)
|
||||
{
|
||||
return ElementPublishingOperationStatusResult(modelResult.Status);
|
||||
}
|
||||
|
||||
Attempt<ContentPublishingResult, ContentPublishingOperationStatus> attempt = await _elementPublishingService.PublishAsync(
|
||||
id,
|
||||
modelResult.Result,
|
||||
CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
return attempt.Success
|
||||
? Ok()
|
||||
: ElementPublishingOperationStatusResult(attempt.Status, attempt.Result.InvalidPropertyAliases);
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element.RecycleBin;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.RecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving child elements within the element recycle bin.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ChildrenElementRecycleBinController : ElementRecycleBinControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChildrenElementRecycleBinController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for retrieving entity data.</param>
|
||||
/// <param name="elementPresentationFactory">Factory responsible for creating element presentation models.</param>
|
||||
public ChildrenElementRecycleBinController(
|
||||
IEntityService entityService,
|
||||
IElementPresentationFactory elementPresentationFactory)
|
||||
: base(entityService, elementPresentationFactory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a paginated collection of child elements in the recycle bin for the specified parent.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="parentId">The unique identifier of the parent element in the recycle bin.</param>
|
||||
/// <param name="skip">The number of items to skip for pagination.</param>
|
||||
/// <param name="take">The number of items to return for pagination.</param>
|
||||
/// <returns>A paginated collection of element recycle bin items.</returns>
|
||||
[HttpGet("children")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<ElementRecycleBinItemResponseModel>), StatusCodes.Status200OK)]
|
||||
[EndpointSummary("Gets a collection of elements in the recycle bin.")]
|
||||
[EndpointDescription("Gets a paginated collection of elements that are children of the provided parent in the recycle bin.")]
|
||||
public async Task<ActionResult<PagedViewModel<ElementRecycleBinItemResponseModel>>> Children(
|
||||
CancellationToken cancellationToken,
|
||||
Guid parentId,
|
||||
int skip = 0,
|
||||
int take = 100)
|
||||
=> await GetChildren(parentId, skip, take);
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
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.Element.RecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for permanently deleting element folders from the recycle bin.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class DeleteElementFolderRecycleBinController : ElementRecycleBinControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
private readonly IElementContainerService _elementContainerService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeleteElementFolderRecycleBinController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize recycle bin deletion operations.</param>
|
||||
/// <param name="entityService">Service for retrieving entity data.</param>
|
||||
/// <param name="elementPresentationFactory">Factory responsible for creating element presentation models.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="elementContainerService">Service for managing element containers.</param>
|
||||
public DeleteElementFolderRecycleBinController(
|
||||
IAuthorizationService authorizationService,
|
||||
IEntityService entityService,
|
||||
IElementPresentationFactory elementPresentationFactory,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IElementContainerService elementContainerService)
|
||||
: base(entityService, elementPresentationFactory)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
_elementContainerService = elementContainerService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Permanently deletes an element folder from the recycle bin.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element folder to permanently delete.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> indicating the outcome of the delete operation.</returns>
|
||||
[HttpDelete("folder/{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Deletes an element folder from the recycle bin.")]
|
||||
[EndpointDescription("Permanently deletes an element folder identified by the provided Id from the recycle bin.")]
|
||||
public async Task<IActionResult> Delete(CancellationToken cancellationToken, Guid id)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.RecycleBin(ActionElementDelete.ActionLetter),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
Attempt<EntityContainer?, EntityContainerOperationStatus> result = await _elementContainerService.DeleteFromRecycleBinAsync(id, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return result.Success
|
||||
? Ok()
|
||||
: OperationStatusResult(result.Status);
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
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.Element.RecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for permanently deleting elements from the recycle bin.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class DeleteElementRecycleBinController : ElementRecycleBinControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
private readonly IElementEditingService _elementEditingService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DeleteElementRecycleBinController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize recycle bin deletion operations.</param>
|
||||
/// <param name="entityService">Service for retrieving entity data.</param>
|
||||
/// <param name="elementPresentationFactory">Factory responsible for creating element presentation models.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="elementEditingService">Service responsible for element editing operations.</param>
|
||||
public DeleteElementRecycleBinController(
|
||||
IAuthorizationService authorizationService,
|
||||
IEntityService entityService,
|
||||
IElementPresentationFactory elementPresentationFactory,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IElementEditingService elementEditingService)
|
||||
: base(entityService, elementPresentationFactory)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
_elementEditingService = elementEditingService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Permanently deletes an element from the recycle bin.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element to permanently delete.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> indicating the outcome of the delete operation.</returns>
|
||||
[HttpDelete("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Deletes an element from the recycle bin.")]
|
||||
[EndpointDescription("Permanently deletes an element identified by the provided Id from the recycle bin.")]
|
||||
public async Task<IActionResult> Delete(CancellationToken cancellationToken, Guid id)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.RecycleBin(ActionElementDelete.ActionLetter),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
Attempt<IElement?, ContentEditingOperationStatus> result = await _elementEditingService.DeleteFromRecycleBinAsync(id, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return result.Success
|
||||
? Ok()
|
||||
: ContentEditingOperationStatusResult(result.Status);
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Element.Folder;
|
||||
using Umbraco.Cms.Api.Management.Controllers.RecycleBin;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.Filters;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element.RecycleBin;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.Entities;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.RecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for element recycle bin operations within the Umbraco CMS Management API.
|
||||
/// Provides shared functionality for derived element recycle bin controllers.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.RecycleBin}/{Constants.UdiEntityType.Element}")]
|
||||
[RequireElementTreeRootAccess]
|
||||
[ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Element))]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessElements)]
|
||||
public class ElementRecycleBinControllerBase : RecycleBinControllerBase<ElementRecycleBinItemResponseModel>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override string EntityName => "element";
|
||||
|
||||
private readonly IEntityService _entityService;
|
||||
private readonly IElementPresentationFactory _elementPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ElementRecycleBinControllerBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for retrieving entity data.</param>
|
||||
/// <param name="elementPresentationFactory">Factory responsible for creating element presentation models.</param>
|
||||
public ElementRecycleBinControllerBase( IEntityService entityService, IElementPresentationFactory elementPresentationFactory)
|
||||
: base(entityService)
|
||||
{
|
||||
_entityService = entityService;
|
||||
_elementPresentationFactory = elementPresentationFactory;
|
||||
}
|
||||
|
||||
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.Element;
|
||||
|
||||
protected override Guid RecycleBinRootKey => Constants.System.RecycleBinElementKey;
|
||||
|
||||
protected override async Task<ElementRecycleBinItemResponseModel> MapRecycleBinViewModelAsync(Guid? parentId, IEntitySlim entity)
|
||||
{
|
||||
ElementRecycleBinItemResponseModel responseModel = await base.MapRecycleBinViewModelAsync(parentId, entity);
|
||||
|
||||
responseModel.Name = entity.Name ?? string.Empty;
|
||||
|
||||
if (entity is IElementEntitySlim elementEntitySlim)
|
||||
{
|
||||
responseModel.Variants = await _elementPresentationFactory.CreateVariantsItemResponseModelsAsync(elementEntitySlim);
|
||||
responseModel.DocumentType = _elementPresentationFactory.CreateDocumentTypeReferenceResponseModel(elementEntitySlim);
|
||||
responseModel.IsFolder = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
responseModel.Variants = [];
|
||||
responseModel.IsFolder = true;
|
||||
}
|
||||
|
||||
return responseModel;
|
||||
}
|
||||
|
||||
protected override IEntitySlim[] GetPagedRootEntities(int skip, int take, out long totalItems)
|
||||
=> GetPagedChildEntities(RecycleBinRootKey, skip, take, out totalItems);
|
||||
|
||||
protected override IEntitySlim[] GetPagedChildEntities(Guid parentKey, int skip, int take, out long totalItems)
|
||||
{
|
||||
IEntitySlim[] rootEntities = _entityService
|
||||
.GetPagedChildren(
|
||||
parentKey,
|
||||
parentObjectTypes: [UmbracoObjectTypes.ElementContainer],
|
||||
childObjectTypes: [UmbracoObjectTypes.ElementContainer, ItemObjectType],
|
||||
skip: skip,
|
||||
take: take,
|
||||
trashed: true,
|
||||
out totalItems)
|
||||
.ToArray();
|
||||
|
||||
return rootEntities;
|
||||
}
|
||||
|
||||
protected override IEntitySlim[] GetSiblingEntities(Guid target, int before, int after, out long totalBefore, out long totalAfter) =>
|
||||
_entityService
|
||||
.GetTrashedSiblings(
|
||||
target,
|
||||
objectTypes: [UmbracoObjectTypes.ElementContainer, ItemObjectType],
|
||||
before,
|
||||
after,
|
||||
out totalBefore,
|
||||
out totalAfter,
|
||||
ordering: Ordering.By(nameof(Infrastructure.Persistence.Dtos.NodeDto.Text)))
|
||||
.ToArray();
|
||||
|
||||
protected IActionResult OperationStatusResult(EntityContainerOperationStatus status)
|
||||
=> ElementFolderControllerBase.OperationStatusResult(status);
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
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.Element.RecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for emptying the element recycle bin in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class EmptyElementRecycleBinController : ElementRecycleBinControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
private readonly IElementContainerService _elementContainerService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EmptyElementRecycleBinController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize recycle bin operations.</param>
|
||||
/// <param name="entityService">Service for retrieving entity data.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="elementContainerService">Service for managing element containers.</param>
|
||||
/// <param name="elementPresentationFactory">Factory responsible for creating element presentation models.</param>
|
||||
public EmptyElementRecycleBinController(
|
||||
IAuthorizationService authorizationService,
|
||||
IEntityService entityService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IElementContainerService elementContainerService,
|
||||
IElementPresentationFactory elementPresentationFactory)
|
||||
: base(entityService, elementPresentationFactory)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
_elementContainerService = elementContainerService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Permanently deletes all elements in the recycle bin.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> indicating the outcome of the operation.</returns>
|
||||
[HttpDelete]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[EndpointSummary("Empties the element recycle bin.")]
|
||||
[EndpointDescription("Permanently deletes all elements in the recycle bin. This operation cannot be undone.")]
|
||||
public async Task<IActionResult> EmptyRecycleBin(CancellationToken cancellationToken)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.RecycleBin(ActionElementDelete.ActionLetter),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
Attempt<EntityContainerOperationStatus> result = await _elementContainerService.EmptyRecycleBinAsync(CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
return result.Success
|
||||
? Ok()
|
||||
: OperationStatusResult(result.Result);
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Models.Entities;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.Querying.RecycleBin;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.RecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving the original parent of an element folder in the recycle bin.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class OriginalParentElementFolderRecycleBinController : ElementRecycleBinControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IElementRecycleBinQueryService _elementRecycleBinQueryService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OriginalParentElementFolderRecycleBinController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for retrieving entity data.</param>
|
||||
/// <param name="elementPresentationFactory">Factory responsible for creating element presentation models.</param>
|
||||
/// <param name="authorizationService">Service used to authorize recycle bin operations.</param>
|
||||
/// <param name="elementRecycleBinQueryService">Service for querying the element recycle bin.</param>
|
||||
public OriginalParentElementFolderRecycleBinController(
|
||||
IEntityService entityService,
|
||||
IElementPresentationFactory elementPresentationFactory,
|
||||
IAuthorizationService authorizationService,
|
||||
IElementRecycleBinQueryService elementRecycleBinQueryService)
|
||||
: base(entityService, elementPresentationFactory)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_elementRecycleBinQueryService = elementRecycleBinQueryService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the original parent location of an element folder before it was moved to the recycle bin.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element folder in the recycle bin.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> containing the original parent reference, or null if the parent was root.</returns>
|
||||
[HttpGet("folder/{id:guid}/original-parent")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(ReferenceByIdModel), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[EndpointSummary("Gets the original parent of an element folder in the recycle bin.")]
|
||||
[EndpointDescription("Gets the original parent location of an element folder before it was moved to the recycle bin.")]
|
||||
public async Task<IActionResult> OriginalParentFolder(CancellationToken cancellationToken, Guid id)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.RecycleBin(ActionElementBrowse.ActionLetter),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
Attempt<IEntitySlim?, RecycleBinQueryResultType> getParentAttempt = await _elementRecycleBinQueryService.GetOriginalParentForContainerAsync(id);
|
||||
return getParentAttempt.Success switch
|
||||
{
|
||||
true when getParentAttempt.Status == RecycleBinQueryResultType.Success
|
||||
=> Ok(new ReferenceByIdModel(getParentAttempt.Result!.Key)),
|
||||
true when getParentAttempt.Status == RecycleBinQueryResultType.ParentIsRoot
|
||||
=> Ok(null),
|
||||
_ => MapRecycleBinQueryAttemptFailure(getParentAttempt.Status, "element folder"),
|
||||
};
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Models.Entities;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.Querying.RecycleBin;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.RecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving the original parent of an element in the recycle bin.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class OriginalParentElementRecycleBinController : ElementRecycleBinControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IElementRecycleBinQueryService _elementRecycleBinQueryService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OriginalParentElementRecycleBinController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for retrieving entity data.</param>
|
||||
/// <param name="elementPresentationFactory">Factory responsible for creating element presentation models.</param>
|
||||
/// <param name="authorizationService">Service used to authorize recycle bin operations.</param>
|
||||
/// <param name="elementRecycleBinQueryService">Service for querying the element recycle bin.</param>
|
||||
public OriginalParentElementRecycleBinController(
|
||||
IEntityService entityService,
|
||||
IElementPresentationFactory elementPresentationFactory,
|
||||
IAuthorizationService authorizationService,
|
||||
IElementRecycleBinQueryService elementRecycleBinQueryService)
|
||||
: base(entityService, elementPresentationFactory)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_elementRecycleBinQueryService = elementRecycleBinQueryService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the original parent location of an element before it was moved to the recycle bin.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element in the recycle bin.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> containing the original parent reference, or null if the parent was root.</returns>
|
||||
[HttpGet("{id:guid}/original-parent")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(ReferenceByIdModel), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[EndpointSummary("Gets the original parent of an element in the recycle bin.")]
|
||||
[EndpointDescription("Gets the original parent location of an element before it was moved to the recycle bin.")]
|
||||
public async Task<IActionResult> OriginalParent(CancellationToken cancellationToken, Guid id)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.RecycleBin(ActionElementBrowse.ActionLetter),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
Attempt<IEntitySlim?, RecycleBinQueryResultType> getParentAttempt = await _elementRecycleBinQueryService.GetOriginalParentAsync(id);
|
||||
return getParentAttempt.Success switch
|
||||
{
|
||||
true when getParentAttempt.Status == RecycleBinQueryResultType.Success
|
||||
=> Ok(new ReferenceByIdModel(getParentAttempt.Result!.Key)),
|
||||
true when getParentAttempt.Status == RecycleBinQueryResultType.ParentIsRoot
|
||||
=> Ok(null),
|
||||
_ => MapRecycleBinQueryAttemptFailure(getParentAttempt.Status, "element"),
|
||||
};
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.RecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving tracked references for elements in the recycle bin.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ReferencedByElementRecycleBinController : ElementRecycleBinControllerBase
|
||||
{
|
||||
private readonly ITrackedReferencesService _trackedReferencesService;
|
||||
private readonly IRelationTypePresentationFactory _relationTypePresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ReferencedByElementRecycleBinController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for retrieving entity data.</param>
|
||||
/// <param name="elementPresentationFactory">Factory responsible for creating element presentation models.</param>
|
||||
/// <param name="trackedReferencesService">Service for tracking content references.</param>
|
||||
/// <param name="relationTypePresentationFactory">Factory for creating relation type presentation models.</param>
|
||||
public ReferencedByElementRecycleBinController(
|
||||
IEntityService entityService,
|
||||
IElementPresentationFactory elementPresentationFactory,
|
||||
ITrackedReferencesService trackedReferencesService,
|
||||
IRelationTypePresentationFactory relationTypePresentationFactory)
|
||||
: base(entityService, elementPresentationFactory)
|
||||
{
|
||||
_trackedReferencesService = trackedReferencesService;
|
||||
_relationTypePresentationFactory = relationTypePresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a paginated collection of tracked references for all items in the element recycle bin.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="skip">The number of items to skip for pagination.</param>
|
||||
/// <param name="take">The number of items to return for pagination.</param>
|
||||
/// <returns>A paginated collection of reference response models.</returns>
|
||||
[HttpGet("referenced-by")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<IReferenceResponseModel>), StatusCodes.Status200OK)]
|
||||
[EndpointSummary("Gets items referencing an element in the recycle bin.")]
|
||||
[EndpointDescription("Gets a paginated collection of items that reference the element in the recycle bin.")]
|
||||
public async Task<ActionResult<PagedViewModel<IReferenceResponseModel>>> ReferencedBy(
|
||||
CancellationToken cancellationToken,
|
||||
int skip = 0,
|
||||
int take = 20)
|
||||
{
|
||||
PagedModel<RelationItemModel> relationItems = await _trackedReferencesService
|
||||
.GetPagedRelationsForRecycleBinAsync(UmbracoObjectTypes.Element, skip, take, true);
|
||||
|
||||
var pagedViewModel = new PagedViewModel<IReferenceResponseModel>
|
||||
{
|
||||
Total = relationItems.Total,
|
||||
Items = await _relationTypePresentationFactory.CreateReferenceResponseModelsAsync(relationItems.Items),
|
||||
};
|
||||
|
||||
return pagedViewModel;
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Folder;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
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.Element.RecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for restoring element folders from the recycle bin.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class RestoreElementFolderRecycleBinController : ElementRecycleBinControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IElementContainerService _elementContainerService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RestoreElementFolderRecycleBinController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize restore operations.</param>
|
||||
/// <param name="elementContainerService">Service for managing element containers.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="entityService">Service for retrieving entity data.</param>
|
||||
/// <param name="elementPresentationFactory">Factory responsible for creating element presentation models.</param>
|
||||
public RestoreElementFolderRecycleBinController(
|
||||
IAuthorizationService authorizationService,
|
||||
IElementContainerService elementContainerService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IEntityService entityService,
|
||||
IElementPresentationFactory elementPresentationFactory)
|
||||
: base(entityService, elementPresentationFactory)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_elementContainerService = elementContainerService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restores an element folder from the recycle bin to its original location or a specified parent.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element folder to restore.</param>
|
||||
/// <param name="moveFolderRequestModel">The model containing the target location for the restored folder.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the outcome of the restore operation.</returns>
|
||||
[HttpPut("folder/{id:guid}/restore")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[EndpointSummary("Restores an element folder from the recycle bin.")]
|
||||
[EndpointDescription("Restores an element folder from the recycle bin to its original location or a specified parent.")]
|
||||
public async Task<IActionResult> RestoreFolder(CancellationToken cancellationToken, Guid id, MoveFolderRequestModel moveFolderRequestModel)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.RecycleBin(ActionElementMove.ActionLetter),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
Attempt<EntityContainerOperationStatus> result = await _elementContainerService.RestoreAsync(
|
||||
id,
|
||||
moveFolderRequestModel.Target?.Id,
|
||||
CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return result.Success
|
||||
? Ok()
|
||||
: OperationStatusResult(result.Result);
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
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.Element.RecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for restoring elements from the recycle bin.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class RestoreElementRecycleBinController : ElementRecycleBinControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IElementEditingService _elementEditingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RestoreElementRecycleBinController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize restore operations.</param>
|
||||
/// <param name="elementEditingService">Service responsible for element editing operations.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="entityService">Service for retrieving entity data.</param>
|
||||
/// <param name="elementPresentationFactory">Factory responsible for creating element presentation models.</param>
|
||||
public RestoreElementRecycleBinController(
|
||||
IAuthorizationService authorizationService,
|
||||
IElementEditingService elementEditingService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IEntityService entityService,
|
||||
IElementPresentationFactory elementPresentationFactory)
|
||||
: base(entityService, elementPresentationFactory)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_elementEditingService = elementEditingService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restores an element from the recycle bin to its original location or a specified parent.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element to restore.</param>
|
||||
/// <param name="moveElementRequestModel">The model containing the target location for the restored element.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the outcome of the restore operation.</returns>
|
||||
[HttpPut("{id:guid}/restore")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[EndpointSummary("Restores an element from the recycle bin.")]
|
||||
[EndpointDescription("Restores an element from the recycle bin to its original location or a specified parent.")]
|
||||
public async Task<IActionResult> Restore(CancellationToken cancellationToken, Guid id, MoveElementRequestModel moveElementRequestModel)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.RecycleBin(ActionElementMove.ActionLetter),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
Attempt<ContentEditingOperationStatus> result = await _elementEditingService.RestoreAsync(
|
||||
id,
|
||||
moveElementRequestModel.Target?.Id,
|
||||
CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return result.Success
|
||||
? Ok()
|
||||
: ContentEditingOperationStatusResult(result.Result);
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element.RecycleBin;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.RecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving root-level elements in the element recycle bin.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class RootElementRecycleBinController : ElementRecycleBinControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RootElementRecycleBinController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for retrieving entity data.</param>
|
||||
/// <param name="elementPresentationFactory">Factory responsible for creating element presentation models.</param>
|
||||
public RootElementRecycleBinController(
|
||||
IEntityService entityService,
|
||||
IElementPresentationFactory elementPresentationFactory)
|
||||
: base(entityService, elementPresentationFactory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a paginated collection of elements at the root level of the recycle bin.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="skip">The number of items to skip for pagination.</param>
|
||||
/// <param name="take">The number of items to return for pagination.</param>
|
||||
/// <returns>A paginated collection of element recycle bin items.</returns>
|
||||
[HttpGet("root")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<ElementRecycleBinItemResponseModel>), StatusCodes.Status200OK)]
|
||||
[EndpointSummary("Gets elements at the root of the recycle bin.")]
|
||||
[EndpointDescription("Gets a paginated collection of elements at the root level of the recycle bin.")]
|
||||
public async Task<ActionResult<PagedViewModel<ElementRecycleBinItemResponseModel>>> Root(
|
||||
CancellationToken cancellationToken,
|
||||
int skip = 0,
|
||||
int take = 100)
|
||||
=> await GetRoot(skip, take);
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element.RecycleBin;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.RecycleBin;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving sibling elements in the element recycle bin.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class SiblingsElementRecycleBinController : ElementRecycleBinControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SiblingsElementRecycleBinController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for retrieving entity data.</param>
|
||||
/// <param name="elementPresentationFactory">Factory responsible for creating element presentation models.</param>
|
||||
public SiblingsElementRecycleBinController(
|
||||
IEntityService entityService,
|
||||
IElementPresentationFactory elementPresentationFactory)
|
||||
: base(entityService, elementPresentationFactory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of sibling elements in the recycle bin at the same level as the specified target.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="target">The unique identifier of the target element.</param>
|
||||
/// <param name="before">The number of sibling items to retrieve before the target.</param>
|
||||
/// <param name="after">The number of sibling items to retrieve after the target.</param>
|
||||
/// <param name="dataTypeId">Optional data type filter.</param>
|
||||
/// <returns>A subset collection of element recycle bin items.</returns>
|
||||
[HttpGet("siblings")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(SubsetViewModel<ElementRecycleBinItemResponseModel>), StatusCodes.Status200OK)]
|
||||
[EndpointSummary("Gets sibling elements in the recycle bin.")]
|
||||
[EndpointDescription("Gets a collection of sibling elements in the recycle bin at the same level as the provided Id.")]
|
||||
public async Task<ActionResult<SubsetViewModel<ElementRecycleBinItemResponseModel>>> Siblings(CancellationToken cancellationToken, Guid target, int before, int after, Guid? dataTypeId = null)
|
||||
=> await GetSiblings(target, before, after);
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.ViewModels;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Mapping;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.References;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for checking whether elements are referenced by other content.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class AreReferencedElementController : ElementControllerBase
|
||||
{
|
||||
private readonly ITrackedReferencesService _trackedReferencesService;
|
||||
private readonly IUmbracoMapper _umbracoMapper;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AreReferencedElementController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="trackedReferencesService">Service for tracking content references.</param>
|
||||
/// <param name="umbracoMapper">Mapper for converting domain models to view models.</param>
|
||||
public AreReferencedElementController(ITrackedReferencesService trackedReferencesService, IUmbracoMapper umbracoMapper)
|
||||
{
|
||||
_trackedReferencesService = trackedReferencesService;
|
||||
_umbracoMapper = umbracoMapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a paged list of the items used in any kind of relation from selected keys.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Used when bulk deleting elements and bulk unpublishing elements (delete and unpublish on List view).
|
||||
/// This is basically finding children of relations.
|
||||
/// </remarks>
|
||||
[HttpGet("are-referenced")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<ReferenceByIdModel>), StatusCodes.Status200OK)]
|
||||
[EndpointSummary("Gets a collection of items that reference elements.")]
|
||||
[EndpointDescription("Gets a paginated collection of items that reference the elements identified by the provided Ids.")]
|
||||
public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> GetPagedReferencedItems(
|
||||
CancellationToken cancellationToken,
|
||||
[FromQuery(Name = "id")] HashSet<Guid> ids,
|
||||
int skip = 0,
|
||||
int take = 20)
|
||||
{
|
||||
PagedModel<Guid> distinctByKeyItemsWithReferencedRelations = await _trackedReferencesService
|
||||
.GetPagedKeysWithDependentReferencesAsync(ids, Constants.ObjectTypes.Element, skip, take);
|
||||
|
||||
var pagedViewModel = new PagedViewModel<ReferenceByIdModel>
|
||||
{
|
||||
Total = distinctByKeyItemsWithReferencedRelations.Total,
|
||||
Items = _umbracoMapper.MapEnumerable<Guid, ReferenceByIdModel>(
|
||||
distinctByKeyItemsWithReferencedRelations.Items),
|
||||
};
|
||||
|
||||
return pagedViewModel;
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.References;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving tracked references for a specific element.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ReferencedByElementController : ElementControllerBase
|
||||
{
|
||||
private readonly ITrackedReferencesService _trackedReferencesService;
|
||||
private readonly IRelationTypePresentationFactory _relationTypePresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ReferencedByElementController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="trackedReferencesService">Service for tracking content references.</param>
|
||||
/// <param name="relationTypePresentationFactory">Factory for creating relation type presentation models.</param>
|
||||
public ReferencedByElementController(
|
||||
ITrackedReferencesService trackedReferencesService,
|
||||
IRelationTypePresentationFactory relationTypePresentationFactory)
|
||||
{
|
||||
_trackedReferencesService = trackedReferencesService;
|
||||
_relationTypePresentationFactory = relationTypePresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a paged list of tracked references for the current item, so you can see where an element is being used.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Used by info tabs on elements and for the delete and unpublish of single items.
|
||||
/// This is basically finding parents of relations.
|
||||
/// </remarks>
|
||||
[HttpGet("{id:guid}/referenced-by")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<IReferenceResponseModel>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Gets items referencing an element.")]
|
||||
[EndpointDescription("Gets a paginated collection of items that reference the element identified by the provided Id.")]
|
||||
public async Task<IActionResult> ReferencedBy(
|
||||
CancellationToken cancellationToken,
|
||||
Guid id,
|
||||
int skip = 0,
|
||||
int take = 20)
|
||||
{
|
||||
Attempt<PagedModel<RelationItemModel>, GetReferencesOperationStatus> relationItemsAttempt =
|
||||
await _trackedReferencesService.GetPagedRelationsForItemAsync(
|
||||
id,
|
||||
UmbracoObjectTypes.Element,
|
||||
skip,
|
||||
take,
|
||||
true);
|
||||
|
||||
if (relationItemsAttempt.Success is false)
|
||||
{
|
||||
return GetReferencesOperationStatusResult(relationItemsAttempt.Status);
|
||||
}
|
||||
|
||||
var pagedViewModel = new PagedViewModel<IReferenceResponseModel>
|
||||
{
|
||||
Total = relationItemsAttempt.Result.Total,
|
||||
Items = await _relationTypePresentationFactory.CreateReferenceResponseModelsAsync(relationItemsAttempt.Result.Items),
|
||||
};
|
||||
|
||||
return Ok(pagedViewModel);
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.ViewModels;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Mapping;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.References;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving referenced descendants of an element folder.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ReferencedDescendantsElementFolderController : ElementControllerBase
|
||||
{
|
||||
private readonly ITrackedReferencesService _trackedReferencesService;
|
||||
private readonly IUmbracoMapper _umbracoMapper;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ReferencedDescendantsElementFolderController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="trackedReferencesService">Service for tracking content references.</param>
|
||||
/// <param name="umbracoMapper">Mapper for converting domain models to view models.</param>
|
||||
public ReferencedDescendantsElementFolderController(
|
||||
ITrackedReferencesService trackedReferencesService,
|
||||
IUmbracoMapper umbracoMapper)
|
||||
{
|
||||
_trackedReferencesService = trackedReferencesService;
|
||||
_umbracoMapper = umbracoMapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a paged list of the descendant nodes of the element folder used in any kind of relation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Used when deleting an element folder to check if it has any descending items that are in any kind of relation.
|
||||
/// </remarks>
|
||||
[HttpGet("folder/{id:guid}/referenced-descendants")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<ReferenceByIdModel>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Gets element folder descendants that are referenced.")]
|
||||
[EndpointDescription("Gets a paginated collection of descendant elements in a folder that are referenced by other content.")]
|
||||
public async Task<IActionResult> ReferencedDescendants(
|
||||
CancellationToken cancellationToken,
|
||||
Guid id,
|
||||
int skip = 0,
|
||||
int take = 20)
|
||||
{
|
||||
Attempt<PagedModel<RelationItemModel>, GetReferencesOperationStatus> relationItemsAttempt =
|
||||
await _trackedReferencesService.GetPagedDescendantsInReferencesAsync(
|
||||
id,
|
||||
UmbracoObjectTypes.ElementContainer,
|
||||
skip,
|
||||
take,
|
||||
true);
|
||||
|
||||
if (relationItemsAttempt.Success is false)
|
||||
{
|
||||
return GetReferencesOperationStatusResult(relationItemsAttempt.Status);
|
||||
}
|
||||
|
||||
var pagedViewModel = new PagedViewModel<ReferenceByIdModel>
|
||||
{
|
||||
Total = relationItemsAttempt.Result.Total,
|
||||
Items = _umbracoMapper.MapEnumerable<RelationItemModel, ReferenceByIdModel>(relationItemsAttempt.Result.Items),
|
||||
};
|
||||
|
||||
return Ok(pagedViewModel);
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.Services.Entities;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
using Umbraco.Cms.Api.Management.Services.PermissionFilter;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.Tree;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving ancestor element tree items.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class AncestorsElementTreeController : ElementTreeControllerBase
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public AncestorsElementTreeController(
|
||||
IEntityService entityService,
|
||||
FlagProviderCollection flagProviders,
|
||||
IUserStartNodeEntitiesService userStartNodeEntitiesService,
|
||||
IDataTypeService dataTypeService,
|
||||
AppCaches appCaches,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IElementPresentationFactory elementPresentationFactory,
|
||||
IElementPermissionFilterService elementPermissionFilterService)
|
||||
: base(entityService, flagProviders, userStartNodeEntitiesService, dataTypeService, appCaches, backOfficeSecurityAccessor, elementPresentationFactory, elementPermissionFilterService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of ancestor element tree items for the specified descendant.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="descendantId">The unique identifier of the descendant element.</param>
|
||||
/// <returns>A collection of ancestor element tree items.</returns>
|
||||
[HttpGet("ancestors")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(IEnumerable<ElementTreeItemResponseModel>), StatusCodes.Status200OK)]
|
||||
[EndpointSummary("Gets a collection of ancestor element items.")]
|
||||
[EndpointDescription("Gets a collection of element items that are ancestors to the provided Id.")]
|
||||
public async Task<ActionResult<IEnumerable<ElementTreeItemResponseModel>>> Ancestors(CancellationToken cancellationToken, Guid descendantId)
|
||||
=> await GetAncestors(descendantId);
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.Services.Entities;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
using Umbraco.Cms.Api.Management.Services.PermissionFilter;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.Tree;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving child element tree items.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ChildrenElementTreeController : ElementTreeControllerBase
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public ChildrenElementTreeController(
|
||||
IEntityService entityService,
|
||||
FlagProviderCollection flagProviders,
|
||||
IUserStartNodeEntitiesService userStartNodeEntitiesService,
|
||||
IDataTypeService dataTypeService,
|
||||
AppCaches appCaches,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IElementPresentationFactory elementPresentationFactory,
|
||||
IElementPermissionFilterService elementPermissionFilterService)
|
||||
: base(entityService, flagProviders, userStartNodeEntitiesService, dataTypeService, appCaches, backOfficeSecurityAccessor, elementPresentationFactory, elementPermissionFilterService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a paginated collection of child element tree items for the specified parent.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="parentId">The unique identifier of the parent element.</param>
|
||||
/// <param name="skip">The number of items to skip for pagination.</param>
|
||||
/// <param name="take">The number of items to return for pagination.</param>
|
||||
/// <param name="foldersOnly">Whether to return only folder items.</param>
|
||||
/// <param name="dataTypeId">An optional data type identifier to filter the element items.</param>
|
||||
/// <returns>A paginated collection of child element tree items.</returns>
|
||||
[HttpGet("children")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<ElementTreeItemResponseModel>), StatusCodes.Status200OK)]
|
||||
[EndpointSummary("Gets a collection of element tree child items.")]
|
||||
[EndpointDescription("Gets a paginated collection of element tree items that are children of the provided parent Id.")]
|
||||
public async Task<ActionResult<PagedViewModel<ElementTreeItemResponseModel>>> Children(CancellationToken cancellationToken, Guid parentId, int skip = 0, int take = 100, bool foldersOnly = false, Guid? dataTypeId = null)
|
||||
{
|
||||
RenderFoldersOnly(foldersOnly);
|
||||
IgnoreUserStartNodesForDataType(dataTypeId);
|
||||
return await GetChildren(parentId, skip, take);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Tree;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Api.Management.Services.Entities;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
using Umbraco.Cms.Api.Management.Services.PermissionFilter;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.Entities;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.Tree;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for element tree operations within the Umbraco CMS Management API.
|
||||
/// Provides shared functionality for derived element tree controllers including user start node support and permission filtering.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.Element}")]
|
||||
[ApiExplorerSettings(GroupName = nameof(Constants.UdiEntityType.Element))]
|
||||
[Authorize(Policy = AuthorizationPolicies.SectionAccessForElementTree)]
|
||||
public class ElementTreeControllerBase : UserStartNodeFolderTreeControllerBase<ElementTreeItemResponseModel>
|
||||
{
|
||||
private readonly AppCaches _appCaches;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
private readonly IElementPresentationFactory _elementPresentationFactory;
|
||||
private readonly IElementPermissionFilterService _elementPermissionFilterService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ElementTreeControllerBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entityService">Service for retrieving entity data.</param>
|
||||
/// <param name="flagProviders">Collection of flag providers for tree item flags.</param>
|
||||
/// <param name="userStartNodeEntitiesService">Service for user start node entity resolution.</param>
|
||||
/// <param name="dataTypeService">Service for data type operations.</param>
|
||||
/// <param name="appCaches">Application caches for performance optimization.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="elementPresentationFactory">Factory responsible for creating element presentation models.</param>
|
||||
/// <param name="elementPermissionFilterService">Service for filtering tree entities based on element permissions.</param>
|
||||
public ElementTreeControllerBase(
|
||||
IEntityService entityService,
|
||||
FlagProviderCollection flagProviders,
|
||||
IUserStartNodeEntitiesService userStartNodeEntitiesService,
|
||||
IDataTypeService dataTypeService,
|
||||
AppCaches appCaches,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IElementPresentationFactory elementPresentationFactory,
|
||||
IElementPermissionFilterService elementPermissionFilterService)
|
||||
: base(entityService, flagProviders, userStartNodeEntitiesService, dataTypeService)
|
||||
{
|
||||
_appCaches = appCaches;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
_elementPresentationFactory = elementPresentationFactory;
|
||||
_elementPermissionFilterService = elementPermissionFilterService;
|
||||
}
|
||||
|
||||
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.Element;
|
||||
|
||||
protected override UmbracoObjectTypes FolderObjectType => UmbracoObjectTypes.ElementContainer;
|
||||
|
||||
protected override int[] GetUserStartNodeIds()
|
||||
=> _backOfficeSecurityAccessor
|
||||
.BackOfficeSecurity?
|
||||
.CurrentUser?
|
||||
.CalculateElementStartNodeIds(EntityService, _appCaches)
|
||||
?? [];
|
||||
|
||||
protected override string[] GetUserStartNodePaths()
|
||||
=> _backOfficeSecurityAccessor
|
||||
.BackOfficeSecurity?
|
||||
.CurrentUser?
|
||||
.GetElementStartNodePaths(EntityService, _appCaches)
|
||||
?? [];
|
||||
|
||||
protected override async Task<ElementTreeItemResponseModel> MapTreeItemViewModelAsync(Guid? parentKey, IEntitySlim entity)
|
||||
{
|
||||
ElementTreeItemResponseModel responseModel = await base.MapTreeItemViewModelAsync(parentKey, entity);
|
||||
|
||||
if (entity is IElementEntitySlim elementEntitySlim)
|
||||
{
|
||||
responseModel.CreateDate = elementEntitySlim.CreateDate;
|
||||
responseModel.DocumentType = _elementPresentationFactory.CreateDocumentTypeReferenceResponseModel(elementEntitySlim);
|
||||
responseModel.Variants = await _elementPresentationFactory.CreateVariantsItemResponseModelsAsync(elementEntitySlim);
|
||||
}
|
||||
|
||||
return responseModel;
|
||||
}
|
||||
|
||||
protected override async Task<ElementTreeItemResponseModel> MapTreeItemViewModelAsNoAccessAsync(Guid? parentKey, IEntitySlim entity)
|
||||
{
|
||||
ElementTreeItemResponseModel viewModel = await MapTreeItemViewModelAsync(parentKey, entity);
|
||||
viewModel.NoAccess = true;
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Task<(IEntitySlim[] Entities, long TotalItems)> FilterTreeEntities(
|
||||
IEntitySlim[] entities,
|
||||
long totalItems)
|
||||
=> _elementPermissionFilterService.FilterAsync(entities, totalItems);
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Task<(IEntitySlim[] Entities, long TotalBefore, long TotalAfter)> FilterTreeEntities(
|
||||
Guid targetKey,
|
||||
IEntitySlim[] entities,
|
||||
long totalBefore,
|
||||
long totalAfter)
|
||||
=> _elementPermissionFilterService.FilterAsync(targetKey, entities, totalBefore, totalAfter);
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.Services.Entities;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
using Umbraco.Cms.Api.Management.Services.PermissionFilter;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.Tree;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving root-level element tree items.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class RootElementTreeController : ElementTreeControllerBase
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public RootElementTreeController(
|
||||
IEntityService entityService,
|
||||
FlagProviderCollection flagProviders,
|
||||
IUserStartNodeEntitiesService userStartNodeEntitiesService,
|
||||
IDataTypeService dataTypeService,
|
||||
AppCaches appCaches,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IElementPresentationFactory elementPresentationFactory,
|
||||
IElementPermissionFilterService elementPermissionFilterService)
|
||||
: base(entityService, flagProviders, userStartNodeEntitiesService, dataTypeService, appCaches, backOfficeSecurityAccessor, elementPresentationFactory, elementPermissionFilterService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a paginated collection of element tree items from the root level.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="skip">The number of items to skip for pagination.</param>
|
||||
/// <param name="take">The number of items to return for pagination.</param>
|
||||
/// <param name="foldersOnly">Whether to return only folder items.</param>
|
||||
/// <param name="dataTypeId">An optional identifier to filter element items by data type.</param>
|
||||
/// <returns>A paginated collection of root element tree items.</returns>
|
||||
[HttpGet("root")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<ElementTreeItemResponseModel>), StatusCodes.Status200OK)]
|
||||
[EndpointSummary("Gets a collection of element items from the root of the tree.")]
|
||||
[EndpointDescription("Gets a paginated collection of element items from the root of the tree with optional filtering.")]
|
||||
public async Task<ActionResult<PagedViewModel<ElementTreeItemResponseModel>>> Root(
|
||||
CancellationToken cancellationToken,
|
||||
int skip = 0,
|
||||
int take = 100,
|
||||
bool foldersOnly = false,
|
||||
Guid? dataTypeId = null)
|
||||
{
|
||||
RenderFoldersOnly(foldersOnly);
|
||||
IgnoreUserStartNodesForDataType(dataTypeId);
|
||||
return await GetRoot(skip, take);
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.Services.Entities;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
using Umbraco.Cms.Api.Management.Services.PermissionFilter;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element.Tree;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving sibling element tree items.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class SiblingsElementTreeController : ElementTreeControllerBase
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public SiblingsElementTreeController(
|
||||
IEntityService entityService,
|
||||
FlagProviderCollection flagProviders,
|
||||
IUserStartNodeEntitiesService userStartNodeEntitiesService,
|
||||
IDataTypeService dataTypeService,
|
||||
AppCaches appCaches,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IElementPresentationFactory elementPresentationFactory,
|
||||
IElementPermissionFilterService elementPermissionFilterService)
|
||||
: base(entityService, flagProviders, userStartNodeEntitiesService, dataTypeService, appCaches, backOfficeSecurityAccessor, elementPresentationFactory, elementPermissionFilterService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of sibling element tree items for the specified target.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="target">The unique identifier of the target element.</param>
|
||||
/// <param name="before">The number of sibling items to retrieve before the target.</param>
|
||||
/// <param name="after">The number of sibling items to retrieve after the target.</param>
|
||||
/// <param name="foldersOnly">Whether to return only folder items.</param>
|
||||
/// <param name="dataTypeId">An optional data type identifier to filter the sibling items.</param>
|
||||
/// <returns>A subset collection of sibling element tree items.</returns>
|
||||
[HttpGet("siblings")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(SubsetViewModel<ElementTreeItemResponseModel>), StatusCodes.Status200OK)]
|
||||
[EndpointSummary("Gets a collection of element tree sibling items.")]
|
||||
[EndpointDescription("Gets a collection of element tree items that are siblings of the provided Id.")]
|
||||
public async Task<ActionResult<SubsetViewModel<ElementTreeItemResponseModel>>> Siblings(
|
||||
CancellationToken cancellationToken,
|
||||
Guid target,
|
||||
int before,
|
||||
int after,
|
||||
bool foldersOnly = false,
|
||||
Guid? dataTypeId = null)
|
||||
{
|
||||
RenderFoldersOnly(foldersOnly);
|
||||
IgnoreUserStartNodesForDataType(dataTypeId);
|
||||
return await GetSiblings(target, before, after);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
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.Element;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for handling unpublish operations on elements in the Umbraco CMS.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class UnpublishElementController : ElementControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly IElementPublishingService _elementPublishingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UnpublishElementController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize element unpublish operations.</param>
|
||||
/// <param name="elementPublishingService">Service responsible for unpublishing elements.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
public UnpublishElementController(
|
||||
IAuthorizationService authorizationService,
|
||||
IElementPublishingService elementPublishingService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
{
|
||||
_authorizationService = authorizationService;
|
||||
_elementPublishingService = elementPublishingService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpublishes an element identified by the specified unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element to unpublish.</param>
|
||||
/// <param name="requestModel">The model containing the cultures to unpublish.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the outcome of the unpublish operation.</returns>
|
||||
[HttpPut("{id:guid}/unpublish")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Unpublishes an element.")]
|
||||
[EndpointDescription("Unpublishes an element identified by the provided Id.")]
|
||||
public async Task<IActionResult> Unpublish(CancellationToken cancellationToken, Guid id, UnpublishElementRequestModel requestModel)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(
|
||||
ActionElementUnpublish.ActionLetter,
|
||||
id,
|
||||
requestModel.Cultures ?? Enumerable.Empty<string>()),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
Attempt<ContentPublishingOperationStatus> attempt = await _elementPublishingService.UnpublishAsync(
|
||||
id,
|
||||
requestModel.Cultures,
|
||||
CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
return attempt.Success
|
||||
? Ok()
|
||||
: ElementPublishingOperationStatusResult(attempt.Result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element;
|
||||
|
||||
/// <summary>
|
||||
/// Controller responsible for handling update operations on elements in the management API.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class UpdateElementController : UpdateElementControllerBase
|
||||
{
|
||||
private readonly IElementEditingPresentationFactory _elementEditingPresentationFactory;
|
||||
private readonly IElementEditingService _elementEditingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UpdateElementController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service for verifying user permissions.</param>
|
||||
/// <param name="elementEditingPresentationFactory">Factory for creating element editing presentation models.</param>
|
||||
/// <param name="elementEditingService">Service for managing element updates.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for the back office user security context.</param>
|
||||
public UpdateElementController(
|
||||
IAuthorizationService authorizationService,
|
||||
IElementEditingPresentationFactory elementEditingPresentationFactory,
|
||||
IElementEditingService elementEditingService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
: base(authorizationService)
|
||||
{
|
||||
_elementEditingPresentationFactory = elementEditingPresentationFactory;
|
||||
_elementEditingService = elementEditingService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>Updates the specified element with new details provided in the request model.</summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element to update.</param>
|
||||
/// <param name="requestModel">The model containing the updated element details.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the outcome of the update operation.</returns>
|
||||
[HttpPut("{id:guid}")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Updates an element.")]
|
||||
[EndpointDescription("Updates an element identified by the provided Id with the details from the request model.")]
|
||||
public async Task<IActionResult> Update(CancellationToken cancellationToken, Guid id, UpdateElementRequestModel requestModel)
|
||||
=> await HandleRequest(id, requestModel, async () =>
|
||||
{
|
||||
ElementUpdateModel model = _elementEditingPresentationFactory.MapUpdateModel(requestModel);
|
||||
Attempt<ElementUpdateResult, ContentEditingOperationStatus> result =
|
||||
await _elementEditingService.UpdateAsync(id, model, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return result.Success
|
||||
? Ok()
|
||||
: ContentEditingOperationStatusResult(result.Status);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for handling update operations on elements within the Umbraco CMS Management API.
|
||||
/// Provides common functionality for derived controllers that manage element updates.
|
||||
/// </summary>
|
||||
public abstract class UpdateElementControllerBase : ElementControllerBase
|
||||
{
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UpdateElementControllerBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize access to element update operations.</param>
|
||||
protected UpdateElementControllerBase(IAuthorizationService authorizationService)
|
||||
=> _authorizationService = authorizationService;
|
||||
|
||||
protected async Task<IActionResult> HandleRequest(Guid id, UpdateElementRequestModel requestModel, Func<Task<IActionResult>> authorizedHandler)
|
||||
{
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementUpdate.ActionLetter, id),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (authorizationResult.Succeeded is false)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
return await authorizedHandler();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for validating element creation requests without persisting changes.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ValidateCreateElementController : CreateElementControllerBase
|
||||
{
|
||||
private readonly IElementEditingPresentationFactory _elementEditingPresentationFactory;
|
||||
private readonly IElementEditingService _elementEditingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ValidateCreateElementController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize access to element creation operations.</param>
|
||||
/// <param name="elementEditingPresentationFactory">Factory for creating element editing presentation models.</param>
|
||||
/// <param name="elementEditingService">Service responsible for element editing functionality.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
public ValidateCreateElementController(
|
||||
IAuthorizationService authorizationService,
|
||||
IElementEditingPresentationFactory elementEditingPresentationFactory,
|
||||
IElementEditingService elementEditingService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
: base(authorizationService)
|
||||
{
|
||||
_elementEditingPresentationFactory = elementEditingPresentationFactory;
|
||||
_elementEditingService = elementEditingService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the request model for creating a new element without actually creating it.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="requestModel">The element creation request model to validate.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the validation result.</returns>
|
||||
[HttpPost("validate")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Validates creating an element.")]
|
||||
[EndpointDescription("Validates the request model for creating a new element without actually creating it.")]
|
||||
public async Task<IActionResult> Validate(CancellationToken cancellationToken, CreateElementRequestModel requestModel)
|
||||
=> await HandleRequest(requestModel, async () =>
|
||||
{
|
||||
ElementCreateModel model = _elementEditingPresentationFactory.MapCreateModel(requestModel);
|
||||
Attempt<ContentValidationResult, ContentEditingOperationStatus> result =
|
||||
await _elementEditingService.ValidateCreateAsync(model, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return result.Success
|
||||
? Ok()
|
||||
: ElementEditingOperationStatusResult(result.Status, requestModel, result.Result);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.Element;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for validating element update requests without persisting changes.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ValidateUpdateElementController : UpdateElementControllerBase
|
||||
{
|
||||
private readonly IElementEditingPresentationFactory _elementEditingPresentationFactory;
|
||||
private readonly IElementEditingService _elementEditingService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ValidateUpdateElementController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authorizationService">Service used to authorize access to element update operations.</param>
|
||||
/// <param name="elementEditingPresentationFactory">Factory for creating element editing presentation models.</param>
|
||||
/// <param name="elementEditingService">Service responsible for element editing functionality.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
public ValidateUpdateElementController(
|
||||
IAuthorizationService authorizationService,
|
||||
IElementEditingPresentationFactory elementEditingPresentationFactory,
|
||||
IElementEditingService elementEditingService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
: base(authorizationService)
|
||||
{
|
||||
_elementEditingPresentationFactory = elementEditingPresentationFactory;
|
||||
_elementEditingService = elementEditingService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the request model for updating an element without actually updating it.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element to validate the update for.</param>
|
||||
/// <param name="requestModel">The element update request model to validate.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the validation result.</returns>
|
||||
[HttpPut("{id:guid}/validate")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[EndpointSummary("Validates updating an element.")]
|
||||
[EndpointDescription("Validates the request model for updating an element without actually updating it.")]
|
||||
public async Task<IActionResult> Validate(CancellationToken cancellationToken, Guid id, ValidateUpdateElementRequestModel requestModel)
|
||||
=> await HandleRequest(id, requestModel, async () =>
|
||||
{
|
||||
ValidateElementUpdateModel model = _elementEditingPresentationFactory.MapValidateUpdateModel(requestModel);
|
||||
Attempt<ContentValidationResult, ContentEditingOperationStatus> result =
|
||||
await _elementEditingService.ValidateUpdateAsync(id, model, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return result.Success
|
||||
? Ok()
|
||||
: ElementEditingOperationStatusResult(result.Status, requestModel, result.Result);
|
||||
});
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.ElementVersion;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for retrieving all versions of a specific element.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class AllElementVersionController : ElementVersionControllerBase
|
||||
{
|
||||
private readonly IElementVersionService _elementVersionService;
|
||||
private readonly IElementVersionPresentationFactory _elementVersionPresentationFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AllElementVersionController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="elementVersionService">Service for managing element versions.</param>
|
||||
/// <param name="elementVersionPresentationFactory">Factory for creating element version presentation models.</param>
|
||||
public AllElementVersionController(
|
||||
IElementVersionService elementVersionService,
|
||||
IElementVersionPresentationFactory elementVersionPresentationFactory)
|
||||
{
|
||||
_elementVersionService = elementVersionService;
|
||||
_elementVersionPresentationFactory = elementVersionPresentationFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a paginated collection of versions for a specific element.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="elementId">The unique identifier of the element to retrieve versions for.</param>
|
||||
/// <param name="culture">Optional culture filter for variant elements.</param>
|
||||
/// <param name="skip">The number of items to skip for pagination.</param>
|
||||
/// <param name="take">The number of items to return for pagination.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> containing a paginated collection of element versions.</returns>
|
||||
[MapToApiVersion("1.0")]
|
||||
[HttpGet]
|
||||
[ProducesResponseType(typeof(PagedViewModel<ElementVersionItemResponseModel>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[EndpointSummary("Gets a paginated collection of versions for a specific element.")]
|
||||
[EndpointDescription("Gets a paginated collection of versions for a specific element and optional culture. Each result describes the version and includes details of the element type, editor, version date, and published status.")]
|
||||
public async Task<IActionResult> All(
|
||||
CancellationToken cancellationToken,
|
||||
[Required] Guid elementId,
|
||||
string? culture,
|
||||
int skip = 0,
|
||||
int take = 100)
|
||||
{
|
||||
Attempt<PagedModel<ContentVersionMeta>?, ContentVersionOperationStatus> attempt =
|
||||
await _elementVersionService.GetPagedContentVersionsAsync(elementId, culture, skip, take);
|
||||
|
||||
if (attempt.Success is false)
|
||||
{
|
||||
return MapFailure(attempt.Status);
|
||||
}
|
||||
|
||||
var pagedViewModel = new PagedViewModel<ElementVersionItemResponseModel>
|
||||
{
|
||||
Total = attempt.Result!.Total,
|
||||
Items = await _elementVersionPresentationFactory.CreateMultipleAsync(attempt.Result!.Items),
|
||||
};
|
||||
|
||||
return Ok(pagedViewModel);
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Element;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Mapping;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.ElementVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Controller for retrieving a specific element version by its unique key.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class ByKeyElementVersionController : ElementVersionControllerBase
|
||||
{
|
||||
private readonly IElementVersionService _elementVersionService;
|
||||
private readonly IUmbracoMapper _umbracoMapper;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ByKeyElementVersionController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="elementVersionService">Service for managing element versions.</param>
|
||||
/// <param name="umbracoMapper">Mapper for converting domain models to view models.</param>
|
||||
public ByKeyElementVersionController(
|
||||
IElementVersionService elementVersionService,
|
||||
IUmbracoMapper umbracoMapper)
|
||||
{
|
||||
_elementVersionService = elementVersionService;
|
||||
_umbracoMapper = umbracoMapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a specific element version by its unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element version to retrieve.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> containing the element version if found.</returns>
|
||||
[MapToApiVersion("1.0")]
|
||||
[HttpGet("{id:guid}")]
|
||||
[ProducesResponseType(typeof(ElementVersionResponseModel), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[EndpointSummary("Gets a specific element version.")]
|
||||
[EndpointDescription("Gets a specific element version by its Id. If found, the result describes the version and includes details of the element type, editor, version date, and published status.")]
|
||||
public async Task<IActionResult> ByKey(CancellationToken cancellationToken, Guid id)
|
||||
{
|
||||
Attempt<IElement?, ContentVersionOperationStatus> attempt =
|
||||
await _elementVersionService.GetAsync(id);
|
||||
|
||||
return attempt.Success
|
||||
? Ok(_umbracoMapper.Map<ElementVersionResponseModel>(attempt.Result))
|
||||
: MapFailure(attempt.Status);
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DocumentVersion;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.ElementVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Serves as the base controller for element version management operations within the Umbraco CMS Management API.
|
||||
/// Provides shared functionality for derived element version controllers.
|
||||
/// </summary>
|
||||
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.Element}-version")]
|
||||
[ApiExplorerSettings(GroupName = $"{nameof(Constants.UdiEntityType.Element)} Version")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessElements)]
|
||||
public abstract class ElementVersionControllerBase : ManagementApiControllerBase
|
||||
{
|
||||
protected IActionResult MapFailure(ContentVersionOperationStatus status)
|
||||
=> DocumentVersionControllerBase.MapFailure(status);
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Actions;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Security.Authorization;
|
||||
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.ElementVersion;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for rolling back an element to a specific version.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class RollbackElementVersionController : ElementVersionControllerBase
|
||||
{
|
||||
private readonly IElementVersionService _elementVersionService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RollbackElementVersionController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="elementVersionService">Service for managing element versions.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
/// <param name="authorizationService">Service used to authorize rollback operations.</param>
|
||||
public RollbackElementVersionController(
|
||||
IElementVersionService elementVersionService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IAuthorizationService authorizationService)
|
||||
{
|
||||
_elementVersionService = elementVersionService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
_authorizationService = authorizationService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls back an element to the version identified by the specified unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element version to roll back to.</param>
|
||||
/// <param name="culture">Optional culture to target for variant elements.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the outcome of the rollback operation.</returns>
|
||||
[MapToApiVersion("1.0")]
|
||||
[HttpPost("{id:guid}/rollback")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[EndpointSummary("Rolls back an element to a specific version.")]
|
||||
[EndpointDescription("Rolls back an element to the version indicated by the provided Id. This will archive the current version of the element and publish the provided one.")]
|
||||
public async Task<IActionResult> Rollback(CancellationToken cancellationToken, Guid id, string? culture)
|
||||
{
|
||||
Attempt<IElement?, ContentVersionOperationStatus> getContentAttempt = await _elementVersionService.GetAsync(id);
|
||||
if (getContentAttempt.Success is false || getContentAttempt.Result is null)
|
||||
{
|
||||
return MapFailure(getContentAttempt.Status);
|
||||
}
|
||||
|
||||
IElement element = getContentAttempt.Result;
|
||||
AuthorizationResult authorizationResult = await _authorizationService.AuthorizeResourceAsync(
|
||||
User,
|
||||
ElementPermissionResource.WithKeys(ActionElementRollback.ActionLetter, element.Key),
|
||||
AuthorizationPolicies.ElementPermissionByResource);
|
||||
|
||||
if (!authorizationResult.Succeeded)
|
||||
{
|
||||
return Forbidden();
|
||||
}
|
||||
|
||||
Attempt<ContentVersionOperationStatus> rollBackAttempt =
|
||||
await _elementVersionService.RollBackAsync(id, culture, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return rollBackAttempt.Success
|
||||
? Ok()
|
||||
: MapFailure(rollBackAttempt.Result);
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.ElementVersion;
|
||||
|
||||
/// <summary>
|
||||
/// API controller responsible for updating the prevent-cleanup status of an element version.
|
||||
/// </summary>
|
||||
[ApiVersion("1.0")]
|
||||
public class UpdatePreventCleanupElementVersionController : ElementVersionControllerBase
|
||||
{
|
||||
private readonly IElementVersionService _elementVersionService;
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UpdatePreventCleanupElementVersionController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="elementVersionService">Service for managing element versions.</param>
|
||||
/// <param name="backOfficeSecurityAccessor">Accessor for back office security context.</param>
|
||||
public UpdatePreventCleanupElementVersionController(
|
||||
IElementVersionService elementVersionService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
|
||||
{
|
||||
_elementVersionService = elementVersionService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the prevent-cleanup status for an element version.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
|
||||
/// <param name="id">The unique identifier of the element version.</param>
|
||||
/// <param name="preventCleanup">Whether the version should be excluded from content history cleanup.</param>
|
||||
/// <returns>An <see cref="IActionResult"/> representing the outcome of the operation.</returns>
|
||||
[MapToApiVersion("1.0")]
|
||||
[HttpPut("{id:guid}/prevent-cleanup")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[EndpointSummary("Sets the prevent clean up status for an element version.")]
|
||||
[EndpointDescription("Sets the prevent clean up boolean status for an element version to the provided value. This controls whether the version will be a candidate for removal in content history clean up.")]
|
||||
public async Task<IActionResult> Set(CancellationToken cancellationToken, Guid id, bool preventCleanup)
|
||||
{
|
||||
Attempt<ContentVersionOperationStatus> attempt =
|
||||
await _elementVersionService.SetPreventCleanupAsync(id, preventCleanup, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return attempt.Success
|
||||
? Ok()
|
||||
: MapFailure(attempt.Result);
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,8 @@ public abstract class FolderManagementControllerBase<TTreeEntity> : ManagementAp
|
||||
return Ok(new FolderResponseModel
|
||||
{
|
||||
Name = container.Name!,
|
||||
Id = container.Key
|
||||
Id = container.Key,
|
||||
IsTrashed = container.Trashed
|
||||
});
|
||||
}
|
||||
|
||||
@@ -81,33 +82,37 @@ public abstract class FolderManagementControllerBase<TTreeEntity> : ManagementAp
|
||||
: OperationStatusResult(result.Status);
|
||||
}
|
||||
|
||||
protected IActionResult OperationStatusResult(EntityContainerOperationStatus status)
|
||||
internal static IActionResult OperationStatusResult(EntityContainerOperationStatus status)
|
||||
=> OperationStatusResult(status, problemDetailsBuilder => status switch
|
||||
{
|
||||
EntityContainerOperationStatus.NotFound => NotFound(problemDetailsBuilder
|
||||
EntityContainerOperationStatus.NotFound => new NotFoundObjectResult(problemDetailsBuilder
|
||||
.WithTitle("The folder could not be found")
|
||||
.Build()),
|
||||
EntityContainerOperationStatus.ParentNotFound => NotFound(problemDetailsBuilder
|
||||
EntityContainerOperationStatus.ParentNotFound => new NotFoundObjectResult(problemDetailsBuilder
|
||||
.WithTitle("The parent folder could not be found")
|
||||
.Build()),
|
||||
EntityContainerOperationStatus.DuplicateName => BadRequest(problemDetailsBuilder
|
||||
EntityContainerOperationStatus.DuplicateName => new BadRequestObjectResult(problemDetailsBuilder
|
||||
.WithTitle("The name is already used")
|
||||
.WithDetail("The folder name must be unique on this parent.")
|
||||
.Build()),
|
||||
EntityContainerOperationStatus.DuplicateKey => BadRequest(problemDetailsBuilder
|
||||
EntityContainerOperationStatus.DuplicateKey => new BadRequestObjectResult(problemDetailsBuilder
|
||||
.WithTitle("The id is already used")
|
||||
.WithDetail("The folder id must be unique.")
|
||||
.Build()),
|
||||
EntityContainerOperationStatus.NotEmpty => BadRequest(problemDetailsBuilder
|
||||
EntityContainerOperationStatus.NotEmpty => new BadRequestObjectResult(problemDetailsBuilder
|
||||
.WithTitle("The folder is not empty")
|
||||
.WithDetail("The folder must be empty to perform this action.")
|
||||
.Build()),
|
||||
EntityContainerOperationStatus.CancelledByNotification => BadRequest(problemDetailsBuilder
|
||||
EntityContainerOperationStatus.CancelledByNotification => new BadRequestObjectResult(problemDetailsBuilder
|
||||
.WithTitle("Cancelled by notification")
|
||||
.WithDetail("A notification handler prevented the folder operation.")
|
||||
.Build()),
|
||||
_ => StatusCode(StatusCodes.Status500InternalServerError, problemDetailsBuilder
|
||||
.WithTitle("Unknown folder operation status.")
|
||||
EntityContainerOperationStatus.HasReferencedDescendants => new BadRequestObjectResult(problemDetailsBuilder
|
||||
.WithTitle("The folder has referenced descendants")
|
||||
.WithDetail("The folder cannot be moved to the recycle bin because it contains items that are referenced by other content.")
|
||||
.Build()),
|
||||
_ => new ObjectResult(problemDetailsBuilder
|
||||
.WithTitle("Unknown folder operation status.")
|
||||
.Build()) { StatusCode = StatusCodes.Status500InternalServerError },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -72,8 +72,8 @@ public abstract class ManagementApiControllerBase : Controller, IUmbracoFeature
|
||||
where TEnum : Enum
|
||||
=> result(new ProblemDetailsBuilder().WithOperationStatus(status));
|
||||
|
||||
protected BadRequestObjectResult SkipTakeToPagingProblem() =>
|
||||
BadRequest(new ProblemDetails
|
||||
protected static BadRequestObjectResult SkipTakeToPagingProblem() =>
|
||||
new(new ProblemDetails
|
||||
{
|
||||
Title = "Invalid skip/take",
|
||||
Detail = "Skip must be a multiple of take - i.e. skip = 10, take = 5",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user