Laravel 13 + Filament 5 admin panel and REST API for a non-profit developer collective, backed by the Pireon OAuth identity server. The public site is a separate, server-rendered application consuming /api/public/v1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
84 lines
2.8 KiB
PHP
84 lines
2.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers\Api\V1;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Resources\UserResource;
|
|
use App\Models\User;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
|
use Illuminate\Validation\Rule;
|
|
use Spatie\Permission\Models\Role;
|
|
|
|
/**
|
|
* Local user administration.
|
|
*
|
|
* Only fields this application owns are writable: the local role assignment,
|
|
* the active flag, and the UI locale. Names and emails belong to the identity
|
|
* server and are refreshed from it on every login, so editing them here would
|
|
* be undone — change those at oauth.pireon.dev instead.
|
|
*/
|
|
class UserController extends Controller
|
|
{
|
|
public function index(Request $request): AnonymousResourceCollection
|
|
{
|
|
$this->authorize('viewAny', User::class);
|
|
|
|
$users = User::query()
|
|
->with('roles')
|
|
->when($request->filled('search'), fn ($q) => $q->where(
|
|
fn ($sub) => $sub
|
|
->where('name', 'like', '%'.$request->string('search').'%')
|
|
->orWhere('email', 'like', '%'.$request->string('search').'%')
|
|
))
|
|
->when($request->has('is_active'), fn ($q) => $q->where('is_active', $request->boolean('is_active')))
|
|
->when($request->filled('role'), fn ($q) => $q->whereHas(
|
|
'roles',
|
|
fn ($sub) => $sub->where('name', $request->string('role'))
|
|
))
|
|
->orderBy('name')
|
|
->paginate(perPage: min($request->integer('per_page', 25), 100))
|
|
->withQueryString();
|
|
|
|
return UserResource::collection($users);
|
|
}
|
|
|
|
public function show(User $user): UserResource
|
|
{
|
|
$this->authorize('view', $user);
|
|
|
|
return UserResource::make($user->load('roles'));
|
|
}
|
|
|
|
public function update(Request $request, User $user): UserResource
|
|
{
|
|
$this->authorize('update', $user);
|
|
|
|
$data = $request->validate([
|
|
'is_active' => ['sometimes', 'boolean'],
|
|
'locale' => ['sometimes', 'nullable', Rule::in(array_keys(config('locales.supported')))],
|
|
'roles' => ['sometimes', 'array'],
|
|
'roles.*' => [Rule::exists('roles', 'name')],
|
|
]);
|
|
|
|
if (array_key_exists('roles', $data)) {
|
|
$this->authorize('update', Role::class);
|
|
|
|
// Only a super admin may hand out super_admin, and nobody may
|
|
// strip their own privileges out from under themselves.
|
|
if (in_array('super_admin', $data['roles'], true) && ! $request->user()->hasRole('super_admin')) {
|
|
abort(403, __('pireon.cannot_grant_super_admin'));
|
|
}
|
|
|
|
$user->syncRoles($data['roles']);
|
|
unset($data['roles']);
|
|
}
|
|
|
|
$user->fill($data)->save();
|
|
|
|
return UserResource::make($user->fresh()->load('roles'));
|
|
}
|
|
}
|