Files
ADconsle/app/Services/AuditLogger.php
T
kzbkowskiandClaude Sonnet 5 1126d96271
CI / PHP 8.2 (push) Failing after 2m46s
CI / PHP 8.3 (push) Failing after 59s
CI / PHP 8.4 (push) Failing after 1m7s
ADconsole v1.0.0
First public release.

- docs: document the audit log, user offboarding, CSV export and the
  "require a reason for destructive actions" setting across README, docs/
  and CLAUDE/AGENTS.md; note retention for panel_audit
- docs: fill the publishing placeholders (repo URL, security contact,
  issue-template links) and add a semantic-versioning policy
- move agent/contributor context into CLAUDE/ (AGENTS.md + a README);
  root CLAUDE.md is now a thin @-import pointer
- add a favicon (shield-lock, matching the login screen) to the login
  page and the app layout
- CHANGELOG: promote [Unreleased] to [1.0.0]; keep the earlier internal
  build as [0.1.0]

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UfuvfwexztdS7LDpGuKsuK
2026-09-08 23:14:39 +02:00

71 lines
2.1 KiB
PHP

<?php
namespace App\Services;
use App\Models\AuditLog;
use Illuminate\Support\Facades\Auth;
/**
* Zapis wpisów do dziennika zmian panelu (`panel_audit`).
*
* Nigdy nie przerywa operacji AD - błąd zapisu logu jest tylko raportowany.
* Tożsamość administratora bierzemy z guarda 'ldap' (fallback: profil w sesji).
*/
class AuditLogger
{
/**
* @param array{
* target_type?: ?string,
* target?: ?string,
* target_dn?: ?string,
* reason?: ?string,
* changes?: ?array<string, mixed>,
* context?: ?array<string, mixed>
* } $opts
*/
public function log(string $action, array $opts = []): void
{
try {
[$actor, $actorName] = $this->resolveActor();
AuditLog::create([
'actor' => $actor,
'actor_name' => $actorName,
'action' => $action,
'target_type' => $opts['target_type'] ?? null,
'target' => $opts['target'] ?? null,
'target_dn' => $opts['target_dn'] ?? null,
'reason' => ($opts['reason'] ?? null) ?: null,
'changes' => ! empty($opts['changes']) ? $opts['changes'] : null,
'context' => ! empty($opts['context']) ? $opts['context'] : null,
'ip' => request()?->ip(),
'created_at' => now(),
]);
} catch (\Throwable $e) {
report($e);
}
}
/**
* @return array{0: string, 1: string} [login, wyświetlana nazwa]
*/
protected function resolveActor(): array
{
$user = Auth::guard('ldap')->user();
if ($user) {
$login = (string) ($user->getFirstAttribute('samaccountname') ?? 'unknown');
$name = (string) ($user->getFirstAttribute('cn') ?? $login);
return [$login, $name];
}
$profile = session('ad_admin');
if (is_array($profile) && ! empty($profile['login'])) {
return [(string) $profile['login'], (string) ($profile['display_name'] ?? $profile['login'])];
}
return ['system', 'system'];
}
}