Merge branch 'v9/feature/move-templates-to-root' into v9/feature/projecttemplate-cleanup

This commit is contained in:
Ronald Barendse
2022-03-24 13:57:38 +01:00
240 changed files with 6657 additions and 2656 deletions

View File

@@ -1,6 +1,7 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System;
using Microsoft.Extensions.Options;
using NUnit.Framework;
using Umbraco.Cms.Core.Configuration.Models;
@@ -15,7 +16,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Configuration.Models.Validati
public void Returns_Success_ForValid_Configuration()
{
var validator = new GlobalSettingsValidator();
GlobalSettings options = BuildGlobalSettings();
var options = new GlobalSettings();
ValidateOptionsResult result = validator.Validate("settings", options);
Assert.True(result.Succeeded);
}
@@ -24,18 +25,55 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Configuration.Models.Validati
public void Returns_Fail_For_Configuration_With_Invalid_SmtpFrom_Field()
{
var validator = new GlobalSettingsValidator();
GlobalSettings options = BuildGlobalSettings(smtpEmail: "invalid");
var options = new GlobalSettings
{
Smtp = new SmtpSettings
{
From = "invalid",
}
};
ValidateOptionsResult result = validator.Validate("settings", options);
Assert.False(result.Succeeded);
}
private static GlobalSettings BuildGlobalSettings(string smtpEmail = "test@test.com") =>
new GlobalSettings
[Test]
public void Returns_Fail_For_Configuration_With_Insufficient_SqlWriteLockTimeOut()
{
var validator = new GlobalSettingsValidator();
var options = new GlobalSettings
{
Smtp = new SmtpSettings
{
From = smtpEmail,
}
SqlWriteLockTimeOut = TimeSpan.Parse("00:00:00.099")
};
ValidateOptionsResult result = validator.Validate("settings", options);
Assert.False(result.Succeeded);
}
[Test]
public void Returns_Fail_For_Configuration_With_Excessive_SqlWriteLockTimeOut()
{
var validator = new GlobalSettingsValidator();
var options = new GlobalSettings
{
SqlWriteLockTimeOut = TimeSpan.Parse("00:00:21")
};
ValidateOptionsResult result = validator.Validate("settings", options);
Assert.False(result.Succeeded);
}
[Test]
public void Returns_Success_For_Configuration_With_Valid_SqlWriteLockTimeOut()
{
var validator = new GlobalSettingsValidator();
var options = new GlobalSettings
{
SqlWriteLockTimeOut = TimeSpan.Parse("00:00:20")
};
ValidateOptionsResult result = validator.Validate("settings", options);
Assert.True(result.Succeeded);
}
}
}

View File

