Skip to content

Commit

Permalink
Merge pull request #6253 from EC-CUBE/4.3-private
Browse files Browse the repository at this point in the history
脆弱性対応(4.3)
  • Loading branch information
shinya authored Jul 29, 2024
2 parents 850b152 + 0615c4d commit c972044
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 14 deletions.
97 changes: 83 additions & 14 deletions src/Eccube/Controller/Admin/Store/OwnerStoreController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -48,6 +50,11 @@ class OwnerStoreController extends AbstractController
*/
protected $pluginService;

/**
* @var ValidatorInterface
*/
protected ValidatorInterface $validator;

/**
* @var ComposerServiceInterface
*/
Expand Down Expand Up @@ -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
Expand All @@ -92,14 +100,16 @@ public function __construct(
SystemService $systemService,
PluginApiService $pluginApiService,
BaseInfoRepository $baseInfoRepository,
CacheUtil $cacheUtil
CacheUtil $cacheUtil,
ValidatorInterface $validatorInterface
) {
$this->pluginRepository = $pluginRepository;
$this->pluginService = $pluginService;
$this->systemService = $systemService;
$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;
Expand Down Expand Up @@ -263,13 +273,32 @@ public function apiInstall(Request $request)

$pluginCode = $request->get('pluginCode');

try {
$log = $this->composerService->execRequire('ec-cube/'.$pluginCode);

return $this->json(['success' => true, 'log' => $log]);
} catch (\Exception $e) {
$log = $e->getMessage();
log_error($e);
$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' => false, 'log' => $log], 500);
Expand Down Expand Up @@ -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);
Expand Down
81 changes: 81 additions & 0 deletions tests/Eccube/Tests/Web/Admin/Store/PluginControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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','入力されていません。'],
];
}
}

0 comments on commit c972044

Please sign in to comment.