CaiWuXiTong/app/Http/Controllers/Business/StoreAccountPasswords.php

85 lines
3.9 KiB
PHP

<?php
namespace App\Http\Controllers\Business;
use App\Services\StoreAccountPasswordClient;
use App\Utilities\SidebarPermissions;
use App\Utilities\SystemAccess;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Modules\EcommerceFinance\Repositories\StoreAccountMirrorRepository;
use Throwable;
class StoreAccountPasswords extends Controller
{
public function reveal(string $account, Request $request, StoreAccountMirrorRepository $accounts, StoreAccountPasswordClient $client)
{
if (app()->bound('debugbar')) {
app('debugbar')->disable();
}
$requestId = (string) Str::uuid();
$purpose = $request->input('purpose');
if (! preg_match('/^[A-Za-z0-9_-]{1,128}$/D', $account)
|| ! in_array($purpose, ['view', 'copy'], true)
|| array_diff(array_keys($request->all()), ['purpose', '_token']) !== [] || $request->query() !== []) {
return $this->respond(422, $requestId);
}
try {
DB::table('store_account_password_audits')->insert([
'request_id' => $requestId, 'actor_user_id' => $request->user()->id,
'company_id' => company_id(), 'store_account_id' => $account,
'purpose' => $purpose, 'created_at' => now(),
]);
} catch (Throwable) {
return $this->respond(503, $requestId);
}
$result = ['status' => 503];
try {
$pages = collect(SidebarPermissions::navigationFor($request->user()))->firstWhere('slug', 'store-management');
// Re-read role membership for every secret request; a cached admin
// role must not survive a permission revocation.
if (! $request->user()->roles()->whereIn('roles.name', [SystemAccess::SUPER_ADMIN, SystemAccess::ADMIN])->exists()
|| ! collect($pages['pages'] ?? [])->contains('slug', 'store-accounts')) {
$result = ['status' => 403];
} elseif (RateLimiter::tooManyAttempts('store-password:'.$request->user()->id, 10)) {
$result = ['status' => 429];
} else {
RateLimiter::hit('store-password:'.$request->user()->id, 60);
$result = $accounts->containsAccount($account)
? $client->reveal($account, $request->user()->id, $purpose)
: ['status' => 404];
}
} catch (Throwable) {
$result = ['status' => 503];
}
try {
$saved = DB::table('store_account_password_audits')->where('request_id', $requestId)->update([
'status' => $result['status'], 'upstream_request_id' => $result['upstream_request_id'] ?? null,
'completed_at' => now(),
]);
if ($saved !== 1) {
return $this->respond(503, $requestId);
}
} catch (Throwable) {
return $this->respond(503, $requestId);
}
return $this->respond($result['status'], $requestId, $result['password'] ?? null);
}
private function respond(int $status, string $requestId, ?string $password = null)
{
$messages = [403 => '当前账号没有查看店铺密码的权限。', 404 => '该账号暂无可读取的密码。',
422 => '请求无效,请刷新页面后重试。', 429 => '操作过于频繁,请稍后再试。',
503 => '密码服务暂不可用,请稍后再试或联系管理员。'];
return response()->json($status === 200
? ['password' => $password, 'requestId' => $requestId]
: ['message' => $messages[$status] ?? $messages[503], 'requestId' => $requestId], $status)
->withHeaders(['Cache-Control' => 'no-store, private', 'Pragma' => 'no-cache',
'X-Content-Type-Options' => 'nosniff', 'Referrer-Policy' => 'no-referrer']);
}
}