From 2c3c84e66fd054a2d9fa8d83e21ecd0486b561c2 Mon Sep 17 00:00:00 2001 From: Lars Gebhardt-Kusche Date: Mon, 15 Jun 2026 23:19:24 +0200 Subject: [PATCH] adasdas --- public/admin/users/index.php | 5 +- public/apps/mining-checker/index.php | 5 +- public/auth/callback/index.php | 8 ++-- public/auth/pending/index.php | 72 ++++++++++++++++++++++++++++ public/index.php | 5 +- src/App/AccountGate.php | 38 ++++++++++++++- src/App/RegistrationService.php | 8 ++++ src/App/RegistrationStore.php | 31 ++++++++++++ 8 files changed, 164 insertions(+), 8 deletions(-) create mode 100644 public/auth/pending/index.php diff --git a/public/admin/users/index.php b/public/admin/users/index.php index b5f9a79e..027146e8 100644 --- a/public/admin/users/index.php +++ b/public/admin/users/index.php @@ -20,7 +20,10 @@ if (isset($_SESSION['desktop_auth']) && is_array($_SESSION['desktop_auth'])) { if (!($accountCheck['allowed'] ?? false)) { unset($_SESSION['desktop_auth']); - header('Location: /auth/inactive/?message=' . urlencode((string) ($accountCheck['message'] ?? 'Dieses Konto ist noch nicht freigeschaltet.')), true, 302); + $target = (string) ($accountCheck['state'] ?? '') === 'pending' + ? '/auth/pending/?username=' . urlencode((string) ($currentAuthUser['username'] ?? '')) + : '/auth/inactive/?message=' . urlencode((string) ($accountCheck['message'] ?? 'Dieses Konto ist noch nicht freigeschaltet.')); + header('Location: ' . $target, true, 302); exit; } } diff --git a/public/apps/mining-checker/index.php b/public/apps/mining-checker/index.php index f31bfea5..bba9bcfa 100644 --- a/public/apps/mining-checker/index.php +++ b/public/apps/mining-checker/index.php @@ -20,7 +20,10 @@ if ($auth->isAuthenticated()) { if (!($accountCheck['allowed'] ?? false)) { $auth->logout(); - header('Location: /auth/inactive/?message=' . urlencode((string) ($accountCheck['message'] ?? 'Dieses Konto ist noch nicht freigeschaltet.')), true, 302); + $target = (string) ($accountCheck['state'] ?? '') === 'pending' + ? '/auth/pending/?username=' . urlencode((string) ($currentUser['username'] ?? '')) + : '/auth/inactive/?message=' . urlencode((string) ($accountCheck['message'] ?? 'Dieses Konto ist noch nicht freigeschaltet.')); + header('Location: ' . $target, true, 302); exit; } } diff --git a/public/auth/callback/index.php b/public/auth/callback/index.php index 07043ca4..8912081e 100644 --- a/public/auth/callback/index.php +++ b/public/auth/callback/index.php @@ -57,9 +57,11 @@ if ($state === '' || $expectedState === '' || !hash_equals($expectedState, $stat if (!($accountCheck['allowed'] ?? false)) { $auth->logout(); - http_response_code(403); - $title = 'Zugriff gesperrt'; - $message = (string) ($accountCheck['message'] ?? 'Dieses Konto ist noch nicht freigeschaltet.'); + $target = (string) ($accountCheck['state'] ?? '') === 'pending' + ? '/auth/pending/?username=' . urlencode($username) + : '/auth/inactive/?message=' . urlencode((string) ($accountCheck['message'] ?? 'Dieses Konto ist noch nicht freigeschaltet.')); + header('Location: ' . $target, true, 302); + exit; } else { $auth->establishSession($tokenPayload, $userPayload); header('Location: ' . $redirectTarget, true, 302); diff --git a/public/auth/pending/index.php b/public/auth/pending/index.php new file mode 100644 index 00000000..5e546511 --- /dev/null +++ b/public/auth/pending/index.php @@ -0,0 +1,72 @@ +findLatestByUsername($username); +$status = (string) ($request['status'] ?? 'pending_approval'); + +$statusMap = [ + 'pending_approval' => [ + 'title' => 'Freigabe ausstehend', + 'copy' => 'Dein Konto wurde angelegt und wartet aktuell auf die manuelle Freigabe.', + 'label' => 'Wartet auf Freigabe', + ], + 'provisioning_failed' => [ + 'title' => 'Bearbeitung erforderlich', + 'copy' => 'Dein Konto konnte technisch noch nicht vollständig vorbereitet werden. Die Anfrage liegt bereits vor und wird geprüft.', + 'label' => 'Technische Prüfung läuft', + ], + 'approved_active' => [ + 'title' => 'Freigeschaltet', + 'copy' => 'Dein Konto wurde bereits freigeschaltet. Bitte melde dich erneut an.', + 'label' => 'Freigeschaltet', + ], +]; + +$view = $statusMap[$status] ?? [ + 'title' => 'Freigabestatus', + 'copy' => 'Der Status deiner Freigabe wird aktuell verarbeitet.', + 'label' => 'In Bearbeitung', +]; +?> + + + + + <?= htmlspecialchars($view['title'], ENT_QUOTES) ?> + + + +
+ +
+ + diff --git a/public/index.php b/public/index.php index 6361c62f..87d42989 100644 --- a/public/index.php +++ b/public/index.php @@ -23,7 +23,10 @@ if ($auth->isAuthenticated()) { if (!($accountCheck['allowed'] ?? false)) { $auth->logout(); - header('Location: /auth/inactive/?message=' . urlencode((string) ($accountCheck['message'] ?? 'Dieses Konto ist noch nicht freigeschaltet.')), true, 302); + $target = (string) ($accountCheck['state'] ?? '') === 'pending' + ? '/auth/pending/?username=' . urlencode((string) ($currentUser['username'] ?? '')) + : '/auth/inactive/?message=' . urlencode((string) ($accountCheck['message'] ?? 'Dieses Konto ist noch nicht freigeschaltet.')); + header('Location: ' . $target, true, 302); exit; } } diff --git a/src/App/AccountGate.php b/src/App/AccountGate.php index 1733fc13..199af003 100644 --- a/src/App/AccountGate.php +++ b/src/App/AccountGate.php @@ -38,28 +38,62 @@ final class AccountGate ]; } - $user = $this->ldap->getUserByUsername($username, ['uid', 'shadowExpire']); + $user = $this->ldap->getUserByUsername($username, ['uid', 'shadowExpire', 'memberOf']); if (!is_array($user)) { return [ 'allowed' => false, + 'state' => 'blocked', 'message' => 'Dieses Konto ist nicht freigeschaltet.', ]; } $shadowExpire = (string) ($user['shadowexpire'] ?? $user['shadowExpire'] ?? ''); $activeShadowExpire = (string) ($this->config['ldap']['active_shadow_expire'] ?? -1); + $pendingGroupDn = strtolower(trim((string) ($this->config['ldap']['pending_group_dn'] ?? ''))); + $memberOf = $this->normalizeMemberOf($user['memberof'] ?? $user['memberOf'] ?? []); + $isPending = $pendingGroupDn !== '' && in_array($pendingGroupDn, $memberOf, true); - if ($shadowExpire !== $activeShadowExpire) { + if ($isPending && $shadowExpire !== $activeShadowExpire) { return [ 'allowed' => false, + 'state' => 'pending', 'message' => 'Dieses Konto ist noch nicht freigeschaltet.', ]; } + if ($shadowExpire !== '' && $shadowExpire !== $activeShadowExpire) { + return [ + 'allowed' => false, + 'state' => 'blocked', + 'message' => 'Dieses Konto ist derzeit deaktiviert.', + ]; + } + return [ 'allowed' => true, + 'state' => 'active', 'message' => 'Konto ist aktiv.', ]; } + + /** + * @param mixed $value + * @return array + */ + private function normalizeMemberOf(mixed $value): array + { + if (is_string($value)) { + $value = [$value]; + } + + if (!is_array($value)) { + return []; + } + + return array_values(array_filter(array_map( + static fn (mixed $item): string => strtolower(trim((string) $item)), + $value + ))); + } } diff --git a/src/App/RegistrationService.php b/src/App/RegistrationService.php index 87485f7d..bceb9669 100644 --- a/src/App/RegistrationService.php +++ b/src/App/RegistrationService.php @@ -51,6 +51,14 @@ final class RegistrationService return $this->store->find($id); } + /** + * @return array|null + */ + public function findLatestByUsername(string $username): ?array + { + return $this->store->findLatestByUsername($username); + } + /** * @param array $input * @return array{success: bool, errors?: array, request?: array} diff --git a/src/App/RegistrationStore.php b/src/App/RegistrationStore.php index 956a1375..e950a187 100644 --- a/src/App/RegistrationStore.php +++ b/src/App/RegistrationStore.php @@ -42,6 +42,37 @@ final class RegistrationStore return null; } + /** + * @return array|null + */ + public function findLatestByUsername(string $username): ?array + { + $username = strtolower(trim($username)); + + if ($username === '') { + return null; + } + + $matches = array_values(array_filter( + $this->read(), + static fn (array $item): bool => strtolower((string) ($item['username'] ?? '')) === $username + )); + + if ($matches === []) { + return null; + } + + usort( + $matches, + static fn (array $left, array $right): int => strcmp( + (string) ($right['created_at'] ?? ''), + (string) ($left['created_at'] ?? '') + ) + ); + + return $matches[0]; + } + /** * @return array|null */