Files
awo-hamburg-intranet/module/tasks/lib/AuthContext.php
Moritz Weinmann 743476f64a Module tasks + knowledgecenter_update aus Kundenprojekt übernehmen (bereinigt)
Beide Module wurden aus einem anderen Kundenprojekt kopiert und bereinigt:

Knowledgecenter:
- Bild-Cache (1.985 Dateien) geleert, Ordnerstruktur mit .gitkeep behalten
- Files-Gallery-Lizenzschlüssel entfernt (config.php)
- Kundenspezifische Kategorien gelöscht: Teil I/II/III QM-Struktur,
  nummerierte QM-Kapitel, Gremien (Präsidium/Finanzausschuss/Landesausschuss),
  Sitzungsservice-Serie, Protokoll-Abteilungen, Testeinträge
- 56 generische Kategorien bleiben (Downloads, Onboarding, Personalthemen …)

Tasks:
- Alle Betriebsdaten gelöscht (114 Tasks, 914 Submissions, 579 Assignments)
- Task-Definitionen und Verlinkungen geleert
- Kategoriestruktur bleibt (Allgemein, IT, Personal, Buchhaltung …)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 09:20:02 +02:00

253 lines
8.4 KiB
PHP

<?php
declare(strict_types=1);
class TaskCertAuthContext
{
private int $contactId;
private int $masterMandantId;
private int $currentMandantId;
public function __construct(int $contactId, int $masterMandantId, int $currentMandantId)
{
$this->contactId = $contactId;
$this->masterMandantId = $masterMandantId;
$this->currentMandantId = $currentMandantId;
}
public static function fromGlobals(): self
{
$mainContact = self::asArray($GLOBALS['main_contact'] ?? ($_SESSION['main_contact'] ?? []));
$contactId = self::firstPositiveInt([
$mainContact['id'] ?? null,
$mainContact['main_contact_id'] ?? null,
$GLOBALS['main_contact_id'] ?? null,
$_SESSION['main_contact_id'] ?? null,
$GLOBALS['contact_id'] ?? null,
$_SESSION['contact_id'] ?? null,
$_SESSION['id'] ?? null,
]);
$masterMandantId = self::firstPositiveInt([
$mainContact['master_mandant_id'] ?? null,
$mainContact['main_mandant_id'] ?? null,
$mainContact['mandant_id'] ?? null,
$GLOBALS['master_mandant_id'] ?? null,
$_SESSION['master_mandant_id'] ?? null,
$GLOBALS['main_mandant_id'] ?? null,
$_SESSION['main_mandant_id'] ?? null,
self::extractMandantId($GLOBALS['mandant'] ?? null),
self::extractMandantId($_SESSION['mandant'] ?? null),
]);
$currentMandantId = self::firstPositiveInt([
$mainContact['current_mandant_id'] ?? null,
$mainContact['main_mandant_id'] ?? null,
$GLOBALS['current_mandant_id'] ?? null,
$_SESSION['current_mandant_id'] ?? null,
self::extractMandantId($GLOBALS['current_mandant'] ?? null),
self::extractMandantId($_SESSION['current_mandant'] ?? null),
self::extractMandantId($GLOBALS['mandant'] ?? null),
self::extractMandantId($_SESSION['mandant'] ?? null),
]);
if ($currentMandantId <= 0) {
$currentMandantId = $masterMandantId;
}
if ($masterMandantId <= 0) {
$masterMandantId = $currentMandantId;
}
return new self($contactId, $masterMandantId, $currentMandantId);
}
public function contactId(): int
{
return $this->contactId;
}
public function masterMandantId(): int
{
return $this->masterMandantId;
}
public function currentMandantId(): int
{
return $this->currentMandantId;
}
public function isLoggedIn(): bool
{
return $this->contactId > 0;
}
public function hasPermission(string $permissionKey): bool
{
if (!$this->isLoggedIn()) {
TaskCertLogger::warning('Permission denied: no contact id in auth context', [
'permission' => $permissionKey,
'contact_id' => $this->contactId,
'master_mandant_id' => $this->masterMandantId,
'current_mandant_id' => $this->currentMandantId,
'request_uri' => (string) ($_SERVER['REQUEST_URI'] ?? ''),
]);
return false;
}
$mandantIds = [];
if ($this->currentMandantId > 0) {
$mandantIds[] = $this->currentMandantId;
}
if ($this->masterMandantId > 0 && !in_array($this->masterMandantId, $mandantIds, true)) {
$mandantIds[] = $this->masterMandantId;
}
if ($mandantIds === []) {
$mandantIds[] = 0;
}
$usedFallback = !function_exists('get_permission_state');
$checkedStates = [];
foreach ($mandantIds as $mandantId) {
try {
$state = $usedFallback
? $this->getPermissionStateFallback($permissionKey, $mandantId)
: (int) get_permission_state($permissionKey, $mandantId, $this->contactId);
$checkedStates[] = [
'mandant_id' => $mandantId,
'state' => $state,
];
if ($state === 1) {
if ($usedFallback) {
TaskCertLogger::info('Permission granted via SQL fallback', [
'permission' => $permissionKey,
'contact_id' => $this->contactId,
'mandant_id' => $mandantId,
]);
}
return true;
}
} catch (Throwable $throwable) {
TaskCertLogger::error('Permission check failed', [
'permission' => $permissionKey,
'contact_id' => $this->contactId,
'mandant_id' => $mandantId,
'fallback_used' => $usedFallback ? 1 : 0,
'exception' => $throwable,
]);
}
}
TaskCertLogger::warning('Permission denied after check', [
'permission' => $permissionKey,
'contact_id' => $this->contactId,
'master_mandant_id' => $this->masterMandantId,
'current_mandant_id' => $this->currentMandantId,
'checked_mandant_ids' => $mandantIds,
'checked_states' => $checkedStates,
'fallback_used' => $usedFallback ? 1 : 0,
'request_uri' => (string) ($_SERVER['REQUEST_URI'] ?? ''),
]);
return false;
}
private static function asArray($value): array
{
if (!is_array($value)) {
return [];
}
return $value;
}
private static function firstPositiveInt(array $values): int
{
foreach ($values as $value) {
$intValue = (int) $value;
if ($intValue > 0) {
return $intValue;
}
}
return 0;
}
private static function extractMandantId($value): int
{
if (!is_array($value)) {
return 0;
}
return self::firstPositiveInt([
$value['id'] ?? null,
$value['main_mandant_id'] ?? null,
$value['mandant_id'] ?? null,
]);
}
private function getPermissionStateFallback(string $permissionKey, int $mandantId): int
{
$conn = $GLOBALS['mysql_con'] ?? null;
if (!($conn instanceof mysqli)) {
throw new RuntimeException('Kein mysqli-Handle für Permission-Fallback verfügbar.');
}
$defaultState = 0;
$permissionId = 0;
$stmtPermission = $conn->prepare(
'SELECT id, default_active FROM main_permission WHERE code = ? LIMIT 1'
);
if (!($stmtPermission instanceof mysqli_stmt)) {
throw new RuntimeException('Statement für main_permission konnte nicht erstellt werden.');
}
$stmtPermission->bind_param('s', $permissionKey);
$stmtPermission->execute();
$resultPermission = $stmtPermission->get_result();
if ($resultPermission instanceof mysqli_result) {
$permission = $resultPermission->fetch_assoc();
if (is_array($permission)) {
$permissionId = (int) ($permission['id'] ?? 0);
$defaultState = (int) ($permission['default_active'] ?? 0) === 1 ? 1 : 0;
}
$resultPermission->free();
}
$stmtPermission->close();
if ($permissionId <= 0) {
return 0;
}
$state = $defaultState;
$stmtContact = $conn->prepare(
'SELECT active FROM main_contact_permission
WHERE main_contact_id = ? AND main_mandant_id = ? AND main_permission_id = ?
LIMIT 1'
);
if (!($stmtContact instanceof mysqli_stmt)) {
throw new RuntimeException('Statement für main_contact_permission konnte nicht erstellt werden.');
}
$contactId = $this->contactId;
$stmtContact->bind_param('iii', $contactId, $mandantId, $permissionId);
$stmtContact->execute();
$resultContact = $stmtContact->get_result();
if ($resultContact instanceof mysqli_result) {
$contactPermission = $resultContact->fetch_assoc();
if (is_array($contactPermission)) {
$state = (int) ($contactPermission['active'] ?? 0) === 1 ? 1 : 0;
}
$resultContact->free();
}
$stmtContact->close();
return $state;
}
}