feat: CI/CD pipeline setup complete - Ansible playbooks updated, secrets configured, workflow ready
This commit is contained in:
@@ -24,6 +24,7 @@ final readonly class LogContext
|
||||
* @param UserContext|null $user Benutzer-Kontext für Audit-Logs
|
||||
* @param RequestContext|null $request HTTP-Request-Kontext
|
||||
* @param ExceptionContext|null $exception Exception-Kontext für strukturiertes Exception-Logging
|
||||
* @param SecurityContext|null $security Security-Kontext für OWASP-konforme Security-Event-Logs
|
||||
* @param array<string, mixed> $metadata Zusätzliche Metadaten
|
||||
*/
|
||||
public function __construct(
|
||||
@@ -34,6 +35,7 @@ final readonly class LogContext
|
||||
public ?UserContext $user = null,
|
||||
public ?RequestContext $request = null,
|
||||
public ?ExceptionContext $exception = null,
|
||||
public ?SecurityContext $security = null,
|
||||
public array $metadata = []
|
||||
) {
|
||||
}
|
||||
@@ -75,6 +77,7 @@ final readonly class LogContext
|
||||
user: $this->user,
|
||||
request: $this->request,
|
||||
exception: $this->exception,
|
||||
security: $this->security,
|
||||
metadata: $this->metadata
|
||||
);
|
||||
}
|
||||
@@ -92,6 +95,7 @@ final readonly class LogContext
|
||||
user: $this->user,
|
||||
request: $this->request,
|
||||
exception: $this->exception,
|
||||
security: $this->security,
|
||||
metadata: $this->metadata
|
||||
);
|
||||
}
|
||||
@@ -109,6 +113,7 @@ final readonly class LogContext
|
||||
user: $this->user,
|
||||
request: $this->request,
|
||||
exception: $this->exception,
|
||||
security: $this->security,
|
||||
metadata: $this->metadata
|
||||
);
|
||||
}
|
||||
@@ -195,6 +200,7 @@ final readonly class LogContext
|
||||
user: $this->user,
|
||||
request: $this->request,
|
||||
exception: $exception,
|
||||
security: $this->security,
|
||||
metadata: $this->metadata
|
||||
);
|
||||
}
|
||||
@@ -236,6 +242,7 @@ final readonly class LogContext
|
||||
user: $this->user,
|
||||
request: $this->request,
|
||||
exception: $this->exception,
|
||||
security: $this->security,
|
||||
metadata: $this->metadata
|
||||
);
|
||||
}
|
||||
@@ -269,6 +276,7 @@ final readonly class LogContext
|
||||
user: $this->user,
|
||||
request: $this->request,
|
||||
exception: $this->exception,
|
||||
security: $this->security,
|
||||
metadata: $this->metadata
|
||||
);
|
||||
}
|
||||
@@ -286,6 +294,7 @@ final readonly class LogContext
|
||||
user: $user,
|
||||
request: $this->request,
|
||||
exception: $this->exception,
|
||||
security: $this->security,
|
||||
metadata: $this->metadata
|
||||
);
|
||||
}
|
||||
@@ -303,10 +312,53 @@ final readonly class LogContext
|
||||
user: $this->user,
|
||||
request: $request,
|
||||
exception: $this->exception,
|
||||
security: $this->security,
|
||||
metadata: $this->metadata
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt Security-Kontext
|
||||
*/
|
||||
public function withSecurityContext(SecurityContext $security): self
|
||||
{
|
||||
return new self(
|
||||
structured: $this->structured,
|
||||
tags: $this->tags,
|
||||
correlationId: $this->correlationId,
|
||||
trace: $this->trace,
|
||||
user: $this->user,
|
||||
request: $this->request,
|
||||
exception: $this->exception,
|
||||
security: $security,
|
||||
metadata: $this->metadata
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt Security-Kontext (Alias für withSecurityContext)
|
||||
*/
|
||||
public function withSecurity(SecurityContext $security): self
|
||||
{
|
||||
return $this->withSecurityContext($security);
|
||||
}
|
||||
|
||||
/**
|
||||
* Holt Security-Kontext
|
||||
*/
|
||||
public function getSecurity(): ?SecurityContext
|
||||
{
|
||||
return $this->security;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft, ob Security-Kontext vorhanden ist
|
||||
*/
|
||||
public function hasSecurity(): bool
|
||||
{
|
||||
return $this->security !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt Metadaten hinzu
|
||||
*/
|
||||
@@ -320,6 +372,7 @@ final readonly class LogContext
|
||||
user: $this->user,
|
||||
request: $this->request,
|
||||
exception: $this->exception,
|
||||
security: $this->security,
|
||||
metadata: array_merge($this->metadata, [$key => $value])
|
||||
);
|
||||
}
|
||||
@@ -337,6 +390,7 @@ final readonly class LogContext
|
||||
user: $other->user ?? $this->user,
|
||||
request: $other->request ?? $this->request,
|
||||
exception: $other->exception ?? $this->exception,
|
||||
security: $other->security ?? $this->security,
|
||||
metadata: array_merge($this->metadata, $other->metadata)
|
||||
);
|
||||
}
|
||||
@@ -403,6 +457,10 @@ final readonly class LogContext
|
||||
$result['exception'] = $this->exception->toArray();
|
||||
}
|
||||
|
||||
if ($this->security !== null) {
|
||||
$result['security'] = $this->security->toArray();
|
||||
}
|
||||
|
||||
if (! empty($this->metadata)) {
|
||||
$result['metadata'] = $this->metadata;
|
||||
}
|
||||
|
||||
244
src/Framework/Logging/ValueObjects/SecurityContext.php
Normal file
244
src/Framework/Logging/ValueObjects/SecurityContext.php
Normal file
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Logging\ValueObjects;
|
||||
|
||||
use App\Framework\Exception\SecurityLogLevel;
|
||||
|
||||
/**
|
||||
* Security Context Value Object für strukturiertes Security-Event-Logging
|
||||
*
|
||||
* Kapselt alle Security-relevanten Informationen für OWASP-konforme Logs.
|
||||
* Nutzt Framework's SecurityLogLevel aus Exception-Modul.
|
||||
*
|
||||
* OWASP Logging Cheat Sheet:
|
||||
* https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html
|
||||
*/
|
||||
final readonly class SecurityContext
|
||||
{
|
||||
/**
|
||||
* @param string $eventId OWASP Event Identifier (z.B. "AUTHN_login_failure")
|
||||
* @param SecurityLogLevel $level Security-spezifisches Log Level
|
||||
* @param string $description Human-readable Event-Beschreibung
|
||||
* @param string|null $category Event-Kategorie (z.B. "authentication", "authorization")
|
||||
* @param bool $requiresAlert Ob Event ein Security-Alert triggern soll
|
||||
* @param string|null $userId Betroffene User-ID (falls zutreffend)
|
||||
* @param string|null $username Betroffener Username (falls zutreffend)
|
||||
* @param string|null $sourceIp Source IP-Adresse
|
||||
* @param string|null $userAgent User-Agent String
|
||||
* @param array<string, mixed> $eventData Zusätzliche Event-spezifische Daten
|
||||
*/
|
||||
public function __construct(
|
||||
public string $eventId,
|
||||
public SecurityLogLevel $level,
|
||||
public string $description,
|
||||
public ?string $category = null,
|
||||
public bool $requiresAlert = false,
|
||||
public ?string $userId = null,
|
||||
public ?string $username = null,
|
||||
public ?string $sourceIp = null,
|
||||
public ?string $userAgent = null,
|
||||
public array $eventData = []
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory: Erstellt SecurityContext für Authentication-Events
|
||||
*/
|
||||
public static function forAuthentication(
|
||||
string $eventId,
|
||||
string $description,
|
||||
SecurityLogLevel $level = SecurityLogLevel::WARN,
|
||||
bool $requiresAlert = false,
|
||||
array $eventData = []
|
||||
): self {
|
||||
return new self(
|
||||
eventId: $eventId,
|
||||
level: $level,
|
||||
description: $description,
|
||||
category: 'authentication',
|
||||
requiresAlert: $requiresAlert,
|
||||
eventData: $eventData
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory: Erstellt SecurityContext für Authorization-Events
|
||||
*/
|
||||
public static function forAuthorization(
|
||||
string $eventId,
|
||||
string $description,
|
||||
SecurityLogLevel $level = SecurityLogLevel::WARN,
|
||||
bool $requiresAlert = false,
|
||||
array $eventData = []
|
||||
): self {
|
||||
return new self(
|
||||
eventId: $eventId,
|
||||
level: $level,
|
||||
description: $description,
|
||||
category: 'authorization',
|
||||
requiresAlert: $requiresAlert,
|
||||
eventData: $eventData
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory: Erstellt SecurityContext für Input-Validation-Events
|
||||
*/
|
||||
public static function forInputValidation(
|
||||
string $eventId,
|
||||
string $description,
|
||||
SecurityLogLevel $level = SecurityLogLevel::WARN,
|
||||
bool $requiresAlert = false,
|
||||
array $eventData = []
|
||||
): self {
|
||||
return new self(
|
||||
eventId: $eventId,
|
||||
level: $level,
|
||||
description: $description,
|
||||
category: 'input_validation',
|
||||
requiresAlert: $requiresAlert,
|
||||
eventData: $eventData
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory: Erstellt SecurityContext für Session-Events
|
||||
*/
|
||||
public static function forSession(
|
||||
string $eventId,
|
||||
string $description,
|
||||
SecurityLogLevel $level = SecurityLogLevel::INFO,
|
||||
bool $requiresAlert = false,
|
||||
array $eventData = []
|
||||
): self {
|
||||
return new self(
|
||||
eventId: $eventId,
|
||||
level: $level,
|
||||
description: $description,
|
||||
category: 'session',
|
||||
requiresAlert: $requiresAlert,
|
||||
eventData: $eventData
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory: Erstellt SecurityContext für Intrusion-Detection-Events
|
||||
*/
|
||||
public static function forIntrusion(
|
||||
string $eventId,
|
||||
string $description,
|
||||
SecurityLogLevel $level = SecurityLogLevel::FATAL,
|
||||
bool $requiresAlert = true,
|
||||
array $eventData = []
|
||||
): self {
|
||||
return new self(
|
||||
eventId: $eventId,
|
||||
level: $level,
|
||||
description: $description,
|
||||
category: 'intrusion_detection',
|
||||
requiresAlert: $requiresAlert,
|
||||
eventData: $eventData
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt User-Informationen
|
||||
*/
|
||||
public function withUser(?string $userId, ?string $username = null): self
|
||||
{
|
||||
return new self(
|
||||
eventId: $this->eventId,
|
||||
level: $this->level,
|
||||
description: $this->description,
|
||||
category: $this->category,
|
||||
requiresAlert: $this->requiresAlert,
|
||||
userId: $userId,
|
||||
username: $username,
|
||||
sourceIp: $this->sourceIp,
|
||||
userAgent: $this->userAgent,
|
||||
eventData: $this->eventData
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt Request-Informationen
|
||||
*/
|
||||
public function withRequestInfo(?string $sourceIp, ?string $userAgent = null): self
|
||||
{
|
||||
return new self(
|
||||
eventId: $this->eventId,
|
||||
level: $this->level,
|
||||
description: $this->description,
|
||||
category: $this->category,
|
||||
requiresAlert: $this->requiresAlert,
|
||||
userId: $this->userId,
|
||||
username: $this->username,
|
||||
sourceIp: $sourceIp,
|
||||
userAgent: $userAgent,
|
||||
eventData: $this->eventData
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt Event-Daten hinzu
|
||||
*/
|
||||
public function withEventData(array $eventData): self
|
||||
{
|
||||
return new self(
|
||||
eventId: $this->eventId,
|
||||
level: $this->level,
|
||||
description: $this->description,
|
||||
category: $this->category,
|
||||
requiresAlert: $this->requiresAlert,
|
||||
userId: $this->userId,
|
||||
username: $this->username,
|
||||
sourceIp: $this->sourceIp,
|
||||
userAgent: $this->userAgent,
|
||||
eventData: array_merge($this->eventData, $eventData)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Konvertiert zu Array für Serialisierung
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$result = [
|
||||
'event_id' => $this->eventId,
|
||||
'level' => $this->level->value,
|
||||
'description' => $this->description,
|
||||
];
|
||||
|
||||
if ($this->category !== null) {
|
||||
$result['category'] = $this->category;
|
||||
}
|
||||
|
||||
if ($this->requiresAlert) {
|
||||
$result['requires_alert'] = true;
|
||||
}
|
||||
|
||||
if ($this->userId !== null) {
|
||||
$result['user_id'] = $this->userId;
|
||||
}
|
||||
|
||||
if ($this->username !== null) {
|
||||
$result['username'] = $this->username;
|
||||
}
|
||||
|
||||
if ($this->sourceIp !== null) {
|
||||
$result['source_ip'] = $this->sourceIp;
|
||||
}
|
||||
|
||||
if ($this->userAgent !== null) {
|
||||
$result['user_agent'] = $this->userAgent;
|
||||
}
|
||||
|
||||
if (!empty($this->eventData)) {
|
||||
$result['event_data'] = $this->eventData;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user