diff --git a/app/Filament/Resources/PermissionResource.php b/app/Filament/Resources/PermissionResource.php new file mode 100644 index 0000000000..ee12e500cb --- /dev/null +++ b/app/Filament/Resources/PermissionResource.php @@ -0,0 +1,75 @@ +schema([ + Forms\Components\TextInput::make('name') + ->required() + ->maxLength(125), + Forms\Components\TextInput::make('guard_name') + ->required() + ->maxLength(125), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('name') + ->searchable(), + Tables\Columns\TextColumn::make('guard_name') + ->searchable(), + Tables\Columns\TextColumn::make('created_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + Tables\Columns\TextColumn::make('updated_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + ]) + ->filters([ + ]) + ->actions([ + Tables\Actions\ViewAction::make(), + ]); + } + + public static function getRelations(): array + { + return [ + RolesRelationManager::class, + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListPermissions::route('/'), + 'view' => Pages\ViewPermission::route('/{record}'), + ]; + } +} diff --git a/app/Filament/Resources/PermissionResource/Pages/ListPermissions.php b/app/Filament/Resources/PermissionResource/Pages/ListPermissions.php new file mode 100644 index 0000000000..8bb30c0de9 --- /dev/null +++ b/app/Filament/Resources/PermissionResource/Pages/ListPermissions.php @@ -0,0 +1,28 @@ + Tab::make('Web') + ->modifyQueryUsing(fn (Builder $query) => $query->web()), + 'api' => Tab::make('Api') + ->modifyQueryUsing(fn (Builder $query) => $query->api()), + ]; + } + + protected function getHeaderActions(): array + { + return []; + } +} diff --git a/app/Filament/Resources/PermissionResource/Pages/ViewPermission.php b/app/Filament/Resources/PermissionResource/Pages/ViewPermission.php new file mode 100644 index 0000000000..751771b372 --- /dev/null +++ b/app/Filament/Resources/PermissionResource/Pages/ViewPermission.php @@ -0,0 +1,17 @@ +schema([ + Forms\Components\TextInput::make('name') + ->required() + ->maxLength(255), + ]); + } + + public function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('name'), + ]) + ->filters([ + ]) + ->headerActions([ + Tables\Actions\CreateAction::make(), + ]) + ->actions([ + Tables\Actions\EditAction::make(), + Tables\Actions\DeleteAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app/Filament/Resources/RoleResource.php b/app/Filament/Resources/RoleResource.php new file mode 100644 index 0000000000..be339d2289 --- /dev/null +++ b/app/Filament/Resources/RoleResource.php @@ -0,0 +1,84 @@ +schema([ + Forms\Components\TextInput::make('name') + ->required() + ->maxLength(125), + Forms\Components\TextInput::make('guard_name') + ->required() + ->maxLength(125), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('name') + ->searchable(), + Tables\Columns\TextColumn::make('guard_name') + ->searchable(), + Tables\Columns\TextColumn::make('created_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + Tables\Columns\TextColumn::make('updated_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + ]) + ->actions([ + Tables\Actions\ViewAction::make(), + ]) + ->bulkActions([ + ]); + } + + public static function getRelations(): array + { + return [ + PermissionsRelationManager::class, + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListRoles::route('/'), + 'create' => Pages\CreateRole::route('/create'), + 'view' => Pages\ViewRole::route('/{record}'), + 'edit' => Pages\EditRole::route('/{record}/edit'), + ]; + } + + public static function getEloquentQuery(): Builder + { + return parent::getEloquentQuery() + ->withoutGlobalScopes([]); + } +} diff --git a/app/Filament/Resources/RoleResource/Pages/CreateRole.php b/app/Filament/Resources/RoleResource/Pages/CreateRole.php new file mode 100644 index 0000000000..0891e261ef --- /dev/null +++ b/app/Filament/Resources/RoleResource/Pages/CreateRole.php @@ -0,0 +1,11 @@ + Tab::make('Web') + ->modifyQueryUsing(fn (Builder $query) => $query->web()), + 'api' => Tab::make('Api') + ->modifyQueryUsing(fn (Builder $query) => $query->api()), + ]; + } + + protected function getHeaderActions(): array + { + return [ + Actions\CreateAction::make(), + ]; + } +} diff --git a/app/Filament/Resources/RoleResource/Pages/ViewRole.php b/app/Filament/Resources/RoleResource/Pages/ViewRole.php new file mode 100644 index 0000000000..b4e8a0c5f2 --- /dev/null +++ b/app/Filament/Resources/RoleResource/Pages/ViewRole.php @@ -0,0 +1,17 @@ +schema([ + Forms\Components\TextInput::make('name') + ->required() + ->maxLength(255), + ]); + } + + public function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('name'), + ]) + ->filters([ + ]) + ->headerActions([ + Tables\Actions\CreateAction::make(), + ]) + ->actions([ + Tables\Actions\EditAction::make(), + Tables\Actions\DeleteAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app/Models/Permission.php b/app/Models/Permission.php index d797c00732..657a2ac806 100644 --- a/app/Models/Permission.php +++ b/app/Models/Permission.php @@ -4,6 +4,7 @@ use Illuminate\Support\Collection; use App\Models\Concerns\DefinesPermissions; +use Illuminate\Contracts\Database\Eloquent\Builder; use Spatie\Permission\Models\Permission as SpatiePermission; class Permission extends SpatiePermission @@ -19,4 +20,14 @@ public function getApiPermissions(): Collection { return collect([]); } + + public function scopeApi(Builder $query): void + { + $query->where('guard_name', 'api'); + } + + public function scopeWeb(Builder $query): void + { + $query->where('guard_name', 'web'); + } } diff --git a/app/Models/Role.php b/app/Models/Role.php index 966d358d2f..680a94e287 100644 --- a/app/Models/Role.php +++ b/app/Models/Role.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Support\Collection; use Illuminate\Database\Eloquent\Builder; use App\Models\Concerns\DefinesPermissions; use Spatie\Permission\Models\Role as SpatieRole; @@ -10,6 +11,16 @@ class Role extends SpatieRole { use DefinesPermissions; + public function getWebPermissions(): Collection + { + return collect(['view-any', '*.view']); + } + + public function getApiPermissions(): Collection + { + return collect([]); + } + public function scopeApi(Builder $query): void { $query->where('guard_name', 'api'); @@ -19,4 +30,14 @@ public function scopeWeb(Builder $query): void { $query->where('guard_name', 'web'); } + + public function scopeSuperAdmin(Builder $query): void + { + $query->where('name', 'super_admin'); + } + + public function scopeAdmin(Builder $query): void + { + $query->where('name', 'admin'); + } } diff --git a/app/Models/User.php b/app/Models/User.php index c6868138e6..a87bcf60a7 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -14,7 +14,6 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Contracts\Translation\HasLocalePreference; -use Illuminate\Database\Eloquent\Relations\BelongsToMany; /** * @mixin IdeHelperUser @@ -111,11 +110,6 @@ public function setPasswordAttribute($input) } } - public function roles(): BelongsToMany - { - return $this->belongsToMany(Role::class); - } - public function getTypeLabelAttribute($value) { return static::TYPE_RADIO[$this->type] ?? null; diff --git a/app/Policies/PermissionPolicy.php b/app/Policies/PermissionPolicy.php new file mode 100644 index 0000000000..17d2a88467 --- /dev/null +++ b/app/Policies/PermissionPolicy.php @@ -0,0 +1,65 @@ +hasPermissionTo('permission.view-any'); + } + + /** + * Determine whether the user can view the model. + */ + public function view(User $user, Permission $permission): bool + { + return $user->hasPermissionTo('permission.*.view'); + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + return false; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, Permission $permission): bool + { + return false; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, Permission $permission): bool + { + return false; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, Permission $permission): bool + { + return false; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, Permission $permission): bool + { + return false; + } +} diff --git a/app/Policies/RolePolicy.php b/app/Policies/RolePolicy.php new file mode 100644 index 0000000000..cdc308647a --- /dev/null +++ b/app/Policies/RolePolicy.php @@ -0,0 +1,65 @@ +hasPermissionTo('role.view-any'); + } + + /** + * Determine whether the user can view the model. + */ + public function view(User $user, Role $role): bool + { + return $user->hasPermissionTo('role.*.view'); + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + return false; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, Role $role): bool + { + return false; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, Role $role): bool + { + return false; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, Role $role): bool + { + return false; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, Role $role): bool + { + return false; + } +} diff --git a/composer.json b/composer.json index 6099777f40..ad2a6f8b6f 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,7 @@ "require-dev": { "barryvdh/laravel-ide-helper": "^2.13", "brianium/paratest": "^7.2", + "doctrine/dbal": "^3.6", "fakerphp/faker": "^1.9.1", "friendsofphp/php-cs-fixer": "^3.21", "laravel/sail": "^1.18", diff --git a/composer.lock b/composer.lock index 02970c0d81..8eca8b1355 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4eaeeaa4c663e8a63741f92397abe458", + "content-hash": "d0601ec464ffdbba08fc7d306ed0a9b1", "packages": [ { "name": "aws/aws-crt-php", diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index e0e21b090d..c4edb051bb 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -12,8 +12,6 @@ class UserFactory extends Factory { /** * Define the model's default state. - * - * @return array */ public function definition(): array { @@ -28,8 +26,6 @@ public function definition(): array /** * Indicate that the model's email address should be unverified. - * - * @return $this */ public function unverified(): static { diff --git a/database/seeders/UsersTableSeeder.php b/database/seeders/UsersTableSeeder.php index fa43d20a74..089db4ea6f 100644 --- a/database/seeders/UsersTableSeeder.php +++ b/database/seeders/UsersTableSeeder.php @@ -2,25 +2,35 @@ namespace Database\Seeders; +use App\Models\Role; use App\Models\User; use Illuminate\Database\Seeder; +use Illuminate\Support\Facades\Hash; class UsersTableSeeder extends Seeder { - public function run() + public function run(): void { - $users = [ - [ - 'id' => 1, - 'name' => 'Admin', - 'email' => 'admin@admin.com', - 'password' => bcrypt('password'), - 'remember_token' => null, - 'locale' => '', - 'emplid' => '', - ], - ]; - - User::insert($users); + /** Super Admin */ + $superAdmin = User::factory()->create([ + 'name' => 'Super Admin', + 'email' => 'superadmin@assist.com', + 'password' => bcrypt('password'), + ]); + + $superAdminRoles = Role::superAdmin()->get(); + + $superAdmin->assignRole($superAdminRoles); + + /** Admin */ + $admin = User::factory()->create([ + 'name' => 'Admin', + 'email' => 'admin@assist.com', + 'password' => Hash::make('password'), + ]); + + $adminRoles = Role::admin()->get(); + + $admin->assignRole($adminRoles); } }