diff --git a/VERSIONS_HOTLINE/49621 b/VERSIONS_HOTLINE/49621 new file mode 100644 index 0000000000000000000000000000000000000000..b287a3ae172a4fc6e1209592c9314b894439cc70 --- /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 e6ced064ebbd47db10fa1595e95b3264b12e0f7d..f51591098a2bc006fd99da3a4c74f84348fe9212 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 b145ffd1df70dda96620ff2d25007b5b1d154265..facf8eddf41a0290d565283b7855706372481f32 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 b835287b50000015cd065cb3d60c0b3fee7c12ea..395c7f26b28a3116d2ef0e107519ac0a384188f1 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 b65b5f84ee547b5a62707d79c8248688d22a2500..bbc693973b9fe20c33473161a0050a2ddeb6f8b0 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 90f3f26f3084d4015dac154475535d1ce2151624..dec8855d7df02ad190fd6c858c9c232d31fb1f08 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()); + } +}