diff --git a/app/Exports/PermissionExport.php b/app/Exports/PermissionExport.php new file mode 100644 index 0000000..598e4b3 --- /dev/null +++ b/app/Exports/PermissionExport.php @@ -0,0 +1,47 @@ +map(function ($permission) { + $permission->roles = $permission->roles($permission); + + return $permission; + }); + } + + public function map($row): array{ + $role = $row->roles->pluck('name')->toArray(); + return [ + $row->id, + $row->name, + $row->roles == null? '' : implode(', ', $role), + $row->created_at + ]; + } + public function headings(): array{ + return [ + 'ID', + 'Permission', + 'Roles', + 'Created At' + ]; + } + + public function columnFormats(): array{ + return [ + 'A' => \PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER, + 'C' => \PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_DATETIME + ]; + } +} diff --git a/app/Http/Controllers/PermissionsController.php b/app/Http/Controllers/PermissionsController.php index bb63264..d7c27e7 100644 --- a/app/Http/Controllers/PermissionsController.php +++ b/app/Http/Controllers/PermissionsController.php @@ -3,67 +3,323 @@ namespace Modules\Usermanagement\Http\Controllers; use App\Http\Controllers\Controller; - use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; + use Illuminate\Support\Facades\Auth; + use Maatwebsite\Excel\Facades\Excel; + use Modules\Usermanagement\Exports\PermissionExport; + use Modules\Usermanagement\Http\Requests\PermissionRequest; + use Modules\Usermanagement\Models\Permission; + use Modules\Usermanagement\Models\PermissionGroup; + /** + * Class PermissionsController + * + * This controller is responsible for managing user permissions within the application. + * + * @package Modules\Usermanagement\Http\Controllers + */ class PermissionsController extends Controller { + /** + * @var \Illuminate\Contracts\Auth\Authenticatable|null + */ + public $user; /** * Display a listing of the resource. * - * @return \Illuminate\Contracts\View\View - * @return \Illuminate\Contracts\View\Factory + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + * @throws \Illuminate\Auth\Access\AuthorizationException */ public function index() { - return view('usermanagement::index'); + // Check if the authenticated user has the required permission to view permissions + if (is_null($this->user) || !$this->user->can('permissions.view')) { + //abort(403, 'Sorry! You are not allowed to view permissions.'); + } + + // Return the view for displaying the permissions + return view('usermanagement::permissions.index'); } + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * + * @return \Illuminate\Http\RedirectResponse + * @throws \Illuminate\Auth\Access\AuthorizationException + */ + public function store(PermissionRequest $request) + { + // Check if the authenticated user has the required permission to store permissions + if (is_null($this->user) || !$this->user->can('permissions.store')) { + //abort(403, 'Sorry! You are not allowed to store permissions.'); + } + + $validate = $request->validated(); + + if($validate){ + try{ + $group = PermissionGroup::create($validate); + $group_name = strtolower($validate['name']); + $data = [ + $group_name . '.create', + $group_name . '.view', + $group_name . '.update', + $group_name . '.delete', + $group_name . '.authorize', + $group_name . '.report' + ]; + + foreach ($data as $permission) { + Permission::create(['name' => $permission,'guard_name' => 'web', 'group_id' => $group->id]); + } + + return redirect()->route('users.permissions.index')->with('success', 'Permission created successfully.'); + } catch (\Exception $e){ + return redirect()->route('users.permissions.index')->with('error', 'Failed to create permission: '.$e->getMessage()); + } + } + + + // Redirect back to the permissions index with a success message + return redirect()->route('users.permissions.index')->with('success', 'Permission created successfully.'); + } /** * Show the form for creating a new resource. * - * This function is responsible for displaying the form to create a new resource. - * It returns the view for creating a new resource, which is located at 'usermanagement::create'. - * - * @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory - * @return \Illuminate\Contracts\View\View + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + * @throws \Illuminate\Auth\Access\AuthorizationException */ public function create() { - return view('usermanagement::create'); + // Check if the authenticated user has the required permission to create permissions + if (is_null($this->user) || !$this->user->can('permissions.create')) { + //abort(403, 'Sorry! You are not allowed to create permissions.'); + } + + // Return the view for creating a new role + return view('usermanagement::permissions.create'); } + public function show($id){ + // Check if the authenticated user has the required permission to view permissions + if (is_null($this->user) ||!$this->user->can('permissions.view')) { + //abort(403, 'Sorry! You are not allowed to view permissions.'); + } - public function store(Request $request) - : RedirectResponse - { - // + // Return the view for editing the role + return view('usermanagement::permissions.create'); } - - public function show($id) - { - return view('usermanagement::show'); - } - - + /** + * Show the form for editing the specified resource. + * + * @param int $id + * + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + * @throws \Illuminate\Auth\Access\AuthorizationException + */ public function edit($id) { - return view('usermanagement::edit'); + // Check if the authenticated user has the required permission to edit permissions + if (is_null($this->user) || !$this->user->can('permissions.edit')) { + //abort(403, 'Sorry! You are not allowed to edit permissions.'); + } + + $permission = PermissionGroup::find($id); + + // Return the view for editing the role + return view('usermanagement::permissions.create', compact('permission')); } - public function update(Request $request, $id) - : RedirectResponse + /** + * Update the specified role in storage. + * + * @param \Modules\Usermanagement\Http\Requests\PermissionRequest $request The request object containing the role data. + * @param int $id The unique identifier of the role to be updated. + * + * @return \Illuminate\Http\RedirectResponse Redirects back to the permissions index with a success message upon successful update. + * + * @throws \Illuminate\Auth\Access\AuthorizationException If the authenticated user does not have the required permission to update permissions. + */ + public function update(PermissionRequest $request, $id) { - // + // Check if the authenticated user has the required permission to update permissions + if (is_null($this->user) || !$this->user->can('permissions.update')) { + //abort(403, 'Sorry! You are not allowed to update permissions.'); + } + + $validated = $request->validated(); + + if ($validated) { + try { + // Process Data + $group = PermissionGroup::find($id); + $group->name = $request->name; + + if ($group->save()) { + $group_name = strtolower($request->name); + $permissions = Permission::where('permission_group_id', $group->id)->get(); + + $data = [ + $group_name . '.create', + $group_name . '.read', + $group_name . '.update', + $group_name . '.delete', + $group_name . '.authorize', + $group_name . '.report' + ]; + + $i = 0; + foreach ($permissions as $permission) { + $permission->name = $data[$i]; + $permission->save(); + + $i++; + } + } + return redirect()->route('users.permissions.index')->with('success', 'Permission updated successfully.'); + } catch (\Exception $e) { + return redirect()->route('users.permissions.index')->with('error', 'Failed to update permission: '.$e->getMessage()); + } + } } - + /** + * Remove the specified resource from storage. + * + * @param int $id + * + * @return \Illuminate\Http\RedirectResponse + * @throws \Illuminate\Auth\Access\AuthorizationException + */ public function destroy($id) { - // + // Check if the authenticated user has the required permission to delete permissions + if (is_null($this->user) || !$this->user->can('permissions.delete')) { + //abort(403, 'Sorry! You are not allowed to delete permissions.'); + } + + $permission = PermissionGroup::find($id); + if (!is_null($permission)) { + if ($permission->delete()) { + Permission::where('permission_group_id', $id)->delete(); + } + } + + // Redirect back to the permissions index with a success message + echo json_encode(['message' => 'Permission deleted successfully.', 'success' => true]); + } + + /** + * Restore a deleted role. + * + * @param int $id + * + * @return \Illuminate\Http\RedirectResponse + * @throws \Illuminate\Auth\Access\AuthorizationException + */ + public function restore($id) + { + // Check if the authenticated user has the required permission to restore permissions + if (is_null($this->user) || !$this->user->can('permissions.restore')) { + abort(403, 'Sorry! You are not allowed to restore permissions.'); + } + + // Fetch the specified role from the database + $permission = PermissionGroup::withTrashed()->find($id); + if(!is_null($permission)) { + // Check if the permission is already restored + if ($permission->trashed()) { + // Process Data + $permission->restore(); + Permission::withTrashed()->where('permission_group_id', $id)->restore(); + } + } + + // Redirect back to the permissions index with a success message + return redirect()->route('users.permissions.index')->with('success', 'Permission restored successfully.'); + } + + /** + * Process support datatables ajax request. + * + * @param \Illuminate\Http\Request $request + * + * @return \Illuminate\Http\JsonResponse + * @throws \Illuminate\Auth\Access\AuthorizationException + */ + public function dataForDatatables(Request $request) + { + if (is_null($this->user) || !$this->user->can('permissions.view')) { + //abort(403, 'Sorry! You are not allowed to view users.'); + } + + // Retrieve data from the database + $query = PermissionGroup::query(); + + // Apply search filter if provided + if ($request->has('search') && !empty($request->get('search'))) { + $search = $request->get('search'); + $query->where(function ($q) use ($search) { + $q->where('name', 'LIKE', "%$search%"); + }); + } + + // Apply sorting if provided + if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) { + $order = $request->get('sortOrder'); + $column = $request->get('sortField'); + $query->orderBy($column, $order); + } + + // Get the total count of records + $totalRecords = $query->count(); + + // Apply pagination if provided + if ($request->has('start') && $request->has('length')) { + $start = $request->get('start'); + $length = $request->get('length'); + $query->skip($start)->take($length); + } + + // Get the filtered count of records + $filteredRecords = $query->count(); + + // Get the data for the current page + $permissions = $query->get(); + + + $permissions = $permissions->map(function ($permission) { + $permission->roles = $permission->roles($permission); + + return $permission; + }); + + // Calculate the page count + $pageCount = ceil($totalRecords); + + // Calculate the current page number + $currentPage = 0 + 1; + + // Return the response data as a JSON object + return response()->json([ + 'draw' => $request->get('draw'), + 'recordsTotal' => $totalRecords, + 'recordsFiltered' => $filteredRecords, + 'pageCount' => $pageCount, + 'page' => $currentPage, + 'totalCount' => $totalRecords, + 'data' => $permissions, + ]); + } + + public function export() + { + return Excel::download(new PermissionExport, 'permissions.xlsx'); } } diff --git a/app/Http/Controllers/RolesController.php b/app/Http/Controllers/RolesController.php index b57bf22..7fcfb95 100644 --- a/app/Http/Controllers/RolesController.php +++ b/app/Http/Controllers/RolesController.php @@ -190,7 +190,7 @@ $role->delete(); // Redirect back to the roles index with a success message - echo json_encode(['message' => 'User deleted successfully.', 'success' => true]); + echo json_encode(['message' => 'Role deleted successfully.', 'success' => true]); } /** diff --git a/app/Http/Requests/PermissionRequest.php b/app/Http/Requests/PermissionRequest.php new file mode 100644 index 0000000..36cd06e --- /dev/null +++ b/app/Http/Requests/PermissionRequest.php @@ -0,0 +1,46 @@ + 'required|string|max:255', + ]; + + if ($this->method() === 'PUT') { + $rules['name'] = 'required|string|max:255|unique:permission_groups,name,' . $this->id; + } else { + $rules['name'] = 'required|string|max:255|unique:permission_groups'; + } + + return $rules; + } + + public function prepareForValidation() + { + $this->merge([ + 'slug' => Str::slug($this->input('name')), + ]); + } + } + + + diff --git a/app/Http/Requests/RoleRequest.php b/app/Http/Requests/RoleRequest.php index ae7e025..e803972 100644 --- a/app/Http/Requests/RoleRequest.php +++ b/app/Http/Requests/RoleRequest.php @@ -28,7 +28,7 @@ if ($this->method() === 'PUT') { $rules['name'] = 'required|string|max:255|unique:roles,name,' . $this->id; } else { - $rules['name'] = 'required|string|max:255'; + $rules['name'] = 'required|string|max:255|unique:roles,name'; } return $rules; diff --git a/app/Models/PermissionGroup.php b/app/Models/PermissionGroup.php index 9e37b8d..0d22b8f 100644 --- a/app/Models/PermissionGroup.php +++ b/app/Models/PermissionGroup.php @@ -45,13 +45,18 @@ { $permission = Permission::where('permission_group_id', $group->id)->first(); - $data = []; - $roles = Role::all(); + $data = []; + if ($permission) { - foreach ($roles as $role) { - if ($role->hasPermissionTo($permission->name)) { - array_push($data, $role); + $roles = Role::all(); + + foreach ($roles as $role) { + if ($role->hasPermissionTo($permission->name)) { + array_push($data, $role); + } } + } else { + $data = Role::all(); } return $data; diff --git a/resources/views/permissions/create.blade.php b/resources/views/permissions/create.blade.php new file mode 100644 index 0000000..87bf098 --- /dev/null +++ b/resources/views/permissions/create.blade.php @@ -0,0 +1,48 @@ +@extends('layouts.main') + +@section('breadcrumbs') + {{ Breadcrumbs::render(request()->route()->getName()) }} +@endsection + +@section('content') +
+ @if(isset($permission->id)) +
+ + @method('PUT') + @else + + @endif + @csrf +
+
+

+ {{ isset($permission->id) ? 'Edit' : 'Add' }} Permission +

+
+ Back +
+
+
+ +
+ +
+ + @error('name') + {{ $message }} + @enderror +
+
+
+ +
+
+
+
+
+@endsection diff --git a/resources/views/permissions/index.blade.php b/resources/views/permissions/index.blade.php new file mode 100644 index 0000000..18e0f5c --- /dev/null +++ b/resources/views/permissions/index.blade.php @@ -0,0 +1,182 @@ +@extends('layouts.main') + +@section('breadcrumbs') + {{ Breadcrumbs::render('users.permissions') }} +@endsection + +@section('content') +
+
+
+
+

+ List of Permissions +

+
+
+ +
+
+ + + +
+ Export to Excel + Add Permission +
+
+
+
+
+ + + + + + + + + +
+ + + Permission + + + Roles + + Action
+
+ +
+
+
+
+@endsection + +@push('scripts') + + + +@endpush + diff --git a/routes/breadcrumbs.php b/routes/breadcrumbs.php index d5525a4..09c6b66 100644 --- a/routes/breadcrumbs.php +++ b/routes/breadcrumbs.php @@ -32,3 +32,19 @@ $trail->parent('users.roles'); $trail->push('Edit Role'); }); + + + Breadcrumbs::for('users.permissions', function (BreadcrumbTrail $trail) { + $trail->parent('users'); + $trail->push('Permissions', route('users.permissions.index')); + }); + + Breadcrumbs::for('users.permissions.create', function (BreadcrumbTrail $trail) { + $trail->parent('users.permissions'); + $trail->push('Add Permission', route('users.permissions.create')); + }); + + Breadcrumbs::for('users.permissions.edit', function (BreadcrumbTrail $trail) { + $trail->parent('users.permissions'); + $trail->push('Edit Permission'); + }); diff --git a/routes/web.php b/routes/web.php index 6f7376d..85dc978 100644 --- a/routes/web.php +++ b/routes/web.php @@ -31,12 +31,12 @@ Route::middleware(['auth'])->group(function () { }); Route::resource('roles', RolesController::class); - Route::resource('permissions', PermissionsController::class); Route::name('permissions.')->prefix('permissions')->group(function () { Route::get('restore/{id}', [PermissionsController::class,'restore'])->name('restore'); Route::get('datatables', [PermissionsController::class, 'dataForDatatables'])->name('datatables'); Route::get('export', [PermissionsController ::class, 'export'])->name('export'); }); + Route::resource('permissions', PermissionsController::class); }); });