@@ -0,0 +1,105 @@
using System.Linq;
using NUnit.Framework;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Tests.Common.Builders;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Models
{
[TestFixture]
public class ContentTypeHistoryCleanupTests
{
[Test]
public void Changing_Keep_all_Makes_ContentType_Dirty()
{
var contentType = ContentTypeBuilder.CreateBasicContentType();
Assert.IsFalse(contentType.IsDirty());
var newValue = 2;
contentType.HistoryCleanup.KeepAllVersionsNewerThanDays = newValue;
Assert.IsTrue(contentType.IsDirty());
Assert.AreEqual(newValue, contentType.HistoryCleanup.KeepAllVersionsNewerThanDays);
}
[Test]
public void Changing_Keep_latest_Makes_ContentType_Dirty()
{
var contentType = ContentTypeBuilder.CreateBasicContentType();
Assert.IsFalse(contentType.IsDirty());
var newValue = 2;
contentType.HistoryCleanup.KeepLatestVersionPerDayForDays = newValue;
Assert.IsTrue(contentType.IsDirty());
Assert.AreEqual(newValue, contentType.HistoryCleanup.KeepLatestVersionPerDayForDays);
}
[Test]
public void Changing_Prevent_Cleanup_Makes_ContentType_Dirty()
{
var contentType = ContentTypeBuilder.CreateBasicContentType();
Assert.IsFalse(contentType.IsDirty());
var newValue = true;
contentType.HistoryCleanup.PreventCleanup = newValue;
Assert.IsTrue(contentType.IsDirty());
Assert.AreEqual(newValue, contentType.HistoryCleanup.PreventCleanup);
}
[Test]
public void Replacing_History_Cleanup_Registers_As_Dirty()
{
var contentType = ContentTypeBuilder.CreateBasicContentType();
Assert.IsFalse(contentType.IsDirty());
contentType.HistoryCleanup = new HistoryCleanup();
Assert.IsTrue(contentType.IsDirty());
Assert.IsTrue(contentType.IsPropertyDirty(nameof(contentType.HistoryCleanup)));
}
[Test]
public void Replacing_History_Cleanup_Removes_Old_Dirty_History_Properties()
{
var contentType = ContentTypeBuilder.CreateBasicContentType();
contentType.Alias = "NewValue";
contentType.HistoryCleanup.KeepAllVersionsNewerThanDays = 2;
contentType.PropertyChanged += (sender, args) =>
{
// Ensure that property changed is only invoked for history cleanup
Assert.AreEqual(nameof(contentType.HistoryCleanup), args.PropertyName);
};
// Since we're replacing the entire HistoryCleanup the changed property is no longer dirty, the entire HistoryCleanup is
contentType.HistoryCleanup = new HistoryCleanup();
Assert.Multiple(() =>
{
Assert.IsTrue(contentType.IsDirty());
Assert.IsFalse(contentType.WasDirty());
Assert.AreEqual(2, contentType.GetDirtyProperties().Count());
Assert.IsTrue(contentType.IsPropertyDirty(nameof(contentType.HistoryCleanup)));
Assert.IsTrue(contentType.IsPropertyDirty(nameof(contentType.Alias)));
});
}
[Test]
public void Old_History_Cleanup_Reference_Doesnt_Make_Content_Type_Dirty()
{
var contentType = ContentTypeBuilder.CreateBasicContentType();
var oldHistoryCleanup = contentType.HistoryCleanup;
contentType.HistoryCleanup = new HistoryCleanup();
contentType.ResetDirtyProperties();
contentType.ResetWereDirtyProperties();
oldHistoryCleanup.KeepAllVersionsNewerThanDays = 2;
Assert.IsFalse(contentType.IsDirty());
Assert.IsFalse(contentType.WasDirty());
}
}
}

View File

