mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-01-11 17:58:41 +00:00
Rename Router to WebRouter and implement SocketRouter
This commit is contained in:
parent
6696066f91
commit
3ee20e9fc8
|
|
@ -12,7 +12,7 @@
|
|||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpOMS\Router;
|
||||
namespace phpOMS\WebRouter;
|
||||
|
||||
use phpOMS\Stdlib\Base\Enum;
|
||||
|
||||
|
|
|
|||
37
Router/RouterInterface.php
Normal file
37
Router/RouterInterface.php
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
/**
|
||||
* Orange Management
|
||||
*
|
||||
* PHP Version 7.4
|
||||
*
|
||||
* @package phpOMS\DataStorage\Database\Schema
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link https://orange-management.org
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpOMS\Router;
|
||||
|
||||
/**
|
||||
* Router interface.
|
||||
*
|
||||
* @package phpOMS\Router
|
||||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*/
|
||||
interface RouterInterface
|
||||
{
|
||||
/**
|
||||
* Add routes from file.
|
||||
*
|
||||
* @param string $path Route file path
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function importFromFile(string $path) : bool;
|
||||
}
|
||||
135
Router/SocketRouter.php
Normal file
135
Router/SocketRouter.php
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
/**
|
||||
* Orange Management
|
||||
*
|
||||
* PHP Version 7.4
|
||||
*
|
||||
* @package phpOMS\Router
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link https://orange-management.org
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpOMS\Router;
|
||||
|
||||
/**
|
||||
* Router class for socket routes.
|
||||
*
|
||||
* @package phpOMS\Router
|
||||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class SocketRouter implements RouterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Routes.
|
||||
*
|
||||
* @var array
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private array $routes = [];
|
||||
|
||||
/**
|
||||
* Add routes from file.
|
||||
*
|
||||
* Files need to return a php array of the following structure:
|
||||
* return [
|
||||
* '{REGEX_PATH}' => [
|
||||
* 'dest' => '{DESTINATION_NAMESPACE:method}', // can also be static by using :: between namespace and function name
|
||||
* 'permission' => [ // optional
|
||||
* 'module' => '{MODULE_NAME}',
|
||||
* 'type' => PermissionType::{TYPE},
|
||||
* 'state' => PermissionState::{STATE},
|
||||
* ],
|
||||
* // define different destination for different verb
|
||||
* ],
|
||||
* // define another regex path, destination, permission here
|
||||
* ];
|
||||
*
|
||||
* @param string $path Route file path
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function importFromFile(string $path) : bool
|
||||
{
|
||||
if (!\file_exists($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
$this->routes += include $path;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add route.
|
||||
*
|
||||
* @param string $route Route regex
|
||||
* @param mixed $destination Destination e.g. Module:function string or callback
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function add(string $route, $destination) : void
|
||||
{
|
||||
if (!isset($this->routes[$route])) {
|
||||
$this->routes[$route] = [];
|
||||
}
|
||||
|
||||
$this->routes[$route][] = [
|
||||
'dest' => $destination,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Route request.
|
||||
*
|
||||
* @param string $uri Route
|
||||
* @param string $app Application name
|
||||
* @param int $orgId Organization id
|
||||
* @param mixed $account Account
|
||||
*
|
||||
* @return array[]
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function route(
|
||||
string $uri,
|
||||
string $app = null,
|
||||
int $orgId = null,
|
||||
$account = null
|
||||
) : array
|
||||
{
|
||||
$bound = [];
|
||||
foreach ($this->routes as $route => $destination) {
|
||||
if (!((bool) \preg_match('~^' . $route . '$~', $uri))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($destination as $d) {
|
||||
// if permission check is invalid
|
||||
if ((isset($d['permission']) && $account === null)
|
||||
|| (isset($d['permission'])
|
||||
&& !$account->hasPermission(
|
||||
$d['permission']['type'], $orgId, $app, $d['permission']['module'], $d['permission']['state']
|
||||
)
|
||||
)
|
||||
) {
|
||||
return $app !== null ? $this->route('/' . \strtolower($app) . '/e403') : $this->route('/e403');
|
||||
}
|
||||
|
||||
$bound[] = ['dest' => $d['dest']];
|
||||
}
|
||||
}
|
||||
|
||||
return $bound;
|
||||
}
|
||||
}
|
||||
|
|
@ -14,18 +14,17 @@ declare(strict_types=1);
|
|||
|
||||
namespace phpOMS\Router;
|
||||
|
||||
use phpOMS\Message\Http\Request;
|
||||
use phpOMS\Uri\Http;
|
||||
use phpOMS\DataStorage\Database\Schema\Grammar\RouterInterface;
|
||||
|
||||
/**
|
||||
* Router class.
|
||||
* Router class for web routes.
|
||||
*
|
||||
* @package phpOMS\Router
|
||||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class Router
|
||||
final class WebRouter implements RouterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpOMS\tests\Router;
|
||||
namespace phpOMS\tests\WebRouter;
|
||||
|
||||
require_once __DIR__ . '/../Autoloader.php';
|
||||
|
||||
|
|
|
|||
163
tests/Router/SocketRouterTest.php
Normal file
163
tests/Router/SocketRouterTest.php
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
<?php
|
||||
/**
|
||||
* Orange Management
|
||||
*
|
||||
* PHP Version 7.4
|
||||
*
|
||||
* @package tests
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link https://orange-management.org
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpOMS\tests\Router;
|
||||
|
||||
use Modules\Admin\Controller\BackendController;
|
||||
use Modules\Admin\Models\PermissionState;
|
||||
use phpOMS\Account\Account;
|
||||
use phpOMS\Account\PermissionAbstract;
|
||||
use phpOMS\Account\PermissionType;
|
||||
use phpOMS\Router\SocketRouter;
|
||||
|
||||
require_once __DIR__ . '/../Autoloader.php';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class SocketRouterTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testAttributes() : void
|
||||
{
|
||||
$router = new SocketRouter();
|
||||
self::assertInstanceOf('\phpOMS\Router\SocketRouter', $router);
|
||||
self::assertObjectHasAttribute('routes', $router);
|
||||
}
|
||||
|
||||
public function testDefault() : void
|
||||
{
|
||||
$router = new SocketRouter();
|
||||
self::assertEmpty($router->route('some_test route'));
|
||||
}
|
||||
|
||||
public function testInvalidRoutingFile() : void
|
||||
{
|
||||
$router = new SocketRouter();
|
||||
self::assertFalse($router->importFromFile(__Dir__ . '/invalidFile.php'));
|
||||
}
|
||||
|
||||
public function testLoadingRoutesFromFile() : void
|
||||
{
|
||||
$router = new SocketRouter();
|
||||
self::assertTrue($router->importFromFile(__Dir__ . '/socketRouterTestFile.php'));
|
||||
}
|
||||
|
||||
public function testRouteMatching() : void
|
||||
{
|
||||
$router = new SocketRouter();
|
||||
self::assertTrue($router->importFromFile(__Dir__ . '/socketRouterTestFile.php'));
|
||||
|
||||
self::assertEquals(
|
||||
[['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']],
|
||||
$router->route('backend_admin -settings=general -t 123')
|
||||
);
|
||||
}
|
||||
|
||||
public function testDynamicRouteAdding() : void
|
||||
{
|
||||
$router = new SocketRouter();
|
||||
self::assertNotEquals(
|
||||
[['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']],
|
||||
$router->route('backends_admin -settings=general -t 123')
|
||||
);
|
||||
|
||||
$router->add('^.*backends_admin -settings=general.*$', 'Controller:test');
|
||||
self::assertEquals(
|
||||
[['dest' => 'Controller:test']],
|
||||
$router->route('backends_admin -settings=general -t 123')
|
||||
);
|
||||
}
|
||||
|
||||
public function testWithValidPermissions() : void
|
||||
{
|
||||
$router = new SocketRouter();
|
||||
self::assertTrue($router->importFromFile(__Dir__ . '/socketRouterTestFilePermission.php'));
|
||||
|
||||
$perm = new class(
|
||||
null,
|
||||
null,
|
||||
BackendController::MODULE_NAME,
|
||||
0,
|
||||
PermissionState::SETTINGS,
|
||||
null,
|
||||
null,
|
||||
PermissionType::READ
|
||||
) extends PermissionAbstract {};
|
||||
|
||||
$account = new Account();
|
||||
$account->addPermission($perm);
|
||||
|
||||
self::assertEquals(
|
||||
[['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']],
|
||||
$router->route('backend_admin -settings=general -t 123',
|
||||
null,
|
||||
null,
|
||||
$account
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function testWithInvalidPermissions() : void
|
||||
{
|
||||
$router = new SocketRouter();
|
||||
self::assertTrue($router->importFromFile(__Dir__ . '/socketRouterTestFilePermission.php'));
|
||||
|
||||
$perm2 = new class(
|
||||
null,
|
||||
null,
|
||||
BackendController::MODULE_NAME,
|
||||
0,
|
||||
PermissionState::SETTINGS,
|
||||
null,
|
||||
null,
|
||||
PermissionType::CREATE
|
||||
) extends PermissionAbstract {};
|
||||
|
||||
$perm3 = new class(
|
||||
null,
|
||||
null,
|
||||
'InvalidModule',
|
||||
0,
|
||||
PermissionState::SETTINGS,
|
||||
null,
|
||||
null,
|
||||
PermissionType::READ
|
||||
) extends PermissionAbstract {};
|
||||
|
||||
$perm4 = new class(
|
||||
null,
|
||||
null,
|
||||
BackendController::MODULE_NAME,
|
||||
0,
|
||||
99,
|
||||
null,
|
||||
null,
|
||||
PermissionType::READ
|
||||
) extends PermissionAbstract {};
|
||||
|
||||
$account2 = new Account();
|
||||
$account2->addPermission($perm2);
|
||||
$account2->addPermission($perm3);
|
||||
$account2->addPermission($perm4);
|
||||
|
||||
self::assertNotEquals(
|
||||
[['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']],
|
||||
$router->route('backend_admin -settings=general -t 123',
|
||||
null,
|
||||
null,
|
||||
$account2
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ use phpOMS\Account\Account;
|
|||
use phpOMS\Account\PermissionAbstract;
|
||||
use phpOMS\Account\PermissionType;
|
||||
use phpOMS\Message\Http\Request;
|
||||
use phpOMS\Router\Router;
|
||||
use phpOMS\Router\WebRouter;
|
||||
use phpOMS\Router\RouteVerb;
|
||||
use phpOMS\Uri\Http;
|
||||
|
||||
|
|
@ -29,18 +29,18 @@ require_once __DIR__ . '/../Autoloader.php';
|
|||
/**
|
||||
* @internal
|
||||
*/
|
||||
class RouterTest extends \PHPUnit\Framework\TestCase
|
||||
class WebRouterTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testAttributes() : void
|
||||
{
|
||||
$router = new Router();
|
||||
self::assertInstanceOf('\phpOMS\Router\Router', $router);
|
||||
$router = new WebRouter();
|
||||
self::assertInstanceOf('\phpOMS\Router\WebRouter', $router);
|
||||
self::assertObjectHasAttribute('routes', $router);
|
||||
}
|
||||
|
||||
public function testDefault() : void
|
||||
{
|
||||
$router = new Router();
|
||||
$router = new WebRouter();
|
||||
self::assertEmpty(
|
||||
$router->route(
|
||||
(new Request(new Http('')))->getUri()->getRoute()
|
||||
|
|
@ -48,11 +48,22 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
);
|
||||
}
|
||||
|
||||
public function testGetSet() : void
|
||||
public function testInvalidRoutingFile() : void
|
||||
{
|
||||
$router = new Router();
|
||||
$router = new WebRouter();
|
||||
self::assertFalse($router->importFromFile(__Dir__ . '/invalidFile.php'));
|
||||
self::assertTrue($router->importFromFile(__Dir__ . '/routerTestFile.php'));
|
||||
}
|
||||
|
||||
public function testLoadingRoutesFromFile() : void
|
||||
{
|
||||
$router = new WebRouter();
|
||||
self::assertTrue($router->importFromFile(__Dir__ . '/webRouterTestFile.php'));
|
||||
}
|
||||
|
||||
public function testRouteMatching() : void
|
||||
{
|
||||
$router = new WebRouter();
|
||||
self::assertTrue($router->importFromFile(__Dir__ . '/webRouterTestFile.php'));
|
||||
|
||||
self::assertEquals(
|
||||
[['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']],
|
||||
|
|
@ -70,6 +81,25 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
new Http('http://test.com/backend/admin/settings/general/something?test')
|
||||
))->getUri()->getRoute(), null, RouteVerb::PUT)
|
||||
);
|
||||
}
|
||||
|
||||
public function testRouteMissMatchingForInvalidVerbs() : void
|
||||
{
|
||||
$router = new WebRouter();
|
||||
self::assertTrue($router->importFromFile(__Dir__ . '/webRouterTestFile.php'));
|
||||
|
||||
self::assertNotEquals(
|
||||
[['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']],
|
||||
$router->route(
|
||||
(new Request(
|
||||
new Http('http://test.com/backend/admin/settings/general/something?test')
|
||||
))->getUri()->getRoute(), null, RouteVerb::PUT)
|
||||
);
|
||||
}
|
||||
|
||||
public function testDynamicRouteAdding() : void
|
||||
{
|
||||
$router = new WebRouter();
|
||||
|
||||
self::assertNotEquals(
|
||||
[['dest' => '\Modules\Admin\Controller:viewSettingsGeneral']],
|
||||
|
|
@ -107,8 +137,8 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
|
||||
public function testWithCSRF() : void
|
||||
{
|
||||
$router = new Router();
|
||||
self::assertTrue($router->importFromFile(__Dir__ . '/routeTestCsrf.php'));
|
||||
$router = new WebRouter();
|
||||
self::assertTrue($router->importFromFile(__Dir__ . '/webRouteTestCsrf.php'));
|
||||
|
||||
self::assertEquals(
|
||||
[['dest' => '\Modules\Admin\Controller:viewCsrf']],
|
||||
|
|
@ -130,10 +160,10 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
);
|
||||
}
|
||||
|
||||
public function testWithPermissions() : void
|
||||
public function testWithValidPermissions() : void
|
||||
{
|
||||
$router = new Router();
|
||||
self::assertTrue($router->importFromFile(__Dir__ . '/routerTestFilePermission.php'));
|
||||
$router = new WebRouter();
|
||||
self::assertTrue($router->importFromFile(__Dir__ . '/webRouterTestFilePermission.php'));
|
||||
|
||||
$perm = new class(
|
||||
null,
|
||||
|
|
@ -160,6 +190,12 @@ class RouterTest extends \PHPUnit\Framework\TestCase
|
|||
$account
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function testWithInvalidPermissions() : void
|
||||
{
|
||||
$router = new WebRouter();
|
||||
self::assertTrue($router->importFromFile(__Dir__ . '/webRouterTestFilePermission.php'));
|
||||
|
||||
$perm2 = new class(
|
||||
null,
|
||||
8
tests/Router/socketRouterTestFile.php
Normal file
8
tests/Router/socketRouterTestFile.php
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?php declare(strict_types=1);
|
||||
return [
|
||||
'^.*backend_admin -settings=general.*$' => [
|
||||
0 => [
|
||||
'dest' => '\Modules\Admin\Controller:viewSettingsGeneral',
|
||||
],
|
||||
],
|
||||
];
|
||||
18
tests/Router/socketRouterTestFilePermission.php
Normal file
18
tests/Router/socketRouterTestFilePermission.php
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
use Modules\Admin\Controller\BackendController;
|
||||
use Modules\Admin\Models\PermissionState;
|
||||
use phpOMS\Account\PermissionType;
|
||||
|
||||
return [
|
||||
'^.*backend_admin -settings=general.*$' => [
|
||||
0 => [
|
||||
'dest' => '\Modules\Admin\Controller:viewSettingsGeneral',
|
||||
'permission' => [
|
||||
'module' => BackendController::MODULE_NAME,
|
||||
'type' => PermissionType::READ,
|
||||
'state' => PermissionState::SETTINGS,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
Loading…
Reference in New Issue
Block a user