Boy132 fc643f57f9
Admin Roles (#502)
* add spatie/permissions

* add policies

* add role resource

* add root admin role handling

* replace some "root_admin" with function

* add model specific permissions

* make permission selection nicer

* fix user creation

* fix tests

* add back subuser checks in server policy

* add custom model for role

* assign new users to role if root_admin is set

* add api for roles

* fix phpstan

* add permissions for settings page

* remove "restore" and "forceDelete" permissions

* add user count to list

* prevent deletion if role has users

* update user list

* fix server policy

* remove old `root_admin` column

* small refactor

* fix tests

* forgot can checks here

* forgot use

* disable editing own roles & disable assigning root admin

* don't allow to rename root admin role

* remove php bombing exception handler

* fix role assignment when creating a user

* fix disableOptionWhen

* fix missing `root_admin` attribute on react frontend

* add permission check for bulk delete

* rename viewAny to viewList

* improve canAccessPanel check

* fix admin not displaying for non-root admins

* make sure non root admins can't edit root admins

* fix import

* fix settings page permission check

* fix server permissions for non-subusers

* fix settings page permission check v2

* small cleanup

* cleanup config file

* move consts from resouce into enum & model

* Update database/migrations/2024_08_01_114538_remove_root_admin_column.php

Co-authored-by: Lance Pioch <lancepioch@gmail.com>

* fix config

* fix phpstan

* fix phpstan 2.0

---------

Co-authored-by: Lance Pioch <lancepioch@gmail.com>
2024-09-21 12:27:41 +02:00

123 lines
4.1 KiB
PHP

<?php
namespace App\Http\Controllers\Api\Application\Users;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Spatie\QueryBuilder\QueryBuilder;
use App\Services\Users\UserUpdateService;
use App\Services\Users\UserCreationService;
use App\Transformers\Api\Application\UserTransformer;
use App\Http\Requests\Api\Application\Users\GetUsersRequest;
use App\Http\Requests\Api\Application\Users\StoreUserRequest;
use App\Http\Requests\Api\Application\Users\DeleteUserRequest;
use App\Http\Requests\Api\Application\Users\UpdateUserRequest;
use App\Http\Controllers\Api\Application\ApplicationApiController;
use App\Http\Requests\Api\Application\Users\AssignUserRolesRequest;
class UserController extends ApplicationApiController
{
/**
* UserController constructor.
*/
public function __construct(
private UserCreationService $creationService,
private UserUpdateService $updateService
) {
parent::__construct();
}
/**
* Handle request to list all users on the panel. Returns a JSON-API representation
* of a collection of users including any defined relations passed in
* the request.
*/
public function index(GetUsersRequest $request): array
{
$users = QueryBuilder::for(User::query())
->allowedFilters(['email', 'uuid', 'username', 'external_id'])
->allowedSorts(['id', 'uuid'])
->paginate($request->query('per_page') ?? 50);
return $this->fractal->collection($users)
->transformWith($this->getTransformer(UserTransformer::class))
->toArray();
}
/**
* Handle a request to view a single user. Includes any relations that
* were defined in the request.
*/
public function view(GetUsersRequest $request, User $user): array
{
return $this->fractal->item($user)
->transformWith($this->getTransformer(UserTransformer::class))
->toArray();
}
/**
* Update an existing user on the system and return the response. Returns the
* updated user model response on success. Supports handling of token revocation
* errors when switching a user from an admin to a normal user.
*
* Revocation errors are returned under the 'revocation_errors' key in the response
* meta. If there are no errors this is an empty array.
*
* @throws \App\Exceptions\Model\DataValidationException
*/
public function update(UpdateUserRequest $request, User $user): array
{
$this->updateService->setUserLevel(User::USER_LEVEL_ADMIN);
$user = $this->updateService->handle($user, $request->validated());
$response = $this->fractal->item($user)
->transformWith($this->getTransformer(UserTransformer::class));
return $response->toArray();
}
/**
* Assign roles to a user.
*/
public function roles(AssignUserRolesRequest $request, User $user): array
{
$user->syncRoles($request->input('roles'));
$response = $this->fractal->item($user)
->transformWith($this->getTransformer(UserTransformer::class));
return $response->toArray();
}
/**
* Store a new user on the system. Returns the created user and an HTTP/201
* header on successful creation.
*
* @throws \Exception
* @throws \App\Exceptions\Model\DataValidationException
*/
public function store(StoreUserRequest $request): JsonResponse
{
$user = $this->creationService->handle($request->validated());
return $this->fractal->item($user)
->transformWith($this->getTransformer(UserTransformer::class))
->addMeta([
'resource' => route('api.application.users.view', [
'user' => $user->id,
]),
])
->respond(201);
}
/**
* Handle a request to delete a user from the Panel. Returns a HTTP/204 response on successful deletion.
*/
public function delete(DeleteUserRequest $request, User $user): JsonResponse
{
$user->delete();
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
}
}