@@ -1,10 +1,14 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System;
using System.Security.Cryptography;
using System.Text;
using Moq;
using NUnit.Framework;
using Umbraco.Cms.Core.Configuration;
using Umbraco.Cms.Core.Security;
using Umbraco.Extensions;
using Constants = Umbraco.Cms.Core.Constants;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Security
@@ -15,7 +19,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Security
[Test]
public void Check_Password_Hashed_Non_KeyedHashAlgorithm()
{
IPasswordConfiguration passwordConfiguration = Mock.Of<IPasswordConfiguration>(x => x.HashAlgorithmType == "SHA256");
IPasswordConfiguration passwordConfiguration = Mock.Of<IPasswordConfiguration>(x => x.HashAlgorithmType == "SHA1");
var passwordSecurity = new LegacyPasswordSecurity();
var pass = "ThisIsAHashedPassword";
@@ -45,14 +49,12 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Security
[Test]
public void Check_Password_Legacy_v4_SHA1()
{
IPasswordConfiguration passwordConfiguration = Mock.Of<IPasswordConfiguration>(x => x.HashAlgorithmType == Constants.Security.AspNetUmbraco4PasswordHashAlgorithmName);
var passwordSecurity = new LegacyPasswordSecurity();
const string clearText = "ThisIsAHashedPassword";
var clearTextUnicodeBytes = Encoding.Unicode.GetBytes(clearText);
using var algorithm = new HMACSHA1(clearTextUnicodeBytes);
var dbPassword = Convert.ToBase64String(algorithm.ComputeHash(clearTextUnicodeBytes));
var pass = "ThisIsAHashedPassword";
var hashed = passwordSecurity.HashNewPassword(passwordConfiguration.HashAlgorithmType, pass, out string salt);
var storedPassword = passwordSecurity.FormatPasswordForStorage(passwordConfiguration.HashAlgorithmType, hashed, salt);
var result = passwordSecurity.VerifyPassword(passwordConfiguration.HashAlgorithmType, "ThisIsAHashedPassword", storedPassword);
var result = new LegacyPasswordSecurity().VerifyLegacyHashedPassword(clearText, dbPassword);
Assert.IsTrue(result);
}

View File

@@ -0,0 +1,77 @@
using System;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Moq;
using NUnit.Framework;
using Umbraco.Cms.Core.Configuration;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Telemetry;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Telemetry
{
[TestFixture]
public class SiteIdentifierServiceTests
{
[TestCase("0F1785C5-7BA0-4C52-AB62-863BD2C8F3FE", true)]
[TestCase("This is not a guid", false)]
[TestCase("", false)]
[TestCase("00000000-0000-0000-0000-000000000000", false)] // Don't count empty GUID as valid
public void TryGetOnlyPassesIfValidId(string guidString, bool shouldSucceed)
{
var globalSettings = CreateGlobalSettings(guidString);
var sut = new SiteIdentifierService(
globalSettings,
Mock.Of<IConfigManipulator>(),
Mock.Of<ILogger<SiteIdentifierService>>());
var result = sut.TryGetSiteIdentifier(out var siteIdentifier);
Assert.AreEqual(shouldSucceed, result);
if (shouldSucceed)
{
// When toString is called on a GUID it will to lower, so do the same to our guidString
Assert.AreEqual(guidString.ToLower(), siteIdentifier.ToString());
}
else
{
Assert.AreEqual(Guid.Empty, siteIdentifier);
}
}
[TestCase("0F1785C5-7BA0-4C52-AB62-863BD2C8F3FE", false)]
[TestCase("This is not a guid", true)]
[TestCase("", true)]
[TestCase("00000000-0000-0000-0000-000000000000", true)] // Don't count empty GUID as valid
public void TryGetOrCreateOnlyCreatesNewGuidIfCurrentIsMissingOrInvalid(string guidString, bool shouldCreate)
{
var globalSettings = CreateGlobalSettings(guidString);
var configManipulatorMock = new Mock<IConfigManipulator>();
var sut = new SiteIdentifierService(
globalSettings,
configManipulatorMock.Object,
Mock.Of<ILogger<SiteIdentifierService>>());
var result = sut.TryGetOrCreateSiteIdentifier(out var identifier);
if (shouldCreate)
{
configManipulatorMock.Verify(x => x.SetGlobalId(It.IsAny<string>()), Times.Once);
Assert.AreNotEqual(Guid.Empty, identifier);
Assert.IsTrue(result);
}
else
{
configManipulatorMock.Verify(x => x.SetGlobalId(It.IsAny<string>()), Times.Never());
Assert.AreEqual(guidString.ToLower(), identifier.ToString());
Assert.IsTrue(result);
}
}
private IOptionsMonitor<GlobalSettings> CreateGlobalSettings(string guidString)
{
var globalSettings = new GlobalSettings { Id = guidString };
return Mock.Of<IOptionsMonitor<GlobalSettings>>(x => x.CurrentValue == globalSettings);
}
}
}

View File

@@ -15,36 +15,36 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Telemetry
[TestFixture]
public class TelemetryServiceTests
{
[TestCase("0F1785C5-7BA0-4C52-AB62-863BD2C8F3FE", true)]
[TestCase("This is not a guid", false)]
[TestCase("", false)]
public void OnlyParsesIfValidId(string guidString, bool shouldSucceed)
[Test]
public void UsesGetOrCreateSiteId()
{
var globalSettings = CreateGlobalSettings(guidString);
var version = CreateUmbracoVersion(9, 1, 1);
var sut = new TelemetryService(globalSettings, Mock.Of<IManifestParser>(), version);
var version = CreateUmbracoVersion(9, 3, 1);
var siteIdentifierServiceMock = new Mock<ISiteIdentifierService>();
var sut = new TelemetryService(Mock.Of<IManifestParser>(), version, siteIdentifierServiceMock.Object);
Guid guid;
var result = sut.TryGetTelemetryReportData(out var telemetryReportData);
siteIdentifierServiceMock.Verify(x => x.TryGetOrCreateSiteIdentifier(out guid), Times.Once);
}
[Test]
public void SkipsIfCantGetOrCreateId()
{
var version = CreateUmbracoVersion(9, 3, 1);
var sut = new TelemetryService(Mock.Of<IManifestParser>(), version, createSiteIdentifierService(false));
var result = sut.TryGetTelemetryReportData(out var telemetry);
Assert.AreEqual(shouldSucceed, result);
if (shouldSucceed)
{
// When toString is called on a GUID it will to lower, so do the same to our guidString
Assert.AreEqual(guidString.ToLower(), telemetry.Id.ToString());
}
else
{
Assert.IsNull(telemetry);
}
Assert.IsFalse(result);
Assert.IsNull(telemetry);
}
[Test]
public void ReturnsSemanticVersionWithoutBuild()
{
var globalSettings = CreateGlobalSettings();
var version = CreateUmbracoVersion(9, 1, 1, "-rc", "-ad2f4k2d");
var sut = new TelemetryService(globalSettings, Mock.Of<IManifestParser>(), version);
var sut = new TelemetryService(Mock.Of<IManifestParser>(), version, createSiteIdentifierService());
var result = sut.TryGetTelemetryReportData(out var telemetry);
@@ -55,7 +55,6 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Telemetry
[Test]
public void CanGatherPackageTelemetry()
{
var globalSettings = CreateGlobalSettings();
var version = CreateUmbracoVersion(9, 1, 1);
var versionPackageName = "VersionPackage";
var packageVersion = "1.0.0";
@@ -66,7 +65,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Telemetry
new () { PackageName = noVersionPackageName }
};
var manifestParser = CreateManifestParser(manifests);
var sut = new TelemetryService(globalSettings, manifestParser, version);
var sut = new TelemetryService(manifestParser, version, createSiteIdentifierService());
var success = sut.TryGetTelemetryReportData(out var telemetry);
@@ -87,15 +86,14 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Telemetry
[Test]
public void RespectsAllowPackageTelemetry()
{
var globalSettings = CreateGlobalSettings();
var version = CreateUmbracoVersion(9, 1, 1);
PackageManifest[] manifests =
{
new () { PackageName = "DoNotTrack", AllowPackageTelemetry = false },
new () { PackageName = "TrackingAllowed", AllowPackageTelemetry = true }
new () { PackageName = "TrackingAllowed", AllowPackageTelemetry = true },
};
var manifestParser = CreateManifestParser(manifests);
var sut = new TelemetryService(globalSettings, manifestParser, version);
var sut = new TelemetryService(manifestParser, version, createSiteIdentifierService());
var success = sut.TryGetTelemetryReportData(out var telemetry);
@@ -121,15 +119,12 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Telemetry
return Mock.Of<IUmbracoVersion>(x => x.SemanticVersion == version);
}
private IOptionsMonitor<GlobalSettings> CreateGlobalSettings(string guidString = null)
private ISiteIdentifierService createSiteIdentifierService(bool shouldSucceed = true)
{
if (guidString is null)
{
guidString = Guid.NewGuid().ToString();
}
var globalSettings = new GlobalSettings { Id = guidString };
return Mock.Of<IOptionsMonitor<GlobalSettings>>(x => x.CurrentValue == globalSettings);
var mock = new Mock<ISiteIdentifierService>();
var siteIdentifier = shouldSucceed ? Guid.NewGuid() : Guid.Empty;
mock.Setup(x => x.TryGetOrCreateSiteIdentifier(out siteIdentifier)).Returns(shouldSucceed);
return mock.Object;
}
}
}

View File

@@ -2,12 +2,15 @@
// See LICENSE for more details.
using System;
using System.Data;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Moq;
using NUnit.Framework;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Runtime;
using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Sync;
@@ -108,6 +111,11 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.HostedServices
var mockServerMessenger = new Mock<IServerMessenger>();
var mockScopeProvider = new Mock<IScopeProvider>();
mockScopeProvider
.Setup(x => x.CreateScope(It.IsAny<IsolationLevel>(), It.IsAny<RepositoryCacheMode>(), It.IsAny<IEventDispatcher>(), It.IsAny<IScopedNotificationPublisher>(), It.IsAny<bool?>(), It.IsAny<bool>(), It.IsAny<bool>()))
.Returns(Mock.Of<IScope>());
return new ScheduledPublishing(
mockRunTimeState.Object,
mockMainDom.Object,
@@ -115,7 +123,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.HostedServices
_mockContentService.Object,
mockUmbracoContextFactory.Object,
_mockLogger.Object,
mockServerMessenger.Object);
mockServerMessenger.Object,
mockScopeProvider.Object);
}
private void VerifyScheduledPublishingNotPerformed() => VerifyScheduledPublishingPerformed(Times.Never());

