diff --git a/Annotation/Loader.php b/Annotation/Loader.php index 21416805..c3900dfd 100644 --- a/Annotation/Loader.php +++ b/Annotation/Loader.php @@ -35,6 +35,7 @@ class Loader extends BaseObject /** * @param $path * @param $namespace + * @throws ComponentException */ public function loader($path, $namespace) { diff --git a/Annotation/Route/Filter.php b/Annotation/Route/Filter.php index 4fa9e1b7..d4a3a51c 100644 --- a/Annotation/Route/Filter.php +++ b/Annotation/Route/Filter.php @@ -5,6 +5,11 @@ namespace Annotation\Route; use Annotation\Attribute; +use HttpServer\HttpFilter; +use ReflectionException; +use Snowflake\Exception\ComponentException; +use Snowflake\Exception\NotFindClassException; +use Snowflake\Snowflake; /** * Class Filter @@ -15,9 +20,9 @@ use Annotation\Attribute; /** * Filter constructor. - * @param string $uri + * @param array $rules */ - public function __construct(public string $uri) + public function __construct(public array $rules) { } @@ -25,10 +30,18 @@ use Annotation\Attribute; /** * @param array $handler * @return array + * @throws ReflectionException + * @throws ComponentException + * @throws NotFindClassException */ public function execute(array $handler): array { - // TODO: Implement execute() method. + [$class, $method] = $handler; + + /** @var HttpFilter $filter */ + $filter = Snowflake::app()->get('filter'); + $filter->register(get_class($class), $method, $this->rules); + return $handler; } diff --git a/HttpServer/HttpFilter.php b/HttpServer/HttpFilter.php new file mode 100644 index 00000000..9cf6a0cb --- /dev/null +++ b/HttpServer/HttpFilter.php @@ -0,0 +1,64 @@ +hash[$className . '::' . $method] = $rules; + return $this; + } + + + /** + * @param string $className + * @param string $method + * @return bool + * @throws Exception + */ + public function check(string $className, string $method): bool|Validator + { + if (!isset($this->hash[$className . '::' . $method])) { + return true; + } + + $rules = $this->hash[$className . '::' . $method][request()->getMethod()] ?? []; + if (empty($rules)) { + return true; + } + + $validator = Validator::getInstance(); + $validator->setParams(Input()->load()); + foreach ($rules as $Key => $val) { + $field = array_shift($val); + if (empty($val)) { + continue; + } + $validator->make($field, $val); + } + return $validator; + } + +} diff --git a/HttpServer/Route/Node.php b/HttpServer/Route/Node.php index 164810cc..b5cd32ee 100644 --- a/HttpServer/Route/Node.php +++ b/HttpServer/Route/Node.php @@ -12,6 +12,7 @@ use HttpServer\Controller; use HttpServer\Http\Request; use Exception; +use HttpServer\HttpFilter; use HttpServer\IInterface\After; use HttpServer\IInterface\Interceptor; use HttpServer\IInterface\Limits; @@ -24,6 +25,7 @@ use Snowflake\Exception\ComponentException; use Snowflake\Exception\NotFindClassException; use Snowflake\Snowflake; use Throwable; +use validator\Validator; use function Input; /** @@ -563,6 +565,31 @@ class Node extends HttpService if (empty($this->callback)) { return Json::to(404, $this->errorMsg()); } + return $this->httpFilter(...func_get_args()); + } + + + /** + * @return mixed + * @throws ComponentException + * @throws NotFindClassException + * @throws ReflectionException + * @throws Exception + */ + private function httpFilter(): mixed + { + if (!is_array($this->handler)) { + return $this->runWith(...func_get_args()); + } + [$class, $method] = $this->handler; + + /** @var HttpFilter $filter */ + $filter = Snowflake::app()->get('filter'); + $validator = $filter->check(get_class($class), $method); + if ($validator instanceof Validator && !$validator->validation()) { + return Json::to(401, $validator->getError()); + } + return $this->runWith(...func_get_args()); } diff --git a/System/Abstracts/BaseApplication.php b/System/Abstracts/BaseApplication.php index 627de245..ceb32f11 100644 --- a/System/Abstracts/BaseApplication.php +++ b/System/Abstracts/BaseApplication.php @@ -14,6 +14,7 @@ use Exception; use HttpServer\Client\Http2; use HttpServer\Http\Request; use HttpServer\Http\Response; +use HttpServer\HttpFilter; use HttpServer\Route\Router; use HttpServer\Server; @@ -292,10 +293,10 @@ abstract class BaseApplication extends Service /** - * @throws ComponentException + * @return SRedis * @throws NotFindClassException * @throws ReflectionException - * @return SRedis + * @throws ComponentException */ public function getRedisFromPool(): SRedis { @@ -443,6 +444,7 @@ abstract class BaseApplication extends Service 'redis' => ['class' => Redis::class], 'jwt' => ['class' => Jwt::class], 'async' => ['class' => Async::class], + 'filter' => ['class' => HttpFilter::class], 'object' => ['class' => ObjectPool::class], 'goto' => ['class' => BaseGoto::class], 'http2' => ['class' => Http2::class],