From 445884782ad145742c343bf8a5594c67e1896141 Mon Sep 17 00:00:00 2001 From: Nurmuhammet Allanov Date: Thu, 14 Dec 2023 19:03:25 +0500 Subject: [PATCH] WIp --- app/Models/User.php | 17 ++- .../Resources/System/Roles/Permission.php | 7 -- app/Policies/Order/Card/CardOrderPolicy.php | 119 ++++++++++++++++++ app/Policies/Order/Card/CardStatePolicy.php | 93 ++++++++++++++ app/Policies/Order/Card/CardTypePolicy.php | 93 ++++++++++++++ app/Policies/Order/Loan/LoanOrderPolicy.php | 4 +- app/Providers/AuthServiceProvider.php | 3 - app/Providers/NovaServiceProvider.php | 32 +++-- app/Repos/Order/Loan/LoanOrderRepo.php | 1 + app/Repos/System/Nova/NovaRepo.php | 41 ++++++ database/seeders/DatabaseSeeder.php | 1 + database/seeders/PermissionTableSeeder.php | 23 ++++ 12 files changed, 404 insertions(+), 30 deletions(-) create mode 100644 app/Policies/Order/Card/CardOrderPolicy.php create mode 100644 app/Policies/Order/Card/CardStatePolicy.php create mode 100644 app/Policies/Order/Card/CardTypePolicy.php create mode 100644 database/seeders/PermissionTableSeeder.php diff --git a/app/Models/User.php b/app/Models/User.php index 0151480..f04e072 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -16,7 +16,6 @@ use Spatie\Permission\Traits\HasRoles; class User extends Authenticatable { - use Actionable; use HasApiTokens; use HasFactory; use HasRoles; @@ -75,6 +74,14 @@ class User extends Authenticatable return $this->hasMany(LoanOrder::class); } + /** + * Check if user has role. + */ + public function withoutRole(): bool + { + return $this->roles->count() === 0; + } + /** * Check if user is me. */ @@ -138,4 +145,12 @@ class User extends Authenticatable { return ! is_null($this->phone_verified_at); } + + /** + * Profile page of user + */ + public function profilePage(): string + { + return '/resources/users/'. $this->id; + } } diff --git a/app/Nova/Resources/System/Roles/Permission.php b/app/Nova/Resources/System/Roles/Permission.php index 3ea30cc..b265b10 100644 --- a/app/Nova/Resources/System/Roles/Permission.php +++ b/app/Nova/Resources/System/Roles/Permission.php @@ -32,13 +32,6 @@ class Permission extends Resource 'id', 'name', ]; - /** - * Indicates if the resource should be displayed in the sidebar. - * - * @var bool - */ - public static $displayInNavigation = false; - /** * Get the fields displayed by the resource. */ diff --git a/app/Policies/Order/Card/CardOrderPolicy.php b/app/Policies/Order/Card/CardOrderPolicy.php new file mode 100644 index 0000000..df833cc --- /dev/null +++ b/app/Policies/Order/Card/CardOrderPolicy.php @@ -0,0 +1,119 @@ +isOperator() && $user->cannot('viewCardOrders')) { + return false; + } + + return true; + } + + /** + * Determine whether the user can view the model. + */ + public function view(User $user, CardOrder $cardOrder): bool + { + if ($user->isAdmin()) { + return true; + } + + if ($user->isOperator() && $user->can('viewCardOrders')) { + return $user->branches()->where('branches.id', $loanOrder->branch_id)->exists(); + } + + if ($user->ownsLoanOrder($loanOrder)) { + return true; + } + + return false; + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + if ($user->isOperator() && $user->cannot('viewCardOrders')) { + return false; + } + + return true; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, CardOrder $cardOrder): bool + { + if ($user->isAdmin()) { + return true; + } + + if ($user->isOperator() && $user->can('viewCardOrders')) { + return $user->branches()->where('branches.id', $loanOrder->branch_id)->exists(); + } + + if ($user->ownsLoanOrder($loanOrder) && in_array($loanOrder->status, [ + OrderRepo::PENDING, + ])) { + return true; + } + + return false; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, CardOrder $cardOrder): bool + { + if ($user->isAdmin()) { + return true; + } + + if ($user->isOperator() && $user->can('viewLoanOrders')) { + return $user->branches()->where('branches.id', $loanOrder->branch_id)->exists(); + } + + if ($user->ownsLoanOrder($loanOrder)) { + return true; + } + + return false; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, CardOrder $cardOrder): bool + { + if ($user->isMe()) { + return true; + } + + return false; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, CardOrder $cardOrder): bool + { + if ($user->isMe()) { + return true; + } + + return false; + } +} diff --git a/app/Policies/Order/Card/CardStatePolicy.php b/app/Policies/Order/Card/CardStatePolicy.php new file mode 100644 index 0000000..02c68d5 --- /dev/null +++ b/app/Policies/Order/Card/CardStatePolicy.php @@ -0,0 +1,93 @@ +isAdmin()) { + return true; + } + + return false; + } + + /** + * Determine whether the user can view the model. + */ + public function view(User $user, CardState $cardState): bool + { + if ($user->isAdmin()) { + return true; + } + + return false; + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + if ($user->isAdmin()) { + return true; + } + + return false; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, CardState $cardState): bool + { + if ($user->isAdmin()) { + return true; + } + + return false; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, CardState $cardState): bool + { + if ($user->isAdmin()) { + return true; + } + + return false; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, CardState $cardState): bool + { + if ($user->isAdmin()) { + return true; + } + + return false; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, CardState $cardState): bool + { + if ($user->isAdmin()) { + return true; + } + + return false; + } +} diff --git a/app/Policies/Order/Card/CardTypePolicy.php b/app/Policies/Order/Card/CardTypePolicy.php new file mode 100644 index 0000000..d19ab47 --- /dev/null +++ b/app/Policies/Order/Card/CardTypePolicy.php @@ -0,0 +1,93 @@ +isAdmin()) { + return true; + } + + return false; + } + + /** + * Determine whether the user can view the model. + */ + public function view(User $user, CardType $cardType): bool + { + if ($user->isAdmin()) { + return true; + } + + return false; + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + if ($user->isAdmin()) { + return true; + } + + return false; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, CardType $cardType): bool + { + if ($user->isAdmin()) { + return true; + } + + return false; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, CardType $cardType): bool + { + if ($user->isAdmin()) { + return true; + } + + return false; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, CardType $cardType): bool + { + if ($user->isAdmin()) { + return true; + } + + return false; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, CardType $cardType): bool + { + if ($user->isAdmin()) { + return true; + } + + return false; + } +} diff --git a/app/Policies/Order/Loan/LoanOrderPolicy.php b/app/Policies/Order/Loan/LoanOrderPolicy.php index 32f5c78..fa86a8c 100644 --- a/app/Policies/Order/Loan/LoanOrderPolicy.php +++ b/app/Policies/Order/Loan/LoanOrderPolicy.php @@ -99,7 +99,7 @@ class LoanOrderPolicy */ public function restore(User $user, LoanOrder $loanOrder): bool { - if ($user->isAdmin()) { + if ($user->isMe()) { return true; } @@ -111,7 +111,7 @@ class LoanOrderPolicy */ public function forceDelete(User $user, LoanOrder $loanOrder): bool { - if ($user->isAdmin()) { + if ($user->isMe()) { return true; } diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 90458c3..8a52e5d 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -61,8 +61,5 @@ class AuthServiceProvider extends ServiceProvider // Tooling permissions... Gate::define('viewPulse', fn ($user) => $user->isMe()); - - // LoanOrder permissions... - Gate::define('viewLoanOrders', fn ($user) => $user->isSystemUser()); } } diff --git a/app/Providers/NovaServiceProvider.php b/app/Providers/NovaServiceProvider.php index 6e944ec..e34492d 100644 --- a/app/Providers/NovaServiceProvider.php +++ b/app/Providers/NovaServiceProvider.php @@ -31,6 +31,14 @@ use Stepanenko3\LogsTool\LogsTool; class NovaServiceProvider extends NovaApplicationServiceProvider { + /** + * Register any application services. + */ + public function register(): void + { + Nova::initialPath(NovaRepo::initialPath()); + } + /** * Bootstrap any application services. */ @@ -39,7 +47,7 @@ class NovaServiceProvider extends NovaApplicationServiceProvider parent::boot(); Nova::withBreadcrumbs(); - Nova::footer(fn () => view('vendor.nova.partials.footer')->render()); + Nova::footer(NovaRepo::footer()); $this->setupNavigation(); $this->setupUserNavigation(); @@ -66,9 +74,7 @@ class NovaServiceProvider extends NovaApplicationServiceProvider */ protected function gate(): void { - Gate::define('viewNova', function ($user) { - return $user->isSystemUser() || $user->phoneIsVerified(); - }); + Gate::define('viewNova', NovaRepo::viewNova()); } /** @@ -92,23 +98,15 @@ class NovaServiceProvider extends NovaApplicationServiceProvider ->onSwitchLocale(NovaRepo::localeSwitcherSave()), BackupTool::make() - ->canSee(fn () => auth()->user()->isMe()), + ->canSee(NovaRepo::isMe()), LogsTool::make() - ->canSee(fn () => Gate::allows('isMe', auth()->user())) - ->canDownload(fn () => Gate::allows('isMe', auth()->user())) - ->canDelete(fn () => Gate::allows('isMe', auth()->user())), + ->canSee(NovaRepo::isMe()) + ->canDownload(NovaRepo::isMe()) + ->canDelete(NovaRepo::isMe()), ]; } - /** - * Register any application services. - */ - public function register(): void - { - // - } - /** * Setup navigation */ @@ -165,7 +163,7 @@ class NovaServiceProvider extends NovaApplicationServiceProvider public function setupUserNavigation(): void { Nova::userMenu(function (Request $request, Menu $menu) { - $menu->prepend(MenuItem::make(__('My Profile'), sprintf('/resources/users/%s', $request->user()->id))); + $menu->prepend(MenuItem::make(__('My Profile'), $request->user()->profilePage())); return $menu; }); diff --git a/app/Repos/Order/Loan/LoanOrderRepo.php b/app/Repos/Order/Loan/LoanOrderRepo.php index 333fa7b..ad4aafa 100644 --- a/app/Repos/Order/Loan/LoanOrderRepo.php +++ b/app/Repos/Order/Loan/LoanOrderRepo.php @@ -3,6 +3,7 @@ namespace App\Repos\Order\Loan; use App\Models\Branch\Branch; +use App\Repos\Order\OrderRepo; use Closure; class LoanOrderRepo diff --git a/app/Repos/System/Nova/NovaRepo.php b/app/Repos/System/Nova/NovaRepo.php index 3196850..bec1452 100644 --- a/app/Repos/System/Nova/NovaRepo.php +++ b/app/Repos/System/Nova/NovaRepo.php @@ -5,10 +5,17 @@ namespace App\Repos\System\Nova; use App\Models\System\Location\Province; use Closure; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Gate; use Laravel\Nova\Events\ServingNova; class NovaRepo { + /** + * Initial path + * @var string + */ + protected static string $initialPath = '/dashboards/main'; + /** * Serving nova application */ @@ -17,6 +24,24 @@ class NovaRepo static::setLocale($event); } + /** + * Initial path for nova + */ + public static function initialPath(): string + { + return request()->user() && request()->user()->withoutRole() + ? request()->user()->profilePage() + : static::$initialPath; + } + + /** + * This gate determines who can access Nova in non-local environments. + */ + public static function viewNova(): Closure + { + return fn ($user) => $user->isSystemUser() || $user->phoneIsVerified(); + } + /** * Set locales */ @@ -43,6 +68,22 @@ class NovaRepo }; } + /** + * Nova Footer + */ + public static function footer(): Closure + { + return fn () => view('vendor.nova.partials.footer')->render(); + } + + /** + * Check if user is me + */ + public static function isMe(): Closure + { + return fn () => Gate::allows('isMe', auth()->user()); + } + /** * Depends on region */ diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 28c62c2..7e988d3 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -17,6 +17,7 @@ class DatabaseSeeder extends Seeder ProvinceTableSeeder::class, BranchTableSeeder::class, LoanTypeSeeder::class, + PermissionTableSeeder::class, ]); } } diff --git a/database/seeders/PermissionTableSeeder.php b/database/seeders/PermissionTableSeeder.php new file mode 100644 index 0000000..a4fd5fc --- /dev/null +++ b/database/seeders/PermissionTableSeeder.php @@ -0,0 +1,23 @@ +each(fn ($name) => Permission::create([ + 'name' => $name, + 'guard_name' => 'web', + ])); + } +}