260 lines
8.8 KiB
PHP
260 lines
8.8 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Http\Resources\UserResource;
|
|
use App\Models\Log;
|
|
use App\Models\User;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Hash;
|
|
|
|
class UserController extends Controller
|
|
{
|
|
private const FIELD_RULES = [
|
|
'username' => 'required|max:100|unique:users',
|
|
'email' => 'required|max:100|unique:users',
|
|
'password' => 'required|min:6|confirmed',
|
|
'type' => 'required|in:admin,user,creator,banned',
|
|
'email_verified_at' => 'nullable|date'
|
|
];
|
|
private const PAGINATED_COUNT = 20;
|
|
/**
|
|
* @OA\Get(
|
|
* path="/api/users",
|
|
* summary="Get list of users (paginated, only admin)",
|
|
* tags={"Users"},
|
|
* security={{"bearerAuth": {}}},
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="List of users retrieved successfully",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="data", type="array",
|
|
* @OA\Items(ref="#/components/schemas/UserResource")
|
|
* ),
|
|
* @OA\Property(property="links", type="object"),
|
|
* @OA\Property(property="meta", type="object")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=403,
|
|
* description="Forbidden — user is not authorized to view users"
|
|
* ),
|
|
* @OA\Response(
|
|
* response=401,
|
|
* description="Unauthenticated"
|
|
* )
|
|
* )
|
|
*/
|
|
public function index()
|
|
{
|
|
$this->authorize('viewAny', User::class);
|
|
return UserResource::collection(User::paginate(self::PAGINATED_COUNT));
|
|
}
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/api/users",
|
|
* summary="Create a new user (only admin)",
|
|
* tags={"Users"},
|
|
* security={{"bearerAuth": {}}},
|
|
* @OA\RequestBody(
|
|
* required=true,
|
|
* @OA\JsonContent(
|
|
* required={"username","email","password","type"},
|
|
* @OA\Property(property="username", type="string", maxLength=100, example="newuser"),
|
|
* @OA\Property(property="email", type="string", format="email", maxLength=100, example="newuser@example.com"),
|
|
* @OA\Property(property="password", type="string", format="password", example="secret123"),
|
|
* @OA\Property(property="type", type="string", enum={"admin","user"}, example="user")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=201,
|
|
* description="User created successfully",
|
|
* @OA\JsonContent(ref="#/components/schemas/UserResource")
|
|
* ),
|
|
* @OA\Response(
|
|
* response=422,
|
|
* description="Validation error",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="message", type="string", example="The given data was invalid."),
|
|
* @OA\Property(
|
|
* property="errors",
|
|
* type="object",
|
|
* example={
|
|
* "email": {"The email has already been taken."},
|
|
* "password": {"The password must be at least 6 characters."}
|
|
* }
|
|
* )
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=403,
|
|
* description="Forbidden — only admins can create users"
|
|
* ),
|
|
* @OA\Response(
|
|
* response=401,
|
|
* description="Unauthenticated"
|
|
* )
|
|
* )
|
|
*/
|
|
public function store(Request $request)
|
|
{
|
|
$this->authorize('create', User::class);
|
|
$fields = $request->validate(self::FIELD_RULES);
|
|
$fields['password'] = Hash::make($fields['password']);
|
|
|
|
$user = User::create($fields);
|
|
|
|
Log::writeLog("User '" . $user->username . "' is created by " . $request->user()->username);
|
|
return new UserResource($user);
|
|
}
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/api/users/{id}",
|
|
* summary="Get a specific user (only admin)",
|
|
* tags={"Users"},
|
|
* security={{"bearerAuth": {}}},
|
|
* @OA\Parameter(
|
|
* name="id",
|
|
* in="path",
|
|
* required=true,
|
|
* description="User ID",
|
|
* @OA\Schema(type="integer", example=1)
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="User retrieved successfully",
|
|
* @OA\JsonContent(ref="#/components/schemas/UserResource")
|
|
* ),
|
|
* @OA\Response(
|
|
* response=404,
|
|
* description="User not found"
|
|
* ),
|
|
* @OA\Response(
|
|
* response=403,
|
|
* description="Forbidden — user not authorized to view this resource"
|
|
* ),
|
|
* @OA\Response(
|
|
* response=401,
|
|
* description="Unauthenticated"
|
|
* )
|
|
* )
|
|
*/
|
|
public function show(User $user)
|
|
{
|
|
$this->authorize('view', $user);
|
|
return new UserResource($user);
|
|
}
|
|
|
|
/**
|
|
* @OA\Put(
|
|
* path="/api/users/{id}",
|
|
* summary="Update an existing user (only admin)",
|
|
* tags={"Users"},
|
|
* security={{"bearerAuth": {}}},
|
|
* @OA\Parameter(
|
|
* name="id",
|
|
* in="path",
|
|
* required=true,
|
|
* description="User ID",
|
|
* @OA\Schema(type="integer", example=1)
|
|
* ),
|
|
* @OA\RequestBody(
|
|
* required=true,
|
|
* @OA\JsonContent(
|
|
* required={"username","email","password","type"},
|
|
* @OA\Property(property="username", type="string", maxLength=100, example="updated_user"),
|
|
* @OA\Property(property="email", type="string", format="email", maxLength=100, example="updated_user@example.com"),
|
|
* @OA\Property(property="password", type="string", format="password", example="newpassword123"),
|
|
* @OA\Property(property="type", type="string", enum={"admin","user"}, example="user")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="User updated successfully",
|
|
* @OA\JsonContent(ref="#/components/schemas/UserResource")
|
|
* ),
|
|
* @OA\Response(
|
|
* response=404,
|
|
* description="User not found"
|
|
* ),
|
|
* @OA\Response(
|
|
* response=422,
|
|
* description="Validation error",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="message", type="string", example="The given data was invalid."),
|
|
* @OA\Property(
|
|
* property="errors",
|
|
* type="object",
|
|
* example={
|
|
* "email": {"The email has already been taken."},
|
|
* "password": {"The password must be at least 6 characters."}
|
|
* }
|
|
* )
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=403,
|
|
* description="Forbidden — only admins can update users"
|
|
* ),
|
|
* @OA\Response(
|
|
* response=401,
|
|
* description="Unauthenticated"
|
|
* )
|
|
* )
|
|
*/
|
|
public function update(Request $request, User $user)
|
|
{
|
|
$this->authorize('update', $user);
|
|
$fields = $request->validate(self::FIELD_RULES);
|
|
|
|
if(!Hash::check($fields['password'], $user->password)) {
|
|
$fields['password'] = Hash::make($fields['password']);
|
|
}
|
|
$user->update($fields);
|
|
|
|
Log::writeLog("User '" . $user->username . "' is updated by " . $request->user()->username);
|
|
return new UserResource($user);
|
|
}
|
|
|
|
/**
|
|
* @OA\Delete(
|
|
* path="/api/users/{id}",
|
|
* summary="Delete a user (only admin)",
|
|
* tags={"Users"},
|
|
* security={{"bearerAuth": {}}},
|
|
* @OA\Parameter(
|
|
* name="id",
|
|
* in="path",
|
|
* required=true,
|
|
* description="User ID",
|
|
* @OA\Schema(type="integer", example=1)
|
|
* ),
|
|
* @OA\Response(
|
|
* response=204,
|
|
* description="User deleted successfully (no content)"
|
|
* ),
|
|
* @OA\Response(
|
|
* response=404,
|
|
* description="User not found"
|
|
* ),
|
|
* @OA\Response(
|
|
* response=403,
|
|
* description="Forbidden — only admins can delete users"
|
|
* ),
|
|
* @OA\Response(
|
|
* response=401,
|
|
* description="Unauthenticated"
|
|
* )
|
|
* )
|
|
*/
|
|
public function destroy(Request $request, User $user)
|
|
{
|
|
$this->authorize('delete', $user);
|
|
$user->delete();
|
|
|
|
Log::writeLog("User '" . $user->username . "' is deleted by " . $request->user()->username);
|
|
}
|
|
}
|