diff --git a/app/Domains/UserManagement/Controllers/LoginController.php b/app/Domains/UserManagement/Controllers/LoginController.php index b931ece..bee7779 100644 --- a/app/Domains/UserManagement/Controllers/LoginController.php +++ b/app/Domains/UserManagement/Controllers/LoginController.php @@ -2,6 +2,7 @@ namespace App\Domains\UserManagement\Controllers; +use App\Enumerations\UserRole; use App\Providers\InertiaProvider; use App\Scopes\CommonController; use Illuminate\Http\Request; @@ -38,20 +39,44 @@ class LoginController extends CommonController { return redirect()->intended('/register/verifyEmail'); } - - #$credentials = ['username' => 'development', 'password' => 'development']; - if (!Auth::attempt($credentials)) { return back()->withErrors([ 'username' => 'Diese Zugangsdaten sind ungültig.', ]); } - $request->session()->regenerate(); $user = Auth::user(); + $tenant = app('tenant'); + // Auf "lv" darf sich grundsätzlich jeder aktive Nutzer einloggen. + // Auf Sub-Tenants gilt: + // - Der Nutzer muss dem Tenant zugeordnet sein (local_group) + // - ODER er hat "Bundesrecht über Landesrecht": + // user_role_main === ROLE_ADMINISTRATOR -> Login auf jedem Sub-Tenant erlaubt. + $isMainAdmin = $user->user_role_main === UserRole::USER_ROLE_ADMIN; + $isMemberOfTenant = $tenant->slug === $user->local_group; -# dd($user->firstname . ' ' . $user->lastname); + if ($tenant->slug !== 'lv' && !$isMainAdmin && !$isMemberOfTenant) { + Auth::logout(); + $request->session()->invalidate(); + $request->session()->regenerateToken(); + + return back()->withErrors([ + 'username' => 'Diese Zugangsdaten sind für diesen Stamm nicht gültig.', + ]); + } + + if (!$user->active) { + Auth::logout(); + $request->session()->invalidate(); + $request->session()->regenerateToken(); + + return back()->withErrors([ + 'username' => 'Dieses Benutzerkonto ist nicht aktiv.', + ]); + } + + $request->session()->regenerate(); return redirect()->intended('/'); } diff --git a/app/Providers/AuthCheckProvider.php b/app/Providers/AuthCheckProvider.php index c695f77..1209f95 100644 --- a/app/Providers/AuthCheckProvider.php +++ b/app/Providers/AuthCheckProvider.php @@ -3,6 +3,7 @@ namespace App\Providers; use App\Enumerations\UserRole; +use App\Models\User; class AuthCheckProvider { public function checkLoggedIn() : bool { @@ -16,7 +17,7 @@ class AuthCheckProvider { return $user->active; } - if ($user->user_role_main === UserRole::USER_ROLE_ADMIN) { + if ($this->isMainAdministrator($user)) { return true; } @@ -28,10 +29,39 @@ class AuthCheckProvider { return null; } + $user = auth()->user(); + if (app('tenant')->slug === 'lv') { - return auth()->user()->user_role_main; + return $user->user_role_main; } - return auth()->user()->user_role_local_group; + // "Bundesrecht steht über Landesrecht": + // Ein ROLE_ADMINISTRATOR auf LV-Ebene ist auf jedem Sub-Tenant automatisch Administrator, + // unabhängig von user_role_local_group. + if ($this->isMainAdministrator($user)) { + return UserRole::USER_ROLE_ADMIN; + } + + return $user->user_role_local_group; + } + + /** + * Gibt true zurück, wenn der Nutzer auf LV-Ebene Administrator ist. + * Diese Rolle hebt das lokale Rechtesystem für alle Sub-Tenants auf. + */ + public function isMainAdministrator(?User $user = null) : bool { + $user ??= auth()->user(); + + return $user !== null + && $user->user_role_main === UserRole::USER_ROLE_ADMIN; + } + + /** + * Bequemer Helper für die Berechtigungs-Checks im gesamten System. + * Gibt true zurück, wenn der aktuell eingeloggte Nutzer im Kontext des + * aktuellen Tenants effektiv Administrator ist. + */ + public function isAdministrator() : bool { + return $this->getUserRole() === UserRole::USER_ROLE_ADMIN; } } diff --git a/app/Providers/GlobalDataProvider.php b/app/Providers/GlobalDataProvider.php index df39737..5fae3ad 100644 --- a/app/Providers/GlobalDataProvider.php +++ b/app/Providers/GlobalDataProvider.php @@ -116,9 +116,11 @@ class GlobalDataProvider { $navigation['personal'][] = ['url' => '/personal-data', 'display' => 'Meine Daten']; $navigation['personal'][] = ['url' => '/messages', 'display' => 'Meine Nachrichten']; + $authCheck = new AuthCheckProvider(); + $effectiveRole = $authCheck->getUserRole(); + if ( - in_array($this->user->user_role_local_group, [UserRole::USER_ROLE_ADMIN, UserRole::USER_ROLE_GROUP_LEADER] ) || - $this->user->user_role_main === UserRole::USER_ROLE_ADMIN + in_array($effectiveRole, [UserRole::USER_ROLE_ADMIN, UserRole::USER_ROLE_GROUP_LEADER], true) ) { $navigation['costunits'][] = ['url' => '/cost-unit/list', 'display' => 'Kostenstellen']; $navigation['costunits'][] = ['url' => '/cost-unit/create', 'display' => 'Neue laufende Tätigkeit']; diff --git a/app/Providers/TenantUserProvider.php b/app/Providers/TenantUserProvider.php index 909769c..5d01b77 100644 --- a/app/Providers/TenantUserProvider.php +++ b/app/Providers/TenantUserProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use App\Enumerations\UserRole; use Illuminate\Auth\EloquentUserProvider; class TenantUserProvider extends EloquentUserProvider @@ -18,15 +19,20 @@ class TenantUserProvider extends EloquentUserProvider } } + // Auf "lv" gilt grundsätzlich keine local_group-Einschränkung. if (app('tenant')->slug === 'lv') { return $query->first(); } - $query->where([ - 'local_group' => app('tenant')->slug, - 'active' => true - - ]); + // Auf Sub-Tenants: + // - Entweder gehört der Nutzer zum aktuellen Tenant (local_group) + // - ODER er ist auf LV-Ebene Administrator + // -> "Bundesrecht steht über Landesrecht": Login überall möglich. + $query->where('active', true) + ->where(function ($q) { + $q->where('local_group', app('tenant')->slug) + ->orWhere('user_role_main', UserRole::USER_ROLE_ADMIN); + }); return $query->first(); } diff --git a/app/Repositories/CostUnitRepository.php b/app/Repositories/CostUnitRepository.php index a976501..37c7f86 100644 --- a/app/Repositories/CostUnitRepository.php +++ b/app/Repositories/CostUnitRepository.php @@ -7,6 +7,7 @@ use App\Enumerations\InvoiceStatus; use App\Enumerations\InvoiceType; use App\Enumerations\UserRole; use App\Models\CostUnit; +use App\Providers\AuthCheckProvider; use App\Resources\CostUnitResource; use App\ValueObjects\Amount; use Illuminate\Database\Capsule\Manager as Capsule; @@ -75,8 +76,8 @@ class CostUnitRepository { } else { if ($tenant->slug !== 'lv') { if ( - $user->user_role_main === UserRole::USER_ROLE_ADMIN || - in_array($user->user_role_local_group, [UserRole::USER_ROLE_GROUP_LEADER, UserRole::USER_ROLE_ADMIN]) + new AuthCheckProvider()->isAdministrator() || + $user->user_role_local_group === UserRole::USER_ROLE_ADMIN ) { $canSeeAll = true; } diff --git a/app/Repositories/EventRepository.php b/app/Repositories/EventRepository.php index 5f38447..46d770c 100644 --- a/app/Repositories/EventRepository.php +++ b/app/Repositories/EventRepository.php @@ -6,6 +6,7 @@ use App\Enumerations\ParticipationType; use App\Enumerations\UserRole; use App\Models\CostUnit; use App\Models\Event; +use App\Providers\AuthCheckProvider; use App\Resources\CostUnitResource; use Illuminate\Database\Eloquent\Collection; use Illuminate\Http\Request; @@ -72,7 +73,10 @@ class EventRepository { if (!$accessCheck) { $canSeeAll = true; } else { - if ($tenant->slug !== 'lv') { + if ( + new AuthCheckProvider()->isAdministrator() || + $user->user_role_local_group === UserRole::USER_ROLE_ADMIN + ) { if ( $user->user_role_main === UserRole::USER_ROLE_ADMIN || in_array($user->user_role_local_group, [UserRole::USER_ROLE_GROUP_LEADER, UserRole::USER_ROLE_ADMIN])