<?php
namespace App\EventSubscriber;
use App\Entity\MerchantUser;
use App\Entity\User;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Security;
class PortalReadOnlySubscriber implements EventSubscriberInterface
{
private Security $security;
public function __construct(Security $security)
{
$this->security = $security;
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => ['enforceReadOnlyPortal', -10],
];
}
public function enforceReadOnlyPortal(RequestEvent $event): void
{
if (!$event->isMainRequest()) {
return;
}
$request = $event->getRequest();
if (strpos($request->getPathInfo(), '/api/') !== 0) {
return;
}
$user = $this->security->getUser();
if (!$user instanceof User) {
return;
}
if (!$user->isEnable() || ($user->getManageUser() && !$user->getManageUser()->isEnable())) {
throw new AccessDeniedHttpException('账户被锁定');
}
if ($request->isMethodSafe() || $user->getManageUser() || $this->security->isGranted('ROLE_SUPER_ADMIN')) {
return;
}
$reason = $this->readOnlyReason($user);
if ($reason) {
throw new AccessDeniedHttpException($reason);
}
}
private function readOnlyReason(User $user): ?string
{
$proxyUser = $user->getProxyUser();
if ($proxyUser && !$proxyUser->isEnable()) {
return '当前代理已被禁用,仅允许查看数据';
}
$merchantUser = $user->getMerchantUser();
if (!$merchantUser) {
return null;
}
if ($merchantUser->getStatus() !== MerchantUser::STATUS_PASS || $merchantUser->isReview()) {
return '当前商户账号未审核通过,仅允许查看数据';
}
if (!$merchantUser->isEnable()) {
return '当前商户已被禁用,仅允许查看数据';
}
$merchantProxyUser = $merchantUser->getProxyUser();
if ($merchantProxyUser && !$merchantProxyUser->isEnable()) {
return '当前所属代理已被禁用,仅允许查看数据';
}
return null;
}
}