feat: menric
This commit is contained in:
@@ -2,8 +2,10 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Concerns\PortalAware;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Admin;
|
||||
use App\Models\User;
|
||||
use App\Services\AdminGoogle2fa;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -11,21 +13,22 @@ use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class Google2faController extends Controller
|
||||
{
|
||||
use PortalAware;
|
||||
|
||||
public function index()
|
||||
{
|
||||
/** @var Admin $admin */
|
||||
$admin = auth('admin')->user();
|
||||
$actor = $this->googleActor();
|
||||
|
||||
return view('admin.security.google2fa', [
|
||||
'enabled' => $admin->requiresLoginGoogle(),
|
||||
'bound' => $admin->hasGoogleBound(),
|
||||
'enabled' => $actor->requiresLoginGoogle(),
|
||||
'bound' => $actor->hasGoogleBound(),
|
||||
'routes' => $this->googleRoutes(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function prepare(Request $request, AdminGoogle2fa $google2fa): JsonResponse
|
||||
{
|
||||
/** @var Admin $admin */
|
||||
$admin = auth('admin')->user();
|
||||
$actor = $this->googleActor();
|
||||
|
||||
$data = $request->validate([
|
||||
'password' => ['required', 'string'],
|
||||
@@ -33,18 +36,18 @@ class Google2faController extends Controller
|
||||
'password.required' => '登陆密码不能为空',
|
||||
]);
|
||||
|
||||
if (! Hash::check($data['password'], $admin->password)) {
|
||||
if (! Hash::check($data['password'], $actor->password)) {
|
||||
return response()->json(['code' => 1, 'msg' => '登陆密码不正确']);
|
||||
}
|
||||
|
||||
if ((int) $admin->google_auth_open === 1 || filled($admin->google_secret)) {
|
||||
if ((int) $actor->google_auth_open === 1 || filled($actor->google_secret)) {
|
||||
return response()->json(['code' => 201, 'msg' => '您已绑定谷歌验证,可直接开启或关闭']);
|
||||
}
|
||||
|
||||
$secret = $google2fa->generateSecret();
|
||||
$request->session()->put('admin_google2fa_pending_secret', $secret);
|
||||
$request->session()->put($this->pendingSecretKey(), $secret);
|
||||
|
||||
$otpAuthUrl = $google2fa->otpAuthUrl($admin, $secret);
|
||||
$otpAuthUrl = $google2fa->otpAuthUrl($actor->username, $secret, $this->isAgentPortal() ? 'agent' : 'admin');
|
||||
|
||||
return response()->json([
|
||||
'code' => 0,
|
||||
@@ -56,8 +59,7 @@ class Google2faController extends Controller
|
||||
|
||||
public function bind(Request $request, AdminGoogle2fa $google2fa): JsonResponse
|
||||
{
|
||||
/** @var Admin $admin */
|
||||
$admin = auth('admin')->user();
|
||||
$actor = $this->googleActor();
|
||||
|
||||
$data = $request->validate([
|
||||
'GAKey' => ['required', 'string', 'max:16'],
|
||||
@@ -68,7 +70,7 @@ class Google2faController extends Controller
|
||||
'GASecret.required' => '参数不完整',
|
||||
]);
|
||||
|
||||
$pending = (string) $request->session()->get('admin_google2fa_pending_secret', '');
|
||||
$pending = (string) $request->session()->get($this->pendingSecretKey(), '');
|
||||
if ($pending === '' || ! hash_equals($pending, $data['GASecret'])) {
|
||||
return response()->json(['code' => 1, 'msg' => '绑定已过期,请重新获取二维码']);
|
||||
}
|
||||
@@ -78,12 +80,12 @@ class Google2faController extends Controller
|
||||
}
|
||||
|
||||
$loginVerify = (int) ($data['login_verify'] ?? 0);
|
||||
$admin->forceFill([
|
||||
$actor->forceFill([
|
||||
'google_auth_open' => $loginVerify,
|
||||
'google_secret' => $data['GASecret'],
|
||||
])->save();
|
||||
|
||||
$request->session()->forget('admin_google2fa_pending_secret');
|
||||
$request->session()->forget($this->pendingSecretKey());
|
||||
|
||||
return response()->json([
|
||||
'code' => 0,
|
||||
@@ -95,8 +97,7 @@ class Google2faController extends Controller
|
||||
|
||||
public function toggle(Request $request, AdminGoogle2fa $google2fa): JsonResponse
|
||||
{
|
||||
/** @var Admin $admin */
|
||||
$admin = auth('admin')->user();
|
||||
$actor = $this->googleActor();
|
||||
|
||||
$data = $request->validate([
|
||||
'password' => ['required', 'string'],
|
||||
@@ -104,21 +105,21 @@ class Google2faController extends Controller
|
||||
'GACode' => ['nullable', 'string', 'max:16'],
|
||||
]);
|
||||
|
||||
if (! Hash::check($data['password'], $admin->password)) {
|
||||
if (! Hash::check($data['password'], $actor->password)) {
|
||||
return response()->json(['code' => 1, 'msg' => '登陆密码不正确']);
|
||||
}
|
||||
|
||||
if (! filled($admin->google_secret)) {
|
||||
if (! filled($actor->google_secret)) {
|
||||
return response()->json(['code' => 1, 'msg' => '您未绑定谷歌验证']);
|
||||
}
|
||||
|
||||
$open = (int) $data['open'];
|
||||
$code = (string) ($data['GACode'] ?? '');
|
||||
if (! $google2fa->verify((string) $admin->google_secret, $code)) {
|
||||
if (! $google2fa->verify((string) $actor->google_secret, $code)) {
|
||||
return response()->json(['code' => 1, 'msg' => '谷歌验证码不正确']);
|
||||
}
|
||||
|
||||
$admin->forceFill(['google_auth_open' => $open])->save();
|
||||
$actor->forceFill(['google_auth_open' => $open])->save();
|
||||
|
||||
return response()->json([
|
||||
'code' => 0,
|
||||
@@ -130,33 +131,65 @@ class Google2faController extends Controller
|
||||
|
||||
public function unbind(Request $request, AdminGoogle2fa $google2fa): JsonResponse
|
||||
{
|
||||
/** @var Admin $admin */
|
||||
$admin = auth('admin')->user();
|
||||
$actor = $this->googleActor();
|
||||
|
||||
$data = $request->validate([
|
||||
'password' => ['required', 'string'],
|
||||
'GACode' => ['required', 'string', 'max:16'],
|
||||
]);
|
||||
|
||||
if (! Hash::check($data['password'], $admin->password)) {
|
||||
if (! Hash::check($data['password'], $actor->password)) {
|
||||
return response()->json(['code' => 1, 'msg' => '登陆密码不正确']);
|
||||
}
|
||||
|
||||
if (! filled($admin->google_secret)) {
|
||||
if (! filled($actor->google_secret)) {
|
||||
return response()->json(['code' => 1, 'msg' => '您未绑定谷歌验证']);
|
||||
}
|
||||
|
||||
if (! $google2fa->verify((string) $admin->google_secret, $data['GACode'])) {
|
||||
if (! $google2fa->verify((string) $actor->google_secret, $data['GACode'])) {
|
||||
return response()->json(['code' => 1, 'msg' => '谷歌验证码不正确']);
|
||||
}
|
||||
|
||||
$admin->forceFill([
|
||||
$actor->forceFill([
|
||||
'google_auth_open' => 0,
|
||||
'google_secret' => null,
|
||||
])->save();
|
||||
|
||||
$request->session()->forget('admin_google2fa_pending_secret');
|
||||
$request->session()->forget($this->pendingSecretKey());
|
||||
|
||||
return response()->json(['code' => 0, 'msg' => '已解除谷歌验证绑定']);
|
||||
}
|
||||
|
||||
private function googleActor(): Admin|User
|
||||
{
|
||||
if ($this->isAgentPortal()) {
|
||||
/** @var User $user */
|
||||
$user = auth('agent')->user();
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/** @var Admin $admin */
|
||||
$admin = auth('admin')->user();
|
||||
|
||||
return $admin;
|
||||
}
|
||||
|
||||
/** @return array{prepare: string, bind: string, toggle: string, unbind: string} */
|
||||
private function googleRoutes(): array
|
||||
{
|
||||
$portal = $this->portal();
|
||||
|
||||
return [
|
||||
'prepare' => route($portal.'.security.google2fa.prepare'),
|
||||
'bind' => route($portal.'.security.google2fa.bind'),
|
||||
'toggle' => route($portal.'.security.google2fa.toggle'),
|
||||
'unbind' => route($portal.'.security.google2fa.unbind'),
|
||||
];
|
||||
}
|
||||
|
||||
private function pendingSecretKey(): string
|
||||
{
|
||||
return $this->isAgentPortal() ? 'agent_google2fa_pending_secret' : 'admin_google2fa_pending_secret';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user