View File

@@ -0,0 +1,47 @@
using AutoFixture.NUnit3;
using Microsoft.Extensions.Options;
using NUnit.Framework;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Infrastructure.Runtime;
using Umbraco.Cms.Tests.UnitTests.AutoFixture;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Runtime
{
[TestFixture]
internal class DefaultMainDomKeyGeneratorTests
{
[Test]
[AutoMoqData]
public void GenerateKey_WithConfiguredDiscriminatorValue_AltersHash(
[Frozen] IHostingEnvironment hostingEnvironment,
[Frozen] GlobalSettings globalSettings,
[Frozen] IOptionsMonitor<GlobalSettings> globalSettingsMonitor,
DefaultMainDomKeyGenerator sut,
string aDiscriminator)
{
var withoutDiscriminator = sut.GenerateKey();
globalSettings.MainDomKeyDiscriminator = aDiscriminator;
var withDiscriminator = sut.GenerateKey();
Assert.AreNotEqual(withoutDiscriminator, withDiscriminator);
}
[Test]
[AutoMoqData]
public void GenerateKey_WithUnchangedDiscriminatorValue_ReturnsSameValue(
[Frozen] IHostingEnvironment hostingEnvironment,
[Frozen] GlobalSettings globalSettings,
[Frozen] IOptionsMonitor<GlobalSettings> globalSettingsMonitor,
DefaultMainDomKeyGenerator sut,
string aDiscriminator)
{
globalSettings.MainDomKeyDiscriminator = aDiscriminator;
var a = sut.GenerateKey();
var b = sut.GenerateKey();
Assert.AreEqual(a, b);
}
}
}

