* Added endpoint and backing service for backoffice login providers and the status per user. * Improve link login redirect forming and error handling * Add responseModel and mapping instead of returning core model * Moved unlink endpoint logic into a service * Refactored ExternalLinkLoginCallback logic into BackofficeExternalLoginService method * typo and minor code style improvements * async method name alignment * Add BackOfficeExternalLoginService tests * Remove helper method that makes less sense that thought. * Minor formatting, clean-up and conventions * Replaced cookie authentication in link-login with a short lived secret Applied PR feedback * Update openapi * Changed link login to a form endpoint * fix broken comment link * Do not store claimsprinciple in secret + comments * update redirect paths --------- Co-authored-by: Sven Geusens <sge@umbraco.dk> Co-authored-by: kjac <kja@umbraco.dk> Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
103 lines
4.2 KiB
C#
103 lines
4.2 KiB
C#
using Moq;
|
|
using NUnit.Framework;
|
|
using Umbraco.Cms.Core;
|
|
using Umbraco.Cms.Core.Security;
|
|
using Umbraco.Cms.Core.Services.OperationStatus;
|
|
|
|
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Cms.Api.Management.Services;
|
|
|
|
public partial class BackOfficeExternalLoginServiceTests
|
|
{
|
|
[Test]
|
|
public async Task ExternalLoginStatusForUser_Returns_All_Registered_Providers()
|
|
{
|
|
// arrange
|
|
var userId = Guid.NewGuid();
|
|
var firstProviderName = "one";
|
|
var secondProviderName = "two";
|
|
var serviceSetup = new BackOfficeExternalLoginServiceSetup();
|
|
serviceSetup.BackOfficeLoginProviders
|
|
.Setup(s => s.GetBackOfficeProvidersAsync())
|
|
.ReturnsAsync(new[]
|
|
{
|
|
TestExternalLoginProviderScheme(firstProviderName, true),
|
|
TestExternalLoginProviderScheme(secondProviderName, true)
|
|
});
|
|
serviceSetup.UserService
|
|
.Setup(s => s.GetLinkedLoginsAsync(userId))
|
|
.ReturnsAsync(Attempt.SucceedWithStatus<ICollection<IIdentityUserLogin>, UserOperationStatus>(
|
|
UserOperationStatus.Success, Array.Empty<IIdentityUserLogin>()));
|
|
|
|
var externalLoginService = serviceSetup.Sut;
|
|
|
|
// act
|
|
var providersAttempt = await externalLoginService.ExternalLoginStatusForUserAsync(userId);
|
|
|
|
Assert.True(providersAttempt.Success);
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.AreEqual(1, providersAttempt.Result.Count(p => p.ProviderSchemeName.Equals(firstProviderName)));
|
|
Assert.AreEqual(1, providersAttempt.Result.Count(p => p.ProviderSchemeName.Equals(secondProviderName)));
|
|
Assert.AreEqual(2, providersAttempt.Result.Count());
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public async Task ExternalLoginStatusForUser_Incorporates_Linked_Logins()
|
|
{
|
|
// arrange
|
|
var userId = Guid.NewGuid();
|
|
var firstProviderName = "one";
|
|
var secondProviderName = "two";
|
|
var serviceSetup = new BackOfficeExternalLoginServiceSetup();
|
|
serviceSetup.BackOfficeLoginProviders
|
|
.Setup(s => s.GetBackOfficeProvidersAsync())
|
|
.ReturnsAsync(new[]
|
|
{
|
|
TestExternalLoginProviderScheme(firstProviderName, true),
|
|
TestExternalLoginProviderScheme(secondProviderName, true)
|
|
});
|
|
serviceSetup.UserService
|
|
.Setup(s => s.GetLinkedLoginsAsync(userId))
|
|
.ReturnsAsync(Attempt.SucceedWithStatus<ICollection<IIdentityUserLogin>, UserOperationStatus>(
|
|
UserOperationStatus.Success,
|
|
new[] { new IdentityUserLogin(firstProviderName, firstProviderName + "ProvKey", userId.ToString()) }));
|
|
|
|
var externalLoginService = serviceSetup.Sut;
|
|
|
|
// act
|
|
var providersAttempt = await externalLoginService.ExternalLoginStatusForUserAsync(userId);
|
|
|
|
Assert.True(providersAttempt.Success);
|
|
Assert.IsTrue(providersAttempt.Result.Single(p => p.ProviderSchemeName == firstProviderName).IsLinkedOnUser);
|
|
}
|
|
|
|
[TestCase(true)]
|
|
[TestCase(false)]
|
|
public async Task ExternalLoginStatusForUser_Returns_Correct_AllowManualLinking(bool allowManualLinking)
|
|
{
|
|
// arrange
|
|
var userId = Guid.NewGuid();
|
|
var providerName = "one";
|
|
var serviceSetup = new BackOfficeExternalLoginServiceSetup();
|
|
serviceSetup.BackOfficeLoginProviders
|
|
.Setup(s => s.GetBackOfficeProvidersAsync())
|
|
.ReturnsAsync(new[] { TestExternalLoginProviderScheme(providerName, allowManualLinking), });
|
|
serviceSetup.UserService
|
|
.Setup(s => s.GetLinkedLoginsAsync(userId))
|
|
.ReturnsAsync(Attempt.SucceedWithStatus<ICollection<IIdentityUserLogin>, UserOperationStatus>(
|
|
UserOperationStatus.Success,
|
|
new[] { new IdentityUserLogin(providerName, providerName + "ProvKey", userId.ToString()) }));
|
|
|
|
var externalLoginService = serviceSetup.Sut;
|
|
|
|
// act
|
|
var providersAttempt = await externalLoginService.ExternalLoginStatusForUserAsync(userId);
|
|
|
|
Assert.True(providersAttempt.Success);
|
|
Assert.AreEqual(
|
|
allowManualLinking,
|
|
providersAttempt.Result.Single(p => p.ProviderSchemeName == providerName).HasManualLinkingEnabled);
|
|
}
|
|
}
|