mirror of
https://gitee.com/ctexthuang/hyperf_rbac_framework_server_ctexthuang.git
synced 2025-12-26 02:17:48 +08:00
108 lines
3.4 KiB
PHP
108 lines
3.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Middleware\Admin;
|
|
|
|
use App\Annotation\Permission;
|
|
use App\Constants\AdminCode;
|
|
use App\Constants\Model\AdminUser\AdminUserStatusCode;
|
|
use App\Exception\ErrException;
|
|
use App\Lib\Jwt\RequestScopedTokenTrait;
|
|
use App\Model\AdminUser;
|
|
use App\Trait\AdminUserTrait;
|
|
use App\Trait\ParserRouterTrait;
|
|
use Hyperf\Collection\Arr;
|
|
use Hyperf\Di\Annotation\AnnotationCollector;
|
|
use Hyperf\HttpServer\Router\Dispatched;
|
|
use Lcobucci\JWT\Token\RegisteredClaims;
|
|
use Psr\Container\ContainerInterface;
|
|
use Psr\Http\Message\ResponseInterface;
|
|
use Psr\Http\Server\MiddlewareInterface;
|
|
use Psr\Http\Message\ServerRequestInterface;
|
|
use Psr\Http\Server\RequestHandlerInterface;
|
|
|
|
class PermissionMiddleware implements MiddlewareInterface
|
|
{
|
|
use RequestScopedTokenTrait;
|
|
use AdminUserTrait;
|
|
use ParserRouterTrait;
|
|
|
|
/**
|
|
* @var AdminUser
|
|
*/
|
|
protected AdminUser $adminUserInfo;
|
|
|
|
/**
|
|
* @param ContainerInterface $container
|
|
*/
|
|
public function __construct(protected ContainerInterface $container) {}
|
|
|
|
/**
|
|
* @param ServerRequestInterface $request
|
|
* @param RequestHandlerInterface $handler
|
|
* @return ResponseInterface
|
|
*/
|
|
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
|
{
|
|
$adminId = $this->getToken()?->claims()?->get(RegisteredClaims::ID) ?? 0;
|
|
if ($adminId <= 0) throw new ErrException('账户不存在');
|
|
|
|
$this->adminUserInfo = $this->getAdminUserInfo($adminId);
|
|
if ($this->adminUserInfo->status == AdminUserStatusCode::DISABLE) throw new ErrException('账号已禁用',AdminCode::DISABLED);
|
|
|
|
// 超级管理员提前下场 不用判断权限
|
|
if ($this->adminUserInfo->isSuperAdmin()) return $handler->handle($request);
|
|
|
|
$this->check($request->getAttribute(Dispatched::class));
|
|
|
|
return $handler->handle($request);
|
|
}
|
|
|
|
/**
|
|
* @param Dispatched $dispatched
|
|
* @return bool
|
|
*/
|
|
private function check(Dispatched $dispatched): bool
|
|
{
|
|
$parseResult = $this->parse($dispatched->handler->callback);
|
|
if (! $parseResult) return true;
|
|
|
|
[$controller, $method] = $parseResult;
|
|
$annotations = AnnotationCollector::getClassMethodAnnotation($controller, $method);
|
|
$classAnnotation = AnnotationCollector::getClassAnnotation($controller, Permission::class);
|
|
/**
|
|
* @var Permission[] $permissions
|
|
*/
|
|
$classAnnotation && $permissions[] = $classAnnotation;
|
|
$methodPermission = Arr::get($annotations, Permission::class);
|
|
$methodPermission && $permissions[] = $methodPermission;
|
|
|
|
foreach ($permissions as $permission) {
|
|
$this->handlePermission($permission);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @param Permission $permission
|
|
* @return void
|
|
*/
|
|
private function handlePermission(Permission $permission): void
|
|
{
|
|
$operation = $permission->getOperation();
|
|
$codes = $permission->getCode();
|
|
|
|
foreach ($codes as $code) {
|
|
$isMenu = $this->adminUserInfo->hasPermission($code);
|
|
|
|
if ($operation === Permission::OPERATION_AND && !$isMenu) throw new ErrException('暂无权限',AdminCode::FORBIDDEN);
|
|
|
|
if ($operation === Permission::OPERATION_OR && $isMenu) return;
|
|
}
|
|
|
|
if ($operation === Permission::OPERATION_OR) throw new ErrException('暂无权限',AdminCode::FORBIDDEN);
|
|
}
|
|
}
|