View File

@@ -0,0 +1,127 @@
using System;
using System.Security.Cryptography;
using System.Text;
using AutoFixture.NUnit3;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Moq;
using NUnit.Framework;
using Umbraco.Cms.Core.Models.Membership;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.Tests.UnitTests.AutoFixture;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Security
{
[TestFixture]
public class UmbracoPasswordHasherTests
{
// Technically MD5, HMACSHA384 & HMACSHA512 were also possible but opt in as opposed to historic defaults.
[Test]
[InlineAutoMoqData("HMACSHA256", "Umbraco9Rocks!", "uB/pLEhhe1W7EtWMv/pSgg==1y8+aso9+h3AKRtJXlVYeg2TZKJUr64hccj82ZZ7Ksk=")] // Actually HMACSHA256
[InlineAutoMoqData("SHA1", "Umbraco9Rocks!", "6tZGfG9NTxJJYp19Fac9og==zzRggqANxhb+CbD/VabEt8cIde8=")] // When SHA1 is set on machine key.
public void VerifyHashedPassword_ValidHashWithoutLegacyEncoding_ReturnsSuccessRehashNeeded(
string algorithm,
string providedPassword,
string hashedPassword,
[Frozen] IJsonSerializer jsonSerializer,
TestUserStub aUser,
UmbracoPasswordHasher<TestUserStub> sut)
{
Mock.Get(jsonSerializer)
.Setup(x => x.Deserialize<PersistedPasswordSettings>(It.IsAny<string>()))
.Returns(new PersistedPasswordSettings{ HashAlgorithm = algorithm });
var result = sut.VerifyHashedPassword(aUser, hashedPassword, providedPassword);
Assert.AreEqual(PasswordVerificationResult.SuccessRehashNeeded, result);
}
[Test]
[InlineAutoMoqData("HMACSHA1", "Umbraco9Rocks!", "t0U8atXTX/efNCtTafukwZeIpr8=")]
[InlineAutoMoqData("HMACSHA256", "Umbraco9Rocks!", "t0U8atXTX/efNCtTafukwZeIpr8=")]
[InlineAutoMoqData("FOOBARBAZQUX", "Umbraco9Rocks!", "t0U8atXTX/efNCtTafukwZeIpr8=")]
[InlineAutoMoqData("", "Umbraco9Rocks!", "t0U8atXTX/efNCtTafukwZeIpr8=")]
[InlineAutoMoqData(null, "Umbraco9Rocks!", "t0U8atXTX/efNCtTafukwZeIpr8=")]
public void VerifyHashedPassword_ValidHashWithLegacyEncoding_ReturnsSuccessRehashNeeded(
string algorithm,
string providedPassword,
string hashedPassword,
[Frozen] IJsonSerializer jsonSerializer,
TestUserStub aUser,
UmbracoPasswordHasher<TestUserStub> sut)
{
Mock.Get(jsonSerializer)
.Setup(x => x.Deserialize<PersistedPasswordSettings>(It.IsAny<string>()))
.Returns(new PersistedPasswordSettings { HashAlgorithm = algorithm });
var result = sut.VerifyHashedPassword(aUser, hashedPassword, providedPassword);
Assert.AreEqual(PasswordVerificationResult.SuccessRehashNeeded, result);
}
[Test]
[InlineAutoMoqData("HMACSHA256", "Umbraco9Rocks!", "aB/cDeFaBcDefAbcD/EfaB==1y8+aso9+h3AKRtJXlVYeg2TZKJUr64hccj82ZZ7Ksk=")]
public void VerifyHashedPassword_WithIncorrectPassword_ReturnsFailed(
string algorithm,
string providedPassword,
string hashedPassword,
[Frozen] IJsonSerializer jsonSerializer,
TestUserStub aUser,
UmbracoPasswordHasher<TestUserStub> sut)
{
Mock.Get(jsonSerializer)
.Setup(x => x.Deserialize<PersistedPasswordSettings>(It.IsAny<string>()))
.Returns(new PersistedPasswordSettings { HashAlgorithm = algorithm });
var result = sut.VerifyHashedPassword(aUser, hashedPassword, providedPassword);
Assert.AreEqual(PasswordVerificationResult.Failed, result);
}
[Test]
[AutoMoqData]
public void VerifyHashedPassword_WithIdentityV1OrV2StyleHash_ReturnsSuccessRehashNeeded(
TestUserStub aUser,
UmbracoPasswordHasher<TestUserStub> sut)
{
var options = Options.Create(new PasswordHasherOptions
{
CompatibilityMode = PasswordHasherCompatibilityMode.IdentityV2
});
var upstreamHasher = new PasswordHasher<TestUserStub>(options);
const string password = "Umbraco9Rocks!";
var identityV1Or2StyleHash = upstreamHasher.HashPassword(aUser, password);
var result = sut.VerifyHashedPassword(aUser, identityV1Or2StyleHash, password);
Assert.AreEqual(PasswordVerificationResult.SuccessRehashNeeded, result);
}
[Test]
[AutoMoqData]
public void VerifyHashedPassword_WithIdentityV3StyleHash_ReturnsSuccess(
TestUserStub aUser,
UmbracoPasswordHasher<TestUserStub> sut)
{
var options = Options.Create(new PasswordHasherOptions
{
CompatibilityMode = PasswordHasherCompatibilityMode.IdentityV3
});
var upstreamHasher = new PasswordHasher<TestUserStub>(options);
const string password = "Umbraco9Rocks!";
var identityV1Or2StyleHash = upstreamHasher.HashPassword(aUser, password);
var result = sut.VerifyHashedPassword(aUser, identityV1Or2StyleHash, password);
Assert.AreEqual(PasswordVerificationResult.Success, result);
}
public class TestUserStub : UmbracoIdentityUser
{
public TestUserStub() => PasswordConfig = "not null or empty";
}
}
}

