auditoria.php
4.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?php
declare(strict_types=1);
require __DIR__ . '/../src/bootstrap.php';
Auth::requireAdmin();
$perPageOptions = [10, 25, 50, 100];
$perPage = (int) ($_GET['per'] ?? 50);
if (!in_array($perPage, $perPageOptions, true)) {
$perPage = 50;
}
$total = (int) Database::pdo()->query('SELECT COUNT(*) FROM audit_log')->fetchColumn();
$totalPages = max(1, (int) ceil($total / $perPage));
$page = max(1, (int) ($_GET['p'] ?? 1));
$page = min($page, $totalPages);
$offset = ($page - 1) * $perPage;
$stmt = Database::pdo()->prepare(
'SELECT * FROM audit_log ORDER BY criado_em DESC, id DESC LIMIT :limit OFFSET :offset'
);
$stmt->bindValue('limit', $perPage, PDO::PARAM_INT);
$stmt->bindValue('offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$logs = $stmt->fetchAll();
$acaoLabels = [
'login' => 'Login',
'login_negado' => 'Login negado (sem permissão)',
'login_falhou' => 'Login falhou (usuário/senha)',
'logout' => 'Logoff',
'habilitou_aluno' => 'Habilitou aluno',
'desabilitou_aluno' => 'Desabilitou aluno',
'alterou_senha_aluno' => 'Alterou senha de aluno',
'adicionou_admin' => 'Adicionou administrador',
'desativou_admin' => 'Desativou administrador',
'reativou_admin' => 'Reativou administrador',
'alterou_papel_admin' => 'Alterou papel de administrador',
'atualizou_settings' => 'Atualizou configurações',
];
View::header('Auditoria');
?>
<div class="card">
<h1>Auditoria</h1>
<p class="hint">
Histórico de logins (inclusive tentativas com senha incorreta), alterações em
alunos, administradores e configurações.
</p>
<div style="display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:12px;margin-bottom:4px">
<span class="hint">
Mostrando <?= count($logs) ?> de <?= $total ?> registros — página <?= $page ?> de <?= $totalPages ?>
</span>
<form method="get" action="auditoria" style="display:flex;align-items:center;gap:8px;margin:0">
<label for="per" style="margin:0;white-space:nowrap">Por página</label>
<select id="per" name="per" onchange="this.form.submit()" style="margin:0;width:auto">
<?php foreach ($perPageOptions as $opt): ?>
<option value="<?= $opt ?>" <?= $opt === $perPage ? 'selected' : '' ?>><?= $opt ?></option>
<?php endforeach; ?>
</select>
</form>
</div>
<table>
<tr>
<th>Data/hora</th>
<th>Usuário</th>
<th>Ação</th>
<th>Alvo</th>
<th>Detalhe</th>
<th>IP</th>
</tr>
<?php foreach ($logs as $log): ?>
<tr>
<td data-label="Data/hora"><?= View::escape($log['criado_em']) ?></td>
<td data-label="Usuário"><?= View::escape($log['usuario']) ?></td>
<td data-label="Ação"><?= View::escape($acaoLabels[$log['acao']] ?? $log['acao']) ?></td>
<td data-label="Alvo"><?= View::escape($log['alvo'] ?? '') ?></td>
<td data-label="Detalhe"><?= View::escape($log['detalhe'] ?? '') ?></td>
<td data-label="IP"><?= View::escape($log['ip'] ?? '') ?></td>
</tr>
<?php endforeach; ?>
<?php if (!$logs): ?>
<tr><td colspan="6">Nenhum registro ainda.</td></tr>
<?php endif; ?>
</table>
<?php if ($totalPages > 1): ?>
<div style="display:flex;align-items:center;gap:10px;margin-top:16px;flex-wrap:wrap">
<?php if ($page > 1): ?>
<a class="btn secondary" href="auditoria?per=<?= $perPage ?>&p=<?= $page - 1 ?>">← Anterior</a>
<?php else: ?>
<span class="btn secondary" style="opacity:.4;pointer-events:none">← Anterior</span>
<?php endif; ?>
<form method="get" action="auditoria" style="display:flex;align-items:center;gap:8px;margin:0">
<input type="hidden" name="per" value="<?= $perPage ?>">
<label for="p" style="margin:0;white-space:nowrap">Página</label>
<select id="p" name="p" onchange="this.form.submit()" style="margin:0;width:auto">
<?php for ($p = 1; $p <= $totalPages; $p++): ?>
<option value="<?= $p ?>" <?= $p === $page ? 'selected' : '' ?>><?= $p ?> de <?= $totalPages ?></option>
<?php endfor; ?>
</select>
</form>
<?php if ($page < $totalPages): ?>
<a class="btn secondary" href="auditoria?per=<?= $perPage ?>&p=<?= $page + 1 ?>">Próxima →</a>
<?php else: ?>
<span class="btn secondary" style="opacity:.4;pointer-events:none">Próxima →</span>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php
View::footer();