From 5cce214d6ca21adc27c256ef9f55756c36a3a099 Mon Sep 17 00:00:00 2001 From: llaffont <llaffont@afi-sa.fr> Date: Tue, 25 Oct 2016 12:09:41 +0200 Subject: [PATCH] hotline #49621 add antispam filter in articles form --- VERSIONS_HOTLINE/49621 | 1 + .../opac/controllers/FormulaireController.php | 8 ++- library/Class/Article.php | 19 +++++- library/ZendAfi/View/Helper/CkEditor.php | 5 +- .../controllers/FormulaireControllerTest.php | 60 +++++++++++++---- tests/library/Class/ArticleFormulaireTest.php | 65 +++++++++++++++---- 6 files changed, 129 insertions(+), 29 deletions(-) create mode 100644 VERSIONS_HOTLINE/49621 diff --git a/VERSIONS_HOTLINE/49621 b/VERSIONS_HOTLINE/49621 new file mode 100644 index 00000000000..b287a3ae172 --- /dev/null +++ b/VERSIONS_HOTLINE/49621 @@ -0,0 +1 @@ + - ticket #49621 : ajout d'un filtre anti-spam dans les formulaires intégrés dans les articles \ No newline at end of file diff --git a/application/modules/opac/controllers/FormulaireController.php b/application/modules/opac/controllers/FormulaireController.php index e6ced064ebb..f51591098a2 100644 --- a/application/modules/opac/controllers/FormulaireController.php +++ b/application/modules/opac/controllers/FormulaireController.php @@ -22,8 +22,14 @@ class FormulaireController extends ZendAfi_Controller_Action { public function addAction() { $article = Class_Article::find($this->_getParam('id_article')); + $post = $this->_request->getPost(); + if ($this->_getParam('emailCheck')) + return $this->_redirect('/'); + + unset($post['emailCheck']); + $formulaire = new Class_Formulaire(); - $formulaire->setData(serialize($this->_request->getPost())) + $formulaire->setData(serialize($post)) ->setUser(Class_Users::getIdentity()) ->setArticle($article) ->save(); diff --git a/library/Class/Article.php b/library/Class/Article.php index b145ffd1df7..facf8eddf41 100644 --- a/library/Class/Article.php +++ b/library/Class/Article.php @@ -954,17 +954,30 @@ class Class_Article extends Storm_Model_Abstract { if (preg_match('/(<form[^>]+)action='.$quote.'http/i', $contenu)) return $contenu; - if (!defined('BASE_URL')) - define('BASE_URL', ''); + $action = Class_Url::assemble(['controller' => 'formulaire', + 'action' => 'add', + 'id_article' => $this->getId()], + null, + true); $replaced_form = preg_replace(['/(<form[^>]+)action='.$quoted_value.'/i', '/(<form[^>]+)method='.$quoted_value.'/i', '/(<form *)/i'], ['$1 ', '$1 ', - '$1 action="'.BASE_URL.'/formulaire/add/id_article/'.$this->getId().'" method="POST" '], + '$1 action="'. $action .'" method="POST" '], $contenu); + + $end_form = '</form>'; + $antispam_tag = '<input data-spambots="true" name="emailCheck" type="text" />'; + + $replaced_form = str_replace($antispam_tag, '', $replaced_form); + if (false === strpos($replaced_form, 'name="emailCheck"')) + $replaced_form = preg_replace('|' . $end_form .'|i', + $antispam_tag . $end_form, + $replaced_form); + $typesubmit = 'type='.$quote.'(?:submit|button)'.$quote; $namesubmit = 'name='.$quoted_value; $otherattributes = '[^>]+'; diff --git a/library/ZendAfi/View/Helper/CkEditor.php b/library/ZendAfi/View/Helper/CkEditor.php index b835287b500..395c7f26b28 100644 --- a/library/ZendAfi/View/Helper/CkEditor.php +++ b/library/ZendAfi/View/Helper/CkEditor.php @@ -38,8 +38,9 @@ class ZendAfi_View_Helper_CkEditor extends ZendAfi_View_Helper_BaseHelper $config['filebrowserImageUploadUrl'] = CKBASEURL."filemanager/upload/php/upload.php?Type=Image&ServerPath=".USERFILESURL; $config['filebrowserFlashUploadUrl'] = CKBASEURL."filemanager/upload/php/upload.php?Type=Flash&ServerPath=".USERFILESURL; $config['imagesPath'] = URL_ADMIN_IMG."ckeditor_templates/"; - $config['templates_files'] = array(URL_ADMIN_JS."ckeditor_templates.js"); - $config['contentsCss'] = array(URL_CSS."global.css"); + $config['templates_files'] = [URL_ADMIN_JS."ckeditor_templates.js"]; + $config['contentsCss'] = [BASE_URL . '/public/opac/css/global.css', + URL_CSS . 'global.css']; $config['toolbar'] = [ ['Preview', 'Templates', 'Source','Maximize'], diff --git a/tests/application/modules/opac/controllers/FormulaireControllerTest.php b/tests/application/modules/opac/controllers/FormulaireControllerTest.php index b65b5f84ee5..bbc693973b9 100644 --- a/tests/application/modules/opac/controllers/FormulaireControllerTest.php +++ b/tests/application/modules/opac/controllers/FormulaireControllerTest.php @@ -20,6 +20,10 @@ */ abstract class FormulaireControllerPostActionTestCase extends AbstractControllerTestCase { + protected + $_storm_default_to_volatile = true; + + public function setUp() { parent::setUp(); @@ -39,6 +43,9 @@ abstract class FormulaireControllerPostActionTestCase extends AbstractController } } + + + class FormulaireControllerWithEmailPostActionTest extends FormulaireControllerPostActionTestCase { protected $_user; @@ -57,15 +64,15 @@ class FormulaireControllerWithEmailPostActionTest extends FormulaireControllerPo $this->mock_transport = new MockMailTransport(); Zend_Mail::setDefaultTransport($this->mock_transport); - $this->postDispatch('/formulaire/add/id_article/45', ['nom' => 'Tinguette' , - 'prenom' => 'Quentin' ] - ,true); + 'prenom' => 'Quentin' ], + true); $this->new_formulaire = Class_Formulaire::find(2); } + /** @test */ public function postFormulaireShouldReturnEmail() { $this->assertXpathContentContains('//div','courriel',true ); @@ -74,7 +81,8 @@ class FormulaireControllerWithEmailPostActionTest extends FormulaireControllerPo /** @test */ public function mailContentShouldContainData() { - $this->assertContains('nom: Tinguette', quoted_printable_decode($this->mock_transport->getSentMails()[0]->getBodyText()->getContent())); + $this->assertContains('nom: Tinguette', + quoted_printable_decode($this->mock_transport->getSentMails()[0]->getBodyText()->getContent())); } @@ -83,18 +91,20 @@ class FormulaireControllerWithEmailPostActionTest extends FormulaireControllerPo $this->assertEquals('sender@example.com', $this->mock_transport->getSentMails()[0]->getFrom()); } + /** @test */ public function emailToShouldBeRecipient() { $this->assertEquals('recipient@example.com', $this->mock_transport->getSentMails()[0]->getRecipients()[0]); } + /** @test */ public function emailSubjectShouldBeFormSent() { $this->assertEquals('[Bokeh] Envoi d\'un formulaire', $this->mock_transport->getSentMails()[0]->getSubject()); } +} -} class FormulaireControllerPostActionTest extends FormulaireControllerPostActionTestCase { @@ -111,12 +121,14 @@ class FormulaireControllerPostActionTest extends FormulaireControllerPostActionT $this->postDispatch('/formulaire/add/id_article/45', ['nom' => 'Tinguette' , - 'prenom' => 'Quentin' ] - ,true); + 'prenom' => 'Quentin', + 'emailCheck' => ''], + true); $this->new_formulaire = Class_Formulaire::find(2); } + /** @test */ public function saveFormulaireShouldHaveNomTinguette() { $this->assertEquals('Tinguette', $this->new_formulaire->getNom()); @@ -176,22 +188,48 @@ class FormulaireControllerWithoutConnectedUserPostActionTest extends FormulaireC parent::setUp(); ZendAfi_Auth::getInstance()->clearIdentity(); - $this->postDispatch('/formulaire/add/id_article/45', ['nom' => 'Tinguette' , - 'prenom' => 'Quentin' ] - ,true); + 'prenom' => 'Quentin' ], + true); $this->new_formulaire = Class_Formulaire::find(2); - } + /** @test */ public function saveFormulaireShouldNotHaveAnyUsers() { $this->assertEmpty($this->new_formulaire->getUser()); + } +} + + + +class FormulaireControllerPostAsBotTest extends FormulaireControllerPostActionTestCase { + public function setUp() { + parent::setUp(); + + $this->postDispatch('/formulaire/add/id_article/45', + ['nom' => 'Tinguette' , + 'prenom' => 'Quentin', + 'emailCheck' => 'i am a bot'], + true); + + $this->new_formulaire = Class_Formulaire::find(2); + } + + + /** @test */ + public function formulaireShouldNotBeCreated() { + $this->assertNull($this->new_formulaire); } + + /** @test */ + public function answerShouldRedirectToRoot() { + $this->assertRedirectTo('/'); + } } ?> \ No newline at end of file diff --git a/tests/library/Class/ArticleFormulaireTest.php b/tests/library/Class/ArticleFormulaireTest.php index 90f3f26f308..dec8855d7df 100644 --- a/tests/library/Class/ArticleFormulaireTest.php +++ b/tests/library/Class/ArticleFormulaireTest.php @@ -16,14 +16,19 @@ * * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE * along with BOKEH; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -class ArticleFormulaireInternalTest extends Storm_Test_ModelTestCase { +class ArticleFormulaireInternalTest extends ModelTestCase { + protected + $_storm_default_to_volatile = true; + public function setUp() { parent::setUp(); - $this->_article = Class_Article::newInstanceWithId(2,['titre' => 'Contactez-nous !', - 'contenu' => '<FORM id="idform" action=\'form\' method="post" name="form" target="_blank"> + $this->_article = $this->fixture('Class_Article', + ['id' => 2, + 'titre' => 'Contactez-nous !', + 'contenu' => '<FORM id="idform" action=\'form\' method="post" name="form" target="_blank"> <p> Donnee 1 :<br /><input name="champs texte" type="text" value="champtxt" /> <input value="champ2" name=\'champs texte\' type="text"/></p> <p> </p> @@ -33,35 +38,46 @@ class ArticleFormulaireInternalTest extends Storm_Test_ModelTestCase { </form> POST<form method="POST"> - + <input type="button" value="likebutton" /> + <input data-spambots="true" name="emailCheck" type="text" /> </form> EMPTY<form> </form> ']); } + /** @test */ public function formIdFormActionShouldBeFormulaireAdd() { - $this->assertContains('<FORM action="'.BASE_URL.'/formulaire/add/id_article/2" method="POST" id="idform" name="form" target="_blank', + $this->assertContains('<FORM action="'.BASE_URL.'/formulaire/add/id_article/2" method="POST" id="idform" name="form" target="_blank', $this->_article->getContenu()); } + /** @test */ + public function eachFormShouldContainsInputEmailCheckForSpamBot() { + $xpath = new Storm_Test_XPath(); + $xpath->assertXPathCount($this->_article->getContenu(), + '//form/input[@name="emailCheck"][@data-spambots="true"]', + 3); + } + + /** @test */ public function formWithMethodPostActionShouldBeFormulaireAdd() { - $this->assertContains('POST<form action="'.BASE_URL.'/formulaire/add/id_article/2" method="POST" >', + $this->assertContains('POST<form action="'.BASE_URL.'/formulaire/add/id_article/2" method="POST" >', $this->_article->getContenu()); } /** @test */ public function emptyFormActionShouldBeFormulaireAdd() { - $this->assertContains('EMPTY<form action="'.BASE_URL.'/formulaire/add/id_article/2" method="POST" >', + $this->assertContains('EMPTY<form action="'.BASE_URL.'/formulaire/add/id_article/2" method="POST" >', $this->_article->getContenu()); } - + /** @test */ public function formSubmitButtonShouldHaveNoName() { $this->assertContains('<input value="click !" type="submit"/>', @@ -99,6 +115,26 @@ class ArticleFormulaireInternalTest extends Storm_Test_ModelTestCase { +class ArticleFormulaireWithLegacyEmailCheckTest extends ModelTestCase { + public function setUp() { + parent::setUp(); + $this->_article = Class_Article::newInstanceWithId(2,['titre' => 'Contactez-nous !', + 'contenu' => ' + <form id="old" > + <input name="extenvoi" value="extenvoi" type="submit"/> + <input name="emailCheck" /> + </form> + ']); + } + + + /** @test */ + public function inputDataSpamBotsShouldNotBeAdded() { + $this->assertNotContains('data-spambots', $this->_article->getContenu()); + } +} + + class ArticleFormulaireExternalTest extends Storm_Test_ModelTestCase { public function setUp() { @@ -111,18 +147,23 @@ class ArticleFormulaireExternalTest extends Storm_Test_ModelTestCase { ']); } - + /** @test */ public function formWithExternalUrlShouldNotChange() { - $this->assertContains('<form id="extern" action="http://monserveur/post" >', + $this->assertContains('<form id="extern" action="http://monserveur/post" >', $this->_article->getContenu()); } + /** @test */ public function formSubmitWithExternalUrlShouldNotChange() { $this->assertContains(' <input name="extenvoi" value="extenvoi" type="submit"/>', $this->_article->getContenu()); } -} + /** @test */ + public function inputEmailCheckShouldNotBePresent() { + $this->assertNotContains('emailCheck', $this->_article->getContenu()); + } +} -- GitLab