View File

@@ -323,6 +323,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.PublishedCache.NuCache
}
[Test]
[Retry(5)] // TODO make this test non-flaky.
public async Task EventuallyCollectNulls()
{
var d = new SnapDictionary<int, string>();

View File

@@ -44,6 +44,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Tests.Common.Builders
.WithAlias(relationTypeAlias)
.WithName(relationTypeName)
.WithIsBidirectional(false)
.WithIsDependency(true)
.WithParentObjectType(parentObjectType)
.WithChildObjectType(childObjectType)
.Done()
@@ -61,6 +62,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Tests.Common.Builders
Assert.AreEqual(relationTypeAlias, relation.RelationType.Alias);
Assert.AreEqual(relationTypeName, relation.RelationType.Name);
Assert.IsFalse(relation.RelationType.IsBidirectional);
Assert.IsTrue((relation.RelationType as IRelationTypeWithIsDependency).IsDependency);
Assert.AreEqual(parentObjectType, relation.RelationType.ParentObjectType);
Assert.AreEqual(childObjectType, relation.RelationType.ChildObjectType);
}

View File

@@ -26,11 +26,12 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Tests.Common.Builders
var parentObjectType = Guid.NewGuid();
var childObjectType = Guid.NewGuid();
const bool isBidirectional = true;
const bool isDependency = true;
var builder = new RelationTypeBuilder();
// Act
IRelationType relationType = builder
var relationType = builder
.WithId(id)
.WithAlias(alias)
.WithName(name)
@@ -41,6 +42,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Tests.Common.Builders
.WithParentObjectType(parentObjectType)
.WithChildObjectType(childObjectType)
.WithIsBidirectional(isBidirectional)
.WithIsDependency(isDependency)
.Build();
// Assert
@@ -54,6 +56,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Tests.Common.Builders
Assert.AreEqual(parentObjectType, relationType.ParentObjectType);
Assert.AreEqual(childObjectType, relationType.ChildObjectType);
Assert.AreEqual(isBidirectional, relationType.IsBidirectional);
Assert.AreEqual(isDependency, relationType.IsDependency);
}
}
}

