Premiere commit - Omika
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
using Omika.Diagnostics.Security;
|
||||
|
||||
namespace Omika.Diagnostics.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// 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 <c>AuthorizeFolder("/")</c> et ne
|
||||
/// sont pas testables ici (le projet de tests ne référence pas Omika.Diagnostics.Web).
|
||||
/// </summary>
|
||||
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<DiagnosticOperator>(), "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<string>()));
|
||||
}
|
||||
|
||||
[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<string>()));
|
||||
}
|
||||
|
||||
[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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user