From 443f03688e4661ed23b22b0d564e8b90563ef40f Mon Sep 17 00:00:00 2001 From: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> Date: Wed, 11 Oct 2023 10:46:25 +0200 Subject: [PATCH 1/7] Fix update to update foreach Group (#14945) --- .../Upgrade/V_14_0_0/AddGuidsToUserGroups.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) 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(); } From 517e0e9d19b2cbf8d6daaffa0d2debeb7fe4549a Mon Sep 17 00:00:00 2001 From: Elitsa Marinovska <21998037+elit0451@users.noreply.github.com> Date: Wed, 11 Oct 2023 14:15:08 +0200 Subject: [PATCH 2/7] Removing dev certificates and adding enc and signing keys that are required by OpenIddict but won't be used when we calling UseDataProtection() (#14958) --- .../UmbracoBuilderAuthExtensions.cs | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Cms.Api.Common/DependencyInjection/UmbracoBuilderAuthExtensions.cs b/src/Umbraco.Cms.Api.Common/DependencyInjection/UmbracoBuilderAuthExtensions.cs index c315d545c0..233630107d 100644 --- a/src/Umbraco.Cms.Api.Common/DependencyInjection/UmbracoBuilderAuthExtensions.cs +++ b/src/Umbraco.Cms.Api.Common/DependencyInjection/UmbracoBuilderAuthExtensions.cs @@ -1,4 +1,6 @@ +using System.Security.Cryptography; using Microsoft.Extensions.DependencyInjection; +using Microsoft.IdentityModel.Tokens; using Umbraco.Cms.Api.Common.Security; using Umbraco.Cms.Core; using Umbraco.Cms.Core.DependencyInjection; @@ -50,14 +52,6 @@ public static class UmbracoBuilderAuthExtensions .RequireProofKeyForCodeExchange() .AllowRefreshTokenFlow(); - // Register the encryption and signing credentials. - // - see https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html - options - // TODO: use actual certificates here, see docs above - .AddDevelopmentEncryptionCertificate() - .AddDevelopmentSigningCertificate() - .DisableAccessTokenEncryption(); - // Register the ASP.NET Core host and configure for custom authentication endpoint. options .UseAspNetCore() @@ -79,6 +73,19 @@ public static class UmbracoBuilderAuthExtensions // and https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview?view=aspnetcore-7.0 // for more information options.UseDataProtection(); + + // Register encryption and signing credentials to protect tokens. + // Note that for tokens generated/validated using ASP.NET Core Data Protection, + // a separate key ring is used, distinct from the credentials discussed in + // https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html + // More details can be found here: https://github.com/openiddict/openiddict-core/issues/1892#issuecomment-1737308506 + // "When using ASP.NET Core Data Protection to generate opaque tokens, the signing and encryption credentials + // registered via Add*Key/Certificate() are not used". But since OpenIddict requires the registration of such, + // we can generate random keys per instance without them taking effect. + // - see also https://github.com/openiddict/openiddict-core/issues/1231 + options + .AddEncryptionKey(new SymmetricSecurityKey(RandomNumberGenerator.GetBytes(32))) // generate a cryptographically secure random 256-bits key + .AddSigningKey(new RsaSecurityKey(RSA.Create(keySizeInBits: 2048))); // generate RSA key with recommended size of 2048-bits }) // Register the OpenIddict validation components. From 6fb2550690f55efa0064f4de6e0039d33234370c Mon Sep 17 00:00:00 2001 From: Sven Geusens Date: Thu, 12 Oct 2023 07:00:06 +0200 Subject: [PATCH 3/7] V14/feature/response model trash tracking (#14948) * Clearify UmbracoMapper functionality trough comment * Add trash tracking to doc/media(item) response models * Add mapping for ITracksTrashing * Removed uneccesary abstraction and seperation * Cleanup after removing abstractions * Cleanup unused DI item * Clean up and formatting --------- Co-authored-by: Sven Geusens Co-authored-by: kjac --- .../Factories/DocumentPresentationFactory.cs | 2 +- .../Mapping/Document/DocumentMapDefinition.cs | 1 + .../Mapping/Items/ItemTypeMapDefinition.cs | 1 + .../Mapping/Media/MediaMapDefinition.cs | 1 + .../ViewModels/Document/DocumentResponseModel.cs | 2 ++ .../ViewModels/Document/Item/DocumentItemResponseModel.cs | 2 ++ .../ViewModels/Media/MediaResponseModel.cs | 2 ++ .../ViewModels/Media/item/MediaItemResponseModel.cs | 2 ++ src/Umbraco.Core/Mapping/IUmbracoMapper.cs | 2 +- 9 files changed, 13 insertions(+), 2 deletions(-) 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/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, From ace8d801836fdc74b34493e5c124fc6b0647735c Mon Sep 17 00:00:00 2001 From: Andreas Zerbst <73799582+andr317c@users.noreply.github.com> Date: Thu, 12 Oct 2023 13:58:51 +0200 Subject: [PATCH 4/7] Refactored from ISystemClock to TimeProvider (#14963) * Removed obsolete ISystemClock. The SecurityStampValidator provides the TimeProvider. * Removed obsolete ISystemClock. * Refactored obsolete ISystemClock with TimeProvider --- .../Security/BackOfficeSecurityStampValidator.cs | 4 ++-- .../Security/BackOfficeSessionIdValidator.cs | 16 ++++++++-------- .../Security/ConfigureBackOfficeCookieOptions.cs | 14 +++++++------- .../Security/MemberSecurityStampValidator.cs | 4 ++-- .../TestServerTest/TestAuthHandler.cs | 3 +-- 5 files changed, 20 insertions(+), 21 deletions(-) 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; From ebc6e38b861e7a3238196433f08ff34e867635a9 Mon Sep 17 00:00:00 2001 From: Ronald Barendse Date: Mon, 23 Oct 2023 11:17:40 +0200 Subject: [PATCH 5/7] Ensure PackageVersion is set correctly before transforming template.json (cherry picked from commit 0170ecaec11a064bcb86e6a264e0024e733a4a7d) (cherry picked from commit 69c1bcec3a5ad92aa4cfc69346919f75c8ba3daa) --- templates/Umbraco.Templates.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/Umbraco.Templates.csproj b/templates/Umbraco.Templates.csproj index 4dd074da79..452095c8db 100644 --- a/templates/Umbraco.Templates.csproj +++ b/templates/Umbraco.Templates.csproj @@ -49,7 +49,7 @@ - + <_TemplateJsonFiles Include="**\.template.config\template.json" Exclude="bin\**;obj\**" /> <_TemplateJsonFiles> From 37082ac53d0af89f0f75957c5bb0695296934f5a Mon Sep 17 00:00:00 2001 From: kjac Date: Mon, 23 Oct 2023 14:00:33 +0200 Subject: [PATCH 6/7] Remove duplicate reference to Core (cherry picked from commit 304a64be5a807c5515b0da4039d3ebd59635358e) --- tools/Umbraco.JsonSchema/Umbraco.JsonSchema.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/Umbraco.JsonSchema/Umbraco.JsonSchema.csproj b/tools/Umbraco.JsonSchema/Umbraco.JsonSchema.csproj index 90f301b2a1..c9275c6b94 100644 --- a/tools/Umbraco.JsonSchema/Umbraco.JsonSchema.csproj +++ b/tools/Umbraco.JsonSchema/Umbraco.JsonSchema.csproj @@ -12,6 +12,5 @@ - From b7a1cd5ab47533cf8bb776bf0db396e83d56268e Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Tue, 24 Oct 2023 10:08:28 +0200 Subject: [PATCH 7/7] Cleaned up V14 TODOs from ContentApiItemControllerBase (#15026) --- .../Content/ContentApiItemControllerBase.cs | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) 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) {