Add legacy non-view actions re-direction

- Listen to legacy non-view calls on the LegacyRedirectListener
- Add LegacyNonViewActionRedirectHandler to re-direct to legacy
-- Using 307 re-direction response to support post re-direction
- Add unit test for LegacyNonViewActionRedirectHandler
This commit is contained in:
Clemente Raposo 2020-05-08 16:12:15 +01:00 committed by Dillon-Brown
parent 6c3e266b5d
commit c1ef13322a
7 changed files with 545 additions and 18 deletions

View file

@ -16,7 +16,7 @@ describe('Action Name Mapper Service', () => {
it('#toFrontend with invalid action name', () => {
const action = service.toFrontend('fake');
expect(action).toEqual(undefined);
expect(action).toEqual('fake');
});
it('#toLegacy with valid action name', () => {
@ -28,7 +28,7 @@ describe('Action Name Mapper Service', () => {
it('#toLegacy with invalid action name', () => {
const action = service.toLegacy('fake');
expect(action).toEqual(undefined);
expect(action).toEqual('fake');
});
it('#isValid with valid action name', () => {

View file

@ -4,6 +4,7 @@ namespace App\EventListener;
use App\Service\LegacyApiRedirectHandler;
use App\Service\LegacyAssetRedirectHandler;
use App\Service\LegacyNonViewActionRedirectHandler;
use App\Service\RouteConverter;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
@ -28,21 +29,28 @@ class LegacyRedirectListener
* @var LegacyApiRedirectHandler
*/
private $legacyApiRedirectHandler;
/**
* @var LegacyNonViewActionRedirectHandler
*/
private $legacyNonViewActionRedirectHandler;
/**
* LegacyRedirectListener constructor.
* @param RouteConverter $routeConverter
* @param LegacyAssetRedirectHandler $legacyAssetHandler
* @param LegacyApiRedirectHandler $legacyApiRedirectHandler
* @param LegacyNonViewActionRedirectHandler $legacyNonViewActionRedirectHandler
*/
public function __construct(
RouteConverter $routeConverter,
LegacyAssetRedirectHandler $legacyAssetHandler,
LegacyApiRedirectHandler $legacyApiRedirectHandler
LegacyApiRedirectHandler $legacyApiRedirectHandler,
LegacyNonViewActionRedirectHandler $legacyNonViewActionRedirectHandler
) {
$this->routeConverter = $routeConverter;
$this->legacyAssetHandler = $legacyAssetHandler;
$this->legacyApiRedirectHandler = $legacyApiRedirectHandler;
$this->legacyNonViewActionRedirectHandler = $legacyNonViewActionRedirectHandler;
}
/**
@ -67,25 +75,31 @@ class LegacyRedirectListener
return;
}
if ($this->isConvertible($event)) {
if ($this->isLegacyViewRoute($event)) {
$url = $this->routeConverter->convert($event->getRequest());
$response = new RedirectResponse($url);
$event->setResponse($response);
}
if ($this->isLegacyNonViewActionRoute($event)) {
$url = $this->legacyNonViewActionRedirectHandler->convert($event->getRequest());
$response = new RedirectResponse($url, 307);
$event->setResponse($response);
}
}
/**
* Check if it is possible to convert the legacy request
* Check if request is a legacy view request
* @param RequestEvent $event
* @return bool
*/
protected function isConvertible(RequestEvent $event): bool
protected function isLegacyViewRoute(RequestEvent $event): bool
{
return $this->routeConverter->isLegacyRoute($event->getRequest());
return $this->routeConverter->isLegacyViewRoute($event->getRequest());
}
/**
* Check if it is legacy asset requests
* Check if it is legacy asset request
* @param RequestEvent $event
* @return bool
*/
@ -95,7 +109,7 @@ class LegacyRedirectListener
}
/**
* Check if it is legacy api requests
* Check if it is legacy api request
* @param RequestEvent $event
* @return bool
*/
@ -103,4 +117,14 @@ class LegacyRedirectListener
{
return $this->legacyApiRedirectHandler->isApiRequest($event->getRequest());
}
/**
* Check if it is legacy non view request
* @param RequestEvent $event
* @return bool
*/
protected function isLegacyNonViewActionRoute(RequestEvent $event): bool
{
return $this->legacyNonViewActionRedirectHandler->isMatch($event->getRequest());
}
}

View file

@ -0,0 +1,60 @@
<?php
namespace App\Service;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\NoConfigurationException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\RouterInterface;
class LegacyNonViewActionRedirectHandler extends LegacyRedirectHandler
{
/**
* @var RouteConverter
*/
private $routeConverter;
/**
* @var RouterInterface
*/
private $router;
/**
* LegacyNonViewActionRedirectHandler constructor.
* @param RouteConverter $routeConverter
* @param RouterInterface $router
* @param String $legacyPath
*/
public function __construct(RouteConverter $routeConverter, RouterInterface $router, String $legacyPath)
{
parent::__construct($legacyPath);
$this->routeConverter = $routeConverter;
$this->router = $router;
}
/**
* Check if the given $request is a non view api request
*
* @param Request $request
* @return bool
*/
public function isMatch(Request $request): bool
{
if ($this->routeConverter->isLegacyViewRoute($request)) {
return false;
}
if ($this->routeConverter->isLegacyRoute($request)) {
return true;
}
$isRegistered = true;
try {
$this->router->matchRequest($request);
} catch (NoConfigurationException | ResourceNotFoundException | MethodNotAllowedException $e) {
$isRegistered = false;
}
return !($isRegistered === true);
}
}

View file

@ -67,6 +67,19 @@ class LegacyRedirectHandler
$queryString = '?' . $queryString;
}
return $request->getBaseUrl() . $this->legacyPath . $request->getPathInfo() . $queryString;
$baseUrl = $request->getBaseUrl();
if (strpos($baseUrl, '.php') !== false) {
$baseUrl = str_replace($request->getBasePath(), $request->getBasePath() . $this->legacyPath, $baseUrl);
} else {
$baseUrl .= $this->legacyPath;
}
if ($request->getPathInfo() !== '/') {
$baseUrl .= $request->getPathInfo();
}
return $baseUrl . $queryString;
}
}

View file

@ -41,7 +41,7 @@ class RouteConverter
* @param Request $request
* @return bool
*/
public function isLegacyRoute(Request $request): bool
public function isLegacyViewRoute(Request $request): bool
{
if (!empty($request->getPathInfo()) && $request->getPathInfo() !== '/') {
return false;
@ -62,6 +62,30 @@ class RouteConverter
return $this->actionNameMapper->isValidAction($action);
}
/**
* Check if the given $request route is a Legacy route
*
* @param Request $request
* @return bool
*/
public function isLegacyRoute(Request $request): bool
{
if ($this->isLegacyViewRoute($request)) {
return true;
}
if ($request->getPathInfo() !== '/') {
return false;
}
$valid = false;
$valid |= !empty($request->get('module'));
$valid |= !empty($request->get('action'));
$valid |= !empty($request->get('entryPoint'));
return $valid;
}
/**
* Convert given $request route
*
@ -196,7 +220,7 @@ class RouteConverter
$validParams = [];
foreach ($queryParams as $name => $value) {
if (in_array($name, $exclude)) {
if (in_array($name, $exclude, true)) {
continue;
}
$validParams[$name] = $value;

View file

@ -0,0 +1,406 @@
<?php namespace App\Tests;
use App\Service\ActionNameMapper;
use App\Service\LegacyNonViewActionRedirectHandler;
use App\Service\ModuleNameMapper;
use App\Service\RouteConverter;
use Codeception\Test\Unit;
use Exception;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Router;
class LegacyNonViewActionRedirectHandlerTest extends Unit
{
/**
* @var UnitTester
*/
protected $tester;
/**
* @var LegacyNonViewActionRedirectHandler
*/
private $handler;
/**
* @throws Exception
*/
protected function _before(): void
{
$legacyModuleNameMap = [
'Contacts' => [
'frontend' => 'contacts',
'core' => 'Contacts'
],
];
$legacyActionNameMap = [
'index ' => 'index',
'DetailView' => 'detail',
'EditView' => 'edit',
'ListView' => 'list',
];
$moduleMapper = new ModuleNameMapper($legacyModuleNameMap);
$actionMapper = new ActionNameMapper($legacyActionNameMap);
$converter = new RouteConverter($moduleMapper, $actionMapper);
$routes = [
'/login',
'/logout',
'/api',
'/session-status'
];
/** @var Router $router */
$router = $this->make(
Router::class,
[
'matchRequest' => static function (Request $request) use ($routes) {
if ($request->getPathInfo() === '/') {
return [];
}
foreach ($routes as $route) {
if (strpos($request->getPathInfo(), $route) === 0) {
return [];
}
}
throw new ResourceNotFoundException('path not found');
},
]
);
$this->handler = new LegacyNonViewActionRedirectHandler($converter, $router, '/legacy');
}
/**
* Test request match with suite 8 api request
*/
public function testMatchCheckWithSuite8Request(): void
{
$queryParams = [
];
$serverParams = [
'REDIRECT_BASE' => '/suiteinstance',
'BASE' => '/suiteinstance',
'HTTP_HOST' => 'localhost',
'HTTP_ORIGIN' => 'http://localhost',
'HTTP_REFERER' => 'http://localhost/suiteinstance/public/docs/graphql-playground/index.html',
'SERVER_NAME' => 'localhost',
'REDIRECT_URL' => '/suiteinstance/api/graphql',
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/suiteinstance/api/graphql',
'SCRIPT_FILENAME' => '/var/www/html/suiteinstance/index.php',
'SCRIPT_NAME' => '/suiteinstance/index.php',
'PHP_SELF' => '/suiteinstance/index.php',
];
$request = new Request($queryParams, [], [], [], [], $serverParams);
$valid = $this->handler->isMatch($request);
static::assertFalse($valid);
}
/**
* Test request match with suite 8 login request
*/
public function testMatchCheckWithSuite8LoginRequest(): void
{
$queryParams = [
];
$serverParams = [
'BASE' => '/suiteinstance',
'HTTP_HOST' => 'localhost',
'SERVER_NAME' => 'localhost',
'REDIRECT_URL' => '/suiteinstance/',
'REDIRECT_QUERY_STRING' => '',
'REQUEST_METHOD' => 'GET',
'QUERY_STRING' => '',
'SCRIPT_FILENAME' => '/var/www/html/suiteinstance/index.php',
'REQUEST_URI' => '/suiteinstance/login',
'SCRIPT_NAME' => '/suiteinstance/index.php',
'PHP_SELF' => '/suiteinstance/index.php'
];
$request = new Request($queryParams, [], [], [], [], $serverParams);
$valid = $this->handler->isMatch($request);
static::assertFalse($valid);
}
/**
* Test request match with legacy view request
*/
public function testMatchCheckWithLegacyViewRequest(): void
{
$queryParams = [
'module' => 'Contacts',
'action' => 'ListView',
];
$serverParams = [
'BASE' => '/suiteinstance',
'HTTP_HOST' => 'localhost',
'SERVER_NAME' => 'localhost',
'REDIRECT_URL' => '/suiteinstance/',
'REDIRECT_QUERY_STRING' => '',
'REQUEST_METHOD' => 'GET',
'QUERY_STRING' => 'module=Accounts&action=index',
'SCRIPT_FILENAME' => '/var/www/html/suiteinstance/index.php',
'REQUEST_URI' => '/suiteinstance/index.php?module=Contacts&action=ListView',
'SCRIPT_NAME' => '/suiteinstance/index.php',
'PHP_SELF' => '/suiteinstance/index.php'
];
$request = new Request($queryParams, [], [], [], [], $serverParams);
$valid = $this->handler->isMatch($request);
static::assertFalse($valid);
}
/**
* Test request match with legacy entry point request
*/
public function testMatchCheckWithLegacyEntryPointRequest(): void
{
$queryParams = [
'entryPoint' => 'generatePdf'
];
$serverParams = [
'BASE' => '/suiteinstance',
'HTTP_HOST' => 'localhost',
'SERVER_NAME' => 'localhost',
'REDIRECT_URL' => '/suiteinstance/',
'REDIRECT_QUERY_STRING' => '',
'REQUEST_METHOD' => 'GET',
'QUERY_STRING' => 'entryPoint=generatePdf',
'SCRIPT_FILENAME' => '/var/www/html/suiteinstance/index.php',
'REQUEST_URI' => '/suiteinstance/index.php?entryPoint=generatePdf',
'SCRIPT_NAME' => '/suiteinstance/index.php',
'PHP_SELF' => '/suiteinstance/index.php'
];
$request = new Request($queryParams, [], [], [], [], $serverParams);
$valid = $this->handler->isMatch($request);
static::assertTrue($valid);
}
/**
* Test request match with legacy subpath request
*/
public function testMatchCheckWithSubPathRequest(): void
{
$queryParams = [
];
$serverParams = [
'BASE' => '/suiteinstance',
'HTTP_HOST' => 'localhost',
'SERVER_NAME' => 'localhost',
'REDIRECT_URL' => '/suiteinstance/',
'REDIRECT_QUERY_STRING' => '',
'REQUEST_METHOD' => 'GET',
'QUERY_STRING' => '',
'SCRIPT_FILENAME' => '/var/www/html/suiteinstance/index.php',
'REQUEST_URI' => '/suiteinstance/something',
'SCRIPT_NAME' => '/suiteinstance/index.php',
'PHP_SELF' => '/suiteinstance/index.php'
];
$request = new Request($queryParams, [], [], [], [], $serverParams);
$valid = $this->handler->isMatch($request);
static::assertTrue($valid);
}
/**
* Test request match with legacy save request
*/
public function testMatchCheckWithLegacySaveRequest(): void
{
$requestParameters = [
'module' => 'Accounts',
'record' => '134f0d4a-3cb8-bf3b-e228-5eb42212b284',
'isDuplicate' => 'false',
'action' => 'Save',
'return_module' => 'Accounts',
'return_action' => 'DetailView',
'return_id' => '134f0d4a-3cb8-bf3b-e228-5eb42212b284',
'module_tab' => '',
'contact_role' => '',
'relate_to' => 'Accounts',
'relate_id' => '134f0d4a-3cb8-bf3b-e228-5eb42212b284',
'offset' => '1',
'name' => 'V8 Api test Account',
'phone_office' => '',
'website' => 'http://',
'phone_fax' => '',
'Accounts_email_widget_id' => '0',
'emailAddressWidget' => '1',
'Accounts0emailAddress0' => '',
'Accounts0emailAddressId0' => '',
'Accounts0emailAddressVerifiedFlag' => 'true',
'Accounts0emailAddressVerifiedEmailValue' => 'true',
'Accounts0emailAddressPrimaryFlag' => 'Accounts0emailAddress0',
'useEmailWidget' => 'true',
'billing_address_street' => '',
'billing_address_city' => '',
'billing_address_state' => '',
'billing_address_postalcode' => '',
'billing_address_country' => '',
'shipping_address_street' => '',
'shipping_address_city' => '',
'shipping_address_state' => '',
'shipping_address_postalcode' => '',
'shipping_address_country' => '',
'description' => '',
'assigned_user_name' => '',
'assigned_user_id' => '',
'account_type' => '',
'industry' => '',
'annual_revenue' => '',
'employees' => '',
'parent_name' => '',
'parent_id' => '',
'campaign_name' => ''
];
$serverParams = [
'BASE' => '/suiteinstance',
'HTTP_HOST' => 'localhost',
'SERVER_NAME' => 'localhost',
'REDIRECT_URL' => '/suiteinstance/',
'REDIRECT_QUERY_STRING' => '',
'REQUEST_METHOD' => 'POST',
'QUERY_STRING' => '',
'SCRIPT_FILENAME' => '/var/www/html/suiteinstance/index.php',
'REQUEST_URI' => '/suiteinstance/index.php',
'SCRIPT_NAME' => '/suiteinstance/index.php',
'PHP_SELF' => '/suiteinstance/index.php'
];
$request = new Request([], $requestParameters, [], [], [], $serverParams);
$valid = $this->handler->isMatch($request);
static::assertTrue($valid);
}
/**
* Test path conversion with legacy entry point request
*/
public function testPathConversionWithLegacyEntryPointRequest(): void
{
$resultingRoute = '/suiteinstance/legacy/index.php?entryPoint=generatePdf';
$queryParams = [
'entryPoint' => 'generatePdf'
];
$serverParams = [
'BASE' => '/suiteinstance',
'HTTP_HOST' => 'localhost',
'SERVER_NAME' => 'localhost',
'REDIRECT_URL' => '/suiteinstance/',
'REDIRECT_QUERY_STRING' => '',
'REQUEST_METHOD' => 'GET',
'QUERY_STRING' => 'entryPoint=generatePdf',
'SCRIPT_FILENAME' => '/var/www/html/suiteinstance/index.php',
'REQUEST_URI' => '/suiteinstance/index.php?entryPoint=generatePdf',
'SCRIPT_NAME' => '/suiteinstance/index.php',
'PHP_SELF' => '/suiteinstance/index.php'
];
$request = new Request($queryParams, [], [], [], [], $serverParams);
$route = $this->handler->convert($request);
static::assertEquals($resultingRoute, $route);
}
/**
* Test path conversion with legacy save request
*/
public function testPathConversionWithLegacySaveRequest(): void
{
$resultingRoute = '/suiteinstance/legacy/index.php';
$requestParameters = [
'module' => 'Accounts',
'record' => '134f0d4a-3cb8-bf3b-e228-5eb42212b284',
'isDuplicate' => 'false',
'action' => 'Save',
'return_module' => 'Accounts',
'return_action' => 'DetailView',
'return_id' => '134f0d4a-3cb8-bf3b-e228-5eb42212b284',
'module_tab' => '',
'contact_role' => '',
'relate_to' => 'Accounts',
'relate_id' => '134f0d4a-3cb8-bf3b-e228-5eb42212b284',
'offset' => '1',
'name' => 'V8 Api test Account',
'phone_office' => '',
'website' => 'http://',
'phone_fax' => '',
'Accounts_email_widget_id' => '0',
'emailAddressWidget' => '1',
'Accounts0emailAddress0' => '',
'Accounts0emailAddressId0' => '',
'Accounts0emailAddressVerifiedFlag' => 'true',
'Accounts0emailAddressVerifiedEmailValue' => 'true',
'Accounts0emailAddressPrimaryFlag' => 'Accounts0emailAddress0',
'useEmailWidget' => 'true',
'billing_address_street' => '',
'billing_address_city' => '',
'billing_address_state' => '',
'billing_address_postalcode' => '',
'billing_address_country' => '',
'shipping_address_street' => '',
'shipping_address_city' => '',
'shipping_address_state' => '',
'shipping_address_postalcode' => '',
'shipping_address_country' => '',
'description' => '',
'assigned_user_name' => '',
'assigned_user_id' => '',
'account_type' => '',
'industry' => '',
'annual_revenue' => '',
'employees' => '',
'parent_name' => '',
'parent_id' => '',
'campaign_name' => ''
];
$serverParams = [
'BASE' => '/suiteinstance',
'HTTP_HOST' => 'localhost',
'SERVER_NAME' => 'localhost',
'REDIRECT_URL' => '/suiteinstance/',
'REDIRECT_QUERY_STRING' => '',
'REQUEST_METHOD' => 'POST',
'QUERY_STRING' => '',
'SCRIPT_FILENAME' => '/var/www/html/suiteinstance/index.php',
'REQUEST_URI' => '/suiteinstance/index.php',
'SCRIPT_NAME' => '/suiteinstance/index.php',
'PHP_SELF' => '/suiteinstance/index.php'
];
$request = new Request([], $requestParameters, [], [], [], $serverParams);
$route = $this->handler->convert($request);
static::assertEquals($resultingRoute, $route);
}
}

View file

@ -63,7 +63,7 @@ class RouteConverterTest extends Unit
$request = new Request($queryParams,[],[],[],[], $serverParams);
$valid = $this->routeConverter->isLegacyRoute($request);
$valid = $this->routeConverter->isLegacyViewRoute($request);
static::assertFalse($valid);
}
@ -91,7 +91,7 @@ class RouteConverterTest extends Unit
$request = new Request($queryParams,[],[],[],[], $serverParams);
$valid = $this->routeConverter->isLegacyRoute($request);
$valid = $this->routeConverter->isLegacyViewRoute($request);
static::assertTrue($valid);
}
@ -106,7 +106,7 @@ class RouteConverterTest extends Unit
$request = new Request($queryParams);
$valid = $this->routeConverter->isLegacyRoute($request);
$valid = $this->routeConverter->isLegacyViewRoute($request);
static::assertTrue($valid);
}
@ -117,7 +117,7 @@ class RouteConverterTest extends Unit
$request = new Request($queryParams);
$valid = $this->routeConverter->isLegacyRoute($request);
$valid = $this->routeConverter->isLegacyViewRoute($request);
static::assertFalse($valid);
}
@ -130,7 +130,7 @@ class RouteConverterTest extends Unit
$request = new Request($queryParams);
$valid = $this->routeConverter->isLegacyRoute($request);
$valid = $this->routeConverter->isLegacyViewRoute($request);
static::assertFalse($valid);
}
@ -145,7 +145,7 @@ class RouteConverterTest extends Unit
$request = new Request($queryParams);
$valid = $this->routeConverter->isLegacyRoute($request);
$valid = $this->routeConverter->isLegacyViewRoute($request);
static::assertFalse($valid);
}