UserAdminController.php 6.9 KB

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