Compare commits
2 Commits
58a28884c4
...
067dae36c4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
067dae36c4 | ||
|
|
79dbeb21ac |
64
app/Http/Controllers/RolesController.php
Normal file
64
app/Http/Controllers/RolesController.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class RolesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
126
app/Http/Controllers/UsersController.php
Normal file
126
app/Http/Controllers/UsersController.php
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\StoreUserRequest;
|
||||
use App\Http\Requests\UpdateUserRequest;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
class UsersController extends Controller
|
||||
{
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
$this->middleware('permission:create-user|edit-user|delete-user', ['only' => ['index', 'show']]);
|
||||
$this->middleware('permission:create-user', ['only' => ['create', 'store']]);
|
||||
$this->middleware('permission:edit-user', ['only' => ['edit', 'update']]);
|
||||
$this->middleware('permission:delete-user', ['only' => ['destroy']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('users.index', [
|
||||
'users' => User::latest('id')->paginate(3)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('users.create', [
|
||||
'roles' => Role::pluck('name')->all()
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(StoreUserRequest $request)
|
||||
{
|
||||
$input = $request->all();
|
||||
$input['password'] = Hash::make($request->password);
|
||||
|
||||
$user = User::create($input);
|
||||
$user->assignRole($request->roles);
|
||||
|
||||
return redirect()->route('users.index')
|
||||
->withSuccess('New user is added successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(User $user)
|
||||
{
|
||||
return view('users.show', [
|
||||
'user' => $user
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(User $user)
|
||||
{
|
||||
// Check Only Super Admin can update his own Profile
|
||||
if ($user->hasRole('ADMIN')){
|
||||
if($user->id != auth()->user()->id){
|
||||
abort(403, 'USER DOES NOT HAVE THE RIGHT PERMISSIONS');
|
||||
}
|
||||
}
|
||||
|
||||
return view('users.edit', [
|
||||
'user' => $user,
|
||||
'roles' => Role::pluck('name')->all(),
|
||||
'userRoles' => $user->roles->pluck('name')->all()
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(UpdateUserRequest $request, User $user)
|
||||
{
|
||||
$input = $request->all();
|
||||
|
||||
if(!empty($request->password)){
|
||||
$input['password'] = Hash::make($request->password);
|
||||
}else{
|
||||
$input = $request->except('password');
|
||||
}
|
||||
|
||||
$user->update($input);
|
||||
|
||||
$user->syncRoles($request->roles);
|
||||
|
||||
return redirect()->back()
|
||||
->withSuccess('User is updated successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(User $user)
|
||||
{
|
||||
// About if user is Super Admin or User ID belongs to Auth User
|
||||
if ($user->hasRole('Super Admin') || $user->id == auth()->user()->id)
|
||||
{
|
||||
abort(403, 'USER DOES NOT HAVE THE RIGHT PERMISSIONS');
|
||||
}
|
||||
|
||||
$user->syncRoles([]);
|
||||
$user->delete();
|
||||
return redirect()->route('users.index')
|
||||
->withSuccess('User is deleted successfully.');
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,12 @@ use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
class WordsController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('role:ADMIN');
|
||||
}
|
||||
|
||||
|
||||
public function index()
|
||||
{
|
||||
return view('words.index', [
|
||||
|
||||
@@ -40,7 +40,7 @@ class Kernel extends HttpKernel
|
||||
|
||||
'api' => [
|
||||
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
||||
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
|
||||
\Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
@@ -64,5 +64,9 @@ class Kernel extends HttpKernel
|
||||
'signed' => \App\Http\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
//SPATIE PERMISSION
|
||||
'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,
|
||||
'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
|
||||
'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
|
||||
];
|
||||
}
|
||||
|
||||
31
app/Http/Requests/StoreUserRequest.php
Normal file
31
app/Http/Requests/StoreUserRequest.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreUserRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|max:250',
|
||||
'email' => 'required|string|email:rfc,dns|max:250|unique:users,email',
|
||||
'password' => 'required|string|min:8|confirmed',
|
||||
'roles' => 'required'
|
||||
];
|
||||
}
|
||||
}
|
||||
31
app/Http/Requests/UpdateUserRequest.php
Normal file
31
app/Http/Requests/UpdateUserRequest.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateUserRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|max:250',
|
||||
'email' => 'required|string|email:rfc,dns|max:250|unique:users,email,'.$this->user->id,
|
||||
'password' => 'nullable|string|min:8|confirmed',
|
||||
'roles' => 'required'
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,13 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
use Spatie\Permission\Models\Role;
|
||||
use Spatie\Permission\Traits\HasRoles;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasApiTokens, HasFactory, Notifiable;
|
||||
use HasApiTokens, HasFactory, Notifiable, HasRoles;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
@@ -42,4 +45,5 @@ class User extends Authenticatable
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Providers;
|
||||
|
||||
// use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
@@ -21,6 +22,8 @@ class AuthServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
//
|
||||
Gate::before(function ($user, $ability) {
|
||||
return $user->hasRole('ADMIN') ? true : null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
"guzzlehttp/guzzle": "^7.2",
|
||||
"laravel/framework": "^10.10",
|
||||
"laravel/sanctum": "^3.3",
|
||||
"laravel/tinker": "^2.8"
|
||||
"laravel/tinker": "^2.8",
|
||||
"spatie/laravel-permission": "^6.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
|
||||
186
config/permission.php
Normal file
186
config/permission.php
Normal file
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'models' => [
|
||||
|
||||
/*
|
||||
* When using the "HasPermissions" trait from this package, we need to know which
|
||||
* Eloquent model should be used to retrieve your permissions. Of course, it
|
||||
* is often just the "Permission" model but you may use whatever you like.
|
||||
*
|
||||
* The model you want to use as a Permission model needs to implement the
|
||||
* `Spatie\Permission\Contracts\Permission` contract.
|
||||
*/
|
||||
|
||||
'permission' => Spatie\Permission\Models\Permission::class,
|
||||
|
||||
/*
|
||||
* When using the "HasRoles" trait from this package, we need to know which
|
||||
* Eloquent model should be used to retrieve your roles. Of course, it
|
||||
* is often just the "Role" model but you may use whatever you like.
|
||||
*
|
||||
* The model you want to use as a Role model needs to implement the
|
||||
* `Spatie\Permission\Contracts\Role` contract.
|
||||
*/
|
||||
|
||||
'role' => Spatie\Permission\Models\Role::class,
|
||||
|
||||
],
|
||||
|
||||
'table_names' => [
|
||||
|
||||
/*
|
||||
* When using the "HasRoles" trait from this package, we need to know which
|
||||
* table should be used to retrieve your roles. We have chosen a basic
|
||||
* default value but you may easily change it to any table you like.
|
||||
*/
|
||||
|
||||
'roles' => 'roles',
|
||||
|
||||
/*
|
||||
* When using the "HasPermissions" trait from this package, we need to know which
|
||||
* table should be used to retrieve your permissions. We have chosen a basic
|
||||
* default value but you may easily change it to any table you like.
|
||||
*/
|
||||
|
||||
'permissions' => 'permissions',
|
||||
|
||||
/*
|
||||
* When using the "HasPermissions" trait from this package, we need to know which
|
||||
* table should be used to retrieve your models permissions. We have chosen a
|
||||
* basic default value but you may easily change it to any table you like.
|
||||
*/
|
||||
|
||||
'model_has_permissions' => 'model_has_permissions',
|
||||
|
||||
/*
|
||||
* When using the "HasRoles" trait from this package, we need to know which
|
||||
* table should be used to retrieve your models roles. We have chosen a
|
||||
* basic default value but you may easily change it to any table you like.
|
||||
*/
|
||||
|
||||
'model_has_roles' => 'model_has_roles',
|
||||
|
||||
/*
|
||||
* When using the "HasRoles" trait from this package, we need to know which
|
||||
* table should be used to retrieve your roles permissions. We have chosen a
|
||||
* basic default value but you may easily change it to any table you like.
|
||||
*/
|
||||
|
||||
'role_has_permissions' => 'role_has_permissions',
|
||||
],
|
||||
|
||||
'column_names' => [
|
||||
/*
|
||||
* Change this if you want to name the related pivots other than defaults
|
||||
*/
|
||||
'role_pivot_key' => null, //default 'role_id',
|
||||
'permission_pivot_key' => null, //default 'permission_id',
|
||||
|
||||
/*
|
||||
* Change this if you want to name the related model primary key other than
|
||||
* `model_id`.
|
||||
*
|
||||
* For example, this would be nice if your primary keys are all UUIDs. In
|
||||
* that case, name this `model_uuid`.
|
||||
*/
|
||||
|
||||
'model_morph_key' => 'model_id',
|
||||
|
||||
/*
|
||||
* Change this if you want to use the teams feature and your related model's
|
||||
* foreign key is other than `team_id`.
|
||||
*/
|
||||
|
||||
'team_foreign_key' => 'team_id',
|
||||
],
|
||||
|
||||
/*
|
||||
* When set to true, the method for checking permissions will be registered on the gate.
|
||||
* Set this to false if you want to implement custom logic for checking permissions.
|
||||
*/
|
||||
|
||||
'register_permission_check_method' => true,
|
||||
|
||||
/*
|
||||
* When set to true, Laravel\Octane\Events\OperationTerminated event listener will be registered
|
||||
* this will refresh permissions on every TickTerminated, TaskTerminated and RequestTerminated
|
||||
* NOTE: This should not be needed in most cases, but an Octane/Vapor combination benefited from it.
|
||||
*/
|
||||
'register_octane_reset_listener' => false,
|
||||
|
||||
/*
|
||||
* Teams Feature.
|
||||
* When set to true the package implements teams using the 'team_foreign_key'.
|
||||
* If you want the migrations to register the 'team_foreign_key', you must
|
||||
* set this to true before doing the migration.
|
||||
* If you already did the migration then you must make a new migration to also
|
||||
* add 'team_foreign_key' to 'roles', 'model_has_roles', and 'model_has_permissions'
|
||||
* (view the latest version of this package's migration file)
|
||||
*/
|
||||
|
||||
'teams' => false,
|
||||
|
||||
/*
|
||||
* Passport Client Credentials Grant
|
||||
* When set to true the package will use Passports Client to check permissions
|
||||
*/
|
||||
|
||||
'use_passport_client_credentials' => false,
|
||||
|
||||
/*
|
||||
* When set to true, the required permission names are added to exception messages.
|
||||
* This could be considered an information leak in some contexts, so the default
|
||||
* setting is false here for optimum safety.
|
||||
*/
|
||||
|
||||
'display_permission_in_exception' => false,
|
||||
|
||||
/*
|
||||
* When set to true, the required role names are added to exception messages.
|
||||
* This could be considered an information leak in some contexts, so the default
|
||||
* setting is false here for optimum safety.
|
||||
*/
|
||||
|
||||
'display_role_in_exception' => false,
|
||||
|
||||
/*
|
||||
* By default wildcard permission lookups are disabled.
|
||||
* See documentation to understand supported syntax.
|
||||
*/
|
||||
|
||||
'enable_wildcard_permission' => false,
|
||||
|
||||
/*
|
||||
* The class to use for interpreting wildcard permissions.
|
||||
* If you need to modify delimiters, override the class and specify its name here.
|
||||
*/
|
||||
// 'permission.wildcard_permission' => Spatie\Permission\WildcardPermission::class,
|
||||
|
||||
/* Cache-specific settings */
|
||||
|
||||
'cache' => [
|
||||
|
||||
/*
|
||||
* By default all permissions are cached for 24 hours to speed up performance.
|
||||
* When permissions or roles are updated the cache is flushed automatically.
|
||||
*/
|
||||
|
||||
'expiration_time' => \DateInterval::createFromDateString('24 hours'),
|
||||
|
||||
/*
|
||||
* The cache key used to store all permissions.
|
||||
*/
|
||||
|
||||
'key' => 'spatie.permission.cache',
|
||||
|
||||
/*
|
||||
* You may optionally indicate a specific cache driver to use for permission and
|
||||
* role caching using any of the `store` drivers listed in the cache.php config
|
||||
* file. Using 'default' here means to use the `default` set in cache.php.
|
||||
*/
|
||||
|
||||
'store' => 'default',
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
$teams = config('permission.teams');
|
||||
$tableNames = config('permission.table_names');
|
||||
$columnNames = config('permission.column_names');
|
||||
$pivotRole = $columnNames['role_pivot_key'] ?? 'role_id';
|
||||
$pivotPermission = $columnNames['permission_pivot_key'] ?? 'permission_id';
|
||||
|
||||
if (empty($tableNames)) {
|
||||
throw new \Exception('Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.');
|
||||
}
|
||||
if ($teams && empty($columnNames['team_foreign_key'] ?? null)) {
|
||||
throw new \Exception('Error: team_foreign_key on config/permission.php not loaded. Run [php artisan config:clear] and try again.');
|
||||
}
|
||||
|
||||
Schema::create($tableNames['permissions'], function (Blueprint $table) {
|
||||
$table->bigIncrements('id'); // permission id
|
||||
$table->string('name'); // For MySQL 8.0 use string('name', 125);
|
||||
$table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125);
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['name', 'guard_name']);
|
||||
});
|
||||
|
||||
Schema::create($tableNames['roles'], function (Blueprint $table) use ($teams, $columnNames) {
|
||||
$table->bigIncrements('id'); // role id
|
||||
if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing
|
||||
$table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable();
|
||||
$table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index');
|
||||
}
|
||||
$table->string('name'); // For MySQL 8.0 use string('name', 125);
|
||||
$table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125);
|
||||
$table->timestamps();
|
||||
if ($teams || config('permission.testing')) {
|
||||
$table->unique([$columnNames['team_foreign_key'], 'name', 'guard_name']);
|
||||
} else {
|
||||
$table->unique(['name', 'guard_name']);
|
||||
}
|
||||
});
|
||||
|
||||
Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames, $pivotPermission, $teams) {
|
||||
$table->unsignedBigInteger($pivotPermission);
|
||||
|
||||
$table->string('model_type');
|
||||
$table->unsignedBigInteger($columnNames['model_morph_key']);
|
||||
$table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index');
|
||||
|
||||
$table->foreign($pivotPermission)
|
||||
->references('id') // permission id
|
||||
->on($tableNames['permissions'])
|
||||
->onDelete('cascade');
|
||||
if ($teams) {
|
||||
$table->unsignedBigInteger($columnNames['team_foreign_key']);
|
||||
$table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index');
|
||||
|
||||
$table->primary([$columnNames['team_foreign_key'], $pivotPermission, $columnNames['model_morph_key'], 'model_type'],
|
||||
'model_has_permissions_permission_model_type_primary');
|
||||
} else {
|
||||
$table->primary([$pivotPermission, $columnNames['model_morph_key'], 'model_type'],
|
||||
'model_has_permissions_permission_model_type_primary');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames, $pivotRole, $teams) {
|
||||
$table->unsignedBigInteger($pivotRole);
|
||||
|
||||
$table->string('model_type');
|
||||
$table->unsignedBigInteger($columnNames['model_morph_key']);
|
||||
$table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index');
|
||||
|
||||
$table->foreign($pivotRole)
|
||||
->references('id') // role id
|
||||
->on($tableNames['roles'])
|
||||
->onDelete('cascade');
|
||||
if ($teams) {
|
||||
$table->unsignedBigInteger($columnNames['team_foreign_key']);
|
||||
$table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index');
|
||||
|
||||
$table->primary([$columnNames['team_foreign_key'], $pivotRole, $columnNames['model_morph_key'], 'model_type'],
|
||||
'model_has_roles_role_model_type_primary');
|
||||
} else {
|
||||
$table->primary([$pivotRole, $columnNames['model_morph_key'], 'model_type'],
|
||||
'model_has_roles_role_model_type_primary');
|
||||
}
|
||||
});
|
||||
|
||||
Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames, $pivotRole, $pivotPermission) {
|
||||
$table->unsignedBigInteger($pivotPermission);
|
||||
$table->unsignedBigInteger($pivotRole);
|
||||
|
||||
$table->foreign($pivotPermission)
|
||||
->references('id') // permission id
|
||||
->on($tableNames['permissions'])
|
||||
->onDelete('cascade');
|
||||
|
||||
$table->foreign($pivotRole)
|
||||
->references('id') // role id
|
||||
->on($tableNames['roles'])
|
||||
->onDelete('cascade');
|
||||
|
||||
$table->primary([$pivotPermission, $pivotRole], 'role_has_permissions_permission_id_role_id_primary');
|
||||
});
|
||||
|
||||
app('cache')
|
||||
->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null)
|
||||
->forget(config('permission.cache.key'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
$tableNames = config('permission.table_names');
|
||||
|
||||
if (empty($tableNames)) {
|
||||
throw new \Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.');
|
||||
}
|
||||
|
||||
Schema::drop($tableNames['role_has_permissions']);
|
||||
Schema::drop($tableNames['model_has_roles']);
|
||||
Schema::drop($tableNames['model_has_permissions']);
|
||||
Schema::drop($tableNames['roles']);
|
||||
Schema::drop($tableNames['permissions']);
|
||||
}
|
||||
};
|
||||
24
database/seeders/AdminUserSeeder.php
Normal file
24
database/seeders/AdminUserSeeder.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class AdminUserSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$superAdmin = User::create([
|
||||
'name' => 'Kagir',
|
||||
'email' => 'kagir.dev@gmail.com ',
|
||||
'password' => Hash::make('Prova123!')
|
||||
]);
|
||||
$superAdmin->assignRole('ADMIN');
|
||||
}
|
||||
}
|
||||
@@ -12,11 +12,10 @@ class DatabaseSeeder extends Seeder
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// \App\Models\User::factory(10)->create();
|
||||
|
||||
// \App\Models\User::factory()->create([
|
||||
// 'name' => 'Test User',
|
||||
// 'email' => 'test@example.com',
|
||||
// ]);
|
||||
$this->call([
|
||||
PermissionSeeder::class,
|
||||
RoleSeeder::class,
|
||||
AdminUserSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
33
database/seeders/PermissionSeeder.php
Normal file
33
database/seeders/PermissionSeeder.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
|
||||
class PermissionSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$permissions = [
|
||||
'create-role',
|
||||
'edit-role',
|
||||
'delete-role',
|
||||
'create-user',
|
||||
'edit-user',
|
||||
'delete-user',
|
||||
'create-product',
|
||||
'edit-product',
|
||||
'delete-product'
|
||||
];
|
||||
|
||||
// Looping and Inserting Array's Permissions into Permission Table
|
||||
foreach ($permissions as $permission) {
|
||||
Permission::create(['name' => $permission]);
|
||||
}
|
||||
}
|
||||
}
|
||||
26
database/seeders/RoleSeeder.php
Normal file
26
database/seeders/RoleSeeder.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
class RoleSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$admin = Role::create(['name' => 'ADMIN']);
|
||||
$admin->givePermissionTo([
|
||||
'create-user',
|
||||
'edit-user',
|
||||
'delete-user',
|
||||
'create-product',
|
||||
'edit-product',
|
||||
'delete-product'
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
<!-- core:js -->
|
||||
<script src="assets/vendors/core/core.js"></script>
|
||||
<script src="/assets/vendors/core/core.js"></script>
|
||||
<!-- endinject -->
|
||||
|
||||
<!-- Plugin js for this page -->
|
||||
<script src="assets/vendors/flatpickr/flatpickr.min.js"></script>
|
||||
<script src="/assets/vendors/flatpickr/flatpickr.min.js"></script>
|
||||
<!-- End plugin js for this page -->
|
||||
|
||||
<!-- inject:js -->
|
||||
<script src="assets/vendors/feather-icons/feather.min.js"></script>
|
||||
<script src="assets/js/template.js"></script>
|
||||
<script src="/assets/vendors/feather-icons/feather.min.js"></script>
|
||||
<script src="/assets/js/template.js"></script>
|
||||
<!-- endinject -->
|
||||
|
||||
<!-- Custom js for this page -->
|
||||
<script src="assets/js/dashboard-dark.js"></script>
|
||||
<script src="/assets/js/dashboard-dark.js"></script>
|
||||
<!-- End custom js for this page -->
|
||||
|
||||
101
resources/views/users/create.blade.php
Normal file
101
resources/views/users/create.blade.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<x-app-layout>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="float-start">
|
||||
Add New User
|
||||
</div>
|
||||
<div class="float-end">
|
||||
<a href="{{ route('users.index') }}" class="btn btn-primary btn-sm">← Back</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form action="{{ route('users.store') }}" method="post">
|
||||
@csrf
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="name" class="col-md-4 col-form-label text-md-end text-start">Name</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control @error('name') is-invalid @enderror" id="name"
|
||||
name="name" value="{{ old('name') }}">
|
||||
@if ($errors->has('name'))
|
||||
<span class="text-danger">{{ $errors->first('name') }}</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-end text-start">Email
|
||||
Address</label>
|
||||
<div class="col-md-6">
|
||||
<input type="email" class="form-control @error('email') is-invalid @enderror" id="email"
|
||||
name="email" value="{{ old('email') }}">
|
||||
@if ($errors->has('email'))
|
||||
<span class="text-danger">{{ $errors->first('email') }}</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="password"
|
||||
class="col-md-4 col-form-label text-md-end text-start">Password</label>
|
||||
<div class="col-md-6">
|
||||
<input type="password" class="form-control @error('password') is-invalid @enderror"
|
||||
id="password" name="password">
|
||||
@if ($errors->has('password'))
|
||||
<span class="text-danger">{{ $errors->first('password') }}</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="password_confirmation" class="col-md-4 col-form-label text-md-end text-start">Confirm
|
||||
Password</label>
|
||||
<div class="col-md-6">
|
||||
<input type="password" class="form-control" id="password_confirmation"
|
||||
name="password_confirmation">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="roles" class="col-md-4 col-form-label text-md-end text-start">Roles</label>
|
||||
<div class="col-md-6">
|
||||
<select class="form-select @error('roles') is-invalid @enderror" multiple
|
||||
aria-label="Roles" id="roles" name="roles[]">
|
||||
@forelse ($roles as $role)
|
||||
|
||||
@if ($role!='Super Admin')
|
||||
<option
|
||||
value="{{ $role }}" {{ in_array($role, old('roles') ?? []) ? 'selected' : '' }}>
|
||||
{{ $role }}
|
||||
</option>
|
||||
@else
|
||||
@if (Auth::user()->hasRole('Super Admin'))
|
||||
<option
|
||||
value="{{ $role }}" {{ in_array($role, old('roles') ?? []) ? 'selected' : '' }}>
|
||||
{{ $role }}
|
||||
</option>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@empty
|
||||
|
||||
@endforelse
|
||||
</select>
|
||||
@if ($errors->has('roles'))
|
||||
<span class="text-danger">{{ $errors->first('roles') }}</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<input type="submit" class="col-md-3 offset-md-5 btn btn-primary" value="Add User">
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-app-layout>
|
||||
102
resources/views/users/edit.blade.php
Normal file
102
resources/views/users/edit.blade.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<x-app-layout>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="float-start">
|
||||
Edit User
|
||||
</div>
|
||||
<div class="float-end">
|
||||
<a href="{{ route('users.index') }}" class="btn btn-primary btn-sm">← Back</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form action="{{ route('users.update', $user->id) }}" method="post">
|
||||
@csrf
|
||||
@method("PUT")
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="name" class="col-md-4 col-form-label text-md-end text-start">Name</label>
|
||||
<div class="col-md-6">
|
||||
<input type="text" class="form-control @error('name') is-invalid @enderror" id="name"
|
||||
name="name" value="{{ $user->name }}">
|
||||
@if ($errors->has('name'))
|
||||
<span class="text-danger">{{ $errors->first('name') }}</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-end text-start">Email
|
||||
Address</label>
|
||||
<div class="col-md-6">
|
||||
<input type="email" class="form-control @error('email') is-invalid @enderror" id="email"
|
||||
name="email" value="{{ $user->email }}">
|
||||
@if ($errors->has('email'))
|
||||
<span class="text-danger">{{ $errors->first('email') }}</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="password"
|
||||
class="col-md-4 col-form-label text-md-end text-start">Password</label>
|
||||
<div class="col-md-6">
|
||||
<input type="password" class="form-control @error('password') is-invalid @enderror"
|
||||
id="password" name="password">
|
||||
@if ($errors->has('password'))
|
||||
<span class="text-danger">{{ $errors->first('password') }}</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="password_confirmation" class="col-md-4 col-form-label text-md-end text-start">Confirm
|
||||
Password</label>
|
||||
<div class="col-md-6">
|
||||
<input type="password" class="form-control" id="password_confirmation"
|
||||
name="password_confirmation">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="roles" class="col-md-4 col-form-label text-md-end text-start">Roles</label>
|
||||
<div class="col-md-6">
|
||||
<select class="form-select @error('roles') is-invalid @enderror" multiple
|
||||
aria-label="Roles" id="roles" name="roles[]">
|
||||
@forelse ($roles as $role)
|
||||
|
||||
@if ($role!='Super Admin')
|
||||
<option
|
||||
value="{{ $role }}" {{ in_array($role, $userRoles ?? []) ? 'selected' : '' }}>
|
||||
{{ $role }}
|
||||
</option>
|
||||
@else
|
||||
@if (Auth::user()->hasRole('Super Admin'))
|
||||
<option
|
||||
value="{{ $role }}" {{ in_array($role, $userRoles ?? []) ? 'selected' : '' }}>
|
||||
{{ $role }}
|
||||
</option>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@empty
|
||||
|
||||
@endforelse
|
||||
</select>
|
||||
@if ($errors->has('roles'))
|
||||
<span class="text-danger">{{ $errors->first('roles') }}</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<input type="submit" class="col-md-3 offset-md-5 btn btn-primary" value="Update User">
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-app-layout>
|
||||
70
resources/views/users/index.blade.php
Normal file
70
resources/views/users/index.blade.php
Normal file
@@ -0,0 +1,70 @@
|
||||
vi
|
||||
<div class="card">
|
||||
<div class="card-header">Manage Users</div>
|
||||
<div class="card-body">
|
||||
@can('create-user')
|
||||
<a href="{{ route('users.create') }}" class="btn btn-success btn-sm my-2"><i class="bi bi-plus-circle"></i> Add New User</a>
|
||||
@endcan
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">S#</th>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Email</th>
|
||||
<th scope="col">Roles</th>
|
||||
<th scope="col">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($users as $user)
|
||||
<tr>
|
||||
<th scope="row">{{ $loop->iteration }}</th>
|
||||
<td>{{ $user->name }}</td>
|
||||
<td>{{ $user->email }}</td>
|
||||
<td>
|
||||
@forelse ($user->getRoleNames() as $role)
|
||||
<span class="badge bg-primary">{{ $role }}</span>
|
||||
@empty
|
||||
@endforelse
|
||||
</td>
|
||||
<td>
|
||||
<form action="{{ route('users.destroy', $user->id) }}" method="post">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
|
||||
<a href="{{ route('users.show', $user->id) }}" class="btn btn-warning btn-sm"><i class="bi bi-eye"></i> Show</a>
|
||||
|
||||
@if (in_array('Super Admin', $user->getRoleNames()->toArray() ?? []) )
|
||||
@if (Auth::user()->hasRole('Super Admin'))
|
||||
<a href="{{ route('users.edit', $user->id) }}" class="btn btn-primary btn-sm"><i class="bi bi-pencil-square"></i> Edit</a>
|
||||
@endif
|
||||
@else
|
||||
@can('edit-user')
|
||||
<a href="{{ route('users.edit', $user->id) }}" class="btn btn-primary btn-sm"><i class="bi bi-pencil-square"></i> Edit</a>
|
||||
@endcan
|
||||
|
||||
@can('delete-user')
|
||||
@if (Auth::user()->id!=$user->id)
|
||||
<button type="submit" class="btn btn-danger btn-sm" onclick="return confirm('Do you want to delete this user?');"><i class="bi bi-trash"></i> Delete</button>
|
||||
@endif
|
||||
@endcan
|
||||
@endif
|
||||
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<td colspan="5">
|
||||
<span class="text-danger">
|
||||
<strong>No User Found!</strong>
|
||||
</span>
|
||||
</td>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{{ $users->links() }}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</x-app-layout>
|
||||
44
resources/views/users/show.blade.php
Normal file
44
resources/views/users/show.blade.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<x-app-layout>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="float-start">
|
||||
User Information
|
||||
</div>
|
||||
<div class="float-end">
|
||||
<a href="{{ route('users.index') }}" class="btn btn-primary btn-sm">← Back</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="name" class="col-md-4 col-form-label text-md-end text-start"><strong>Name:</strong></label>
|
||||
<div class="col-md-6" style="line-height: 35px;">
|
||||
{{ $user->name }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-end text-start"><strong>Email
|
||||
Address:</strong></label>
|
||||
<div class="col-md-6" style="line-height: 35px;">
|
||||
{{ $user->email }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label for="roles"
|
||||
class="col-md-4 col-form-label text-md-end text-start"><strong>Roles:</strong></label>
|
||||
<div class="col-md-6" style="line-height: 35px;">
|
||||
@forelse ($user->getRoleNames() as $role)
|
||||
<span class="badge bg-primary">{{ $role }}</span>
|
||||
@empty
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-app-layout>
|
||||
@@ -1,9 +1,12 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\ProfileController;
|
||||
use App\Http\Controllers\RolesController;
|
||||
use App\Http\Controllers\UsersController;
|
||||
use App\Http\Controllers\WordsController;
|
||||
use App\Http\Controllers\FileController;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
/*
|
||||
@@ -40,6 +43,7 @@ Route::get('/pippo', function (Request $request) {
|
||||
});
|
||||
|
||||
|
||||
|
||||
Route::view('/prova','test')->name('prova');
|
||||
|
||||
Route::get('/dashboard', function () {
|
||||
@@ -64,6 +68,11 @@ Route::post('update_record/{id}', [WordsController::class, 'update'])->name('wor
|
||||
//***** FILE *****\\
|
||||
Route::post('datasubmit', [FileController::class, 'datasubmit'])->name("store");
|
||||
|
||||
Route::resources([
|
||||
'roles' => RolesController::class,
|
||||
'users' => UsersController::class,
|
||||
]);
|
||||
|
||||
require __DIR__ . '/auth.php';
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user