using SameBeat.Application.Interfejsy; using SameBeat.Domain.Encje; using SameBeat.Infrastructure.Autoryzacja; using Xunit; namespace SameBeat.Tests.Unit; public class UslugaHaszowaniaSekretowSesjiTests { private readonly IUslugaHaszowaniaSekretowSesji _usluga = new UslugaHaszowaniaSekretowSesji(); private static readonly Guid WydarzenieId = Guid.NewGuid(); private static UczestnikOczekujacy UtworzUczestnika() => UczestnikOczekujacy.Dolacz(WydarzenieId, "Piotr"); [Fact] public void WygenerujSekret_MaCoNajmniej32BajtyLosowosci() { var sekret = _usluga.WygenerujSekret(); // Base64Url bez wyrownania: 32 bajty koduja sie na ceil(32/3*4)=44 znaki (bez '='). var bajty = Convert.FromBase64String(PrzywrocStandardowyBase64(sekret)); Assert.True(bajty.Length >= 32, "Sekret sesji musi miec co najmniej 32 bajty (256 bitow) losowosci."); } [Fact] public void WygenerujSekret_ZaKazdymRazemDajeInnaWartosc() { var sekret1 = _usluga.WygenerujSekret(); var sekret2 = _usluga.WygenerujSekret(); Assert.NotEqual(sekret1, sekret2); } [Fact] public void WygenerujSekret_NieZawieraZnakowNiebezpiecznychWUrl() { // Base64Url: brak '+', '/', '=' -- bezpieczny do przekazania jako parametr query (?sekret=...). var sekret = _usluga.WygenerujSekret(); Assert.DoesNotContain('+', sekret); Assert.DoesNotContain('/', sekret); Assert.DoesNotContain('=', sekret); } [Fact] public void Weryfikuj_DlaPoprawnegoSekretu_ZwracaPoprawne() { var uczestnik = UtworzUczestnika(); var sekretJawny = _usluga.WygenerujSekret(); var hash = _usluga.Haszuj(uczestnik, sekretJawny); var wynik = _usluga.Weryfikuj(uczestnik, hash, sekretJawny); Assert.Equal(WynikWeryfikacjiHasla.Poprawne, wynik); } [Fact] public void Weryfikuj_DlaBlednegoSekretu_ZwracaNiepoprawne() { var uczestnik = UtworzUczestnika(); var hash = _usluga.Haszuj(uczestnik, _usluga.WygenerujSekret()); var wynik = _usluga.Weryfikuj(uczestnik, hash, "zgadywany-sekret-atakujacego"); Assert.Equal(WynikWeryfikacjiHasla.Niepoprawne, wynik); } [Fact] public void Haszuj_DlaTegoSamegoSekretu_ZaKazdymRazemDajeInnyHash() { // PasswordHasher soli hash losowa wartoscia -- to samo co przy hasle, patrz UslugaHaszowaniaHaselTests. var uczestnik = UtworzUczestnika(); var sekretJawny = _usluga.WygenerujSekret(); var hash1 = _usluga.Haszuj(uczestnik, sekretJawny); var hash2 = _usluga.Haszuj(uczestnik, sekretJawny); Assert.NotEqual(hash1, hash2); } private static string PrzywrocStandardowyBase64(string base64Url) { var wynik = base64Url.Replace('-', '+').Replace('_', '/'); return wynik.PadRight(wynik.Length + (4 - wynik.Length % 4) % 4, '='); } }