You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
3.1 KiB

1 month ago
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Competition;
use App\Models\Reviewer;
use App\Models\ReviewerScope;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
class ReviewAuthController extends Controller
{
/**
* 评审端:账户 + 密码登录(须已配置本场 reviewer_scopes
*/
public function login(Request $request): JsonResponse
{
$data = $request->validate([
'username' => ['required', 'string', 'max:64'],
'password' => ['required', 'string', 'max:255'],
'competition_slug' => ['required', 'string', 'max:64'],
]);
$competition = Competition::query()
->where('slug', $data['competition_slug'])
->where('published', true)
->first();
if ($competition === null) {
throw ValidationException::withMessages([
'competition_slug' => ['赛事不存在或未发布'],
]);
}
$reviewer = Reviewer::query()
->where('username', $data['username'])
->where('status', 'active')
->first();
$passwordMatches = $reviewer !== null
&& ($reviewer->password_hash ?? '') !== ''
&& Hash::check($data['password'], $reviewer->password_hash);
if (! $passwordMatches) {
throw ValidationException::withMessages([
'username' => ['账号或密码错误'],
]);
}
/** @var Reviewer $reviewer */
$hasScope = ReviewerScope::query()
->where('reviewer_id', $reviewer->id)
->where('competition_id', $competition->id)
->exists();
if (! $hasScope) {
throw ValidationException::withMessages([
'username' => ['您暂无本场赛事的评审权限'],
]);
}
$reviewer->forceFill(['last_login_at' => now()])->save();
$reviewer->tokens()->where('name', 'review')->delete();
$token = $reviewer->createToken('review')->plainTextToken;
return response()->json([
'token' => $token,
'token_type' => 'Bearer',
'reviewer' => [
'id' => $reviewer->id,
'name' => $reviewer->name,
'username' => $reviewer->username,
],
'competition' => [
'id' => $competition->id,
'slug' => $competition->slug,
'name' => $competition->name,
],
]);
}
/**
* 当前评审员Bearer reviewer token
*/
public function me(Request $request): JsonResponse
{
/** @var Reviewer $reviewer */
$reviewer = $request->user();
return response()->json([
'reviewer' => [
'id' => $reviewer->id,
'name' => $reviewer->name,
'username' => $reviewer->username,
'mobile' => $reviewer->mobile,
],
]);
}
}