Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

テキストメール用の Escaper を実装 #5077

Merged
merged 4 commits into from
Jul 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ http://www.ec-cube.co.jp/
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
#}
{% autoescape false %}
{% autoescape 'safe_textmail' %}
※本メールは自動配信メールです。

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ http://www.ec-cube.co.jp/
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
#}
{% autoescape false %}
{% autoescape 'safe_textmail' %}
※本メールは自動配信メールです。

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ http://www.ec-cube.co.jp/
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
#}
{% autoescape false %}
{% autoescape 'safe_textmail' %}
※本メールは自動配信メールです。

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ http://www.ec-cube.co.jp/
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
#}
{% autoescape false %}
{% autoescape 'safe_textmail' %}
※本メールは自動配信メールです。

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
Expand Down
2 changes: 1 addition & 1 deletion src/Eccube/Resource/template/default/Mail/forgot_mail.twig
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ http://www.ec-cube.co.jp/
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
#}
{% autoescape false %}
{% autoescape 'safe_textmail' %}
※本メールは自動配信メールです。

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
Expand Down
2 changes: 1 addition & 1 deletion src/Eccube/Resource/template/default/Mail/order.twig
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ http://www.ec-cube.co.jp/
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
#}
{% autoescape false %}
{% autoescape 'safe_textmail' %}
{{ Order.name01 }} {{ Order.name02 }} 様

この度はご注文いただき誠にありがとうございます。下記ご注文内容にお間違えがないかご確認下さい。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ http://www.ec-cube.co.jp/
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
#}
{% autoescape false %}
{% autoescape 'safe_textmail' %}
※本メールは自動配信メールです。

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ http://www.ec-cube.co.jp/
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
#}
{% autoescape false %}
{% autoescape 'safe_textmail' %}
{{ Order.name01 }} {{ Order.name02 }} 様

お客さまがご注文された以下の商品を発送いたしました。商品の到着まで、今しばらくお待ちください。
Expand Down
29 changes: 29 additions & 0 deletions src/Eccube/Twig/Extension/SafeTextmailEscaperExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

/*
* This file is part of EC-CUBE
*
* Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
*
* http://www.ec-cube.co.jp/
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Eccube\Twig\Extension;

use Twig\Extension\AbstractExtension;
use Twig\Extension\EscaperExtension;

class SafeTextmailEscaperExtension extends AbstractExtension
{
public function __construct(\Twig\Environment $twig)
{
$twig->getExtension(EscaperExtension::class)->setEscaper(
'safe_textmail', function ($twig, $string, $charset) {
return str_replace(['<', '>'], ['<', '>'], $string);
}
);
}
}
1 change: 1 addition & 0 deletions tests/Eccube/Tests/Service/CsvImportServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ public function testReadCsvFileWithManualColumnHeaders()
public function testReadCsvFileWithTrailingBlankLines()
{
$file = new \SplFileObject(__DIR__.'/../../../Fixtures/data_blank_lines.csv');

$CsvImportService = new CsvImportService($file);
$CsvImportService->setColumnHeaders(['id', 'number', 'description']);

Expand Down
41 changes: 41 additions & 0 deletions tests/Eccube/Tests/Web/Admin/Order/ShippingControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,47 @@ public function testSendNotifyMail()
self::assertEquals([$Order->getEmail() => null], $Message->getTo());
}

public function testSendNotifyMailWithSanitize()
{
$this->client->enableProfiler();
$Customer = $this->createCustomer();
$Customer->setName01('<Sanitize&>');

$Order = $this->createOrder($Customer);
/** @var Shipping $Shipping */
$Shipping = $Order->getShippings()->first();

$shippingDate = new \DateTime();
$Shipping->setShippingDate($shippingDate);
$this->entityManager->persist($Shipping);
$this->entityManager->flush();

$this->client->request(
'PUT',
$this->generateUrl('admin_shipping_notify_mail', ['id' => $Shipping->getId()])
);

$this->assertTrue($this->client->getResponse()->isSuccessful());

$Messages = $this->getMailCollector(false)->getMessages();
self::assertEquals(1, count($Messages));

/** @var \Swift_Message $Message */
$Message = $Messages[0];

self::assertRegExp('/\[.*?\] 商品出荷のお知らせ/', $Message->getSubject());
self::assertEquals([$Order->getEmail() => null], $Message->getTo());

$this->assertContains('<Sanitize&>', $Message->getBody(), 'テキストメールがサニタイズされている');

$MultiPart = $Message->getChildren();
foreach ($MultiPart as $Part) {
if ($Part->getContentType() == 'text/html') {
$this->assertContains('&lt;Sanitize&amp;&gt;', $Part->getBody(), 'HTMLメールがサニタイズされている');
}
}
}

public function testNotSendNotifyMail()
{
$this->client->enableProfiler();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ public function tearDown()
if (file_exists($themeDir.'/Mail/order.twig')) {
unlink($themeDir.'/Mail/order.twig');
}
if (file_exists($themeDir.'/Mail/order.html.twig')) {
unlink($themeDir.'/Mail/order.html.twig');
}
parent::tearDown();
}

Expand Down
37 changes: 37 additions & 0 deletions tests/Eccube/Tests/Web/ContactControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,43 @@ public function testComplete()
$this->verify();
}

