using Flaro.Core.Users;
namespace Flaro.Core.Tests;
public class PasswordHasherTests
{
[Test]
public void Richtiges_Passwort_wird_angenommen()
{
var hash = PasswordHasher.Hash("geheim-und-lang");
Assert.That(PasswordHasher.Verify("geheim-und-lang", hash), Is.True);
}
[Test]
public void Falsches_Passwort_wird_abgelehnt()
{
var hash = PasswordHasher.Hash("geheim-und-lang");
Assert.That(PasswordHasher.Verify("geheim-und-kurz", hash), Is.False);
}
/// Gleiches Passwort, zwei Hashes — sonst wäre das Salz wirkungslos.
///
///
/// Ohne diese Eigenschaft verrät die Datenbank, welche Konten dasselbe
/// Passwort benutzen, und eine einmal gebaute Tabelle knackt alle auf
/// einen Schlag.
///
[Test]
public void Zweimal_dasselbe_Passwort_ergibt_zwei_verschiedene_Hashes()
{
var a = PasswordHasher.Hash("dasselbe");
var b = PasswordHasher.Hash("dasselbe");
Assert.That(a, Is.Not.EqualTo(b));
Assert.That(PasswordHasher.Verify("dasselbe", a), Is.True);
Assert.That(PasswordHasher.Verify("dasselbe", b), Is.True);
}
[Test]
public void Der_Hash_nennt_seine_Kennwerte()
{
var hash = PasswordHasher.Hash("egal");
Assert.That(hash, Does.StartWith("$argon2id$v=19$m=19456,t=2,p=1$"));
}
/// Eine beschädigte Zeile lehnt ab, statt den Server umzuwerfen.
[TestCase("")]
[TestCase("kein-hash")]
[TestCase("$argon2id$v=19$m=19456,t=2,p=1$nur-vier-teile")]
[TestCase("$bcrypt$v=19$m=19456,t=2,p=1$c2FsenNhbHo$aGFzaA")]
[TestCase("$argon2id$v=19$m=x,t=2,p=1$c2FsenNhbHo$aGFzaA")]
[TestCase("$argon2id$v=19$m=19456,t=2,p=1$!!!kein-base64!!!$aGFzaA")]
public void Unlesbarer_Hash_wirft_nicht_sondern_lehnt_ab(string kaputt)
{
Assert.That(PasswordHasher.Verify("egal", kaputt), Is.False);
}
[Test]
public void Leeres_Passwort_wird_abgelehnt_statt_gehasht()
{
Assert.Throws(() => PasswordHasher.Hash(""));
Assert.That(PasswordHasher.Verify("", PasswordHasher.Hash("echt")), Is.False);
}
/// Alte, schwächere Hashes sollen beim nächsten Anmelden auffallen.
[Test]
public void Schwaechere_Kennwerte_verlangen_ein_Neuhashen()
{
Assert.That(PasswordHasher.NeedsRehash("$argon2id$v=19$m=4096,t=1,p=1$c2FsenNhbHo$aGFzaA"), Is.True);
Assert.That(PasswordHasher.NeedsRehash("$2a$10$irgendwas"), Is.True);
Assert.That(PasswordHasher.NeedsRehash(PasswordHasher.Hash("aktuell")), Is.False);
}
}