v0.1.0: logo, i18n pt/en, CI com caches, testes e documentação

- Logo oficial (sabia.png) e conjunto de ícones do app desktop.
- Interface em português e inglês: tradutor por observação do DOM, seletor
  de idioma e checagem de cobertura de tradução no CI.
- CI/CD com caches (rust-cache, .deb do Tauri em cache) e pipeline de release
  multiplataforma (CLI em 5 alvos + app desktop via tauri-action), templates
  de issue/PR.
- Suíte de testes de integração do sabia-core (scan e2e, handshake/crack
  4-way e PMKID, pcap, trilha de auditoria) — 46 testes verdes.
- Documentação completa pt/en: README, ROADMAP, SECURITY, CONTRIBUTING,
  CHANGELOG e docs/ (cli, interface, arquitetura), com enquadramento de uso
  autorizado.
- Correções de clippy (-D warnings) e formatação em toda a árvore.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas RayanandClaude Opus 5.5 committed 2026-10-23 12:46:19 -03:00
1 parent df27974359
commit 791538c9d9
112 files changed
+15620 -494

No files matched your search

+77
View File
@@ -0,0 +1,77 @@
//! Integração: trilha de auditoria encadeada por hash — grava entradas,
//! confirma que a cadeia valida, depois adultera um registro no disco e
//! confirma que a verificação detecta a falha.
mod common;
use sabia_core::audit::AuditLog;
use std::io::Write;
#[test]
fn chain_validates_after_recording_entries() {
let dir = tempfile::tempdir().expect("tempdir");
let path = dir.path().join("audit.log");
{
let mut log = AuditLog::open(&path).expect("open");
log.record("monitor-on", "wlan0", "modo monitor ativado")
.expect("record 1");
log.record("scan-start", "wlan0", "início da captura")
.expect("record 2");
log.record("deauth", "00:11:22:33:44:55", "teste de deautenticação")
.expect("record 3");
}
let entries = AuditLog::read_entries(&path, None).expect("read_entries");
assert_eq!(entries.len(), 3);
assert_eq!(entries[0].action, "monitor-on");
assert_eq!(entries[2].action, "deauth");
// cadeia encadeada corretamente
assert_eq!(entries[1].prev_hash, entries[0].hash);
assert_eq!(entries[2].prev_hash, entries[1].hash);
let result = AuditLog::verify(&path).expect("verify");
assert_eq!(
result, None,
"cadeia íntegra não deve apontar entrada inválida"
);
}
#[test]
fn tampering_with_an_entry_breaks_verification() {
let dir = tempfile::tempdir().expect("tempdir");
let path = dir.path().join("audit.log");
{
let mut log = AuditLog::open(&path).expect("open");
log.record("monitor-on", "wlan0", "modo monitor ativado")
.expect("record 1");
log.record("scan-start", "wlan0", "início da captura")
.expect("record 2");
log.record("scan-stop", "wlan0", "fim da captura")
.expect("record 3");
}
// Confirma que, intacta, a cadeia passa.
assert_eq!(AuditLog::verify(&path).expect("verify ok"), None);
// Adultera o "detail" da segunda entrada sem recalcular o hash,
// simulando uma edição retroativa do log.
let contents = std::fs::read_to_string(&path).expect("read");
let mut lines: Vec<String> = contents.lines().map(|l| l.to_string()).collect();
assert_eq!(lines.len(), 3);
assert!(lines[1].contains("início da captura"));
lines[1] = lines[1].replace("início da captura", "evento adulterado");
let mut file = std::fs::File::create(&path).expect("recreate");
for line in &lines {
writeln!(file, "{line}").expect("write tampered line");
}
let result = AuditLog::verify(&path).expect("verify");
assert_eq!(
result,
Some(1),
"verificação deveria apontar a entrada adulterada (índice 1)"
);
}