Merge remote-tracking branch 'origin/v12/dev' into v13/dev

# Conflicts:
#	src/Umbraco.Infrastructure/CompatibilitySuppressions.xml
#	tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/BlockGridEditor/Content/blockGridEditorAdvanced.spec.ts
This commit is contained in:
Bjarke Berg
2023-05-15 08:50:05 +02:00
18 changed files with 63 additions and 18 deletions

View File

@@ -29,7 +29,7 @@
<!-- Package Validation -->
<PropertyGroup>
<GenerateCompatibilitySuppressionFile>false</GenerateCompatibilitySuppressionFile>
<GenerateCompatibilitySuppressionFile>true</GenerateCompatibilitySuppressionFile>
<EnablePackageValidation>true</EnablePackageValidation>
<PackageValidationBaselineVersion>11.0.0</PackageValidationBaselineVersion>
<EnableStrictModeForCompatibleFrameworksInPackage>true</EnableStrictModeForCompatibleFrameworksInPackage>

View File

@@ -50,7 +50,7 @@ public class SqlServerDatabaseProviderMetadata : IDatabaseProviderMetadata
public bool RequiresConnectionTest => true;
/// <inheritdoc />
public bool ForceCreateDatabase => false;
public bool ForceCreateDatabase => true;
/// <inheritdoc />
public bool CanRecognizeConnectionString(string? connectionString)

View File

@@ -6,6 +6,7 @@ namespace Umbraco.Cms.Core.Actions;
/// <summary>
/// This action is invoked when children to a document is being sent to published (by an editor without publishrights).
/// </summary>
[Obsolete("Scheduled for removal in v13")]
public class ActionToPublish : IAction
{
/// <inheritdoc cref="IAction.ActionLetter"/>

View File

@@ -107,6 +107,7 @@ public sealed class UserNotificationsHandler :
_notifier.Notify(_actions.GetAction<ActionUpdate>(), updatedEntities.ToArray());
}
[Obsolete("Scheduled for removal in v13")]
public void Handle(ContentSentToPublishNotification notification) =>
_notifier.Notify(_actions.GetAction<ActionToPublish>(), notification.Entity);

View File

