using Omika.Diagnostics.Security;
namespace Omika.Diagnostics.Tests;
///
/// Tâche 9 — Authentification : logique de sécurité PURE (hachage PBKDF2, authentification
/// d'opérateur, règles de rôles/policies). Les comportements HTTP (cookie, redirection,
/// 403) sont appliqués par la convention ASP.NET Core AuthorizeFolder("/") et ne
/// sont pas testables ici (le projet de tests ne référence pas Omika.Diagnostics.Web).
///
public class DiagnosticAuthTests
{
// -------------------------------------------------- Hachage ----
[Fact]
public void PasswordHasher_HashAndVerify_RoundTrip()
{
string hash = DiagnosticPasswordHasher.Hash("s3cret-pass!");
Assert.True(DiagnosticPasswordHasher.Verify("s3cret-pass!", hash));
}
[Fact]
public void PasswordHasher_WrongPassword_Fails()
{
string hash = DiagnosticPasswordHasher.Hash("s3cret-pass!");
Assert.False(DiagnosticPasswordHasher.Verify("autre", hash));
}
[Fact]
public void PasswordHasher_UniqueSalts()
{
string h1 = DiagnosticPasswordHasher.Hash("same");
string h2 = DiagnosticPasswordHasher.Hash("same");
Assert.NotEqual(h1, h2); // sel aléatoire → hash différent.
}
[Theory]
[InlineData("")]
[InlineData("not-a-valid-hash")]
[InlineData("bad.bad.bad")]
[InlineData("100000.!!!.###")]
public void PasswordHasher_MalformedOrEmpty_Fails(string storedHash)
{
Assert.False(DiagnosticPasswordHasher.Verify("x", storedHash));
}
// -------------------------------------------------- Authentification opérateur ----
[Fact]
public void Authenticate_ValidCredentials_ReturnsOperator()
{
string hash = DiagnosticPasswordHasher.Hash("pw");
var op = new DiagnosticOperator("alice", hash, new[] { DiagnosticRoles.Support });
DiagnosticOperator? result = DiagnosticOperatorAuthenticator.Authenticate(new[] { op }, "alice", "pw");
Assert.NotNull(result);
Assert.Equal("alice", result.Username);
Assert.Contains(DiagnosticRoles.Support, result.Roles);
}
[Fact]
public void Authenticate_WrongPassword_ReturnsNull()
{
var op = new DiagnosticOperator("alice", DiagnosticPasswordHasher.Hash("pw"), new[] { "Support" });
Assert.Null(DiagnosticOperatorAuthenticator.Authenticate(new[] { op }, "alice", "nope"));
}
[Fact]
public void Authenticate_UnknownUser_ReturnsNull()
{
var op = new DiagnosticOperator("alice", DiagnosticPasswordHasher.Hash("pw"), new[] { "Support" });
Assert.Null(DiagnosticOperatorAuthenticator.Authenticate(new[] { op }, "bob", "pw"));
}
[Fact]
public void Authenticate_NoOperators_FailClosed()
{
// Production sans configuration → aucun accès (§T9/30).
Assert.Null(DiagnosticOperatorAuthenticator.Authenticate(Array.Empty(), "alice", "pw"));
}
[Fact]
public void Authenticate_BlankInput_Fails()
{
var op = new DiagnosticOperator("alice", DiagnosticPasswordHasher.Hash("pw"), new[] { "Support" });
Assert.Null(DiagnosticOperatorAuthenticator.Authenticate(new[] { op }, " ", "pw"));
Assert.Null(DiagnosticOperatorAuthenticator.Authenticate(new[] { op }, "alice", " "));
}
// -------------------------------------------------- Rôles / policies ----
[Fact]
public void IsSupport_SupportOrAdmin()
{
Assert.True(DiagnosticAuthorization.IsSupport(new[] { DiagnosticRoles.Support }));
Assert.True(DiagnosticAuthorization.IsSupport(new[] { DiagnosticRoles.Admin }));
Assert.True(DiagnosticAuthorization.IsSupport(new[] { DiagnosticRoles.Support, DiagnosticRoles.Admin }));
Assert.False(DiagnosticAuthorization.IsSupport(new[] { "Autre" }));
Assert.False(DiagnosticAuthorization.IsSupport(Array.Empty()));
}
[Fact]
public void IsAdmin_OnlyAdmin()
{
Assert.True(DiagnosticAuthorization.IsAdmin(new[] { DiagnosticRoles.Admin }));
Assert.False(DiagnosticAuthorization.IsAdmin(new[] { DiagnosticRoles.Support }));
Assert.False(DiagnosticAuthorization.IsAdmin(Array.Empty()));
}
[Fact]
public void Roles_AreCaseInsensitive()
{
Assert.True(DiagnosticAuthorization.IsSupport(new[] { "support" }));
Assert.True(DiagnosticAuthorization.IsAdmin(new[] { "admin" }));
}
[Fact]
public void RoleConstants_AreStable()
{
Assert.Equal("Support", DiagnosticRoles.Support);
Assert.Equal("Admin", DiagnosticRoles.Admin);
Assert.Equal("DiagnosticsSupport", DiagnosticAuthPolicies.Support);
Assert.Equal("DiagnosticsAdmin", DiagnosticAuthPolicies.Admin);
}
}