diff --git a/src/Eccube/Form/Type/Admin/SecurityType.php b/src/Eccube/Form/Type/Admin/SecurityType.php index e191e8174af..f48ad6f6545 100644 --- a/src/Eccube/Form/Type/Admin/SecurityType.php +++ b/src/Eccube/Form/Type/Admin/SecurityType.php @@ -22,6 +22,7 @@ use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormEvents; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\Routing\RouterInterface; use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Validator\ValidatorInterface; @@ -42,17 +43,25 @@ class SecurityType extends AbstractType */ protected $requestStack; + /** + * @var RouterInterface + */ + protected $router; + /** * SecurityType constructor. * * @param EccubeConfig $eccubeConfig * @param ValidatorInterface $validator + * @param RequestStack $requestStack + * @param RouterInterface $router */ - public function __construct(EccubeConfig $eccubeConfig, ValidatorInterface $validator, RequestStack $requestStack) + public function __construct(EccubeConfig $eccubeConfig, ValidatorInterface $validator, RequestStack $requestStack, RouterInterface $router) { $this->eccubeConfig = $eccubeConfig; $this->validator = $validator; $this->requestStack = $requestStack; + $this->router = $router; } /** @@ -66,6 +75,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) $denyHosts = $this->eccubeConfig->get('eccube_admin_deny_hosts'); $denyHosts = implode("\n", $denyHosts); + $routes = $this->getRouteCollection(); $allowFrontHosts = $this->eccubeConfig->get('eccube_front_allow_hosts'); $allowFrontHosts = implode("\n", $allowFrontHosts); @@ -80,6 +90,9 @@ public function buildForm(FormBuilderInterface $builder, array $options) new Assert\Regex([ 'pattern' => '/\A\w+\z/', ]), + new Assert\Regex([ + 'pattern' => "/^(?!($routes)$).*$/", + ]), ], 'data' => $this->eccubeConfig->get('eccube_admin_route'), ]) @@ -202,6 +215,34 @@ public function buildForm(FormBuilderInterface $builder, array $options) ; } + /** + * フロントURL一覧を取得 + * @return string + */ + private function getRouteCollection(): string + { + $frontRoutesUrlList = []; + $routes = $this->router->getRouteCollection(); + foreach ($routes as $routeName => $route) { + $path = $route->getPath(); + // 管理画面以外 + if (false === stripos($routeName, 'admin') + && false === stripos($path, '/_') + && false === stripos($path, 'admin') + ) { + $arr = explode('/', $path); + foreach ($arr as $target) { + if (!empty($target)) { + $target = preg_quote($target); + $frontRoutesUrlList[$target] = $target; + } + } + } + } + + return implode('|', $frontRoutesUrlList); + } + /** * {@inheritdoc} */ diff --git a/tests/Eccube/Tests/Form/Type/Admin/SecurityTypeTest.php b/tests/Eccube/Tests/Form/Type/Admin/SecurityTypeTest.php index a926116c77a..e83c441ae2b 100644 --- a/tests/Eccube/Tests/Form/Type/Admin/SecurityTypeTest.php +++ b/tests/Eccube/Tests/Form/Type/Admin/SecurityTypeTest.php @@ -126,6 +126,174 @@ public function adminRouteDirParams() ['admin/route', false], ['admin&', false], ['admin?', false], + ['/admin/content/news/page/{page_no}', false], + ['/admin/disable_maintenance/{mode}', false], + ['/admin/content/news/page/{page_no}', false], + ['/admin/product/class_category/{class_name_id}/{id}/edit', false], + ['cart_admin', true], + ['admin_cart', true], + ['product_admin', true], + ['admin_products', true], + ['cart', false], + ['cart&', false], + ['cart?', false], + ['/cart', false], + ['/cart/', false], + ['/cart/buystep', false], + ['/cart/buystep&', false], + ['/cart/buystep?', false], + ['/cart/buystep/', false], + ['/cart/buystep/{cart_key}', false], + ['/cart/{operation}/{productClassId}', false], + ['contact', false], + ['contact&', false], + ['contact?', false], + ['/contact', false], + ['/contact/', false], + ['/contact/complete', false], + ['/contact/complete&', false], + ['/contact/complete?', false], + ['entry', false], + ['entry?', false], + ['entry&', false], + ['/entry', false], + ['/entry&', false], + ['/entry?', false], + ['/entry/', false], + ['/entry/complete', false], + ['/entry/complete&', false], + ['/entry/complete?', false], + ['/entry/activate', false], + ['/entry/activate?', false], + ['/entry/activate&', false], + ['/entry/activate/', false], + ['/entry/activate/{secret_key}/{qtyInCart}', false], + ['/forgot', false], + ['/forgot&', false], + ['/forgot?', false], + ['/forgot/complete', false], + ['/forgot/complete?', false], + ['/forgot/complete&', false], + ['/forgot/reset', false], + ['/forgot/reset&', false], + ['/forgot/reset?', false], + ['/forgot/reset/', false], + ['/forgot/reset/{reset_key}', false], + ['/help/tradelaw', false], + ['/help/tradelaw&', false], + ['/help/tradelaw?', false], + ['/guide', false], + ['/guide&', false], + ['/guide?', false], + ['/help/about', false], + ['/help/about&', false], + ['/help/about?', false], + ['/help/privacy', false], + ['/help/privacy&', false], + ['/help/privacy?', false], + ['/help/agreement', false], + ['/help/agreement&', false], + ['/help/agreement?', false], + ['/install/plugins', false], + ['/install/plugins&', false], + ['/install/plugins?', false], + ['/install/plugin', false], + ['/install/plugin&', false], + ['/install/plugin?', false], + ['/install/plugin/', false], + ['/install/plugin/redirect', false], + ['/install/plugin/redirect?', false], + ['/install/plugin/redirect&', false], + ['/install/plugin/{code}/enable', false], + ['/install', false], + ['/install?', false], + ['/install&', false], + ['/install/', false], + ['/install/step1', false], + ['/install/step1?', false], + ['/install/step1&', false], + ['/install/step1/', false], + ['/install/step2', false], + ['/install/step2?', false], + ['/install/step2&', false], + ['/install/step2/', false], + ['/install/step3', false], + ['/install/step3?', false], + ['/install/step3&', false], + ['/install/step3/', false], + ['/install/step4', false], + ['/install/step4?', false], + ['/install/step4&', false], + ['/install/step4/', false], + ['/install/step5', false], + ['/install/step5?', false], + ['/install/step5&', false], + ['/install/step5/', false], + ['/install/complete', false], + ['/install/complete?', false], + ['/install/complete&', false], + ['/mypage/change', false], + ['/mypage/change?', false], + ['/mypage/change&', false], + ['/mypage/change/', false], + ['/mypage/change_complete', false], + ['/mypage/change_complete?', false], + ['/mypage/change_complete&', false], + ['/mypage/change_complete/', false], + ['/mypage/delivery', false], + ['/mypage/delivery?', false], + ['/mypage/delivery&', false], + ['/mypage/delivery/', false], + ['/mypage/delivery/new', false], + ['/mypage/delivery/new?', false], + ['/mypage/delivery/new&', false], + ['/mypage/delivery/new/', false], + ['/mypage/delivery/{id}/edit', false], + ['/mypage/login', false], + ['/mypage/login?', false], + ['/mypage/login&', false], + ['/mypage/login/', false], + ['/mypage/', false], + ['/mypage/history', false], + ['/mypage/history?', false], + ['/mypage/history&', false], + ['/mypage/history/', false], + ['/mypage/order', false], + ['/mypage/order?', false], + ['/mypage/order&', false], + ['/mypage/order/', false], + ['/mypage/order/{order_no}', false], + ['/mypage/favorite', false], + ['/mypage/withdraw', false], + ['/mypage/withdraw', false], + ['/mypage/withdraw_complete', false], + ['/shopping/nonmember', false], + ['/shopping/customer', false], + ['products', false], + ['products?', false], + ['products&', false], + ['/products', false], + ['/products/list', false], + ['/products/detail/{id}', false], + ['/products/add_favorite/{id}', false], + ['/products/add_cart/{id}', false], + ['/shopping/shipping_multiple', false], + ['/shopping/shipping_multiple_edit', false], + ['/shopping/shipping/{id}', false], + ['/shopping', false], + ['/shopping/redirect_to', false], + ['/shopping/confirm', false], + ['/shopping/checkout', false], + ['/shopping/complete', false], + ['/shopping/login', false], + ['/shopping/error', false], + ['/', false], + ['/logout', false], + ['/sitemap.xml', false], + ['/sitemap_category.xml', false], + ['/sitemap_product_{page}.xml', false], + ['/sitemap_page.xml', false], + ['/user_data/{route}', false], ]; }