UserAdminController.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <?php
  2. namespace App\Http\Controllers\Admin;
  3. /*
  4. * UserAdminController — управление пользователями и правами в административной панели.
  5. *
  6. * index() — список всех пользователей (только для users.view)
  7. * edit() — форма редактирования роли и прав конкретного пользователя
  8. * update() — сохранение роли и индивидуальных override-прав
  9. * destroy() — удаление пользователя (superadmin удалить нельзя)
  10. *
  11. * Управлять можно только теми, кем текущий пользователь canManage() — защита иерархии.
  12. */
  13. use App\Http\Controllers\Controller;
  14. use App\Models\User;
  15. use App\Models\UserPermission;
  16. use App\Services\PermissionService;
  17. use Illuminate\Http\RedirectResponse;
  18. use Illuminate\Http\Request;
  19. use Illuminate\Support\Facades\Auth;
  20. use Illuminate\View\View;
  21. class UserAdminController extends Controller
  22. {
  23. public function index(): View
  24. {
  25. $this->authorize('users.view');
  26. $users = User::with('userPermissions')->orderBy('id')->get();
  27. $roleLabels = PermissionService::roleLabels();
  28. return view('admin.users.index', compact('users', 'roleLabels'));
  29. }
  30. public function edit(User $user): View
  31. {
  32. $this->authorize('users.manage');
  33. abort_unless(Auth::user()->canManage($user), 403, 'Недостаточно прав для управления этим пользователем.');
  34. $user->load('userPermissions');
  35. $permissions = PermissionService::all();
  36. $roleLabels = PermissionService::roleLabels();
  37. $roleDefaults = $user->role ? PermissionService::roleDefaults($user->role) : [];
  38. $overrides = $user->userPermissions->keyBy('permission');
  39. return view('admin.users.edit', compact('user', 'permissions', 'roleLabels', 'roleDefaults', 'overrides'));
  40. }
  41. public function update(Request $request, User $user): RedirectResponse
  42. {
  43. $this->authorize('users.manage');
  44. abort_unless(Auth::user()->canManage($user), 403, 'Недостаточно прав для управления этим пользователем.');
  45. $request->validate([
  46. 'role' => 'nullable|in:superadmin,admin,editor,viewer',
  47. 'permissions' => 'nullable|array',
  48. 'permissions.*' => 'in:allow,deny',
  49. ]);
  50. // superadmin не может снять роль superadmin сам у себя, если он единственный
  51. if ($user->role === 'superadmin' && $request->input('role') !== 'superadmin') {
  52. $superCount = User::where('role', 'superadmin')->count();
  53. abort_if($superCount <= 1, 422, 'Нельзя снять роль у единственного суперадминистратора.');
  54. }
  55. // Только superadmin может назначать роль superadmin или admin
  56. $newRole = $request->input('role');
  57. if (in_array($newRole, ['superadmin', 'admin']) && Auth::user()->role !== 'superadmin') {
  58. abort(403, 'Только суперадминистратор может назначать эту роль.');
  59. }
  60. $user->update([
  61. 'role' => $newRole ?: null,
  62. 'is_admin' => ! empty($newRole), // синхронизируем legacy-флаг
  63. ]);
  64. // Перезаписываем индивидуальные overrides
  65. UserPermission::where('user_id', $user->id)->delete();
  66. $allKeys = PermissionService::keys();
  67. foreach ($request->input('permissions', []) as $key => $action) {
  68. if (! in_array($key, $allKeys, true)) {
  69. continue;
  70. }
  71. if (! in_array($action, ['allow', 'deny'], true)) {
  72. continue;
  73. }
  74. UserPermission::create([
  75. 'user_id' => $user->id,
  76. 'permission' => $key,
  77. 'action' => $action,
  78. ]);
  79. }
  80. return redirect()->route('admin.users.index')
  81. ->with('success', 'Пользователь «'.$user->name.'» обновлён.');
  82. }
  83. public function destroy(User $user): RedirectResponse
  84. {
  85. $this->authorize('users.manage');
  86. abort_unless(Auth::user()->canManage($user), 403);
  87. abort_if($user->id === Auth::id(), 422, 'Нельзя удалить самого себя.');
  88. $user->delete();
  89. return redirect()->route('admin.users.index')
  90. ->with('success', 'Пользователь удалён.');
  91. }
  92. }