diff --git a/src/Umbraco.Cms.Api.Common/DependencyInjection/UmbracoBuilderAuthExtensions.cs b/src/Umbraco.Cms.Api.Common/DependencyInjection/UmbracoBuilderAuthExtensions.cs index 4bb501edb1..30fec59c23 100644 --- a/src/Umbraco.Cms.Api.Common/DependencyInjection/UmbracoBuilderAuthExtensions.cs +++ b/src/Umbraco.Cms.Api.Common/DependencyInjection/UmbracoBuilderAuthExtensions.cs @@ -34,14 +34,14 @@ public static class UmbracoBuilderAuthExtensions // FIXME: swap paths here so member API is first (see comment above) options .SetAuthorizationEndpointUris( - Paths.BackOfficeApi.AuthorizationEndpoint.TrimStart(Constants.CharArrays.ForwardSlash), - Paths.MemberApi.AuthorizationEndpoint.TrimStart(Constants.CharArrays.ForwardSlash)) + Paths.MemberApi.AuthorizationEndpoint.TrimStart(Constants.CharArrays.ForwardSlash), + Paths.BackOfficeApi.AuthorizationEndpoint.TrimStart(Constants.CharArrays.ForwardSlash)) .SetTokenEndpointUris( - Paths.BackOfficeApi.TokenEndpoint.TrimStart(Constants.CharArrays.ForwardSlash), - Paths.MemberApi.TokenEndpoint.TrimStart(Constants.CharArrays.ForwardSlash)) + Paths.MemberApi.TokenEndpoint.TrimStart(Constants.CharArrays.ForwardSlash), + Paths.BackOfficeApi.TokenEndpoint.TrimStart(Constants.CharArrays.ForwardSlash)) .SetLogoutEndpointUris( - Paths.BackOfficeApi.LogoutEndpoint.TrimStart(Constants.CharArrays.ForwardSlash), - Paths.MemberApi.LogoutEndpoint.TrimStart(Constants.CharArrays.ForwardSlash)) + Paths.MemberApi.LogoutEndpoint.TrimStart(Constants.CharArrays.ForwardSlash), + Paths.BackOfficeApi.LogoutEndpoint.TrimStart(Constants.CharArrays.ForwardSlash)) .SetRevocationEndpointUris( Paths.BackOfficeApi.RevokeEndpoint.TrimStart(Constants.CharArrays.ForwardSlash), Paths.MemberApi.RevokeEndpoint.TrimStart(Constants.CharArrays.ForwardSlash)); diff --git a/src/Umbraco.Cms.Api.Delivery/Controllers/Content/ContentApiItemControllerBase.cs b/src/Umbraco.Cms.Api.Delivery/Controllers/Content/ContentApiItemControllerBase.cs index 895cd376cd..b5c2cfe70d 100644 --- a/src/Umbraco.Cms.Api.Delivery/Controllers/Content/ContentApiItemControllerBase.cs +++ b/src/Umbraco.Cms.Api.Delivery/Controllers/Content/ContentApiItemControllerBase.cs @@ -1,35 +1,18 @@ using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Core.DeliveryApi; -using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.Security; -using Umbraco.Cms.Core.Services; namespace Umbraco.Cms.Api.Delivery.Controllers.Content; public abstract class ContentApiItemControllerBase : ContentApiControllerBase { - // TODO: Remove this in V14 when the obsolete constructors have been removed - private readonly IPublicAccessService _publicAccessService; - - [Obsolete($"Please use the constructor that does not accept {nameof(IPublicAccessService)}. Will be removed in V14.")] - protected ContentApiItemControllerBase( - IApiPublishedContentCache apiPublishedContentCache, - IApiContentResponseBuilder apiContentResponseBuilder, - IPublicAccessService publicAccessService) - : this(apiPublishedContentCache, apiContentResponseBuilder) - { - } - protected ContentApiItemControllerBase( IApiPublishedContentCache apiPublishedContentCache, IApiContentResponseBuilder apiContentResponseBuilder) : base(apiPublishedContentCache, apiContentResponseBuilder) - => _publicAccessService = StaticServiceProvider.Instance.GetRequiredService(); - - [Obsolete($"Please use {nameof(IPublicAccessService)} to test for content protection. Will be removed in V14.")] - protected bool IsProtected(IPublishedContent content) => _publicAccessService.IsProtected(content.Path); + { + } protected async Task HandleMemberAccessAsync(IPublishedContent contentItem, IRequestMemberAccessService requestMemberAccessService) { diff --git a/src/Umbraco.Cms.Api.Management/Factories/DocumentPresentationFactory.cs b/src/Umbraco.Cms.Api.Management/Factories/DocumentPresentationFactory.cs index 21a1494c9c..be11fadaf5 100644 --- a/src/Umbraco.Cms.Api.Management/Factories/DocumentPresentationFactory.cs +++ b/src/Umbraco.Cms.Api.Management/Factories/DocumentPresentationFactory.cs @@ -1,7 +1,6 @@ using Umbraco.Cms.Api.Management.ViewModels.Document; using Umbraco.Cms.Api.Management.ViewModels.Document.Item; using Umbraco.Cms.Api.Management.ViewModels.DocumentBlueprint.Item; -using Umbraco.Cms.Core; using Umbraco.Cms.Core.Mapping; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; @@ -49,6 +48,7 @@ public class DocumentPresentationFactory : IDocumentPresentationFactory Name = entity.Name ?? string.Empty, Id = entity.Key, Icon = entity.ContentTypeIcon, + IsTrashed = entity.Trashed }; IContentType? contentType = _contentTypeService.Get(entity.ContentTypeAlias); diff --git a/src/Umbraco.Cms.Api.Management/Mapping/Document/DocumentMapDefinition.cs b/src/Umbraco.Cms.Api.Management/Mapping/Document/DocumentMapDefinition.cs index 0bfd701765..8f84060fb5 100644 --- a/src/Umbraco.Cms.Api.Management/Mapping/Document/DocumentMapDefinition.cs +++ b/src/Umbraco.Cms.Api.Management/Mapping/Document/DocumentMapDefinition.cs @@ -32,6 +32,7 @@ public class DocumentMapDefinition : ContentMapDefinition Urls { get; set; } = Array.Empty(); public Guid? TemplateId { get; set; } + + public bool IsTrashed { get; set; } } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Document/Item/DocumentItemResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Document/Item/DocumentItemResponseModel.cs index 477c3503bd..10dab656be 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Document/Item/DocumentItemResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Document/Item/DocumentItemResponseModel.cs @@ -7,4 +7,6 @@ public class DocumentItemResponseModel : ItemResponseModelBase public string? Icon { get; set; } public Guid ContentTypeId { get; set; } + + public bool IsTrashed { get; set; } } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Media/MediaResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Media/MediaResponseModel.cs index 384e4e2895..e1f044e561 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Media/MediaResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Media/MediaResponseModel.cs @@ -5,4 +5,6 @@ namespace Umbraco.Cms.Api.Management.ViewModels.Media; public class MediaResponseModel : ContentResponseModelBase { public IEnumerable Urls { get; set; } = Array.Empty(); + + public bool IsTrashed { get; set; } } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Media/item/MediaItemResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Media/item/MediaItemResponseModel.cs index d638c3216c..6775bc1a91 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/Media/item/MediaItemResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/Media/item/MediaItemResponseModel.cs @@ -5,4 +5,6 @@ namespace Umbraco.Cms.Api.Management.ViewModels.Media.Item; public class MediaItemResponseModel : ItemResponseModelBase { public string? Icon { get; set; } + + public bool IsTrashed { get; set; } } diff --git a/src/Umbraco.Core/DeliveryApi/IApiContentQueryProvider.cs b/src/Umbraco.Core/DeliveryApi/IApiContentQueryProvider.cs index 1e49ae7ffa..748b031a12 100644 --- a/src/Umbraco.Core/DeliveryApi/IApiContentQueryProvider.cs +++ b/src/Umbraco.Core/DeliveryApi/IApiContentQueryProvider.cs @@ -8,16 +8,6 @@ namespace Umbraco.Cms.Core.DeliveryApi; /// public interface IApiContentQueryProvider { - [Obsolete($"Use the {nameof(ExecuteQuery)} method that accepts {nameof(ProtectedAccess)}. Will be removed in V14.")] - PagedModel ExecuteQuery( - SelectorOption selectorOption, - IList filterOptions, - IList sortOptions, - string culture, - bool preview, - int skip, - int take); - /// /// Returns a page of item ids that passed the search criteria. /// @@ -38,7 +28,7 @@ public interface IApiContentQueryProvider ProtectedAccess protectedAccess, bool preview, int skip, - int take) => new(); + int take); /// /// Returns a selector option that can be applied to fetch "all content" (i.e. if a selector option is not present when performing a search). diff --git a/src/Umbraco.Core/Mapping/IUmbracoMapper.cs b/src/Umbraco.Core/Mapping/IUmbracoMapper.cs index 5cbee7164c..4cfd976a12 100644 --- a/src/Umbraco.Core/Mapping/IUmbracoMapper.cs +++ b/src/Umbraco.Core/Mapping/IUmbracoMapper.cs @@ -30,7 +30,7 @@ public interface IUmbracoMapper /// /// The source type. /// The target type. - /// A constructor method. + /// A constructor method. Will not be used if the mapping call receives a Target object /// A mapping method. void Define( Func ctor, diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_14_0_0/AddGuidsToUserGroups.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_14_0_0/AddGuidsToUserGroups.cs index c481fc7694..32337f8f39 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_14_0_0/AddGuidsToUserGroups.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_14_0_0/AddGuidsToUserGroups.cs @@ -46,9 +46,13 @@ public class AddGuidsToUserGroups : UnscopedMigrationBase AddColumnIfNotExists(columns, NewColumnName); // We want specific keys for the default user groups, so we need to fetch the user groups again to set their keys. - IEnumerable updatedUserGroups = Database.Fetch() - .Select(x => x.Key = ResolveAliasToGuid(x.Alias)); - Database.Update(updatedUserGroups); + List? userGroups = Database.Fetch(); + + foreach (UserGroupDto userGroup in userGroups) + { + userGroup.Key = ResolveAliasToGuid(userGroup.Alias); + Database.Update(userGroup); + } scope.Complete(); } diff --git a/src/Umbraco.Web.BackOffice/Security/BackOfficeSecurityStampValidator.cs b/src/Umbraco.Web.BackOffice/Security/BackOfficeSecurityStampValidator.cs index 577dc8ce08..755367312f 100644 --- a/src/Umbraco.Web.BackOffice/Security/BackOfficeSecurityStampValidator.cs +++ b/src/Umbraco.Web.BackOffice/Security/BackOfficeSecurityStampValidator.cs @@ -13,8 +13,8 @@ public class BackOfficeSecurityStampValidator : SecurityStampValidator options, - BackOfficeSignInManager signInManager, ISystemClock clock, ILoggerFactory logger) - : base(options, signInManager, clock, logger) + BackOfficeSignInManager signInManager, ILoggerFactory logger) + : base(options, signInManager, logger) { } } diff --git a/src/Umbraco.Web.BackOffice/Security/BackOfficeSessionIdValidator.cs b/src/Umbraco.Web.BackOffice/Security/BackOfficeSessionIdValidator.cs index f0cb1beee5..5078b20d4a 100644 --- a/src/Umbraco.Web.BackOffice/Security/BackOfficeSessionIdValidator.cs +++ b/src/Umbraco.Web.BackOffice/Security/BackOfficeSessionIdValidator.cs @@ -35,15 +35,15 @@ public class BackOfficeSessionIdValidator { public const string CookieName = "UMB_UCONTEXT_C"; private readonly GlobalSettings _globalSettings; - private readonly ISystemClock _systemClock; + private readonly TimeProvider _timeProvider; private readonly IBackOfficeUserManager _userManager; /// /// Initializes a new instance of the class. /// - public BackOfficeSessionIdValidator(ISystemClock systemClock, IOptionsSnapshot globalSettings, IBackOfficeUserManager userManager) + public BackOfficeSessionIdValidator(TimeProvider timeProvider, IOptionsSnapshot globalSettings, IBackOfficeUserManager userManager) { - _systemClock = systemClock; + _timeProvider = timeProvider; _globalSettings = globalSettings.Value; _userManager = userManager; } @@ -55,7 +55,7 @@ public class BackOfficeSessionIdValidator return; } - var valid = await ValidateSessionAsync(validateInterval, context.HttpContext, context.Options.CookieManager, _systemClock, context.Properties.IssuedUtc, context.Principal?.Identity as ClaimsIdentity); + var valid = await ValidateSessionAsync(validateInterval, context.HttpContext, context.Options.CookieManager, _timeProvider, context.Properties.IssuedUtc, context.Principal?.Identity as ClaimsIdentity); if (valid == false) { @@ -68,7 +68,7 @@ public class BackOfficeSessionIdValidator TimeSpan validateInterval, HttpContext httpContext, ICookieManager cookieManager, - ISystemClock systemClock, + TimeProvider timeProvider, DateTimeOffset? authTicketIssueDate, ClaimsIdentity? currentIdentity) { @@ -82,9 +82,9 @@ public class BackOfficeSessionIdValidator throw new ArgumentNullException(nameof(cookieManager)); } - if (systemClock == null) + if (timeProvider == null) { - throw new ArgumentNullException(nameof(systemClock)); + throw new ArgumentNullException(nameof(timeProvider)); } if (currentIdentity == null) @@ -93,7 +93,7 @@ public class BackOfficeSessionIdValidator } DateTimeOffset? issuedUtc = null; - DateTimeOffset currentUtc = systemClock.UtcNow; + DateTimeOffset currentUtc = timeProvider.GetUtcNow(); // read the last checked time from a custom cookie var lastCheckedCookie = cookieManager.GetRequestCookie(httpContext, CookieName); diff --git a/src/Umbraco.Web.BackOffice/Security/ConfigureBackOfficeCookieOptions.cs b/src/Umbraco.Web.BackOffice/Security/ConfigureBackOfficeCookieOptions.cs index ae2312c67e..fea4d3b4a1 100644 --- a/src/Umbraco.Web.BackOffice/Security/ConfigureBackOfficeCookieOptions.cs +++ b/src/Umbraco.Web.BackOffice/Security/ConfigureBackOfficeCookieOptions.cs @@ -31,7 +31,7 @@ public class ConfigureBackOfficeCookieOptions : IConfigureNamedOptionsThe /// The /// The - /// The + /// The /// The /// The public ConfigureBackOfficeCookieOptions( @@ -61,7 +61,7 @@ public class ConfigureBackOfficeCookieOptions : IConfigureNamedOptions @@ -296,7 +296,7 @@ public class ConfigureBackOfficeCookieOptions : IConfigureNamedOptions options, - MemberSignInManager signInManager, ISystemClock clock, ILoggerFactory logger) - : base(options, signInManager, clock, logger) + MemberSignInManager signInManager, ILoggerFactory logger) + : base(options, signInManager, logger) { } diff --git a/tests/Umbraco.Tests.Integration/TestServerTest/TestAuthHandler.cs b/tests/Umbraco.Tests.Integration/TestServerTest/TestAuthHandler.cs index 5592d7eded..dd8bb3608a 100644 --- a/tests/Umbraco.Tests.Integration/TestServerTest/TestAuthHandler.cs +++ b/tests/Umbraco.Tests.Integration/TestServerTest/TestAuthHandler.cs @@ -27,11 +27,10 @@ public class TestAuthHandler : AuthenticationHandler options, ILoggerFactory logger, UrlEncoder encoder, - ISystemClock clock, IBackOfficeSignInManager backOfficeSignInManager, IUserService userService, IUmbracoMapper umbracoMapper) - : base(options, logger, encoder, clock) + : base(options, logger, encoder) { _backOfficeSignInManager = backOfficeSignInManager;