diff --git a/package-lock.json b/package-lock.json index 80f89662e80..ff0ecdccf04 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "eccube", - "version": "4.2.3", + "version": "4.2.3-p1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 466d97ea39b..3fe10c7c147 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eccube", - "version": "4.2.3", + "version": "4.2.3-p1", "description": "EC-CUBE EC open platform.", "main": "index.js", "directories": { diff --git a/src/Eccube/Common/Constant.php b/src/Eccube/Common/Constant.php index 826eef987cc..177623cc479 100644 --- a/src/Eccube/Common/Constant.php +++ b/src/Eccube/Common/Constant.php @@ -18,7 +18,7 @@ class Constant /** * EC-CUBE VERSION. */ - public const VERSION = '4.2.3'; + public const VERSION = '4.2.3-p1'; /** * Enable value. diff --git a/src/Eccube/Controller/Admin/Store/OwnerStoreController.php b/src/Eccube/Controller/Admin/Store/OwnerStoreController.php index 9fe068412ab..882ae87cfb1 100644 --- a/src/Eccube/Controller/Admin/Store/OwnerStoreController.php +++ b/src/Eccube/Controller/Admin/Store/OwnerStoreController.php @@ -32,6 +32,8 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Validator\Constraints as Assert; +use Symfony\Component\Validator\Validator\ValidatorInterface; /** * @Route("/%eccube_admin_route%/store/plugin/api") @@ -48,6 +50,11 @@ class OwnerStoreController extends AbstractController */ protected $pluginService; + /** + * @var ValidatorInterface + */ + protected ValidatorInterface $validator; + /** * @var ComposerServiceInterface */ @@ -81,6 +88,7 @@ class OwnerStoreController extends AbstractController * @param PluginApiService $pluginApiService * @param BaseInfoRepository $baseInfoRepository * @param CacheUtil $cacheUtil + * @param ValidatorInterface $validatorInterface * * @throws \Doctrine\ORM\NoResultException * @throws \Doctrine\ORM\NonUniqueResultException @@ -92,7 +100,8 @@ public function __construct( SystemService $systemService, PluginApiService $pluginApiService, BaseInfoRepository $baseInfoRepository, - CacheUtil $cacheUtil + CacheUtil $cacheUtil, + ValidatorInterface $validatorInterface ) { $this->pluginRepository = $pluginRepository; $this->pluginService = $pluginService; @@ -100,6 +109,7 @@ public function __construct( $this->pluginApiService = $pluginApiService; $this->BaseInfo = $baseInfoRepository->get(); $this->cacheUtil = $cacheUtil; + $this->validator = $validatorInterface; // TODO: Check the flow of the composer service below $this->composerService = $composerService; @@ -263,13 +273,32 @@ public function apiInstall(Request $request) $pluginCode = $request->get('pluginCode'); - try { - $log = $this->composerService->execRequire('ec-cube/'.$pluginCode); + $errors = $this->validator->validate( + $pluginCode, + [ + new Assert\NotBlank(), + new Assert\Regex( + [ + 'pattern' => '/^[a-zA-Z0-9_]+$/', + ] + ), + ] + ); + + if ($errors->count() != 0) { + $log = []; + foreach ($errors as $error) { + $log[] = $error->getMessage(); + } + } else { + try { + $log = $this->composerService->execRequire('ec-cube/'.$pluginCode); - return $this->json(['success' => true, 'log' => $log]); - } catch (\Exception $e) { - $log = $e->getMessage(); - log_error($e); + return $this->json(['success' => true, 'log' => $log]); + } catch (\Exception $e) { + $log = $e->getMessage(); + log_error($e); + } } return $this->json(['success' => false, 'log' => $log], 500); @@ -343,13 +372,53 @@ public function apiUpgrade(Request $request) $pluginCode = $request->get('pluginCode'); $version = $request->get('version'); - try { - $log = $this->composerService->execRequire('ec-cube/'.$pluginCode.':'.$version); + $log = []; + + $errors = $this->validator->validate( + $pluginCode, + [ + new Assert\NotBlank(), + new Assert\Regex( + [ + 'pattern' => '/^[a-zA-Z0-9_]+$/', + ] + ), + ] + ); + + if ($errors->count() != 0) { + foreach ($errors as $error) { + $log[] = $error->getMessage(); + } + } - return $this->json(['success' => true, 'log' => $log]); - } catch (\Exception $e) { - $log = $e->getMessage(); - log_error($e); + $errors = $this->validator->validate( + $version, + [ + new Assert\NotBlank(), + new Assert\Regex( + [ + 'pattern' => '/^[0-9.]+$/', + ] + ), + ] + ); + + if ($errors->count() != 0) { + foreach ($errors as $error) { + $log[] = $error->getMessage(); + } + } + + if (empty($log)) { + try { + $log = $this->composerService->execRequire('ec-cube/'.$pluginCode.':'.$version); + + return $this->json(['success' => true, 'log' => $log]); + } catch (\Exception $e) { + $log = $e->getMessage(); + log_error($e); + } } return $this->json(['success' => false, 'log' => $log], 500); diff --git a/tests/Eccube/Tests/Fixture/Generator.php b/tests/Eccube/Tests/Fixture/Generator.php index 7c2f4e1c15d..fa63caeca4e 100644 --- a/tests/Eccube/Tests/Fixture/Generator.php +++ b/tests/Eccube/Tests/Fixture/Generator.php @@ -55,6 +55,7 @@ use Eccube\Service\PurchaseFlow\PurchaseContext; use Eccube\Service\PurchaseFlow\PurchaseFlow; use Eccube\Util\StringUtil; +use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\HttpFoundation\Session\SessionInterface; /** @@ -412,11 +413,11 @@ public function createProduct($product_name = null, $product_class_num = 3, $wit for ($i = 0; $i < 3; $i++) { $ProductImage = new ProductImage(); if ($with_image) { - $width = $faker->numberBetween(480, 640); - $height = $faker->numberBetween(480, 640); - $image = $faker->uuid.'.jpg'; - $src = file_get_contents('https://placekitten.com/'.$width.'/'.$height); - file_put_contents(__DIR__.'/../../../../html/upload/save_image/'.$image, $src); + $image = $faker->uuid.'.png'; + $src = __DIR__.'/../../../../html/upload/save_image/no_image_product.png'; + $dist = __DIR__.'/../../../../html/upload/save_image/'.$image; + $fs = new Filesystem(); + $fs->copy($src, $dist); } else { $image = $faker->word.'.jpg'; } diff --git a/tests/Eccube/Tests/Web/Admin/Store/PluginControllerTest.php b/tests/Eccube/Tests/Web/Admin/Store/PluginControllerTest.php index 4bfdee3a80e..d762c2934b5 100644 --- a/tests/Eccube/Tests/Web/Admin/Store/PluginControllerTest.php +++ b/tests/Eccube/Tests/Web/Admin/Store/PluginControllerTest.php @@ -49,4 +49,85 @@ public function testSubmit() $this->actual = $this->entityManager->getRepository(\Eccube\Entity\BaseInfo::class)->get()->getPhpPath(); $this->verify(); } + + /** + * 異常系を確認。正常系のインストールはE2Eテストの方で実施 + * + * @dataProvider OwnerStoreInstallParam + * + */ + public function testFailureInstall($param1, $param2, $message) + { + $form = [ + 'pluginCode' => $param1, + 'version' => $param2, + ]; + + $crawler = $this->client->request('POST', + $this->generateUrl('admin_store_plugin_api_install', $form), + [], + [], + [ + 'HTTP_X-Requested-With' => 'XMLHttpRequest', + 'CONTENT_TYPE' => 'application/json', + ] + ); + // ダウンロードできないことを確認 + $this->assertEquals(500, $this->client->getResponse()->getStatusCode()); + // ログを確認 + $this->assertContains($message, json_decode($this->client->getResponse()->getContent())->log); + } + + /** + * 異常系を確認。正常系のアップデートはE2Eテストの方で実施 + * + * @dataProvider OwnerStoreUpgradeParam + * + */ + public function testFailureUpgrade($param1, $param2, $message) + { + $form = [ + 'pluginCode' => $param1, + 'version' => $param2, + ]; + + $crawler = $this->client->request('POST', + $this->generateUrl('admin_store_plugin_api_upgrade', $form), + [], + [], + [ + 'HTTP_X-Requested-With' => 'XMLHttpRequest', + 'CONTENT_TYPE' => 'application/json', + ] + ); + // ダウンロードできないことを確認 + $this->assertEquals(500, $this->client->getResponse()->getStatusCode()); + + // ログを確認 + $this->assertStringContainsString($message, implode(',', json_decode($this->client->getResponse()->getContent())->log)); + } + + /** + * 異常系のテストケース + */ + public function OwnerStoreInstallParam() + { + return [ + ['api42+symfony/yaml:5.3', '4.3.0', '有効な値ではありません。'], + ['', '4.3.0','入力されていません。'], + ]; + } + + /** + * 異常系のテストケース + */ + public function OwnerStoreUpgradeParam() + { + return [ + ['api42+symfony/yaml:5.3', '4.3.0', '有効な値ではありません。'], + ['api42', '4.3.0 symfony/yaml:5.3', '有効な値ではありません。'], + ['api42', '','入力されていません。'], + ['', '4.3.0','入力されていません。'], + ]; + } }