public function testCompleteWithSanitize()
{
$this->client->enableProfiler();
$form = $this->createFormData();
$form['name']['name01'] .= '<Sanitize&>';
$crawler = $this->client->request(
'POST',
$this->generateUrl('contact'),
['contact' => $form,
'mode' => 'complete', ]
);

$this->assertTrue($this->client->getResponse()->isRedirect($this->generateUrl('contact_complete')));

$BaseInfo = $this->entityManager->find(BaseInfo::class, 1);

$mailCollector = $this->getMailCollector(false);
$this->assertEquals(1, $mailCollector->getMessageCount());

$collectedMessages = $mailCollector->getMessages();
/** @var \Swift_Message $Message */
$Message = $collectedMessages[0];

$this->expected = '['.$BaseInfo->getShopName().'] お問い合わせを受け付けました。';
$this->actual = $Message->getSubject();
$this->verify();

$this->assertContains('<Sanitize&>', $Message->getBody(), 'テキストメールがサニタイズされている');

$MultiPart = $Message->getChildren();
foreach ($MultiPart as $Part) {
if ($Part->getContentType() == 'text/html') {
$this->assertContains('&lt;Sanitize&amp;&gt;', $Part->getBody(), 'HTMLメールがサニタイズされている');
}
}
}

/**
* 必須項目のみのテストケース
*
Expand Down
68 changes: 68 additions & 0 deletions tests/Eccube/Tests/Web/EntryControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,43 @@ public function testCompleteWithActivate()
$this->verify();
}

public function testCompleteWithActivateWithMultipartSanitize()
{
$BaseInfo = $this->entityManager->getRepository(\Eccube\Entity\BaseInfo::class)->get();
$BaseInfo->setOptionCustomerActivate(1);
$this->entityManager->flush();

$client = $this->client;
$form = $this->createFormData();
$form['name']['name01'] .= '<Sanitize&>'; // サニタイズ対象の文字列
$crawler = $client->request('POST',
$this->generateUrl('entry'),
[
'entry' => $form,
'mode' => 'complete',
]
);

$this->assertTrue($client->getResponse()->isRedirect($this->generateUrl('entry_complete')));

$collectedMessages = $this->getMailCollector(false)->getMessages();
/** @var \Swift_Message $Message */
$Message = $collectedMessages[0];

$this->expected = '['.$BaseInfo->getShopName().'] 会員登録のご確認';
$this->actual = $Message->getSubject();
$this->verify();

$this->assertContains('<Sanitize&>', $Message->getBody(), 'テキストメールがサニタイズされている');

$MultiPart = $Message->getChildren();
foreach ($MultiPart as $Part) {
if ($Part->getContentType() == 'text/html') {
$this->assertContains('&lt;Sanitize&amp;&gt;', $Part->getBody(), 'HTMLメールがサニタイズされている');
}
}
}

public function testRoutingComplete()
{
$client = $this->client;
Expand Down Expand Up @@ -192,6 +229,37 @@ public function testActivate()
$this->verify();
}

public function testActivateWithSanitize()
{
$BaseInfo = $this->entityManager->getRepository(\Eccube\Entity\BaseInfo::class)->get();
$Customer = $this->createCustomer();
$Customer->setName01('<Sanitize&>');
$secret_key = $Customer->getSecretKey();
$Status = $this->entityManager->getRepository('Eccube\Entity\Master\CustomerStatus')->find(CustomerStatus::NONACTIVE);
$Customer->setStatus($Status);
$this->entityManager->flush();

$client = $this->client;
$client->request('GET', $this->generateUrl('entry_activate', ['secret_key' => $secret_key]));

$this->assertTrue($client->getResponse()->isSuccessful());
$collectedMessages = $this->getMailCollector(false)->getMessages();
/** @var \Swift_Message $Message */
$Message = $collectedMessages[0];
$this->expected = '['.$BaseInfo->getShopName().'] 会員登録が完了しました。';
$this->actual = $Message->getSubject();
$this->verify();

$this->assertContains('<Sanitize&>', $Message->getBody(), 'テキストメールがサニタイズされている');

$MultiPart = $Message->getChildren();
foreach ($MultiPart as $Part) {
if ($Part->getContentType() == 'text/html') {
$this->assertContains('&lt;Sanitize&amp;&gt;', $Part->getBody(), 'HTMLメールがサニタイズされている');
}
}
}

public function testActivateWithNotFound()
{
$this->client->request('GET', $this->generateUrl('entry_activate', ['secret_key' => 'aaaaa']));
Expand Down
40 changes: 40 additions & 0 deletions tests/Eccube/Tests/Web/Mypage/WithdrawControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,46 @@ public function testIndexWithPostComplete()
$this->verify();
}

public function testIndexWithPostCompleteWithSanitize()
{
$this->Customer->setName01('<Sanitize&>');
$this->entityManager->flush();

$this->client->enableProfiler();
$this->logInTo($this->Customer);

$crawler = $this->client->request(
'POST',
$this->generateUrl('mypage_withdraw'),
[
'form' => ['_token' => 'dummy'],
'mode' => 'complete',
]
);

$this->assertRegExp('/@dummy.dummy/', $this->Customer->getEmail());

$this->assertTrue($this->client->getResponse()->isRedirect($this->generateUrl('mypage_withdraw_complete')));

$Messages = $this->getMailCollector(false)->getMessages();
/** @var \Swift_Message $Message */
$Message = $Messages[0];

$BaseInfo = $this->entityManager->getRepository(\Eccube\Entity\BaseInfo::class)->get();
$this->expected = '['.$BaseInfo->getShopName().'] 退会手続きのご完了';
$this->actual = $Message->getSubject();
$this->verify();

$this->assertContains('<Sanitize&>', $Message->getBody(), 'テキストメールがサニタイズされている');

$MultiPart = $Message->getChildren();
foreach ($MultiPart as $Part) {
if ($Part->getContentType() == 'text/html') {
$this->assertContains('&lt;Sanitize&amp;&gt;', $Part->getBody(), 'HTMLメールがサニタイズされている');
}
}
}

public function testComplete()
{
$this->client->request(
Expand Down
Loading