From 58400d3dc3f31d4069c89b2e0612e4f4a7d8d3ef Mon Sep 17 00:00:00 2001 From: Boban Blaskovic Date: Fri, 22 May 2026 01:42:00 +0200 Subject: [PATCH] feat(auth): UserPolicy + LicensePolicy + TenantPolicy + ParentChildPolicy + EnsureActiveLicense placeholder Co-Authored-By: Claude Sonnet 4.6 --- app/Http/Middleware/EnsureActiveLicense.php | 15 ++++++++ app/Policies/LicensePolicy.php | 30 ++++++++++++++++ app/Policies/ParentChildPolicy.php | 20 +++++++++++ app/Policies/TenantPolicy.php | 30 ++++++++++++++++ app/Policies/UserPolicy.php | 38 +++++++++++++++++++++ app/Providers/AppServiceProvider.php | 16 ++++++++- 6 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 app/Http/Middleware/EnsureActiveLicense.php create mode 100644 app/Policies/LicensePolicy.php create mode 100644 app/Policies/ParentChildPolicy.php create mode 100644 app/Policies/TenantPolicy.php create mode 100644 app/Policies/UserPolicy.php diff --git a/app/Http/Middleware/EnsureActiveLicense.php b/app/Http/Middleware/EnsureActiveLicense.php new file mode 100644 index 0000000..2e98f1b --- /dev/null +++ b/app/Http/Middleware/EnsureActiveLicense.php @@ -0,0 +1,15 @@ +hasRole('platform-admin') || $actor->hasRole('school-admin'); + } + + public function view(User $actor, License $license): bool + { + if ($actor->hasRole('platform-admin')) return true; + return $actor->tenant_id === $license->tenant_id; + } + + public function create(User $actor): bool + { + return $actor->hasRole('platform-admin'); + } + + public function update(User $actor, License $license): bool + { + return $actor->hasRole('platform-admin'); + } +} diff --git a/app/Policies/ParentChildPolicy.php b/app/Policies/ParentChildPolicy.php new file mode 100644 index 0000000..a285e5d --- /dev/null +++ b/app/Policies/ParentChildPolicy.php @@ -0,0 +1,20 @@ +hasRole('platform-admin')) return true; + return $actor->hasRole('parent') && $actor->id === $parent->id; + } + + public function detach(User $actor, User $parent, User $child): bool + { + if ($actor->hasRole('platform-admin')) return true; + return $actor->hasRole('parent') && $actor->id === $parent->id; + } +} diff --git a/app/Policies/TenantPolicy.php b/app/Policies/TenantPolicy.php new file mode 100644 index 0000000..ab7488e --- /dev/null +++ b/app/Policies/TenantPolicy.php @@ -0,0 +1,30 @@ +hasRole('platform-admin'); + } + + public function view(User $actor, Tenant $tenant): bool + { + if ($actor->hasRole('platform-admin')) return true; + return $actor->tenant_id === $tenant->id; + } + + public function create(User $actor): bool + { + return $actor->hasRole('platform-admin'); + } + + public function update(User $actor, Tenant $tenant): bool + { + return $actor->hasRole('platform-admin'); + } +} diff --git a/app/Policies/UserPolicy.php b/app/Policies/UserPolicy.php new file mode 100644 index 0000000..627ef04 --- /dev/null +++ b/app/Policies/UserPolicy.php @@ -0,0 +1,38 @@ +hasRole('platform-admin') + || $actor->hasRole('school-admin') + || $actor->hasRole('teacher'); + } + + public function view(User $actor, User $target): bool + { + if ($actor->hasRole('platform-admin')) return true; + return $actor->tenant_id === $target->tenant_id; + } + + public function create(User $actor): bool + { + return $actor->hasRole('platform-admin') || $actor->hasRole('school-admin'); + } + + public function update(User $actor, User $target): bool + { + if ($actor->hasRole('platform-admin')) return true; + return $actor->hasRole('school-admin') && $actor->tenant_id === $target->tenant_id; + } + + public function delete(User $actor, User $target): bool + { + if ($actor->hasRole('platform-admin')) return true; + return $actor->hasRole('school-admin') && $actor->tenant_id === $target->tenant_id; + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 452e6b6..0447918 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,6 +2,14 @@ namespace App\Providers; +use App\Models\License; +use App\Models\Tenant; +use App\Models\User; +use App\Policies\LicensePolicy; +use App\Policies\TenantPolicy; +use App\Policies\UserPolicy; +use Illuminate\Support\Facades\Gate; +use Illuminate\Support\Facades\URL; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider @@ -19,6 +27,12 @@ class AppServiceProvider extends ServiceProvider */ public function boot(): void { - // + if (app()->environment() !== 'testing') { + URL::forceScheme('https'); + } + + Gate::policy(User::class, UserPolicy::class); + Gate::policy(License::class, LicensePolicy::class); + Gate::policy(Tenant::class, TenantPolicy::class); } }