Initial commit: Pireon Admin — headless admin panel and public API

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>
This commit is contained in:
2026-08-19 17:55:27 +02:00
commit 3897113313
534 changed files with 64050 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
<?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'));
}
}