@@ -7,7 +7,15 @@ namespace Umbraco.Cms.Core.Models.PublishedContent;
/// <para>This is for tests etc - does not implement fallback at all.</para>
/// </remarks>
public class NoopPublishedValueFallback : IPublishedValueFallback
{
/// <inheritdoc />
public IVariationContextAccessor VariationContextAccessor
{
get => new ThreadCultureVariationContextAccessor();
set { }
}
/// <inheritdoc />
public bool TryGetValue(IPublishedProperty property, string? culture, string? segment, Fallback fallback, object? defaultValue, out object? value)
{

View File

@@ -122,7 +122,7 @@ public class MediaPickerValueConverter : PropertyValueConverterBase, IDeliveryAp
return source;
}
public PropertyCacheLevel GetDeliveryApiPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Element;
public PropertyCacheLevel GetDeliveryApiPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Elements;
public Type GetDeliveryApiPropertyValueType(IPublishedPropertyType propertyType) => typeof(IEnumerable<IApiMedia>);

View File

@@ -60,7 +60,7 @@ public class MetricsConsentService : IMetricsConsentService
if (analyticsLevelString is null ||
Enum.TryParse(analyticsLevelString, out TelemetryLevel analyticsLevel) is false)
{
return TelemetryLevel.Basic;
return TelemetryLevel.Detailed;
}
return analyticsLevel;

View File

@@ -38,7 +38,7 @@ internal abstract class NestedPropertyIndexValueFactoryBase<TSerialized, TItem>
var propertyTypeDictionary =
contentType
.PropertyGroups
.CompositionPropertyGroups
.SelectMany(x => x.PropertyTypes!)
.Select(propertyType =>
{

View File

@@ -1,7 +1,9 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Core.DeliveryApi;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Logging;
using Umbraco.Cms.Core.Models.Blocks;
using Umbraco.Cms.Core.Models.DeliveryApi;
@@ -20,9 +22,20 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters
private readonly IJsonSerializer _jsonSerializer;
private readonly IApiElementBuilder _apiElementBuilder;
[Obsolete("Please use non-obsolete cconstrutor. This will be removed in Umbraco 14.")]
public BlockGridPropertyValueConverter(
IProfilingLogger proflog,
BlockEditorConverter blockConverter,
IJsonSerializer jsonSerializer)
: this(proflog, blockConverter, jsonSerializer, StaticServiceProvider.Instance.GetRequiredService<IApiElementBuilder>())
{
}
// Niels, Change: I would love if this could be general, so we don't need a specific one for each block property editor....
public BlockGridPropertyValueConverter(
IProfilingLogger proflog, BlockEditorConverter blockConverter,
IProfilingLogger proflog,
BlockEditorConverter blockConverter,
IJsonSerializer jsonSerializer,
IApiElementBuilder apiElementBuilder)
: base(blockConverter)

View File

@@ -120,7 +120,7 @@ public class MediaPickerWithCropsValueConverter : PropertyValueConverterBase, ID
return isMultiple ? mediaItems : mediaItems.FirstOrDefault();
}
public PropertyCacheLevel GetDeliveryApiPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Element;
public PropertyCacheLevel GetDeliveryApiPropertyCacheLevel(IPublishedPropertyType propertyType) => PropertyCacheLevel.Elements;
public Type GetDeliveryApiPropertyValueType(IPublishedPropertyType propertyType) => typeof(IEnumerable<ApiMediaWithCrops>);

View File

@@ -8,5 +8,5 @@ public class InstallData
public DatabaseInstallData Database { get; set; } = null!;
public TelemetryLevel TelemetryLevel { get; set; } = TelemetryLevel.Basic;
public TelemetryLevel TelemetryLevel { get; set; } = TelemetryLevel.Detailed;
}

View File

@@ -278,7 +278,7 @@ public class CurrentUserController : UmbracoAuthorizedJsonController
// all current users have access to reset/manually change their password
Attempt<PasswordChangedModel?> passwordChangeResult =
await _passwordChanger.ChangePasswordWithIdentityAsync(changingPasswordModel, _backOfficeUserManager);
await _passwordChanger.ChangePasswordWithIdentityAsync(changingPasswordModel, _backOfficeUserManager, currentUser);
if (passwordChangeResult.Success)
{

View File

@@ -623,7 +623,7 @@ public class MemberController : ContentControllerBase
// Change and persist the password
Attempt<PasswordChangedModel?> passwordChangeResult =
await _passwordChanger.ChangePasswordWithIdentityAsync(changingPasswordModel, _memberManager);
await _passwordChanger.ChangePasswordWithIdentityAsync(changingPasswordModel, _memberManager, _backOfficeSecurityAccessor.BackOfficeSecurity?.CurrentUser);
if (!passwordChangeResult.Success)
{

View File

@@ -759,7 +759,7 @@ public class UsersController : BackOfficeNotificationsController
}
Attempt<PasswordChangedModel?> passwordChangeResult =
await _passwordChanger.ChangePasswordWithIdentityAsync(changingPasswordModel, _userManager);
await _passwordChanger.ChangePasswordWithIdentityAsync(changingPasswordModel, _userManager, currentUser);
if (passwordChangeResult.Success)
{

View File

@@ -1,12 +1,19 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Membership;
using Umbraco.Cms.Core.Security;
namespace Umbraco.Cms.Web.Common.Security;
public interface IPasswordChanger<TUser> where TUser : UmbracoIdentityUser
{
[Obsolete("Please use method that also takes a nullable IUser, scheduled for removal in v13")]
public Task<Attempt<PasswordChangedModel?>> ChangePasswordWithIdentityAsync(
ChangingPasswordModel passwordModel,
IUmbracoUserManager<TUser> userMgr);
public Task<Attempt<PasswordChangedModel?>> ChangePasswordWithIdentityAsync(
ChangingPasswordModel passwordModel,
IUmbracoUserManager<TUser> userMgr,
IUser? currentUser) => ChangePasswordWithIdentityAsync(passwordModel, userMgr);
}

View File

@@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Membership;
using Umbraco.Cms.Core.Security;
using Umbraco.Extensions;
@@ -22,16 +23,20 @@ internal class PasswordChanger<TUser> : IPasswordChanger<TUser> where TUser : Um
/// <param name="logger">Logger for this class</param>
public PasswordChanger(ILogger<PasswordChanger<TUser>> logger) => _logger = logger;
public Task<Attempt<PasswordChangedModel?>> ChangePasswordWithIdentityAsync(ChangingPasswordModel passwordModel, IUmbracoUserManager<TUser> userMgr) => ChangePasswordWithIdentityAsync(passwordModel, userMgr, null);
/// <summary>
/// Changes the password for a user based on the many different rules and config options
/// </summary>
/// <param name="changingPasswordModel">The changing password model</param>
/// <param name="userMgr">The identity manager to use to update the password</param>
/// <param name="changingPasswordModel">The changing password model.</param>
/// <param name="userMgr">The identity manager to use to update the password.</param>
/// <param name="currentUser">The user performing the operation.</param>
/// Create an adapter to pass through everything - adapting the member into a user for this functionality
/// <returns>The outcome of the password changed model</returns>
public async Task<Attempt<PasswordChangedModel?>> ChangePasswordWithIdentityAsync(
ChangingPasswordModel changingPasswordModel,
IUmbracoUserManager<TUser> userMgr)
IUmbracoUserManager<TUser> userMgr,
IUser? currentUser)
{
if (changingPasswordModel == null)
{
@@ -65,6 +70,14 @@ internal class PasswordChanger<TUser> : IPasswordChanger<TUser> where TUser : Um
// Are we just changing another user/member's password?
if (changingPasswordModel.OldPassword.IsNullOrWhiteSpace())
{
if (changingPasswordModel.Id == currentUser?.Id)
{
return Attempt.Fail(new PasswordChangedModel
{
ChangeError = new ValidationResult("Cannot change the password of current user without the old password", new[] { "value" }),
});
}
// ok, we should be able to reset it
var resetToken = await userMgr.GeneratePasswordResetTokenAsync(identityUser);

View File

@@ -81,7 +81,7 @@ public class TelemetryServiceTests
};
var packageManifestService = CreatePackageManifestService(manifests);
var metricsConsentService = new Mock<IMetricsConsentService>();
metricsConsentService.Setup(x => x.GetConsentLevel()).Returns(TelemetryLevel.Basic);
metricsConsentService.Setup(x => x.GetConsentLevel()).Returns(TelemetryLevel.Detailed);
var sut = new TelemetryService(
version,
CreateSiteIdentifierService(),
@@ -116,7 +116,7 @@ public class TelemetryServiceTests
};
var packageManifestService = CreatePackageManifestService(manifests);
var metricsConsentService = new Mock<IMetricsConsentService>();
metricsConsentService.Setup(x => x.GetConsentLevel()).Returns(TelemetryLevel.Basic);
metricsConsentService.Setup(x => x.GetConsentLevel()).Returns(TelemetryLevel.Detailed);
var sut = new TelemetryService(
version,
CreateSiteIdentifierService(),

View File

@@ -358,7 +358,8 @@ public class MemberControllerUnitTests
Mock.Get(passwordChanger)
.Setup(x => x.ChangePasswordWithIdentityAsync(
It.IsAny<ChangingPasswordModel>(),
umbracoMembersUserManager))
umbracoMembersUserManager,
null))
.ReturnsAsync(() => attempt);
}
else
@@ -367,7 +368,8 @@ public class MemberControllerUnitTests
Mock.Get(passwordChanger)
.Setup(x => x.ChangePasswordWithIdentityAsync(
It.IsAny<ChangingPasswordModel>(),
umbracoMembersUserManager))
umbracoMembersUserManager,
null))
.ReturnsAsync(() => attempt);
}
}