Files
jabali-panel/app/Models/AuditLog.php
2026-01-24 19:36:46 +02:00

194 lines
5.3 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\Auth;
class AuditLog extends Model
{
protected $fillable = [
'user_id',
'action',
'category',
'description',
'target_type',
'target_id',
'target_name',
'ip_address',
'user_agent',
'metadata',
];
protected function casts(): array
{
return [
'metadata' => 'array',
];
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
/**
* Log a privileged action.
*/
public static function log(
string $action,
string $category,
string $description,
?string $targetType = null,
?int $targetId = null,
?string $targetName = null,
?array $metadata = null
): self {
return self::create([
'user_id' => Auth::id(),
'action' => $action,
'category' => $category,
'description' => $description,
'target_type' => $targetType,
'target_id' => $targetId,
'target_name' => $targetName,
'ip_address' => request()->ip(),
'user_agent' => request()->userAgent(),
'metadata' => $metadata,
]);
}
/**
* Log user management actions.
*/
public static function logUserAction(string $action, User $targetUser, ?array $metadata = null): self
{
return self::log(
action: $action,
category: 'user',
description: "{$action} user: {$targetUser->username}",
targetType: 'user',
targetId: $targetUser->id,
targetName: $targetUser->username,
metadata: $metadata
);
}
/**
* Log domain management actions.
*/
public static function logDomainAction(string $action, string $domain, ?int $domainId = null, ?array $metadata = null): self
{
return self::log(
action: $action,
category: 'domain',
description: "{$action} domain: {$domain}",
targetType: 'domain',
targetId: $domainId,
targetName: $domain,
metadata: $metadata
);
}
/**
* Log database management actions.
*/
public static function logDatabaseAction(string $action, string $database, ?array $metadata = null): self
{
return self::log(
action: $action,
category: 'database',
description: "{$action} database: {$database}",
targetType: 'database',
targetId: null,
targetName: $database,
metadata: $metadata
);
}
/**
* Log service management actions.
*/
public static function logServiceAction(string $action, string $service, ?array $metadata = null): self
{
return self::log(
action: $action,
category: 'service',
description: "{$action} service: {$service}",
targetType: 'service',
targetId: null,
targetName: $service,
metadata: $metadata
);
}
/**
* Log email/mailbox management actions.
*/
public static function logEmailAction(string $action, string $email, ?array $metadata = null): self
{
return self::log(
action: $action,
category: 'email',
description: "{$action} mailbox: {$email}",
targetType: 'mailbox',
targetId: null,
targetName: $email,
metadata: $metadata
);
}
/**
* Log firewall actions.
*/
public static function logFirewallAction(string $action, ?string $rule = null, ?array $metadata = null): self
{
return self::log(
action: $action,
category: 'firewall',
description: $rule ? "{$action} firewall rule: {$rule}" : "{$action} firewall",
targetType: 'firewall',
targetId: null,
targetName: $rule,
metadata: $metadata
);
}
/**
* Log authentication events.
*/
public static function logAuth(string $action, ?User $user = null, ?array $metadata = null): self
{
$username = $user?->username ?? Auth::user()?->username ?? 'unknown';
return self::create([
'user_id' => $user?->id ?? Auth::id(),
'action' => $action,
'category' => 'auth',
'description' => "{$action}: {$username}",
'target_type' => 'user',
'target_id' => $user?->id ?? Auth::id(),
'target_name' => $username,
'ip_address' => request()->ip(),
'user_agent' => request()->userAgent(),
'metadata' => $metadata,
]);
}
/**
* Prune audit logs older than the specified number of days.
*
* @param int|null $days Number of days to keep (default: from settings or 90)
* @return int Number of deleted records
*/
public static function prune(?int $days = null): int
{
$days = $days ?? (int) DnsSetting::get('audit_log_retention_days', 90);
return self::where('created_at', '<', now()->subDays($days))->delete();
}
}