View File

@@ -0,0 +1,44 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using Microsoft.AspNetCore.Authentication;
using NUnit.Framework;
using Umbraco.Cms.Core;
using Umbraco.Cms.Web.BackOffice.Security;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Web.BackOffice.Security
{
[TestFixture]
public class BackOfficeAuthenticationBuilderTests
{
[Test]
public void EnsureBackOfficeScheme_When_Backoffice_Auth_Scheme_Expect_Updated_SignInScheme()
{
var scheme = $"{Constants.Security.BackOfficeExternalAuthenticationTypePrefix}test";
var options = new RemoteAuthenticationOptions
{
SignInScheme = "my_cookie"
};
var sut = new BackOfficeAuthenticationBuilder.EnsureBackOfficeScheme<RemoteAuthenticationOptions>();
sut.PostConfigure(scheme, options);
Assert.AreEqual(options.SignInScheme, Constants.Security.BackOfficeExternalAuthenticationType);
}
[Test]
public void EnsureBackOfficeScheme_When_Not_Backoffice_Auth_Scheme_Expect_No_Change()
{
var scheme = "test";
var options = new RemoteAuthenticationOptions
{
SignInScheme = "my_cookie"
};
var sut = new BackOfficeAuthenticationBuilder.EnsureBackOfficeScheme<RemoteAuthenticationOptions>();
sut.PostConfigure(scheme, options);
Assert.AreNotEqual(options.SignInScheme, Constants.Security.BackOfficeExternalAuthenticationType);
}
}
}