115 lines
3.9 KiB
C#
115 lines
3.9 KiB
C#
using SGU.AuthBroker.Core.Authentication;
|
|
using SGU.AuthBroker.Core.Directory;
|
|
using SGU.AuthBroker.Core.Identity;
|
|
using SGU.AuthBroker.Core.Profiles;
|
|
using Xunit;
|
|
|
|
namespace SGU.AuthBroker.Core.Tests;
|
|
|
|
public sealed class AuthenticationWorkflowTests
|
|
{
|
|
[Fact]
|
|
public async Task PassesTheExactOriginalPasswordToNtlmAndActiveDirectory()
|
|
{
|
|
const string original = "Árbol-Exacto-🔐-NoDerivar-27!";
|
|
InstitutionalProfile profile = new(
|
|
EmployeeNumber: "123456",
|
|
DisplayName: "Persona de Prueba",
|
|
Email: "persona@lasalle.mx",
|
|
JobTitle: "DOCENTE",
|
|
Department: "FACULTAD DE PRUEBA");
|
|
CapturingNtlmValidator ntlm = new(NtlmValidationResult.Valid(profile));
|
|
CapturingDirectorySynchronizer directory = new();
|
|
AuthenticationWorkflow workflow = new(ntlm, directory);
|
|
|
|
AuthenticationFlowResult result = await workflow.AuthenticateAsync(
|
|
"do123456",
|
|
original,
|
|
TestContext.Current.CancellationToken);
|
|
|
|
Assert.Equal(AuthenticationFlowOutcome.Authorized, result.Outcome);
|
|
Assert.Same(original, ntlm.Password);
|
|
Assert.Same(original, directory.Password);
|
|
Assert.Equal("DO123456", ntlm.Identity?.UserName);
|
|
Assert.Equal(InstitutionalRole.Professor, directory.Identity?.Role);
|
|
Assert.Same(profile, directory.Profile);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task InvalidNtlmCredentialsNeverReachActiveDirectory()
|
|
{
|
|
CapturingDirectorySynchronizer directory = new();
|
|
AuthenticationWorkflow workflow = new(
|
|
new CapturingNtlmValidator(NtlmValidationResult.Invalid()),
|
|
directory);
|
|
|
|
AuthenticationFlowResult result = await workflow.AuthenticateAsync(
|
|
"AL123456",
|
|
"Wrong",
|
|
TestContext.Current.CancellationToken);
|
|
|
|
Assert.Equal(AuthenticationFlowOutcome.InvalidCredentials, result.Outcome);
|
|
Assert.Null(directory.Password);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task NtlmOutageIsReportedAsUnavailableForProviderFallback()
|
|
{
|
|
CapturingDirectorySynchronizer directory = new();
|
|
AuthenticationWorkflow workflow = new(
|
|
new CapturingNtlmValidator(NtlmValidationResult.Unavailable()),
|
|
directory);
|
|
|
|
AuthenticationFlowResult result = await workflow.AuthenticateAsync(
|
|
"AD123456",
|
|
"LastKnownPassword",
|
|
TestContext.Current.CancellationToken);
|
|
|
|
Assert.Equal(AuthenticationFlowOutcome.Unavailable, result.Outcome);
|
|
Assert.Null(directory.Password);
|
|
}
|
|
|
|
private sealed class CapturingNtlmValidator(NtlmValidationResult result) : INtlmCredentialValidator
|
|
{
|
|
public UserIdentity? Identity { get; private set; }
|
|
|
|
public string? Password { get; private set; }
|
|
|
|
public Task<NtlmValidationResult> ValidateAsync(
|
|
UserIdentity identity,
|
|
string password,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
Identity = identity;
|
|
Password = password;
|
|
return Task.FromResult(result);
|
|
}
|
|
}
|
|
|
|
private sealed class CapturingDirectorySynchronizer : IActiveDirectorySynchronizer
|
|
{
|
|
public UserIdentity? Identity { get; private set; }
|
|
|
|
public string? Password { get; private set; }
|
|
|
|
public InstitutionalProfile? Profile { get; private set; }
|
|
|
|
public Task<DirectorySyncResult> SynchronizeAsync(
|
|
UserIdentity identity,
|
|
InstitutionalProfile? profile,
|
|
string password,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
Identity = identity;
|
|
Profile = profile;
|
|
Password = password;
|
|
return Task.FromResult(new DirectorySyncResult(
|
|
"LCI",
|
|
identity.UserName,
|
|
$"{identity.UserName}@lci.lasalle.mx",
|
|
true,
|
|
false));
|
|
}
|
|
}
|
|
}
|