ESDEV-2769 Extract capcha functionality into contrib module

Extract code into module.
Add tests.
This commit is contained in:
hkreuter 2016-01-19 15:30:55 +01:00
parent 2a1313850f
commit 7a4ae598f6
25 changed files with 1666 additions and 1 deletions

View File

@ -1,3 +1,3 @@
captcha_module captcha_module
Contrib module contaning captcha logic. Contrib module containing captcha logic.

View File

@ -0,0 +1,44 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
class oeCaptchaContact extends oeCaptchaContact_parent
{
/**
* Class handling CAPTCHA image.
*
* @var object
*/
protected $captcha = null;
/**
* Composes and sends user written message, returns false if some parameters
* are missing.
*
* @return bool
*/
public function send()
{
if (!$this->getCaptcha()->passCaptcha()) {
return false;
}
return parent::send();
}
/**
* Template variable getter. Returns object of handling CAPTCHA image
*
* @return object
*/
public function getCaptcha()
{
if ($this->captcha === null) {
$this->captcha = oxNew('oeCaptcha');
}
return $this->captcha;
}
}

View File

@ -0,0 +1,52 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
/**
* Class oeCaptchaDetails.
* Extends Details.
*
* @see Details
*/
class oeCaptchaDetails extends oeCaptchaDetails_parent
{
/**
* Class handling CAPTCHA image.
*
* @var object
*/
protected $captcha = null;
/**
* Validates email
* address. If email is wrong - returns false and exits. If email
* address is OK - creates price alarm object and saves it
* (oxpricealarm::save()). Sends price alarm notification mail
* to shop owner.
*
* @return bool false on error
*/
public function addme()
{
if (!$this->getCaptcha()->passCaptcha(false)) {
$this->_iPriceAlarmStatus = 2;
return;
}
return parent::addme();
}
/**
* Template variable getter. Returns object of handling CAPTCHA image
*
* @return object
*/
public function getCaptcha()
{
if ($this->captcha === null) {
$this->captcha = oxNew('oeCaptcha');
}
return $this->captcha;
}
}

View File

@ -0,0 +1,49 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
/**
* Article suggestion page.
* Collects some article base information, sets default recommendation text,
* sends suggestion mail to user.
*/
class oeCaptchaInvite extends oeCaptchaInvite_parent
{
/**
* Class handling CAPTCHA image.
*
* @var object
*/
protected $captcha = null;
/**
* Sends product suggestion mail and returns a URL according to
* URL formatting rules.
*
* @return null
*/
public function send()
{
if (!$this->getCaptcha()->passCaptcha()) {
return false;
}
return parent::send();
}
/**
* Template variable getter. Returns object of handling CAPTCHA image
*
* @return object
*/
public function getCaptcha()
{
if ($this->captcha === null) {
$this->captcha = oxNew('oeCaptcha');
}
return $this->captcha;
}
}

View File

@ -0,0 +1,37 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
/**
* Pricealarm window.
* Arranges "pricealarm" window, by sending eMail and storing into Database (etc.)
* submission. Result - "pricealarm.tpl" template. After user correctly
* fulfils all required fields all information is sent to shop owner by
* email.
* OXID eShop -> pricealarm.
*/
class oeCaptchaPricealarm extends oeCaptchaPricealarm_parent
{
/**
* Validates email
* address. If email is wrong - returns false and exits. If email
* address is OK - creates prcealarm object and saves it
* (oxpricealarm::save()). Sends pricealarm notification mail
* to shop owner.
*
* @return bool false on error
*/
public function addme()
{
//control captcha
$captcha = oxNew('oeCaptcha');
if (!$captcha->passCaptcha(false)) {
$this->_iPriceAlarmStatus = 2;
return;
}
return parent::addme();
}
}

View File

@ -0,0 +1,52 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
/**
* Article suggestion page.
* Collects some article base information, sets default recomendation text,
* sends suggestion mail to user.
*/
class oeCaptchaSuggest extends oeCaptchaSuggest_parent
{
/**
* Class handling CAPTCHA image.
*
* @var object
*/
protected $captcha = null;
/**
* Sends product suggestion mail and returns a URL according to
* URL formatting rules.
*
* Template variables:
* <b>editval</b>, <b>error</b>
*
* @return null
*/
public function send()
{
// spam spider prevension
if (!$this->getCaptcha()->passCaptcha()) {
return false;
}
return parent::send();
}
/**
* Template variable getter. Returns object of handling CAPTCHA image
*
* @return object
*/
public function getCaptcha()
{
if ($this->captcha === null) {
$this->captcha = oxNew('oeCaptcha');
}
return $this->captcha;
}
}

234
core/oecaptcha.php Normal file
View File

@ -0,0 +1,234 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
/**
* Class handling CAPTCHA image
* This class requires utility file utils/verificationimg.php as image generator
*
*/
class oeCaptcha extends oxSuperCfg
{
/**
* CAPTCHA length
*
* @var int
*/
protected $macLength = 5;
/**
* Captcha text
*
* @var string
*/
protected $text = null;
/**
* Possible CAPTCHA chars, no ambiguities
*
* @var string
*/
protected $macChars = 'abcdefghijkmnpqrstuvwxyz23456789';
/**
* Captcha timeout 60 * 5 = 5 minutes
*
* @var int
*/
protected $timeout = 300;
/**
* Returns text
*
* @return string
*/
public function getText()
{
if (!$this->text) {
$this->text = '';
for ($i = 0; $i < $this->macLength; $i++) {
$this->text .= strtolower($this->macChars{rand(0, strlen($this->macChars) - 1)});
}
}
return $this->text;
}
/**
* Returns text hash
*
* @param string $text User supplie text
*
* @return string
*/
public function getHash($text = null)
{
// inserting captcha record
$time = time() + $this->timeout;
$textHash = $this->getTextHash($text);
// if session is started - storing captcha info here
$session = $this->getSession();
if ($session->isSessionStarted()) {
$hash = oxUtilsObject::getInstance()->generateUID();
$hashArray = $session->getVariable('captchaHashes');
$hashArray[$hash] = array($textHash => $time);
$session->setVariable('captchaHashes', $hashArray);
} else {
$database = oxDb::getDb();
$query = "insert into oecaptcha (oxhash, oxtime) values (" .
$database->quote($textHash) . ", " . $database->quote($time) . ")";
$database->execute($query);
$hash = $database->getOne('select LAST_INSERT_ID()', false, false);
}
return $hash;
}
/**
* Returns given string captcha hash
*
* @param string $text string to hash
*
* @return string
*/
public function getTextHash($text)
{
if (!$text) {
$text = $this->getText();
}
$text = strtolower($text);
return md5('ox' . $text);
}
/**
* Returns url to CAPTCHA image generator.
*
* @return string
*/
public function getImageUrl()
{
$url = $this->getConfig()->getCurrentShopUrl() . 'modules/oe/captcha/core/utils/verificationimg.php?e_mac=';
$key = $this->getConfig()->getConfigParam('oecaptchakey');
$key = empty($key) ? null : $key;
$url .= oxRegistry::getUtils()->strMan($this->getText(), $key);
return $url;
}
/**
* Checks if image could be generated
*
* @return bool
*/
public function isImageVisible()
{
return ((function_exists('imagecreatetruecolor') || function_exists('imagecreate')) && $this->getConfig()->getConfigParam('iUseGDVersion') > 1);
}
/**
* Check if captcha is passed.
*
* @return bool
*/
public function passCaptcha($displayError = true)
{
$return = true;
// spam spider prevention
$mac = $this->getConfig()->getRequestParameter('c_mac');
$macHash = $this->getConfig()->getRequestParameter('c_mach');
if (!$this->pass($mac, $macHash)) {
$return = false;
}
if (!$return && $displayError) {
// even if there is no exception, use this as a default display method
oxRegistry::get('oxUtilsView')->addErrorToDisplay('MESSAGE_WRONG_VERIFICATION_CODE');
}
return $return;
}
/**
* Verifies captcha input vs supplied hash. Returns true on success.
*
* @param string $mac User supplied text
* @param string $macHash Generated hash
*
* @return bool
*/
protected function pass($mac, $macHash)
{
$time = time();
$hash = $this->getTextHash($mac);
$pass = $this->passFromSession($macHash, $hash, $time);
// if captcha info was NOT stored in session
if ($pass === null) {
$pass = $this->passFromDb((int) $macHash, $hash, $time);
}
return (bool) $pass;
}
/**
* Checks for session captcha hash validity
*
* @param string $macHash hash key
* @param string $hash captcha hash
* @param int $time check time
*
* @return bool
*/
protected function passFromSession($macHash, $hash, $time)
{
$pass = null;
$session = $this->getSession();
if (($hashArray = $session->getVariable('captchaHashes'))) {
$pass = (isset($hashArray[$macHash][$hash]) && $hashArray[$macHash][$hash] >= $time) ? true : false;
unset($hashArray[$macHash]);
if (!empty($hashArray)) {
$session->setVariable('captchaHashes', $hashArray);
} else {
$session->deleteVariable('captchaHashes');
}
}
return $pass;
}
/**
* Checks for DB captcha hash validity
*
* @param int $macHash hash key
* @param string $hash captcha hash
* @param int $time check time
*
* @return bool
*/
protected function passFromDb($macHash, $hash, $time)
{
$database = oxDb::getDb();
$where = "where oxid = " . $database->quote($macHash) . " and oxhash = " . $database->quote($hash);
$query = "select 1 from oecaptcha " . $where;
$pass = (bool) $database->getOne($query, false, false);
if ($pass) {
// cleanup
$query = "delete from oecaptcha " . $where;
$database->execute($query);
}
// garbage cleanup
$query = "delete from oecaptcha where oxtime < $time";
$database->execute($query);
return $pass;
}
}

62
core/oecaptchaevents.php Normal file
View File

@ -0,0 +1,62 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
/**
* Class defines what module does on Shop events.
*/
class oeCaptchaEvents
{
/**
* Add table oecaptcha.
*/
public static function addCaptchaTable()
{
$query = "CREATE TABLE IF NOT EXISTS `oecaptcha` (" .
"`OXID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Captcha id'," .
"`OXHASH` char(32) NOT NULL default '' COMMENT 'Hash'," .
"`OXTIME` int(11) NOT NULL COMMENT 'Validation time'," .
"`OXTIMESTAMP` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT 'Timestamp'," .
"PRIMARY KEY (`OXID`), " .
"KEY `OXID` (`OXID`,`OXHASH`), " .
"KEY `OXTIME` (`OXTIME`) " .
") ENGINE=MEMORY AUTO_INCREMENT=1 COMMENT 'If session is not available, this is where captcha information is stored';";
oxDb::getDb()->execute($query);
}
/**
* Remove table oecaptcha.
* NOTE: table oecaptcha contains temporary data if any and can be
* removed without side effects on module deactivation
*/
public static function removeCaptchaTable()
{
$query = "DROP TABLE IF EXISTS `oecaptcha`";
oxDb::getDb()->execute($query);
}
/**
* Execute action on activate event
*
* @return null
*/
public static function onActivate()
{
self::addCaptchaTable();
}
/**
* Execute action on deactivate event
*
* @return null
*/
public static function onDeactivate()
{
self::removeCaptchaTable();
}
}

View File

@ -0,0 +1,106 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
// #1428C - spam spider prevention
if (isset($_GET['e_mac'])) {
$emac = $_GET['e_mac'];
} else {
return;
}
require_once '../../../../../bootstrap.php';
if (!function_exists('generateVerificationImg')) {
/**
* Generates image
*
* @param string $mac verification code
*
* @return null
*/
function generateVerificationImg($mac)
{
$width = 80;
$height = 18;
$fontSize = 14;
if (function_exists('imagecreatetruecolor')) {
// GD2
$image = imagecreatetruecolor($width, $height);
} elseif (function_exists('imagecreate')) {
// GD1
$image = imagecreate($width, $height);
} else {
// GD not found
return;
}
$textX = ($width - strlen($mac) * imagefontwidth($fontSize)) / 2;
$textY = ($height - imagefontheight($fontSize)) / 2;
$colors = array();
$colors["text"] = imagecolorallocate($image, 0, 0, 0);
$colors["shadow1"] = imagecolorallocate($image, 200, 200, 200);
$colors["shadow2"] = imagecolorallocate($image, 100, 100, 100);
$colors["background"] = imagecolorallocate($image, 255, 255, 255);
$colors["border"] = imagecolorallocate($image, 0, 0, 0);
imagefill($image, 0, 0, $colors["background"]);
imagerectangle($image, 0, 0, $width - 1, $height - 1, $colors["border"]);
imagestring($image, $fontSize, $textX + 1, $textY + 0, $mac, $colors["shadow2"]);
imagestring($image, $fontSize, $textX + 0, $textY + 1, $mac, $colors["shadow1"]);
imagestring($image, $fontSize, $textX, $textY, $mac, $colors["text"]);
header('Content-type: image/png');
imagepng($image);
imagedestroy($image);
}
}
if (!function_exists('strRem')) {
require_once getShopBasePath() . '/core/oxdecryptor.php';
/**
* OXID specific string manipulation method
*
* @param string $value string
*
* @return string
*/
function strRem($value)
{
$decryptor = new oxDecryptor;
$key = oxRegistry::getConfig()->getConfigParam('oecaptchakey');
if (empty($key)) {
$key = getOxConfKey();
}
return $decryptor->decrypt($value, $key);
}
}
if (!function_exists('getOxConfKey')) {
/**
* Get default config key.
*
* @return string
*/
function getOxConfKey()
{
$fileName = getShopBasePath() . '/core/oxconfk.php';
$configFile = new oxConfigFile($fileName);
return $configFile->getVar("sConfigKey");
}
}
$mac = strRem($emac);
generateVerificationImg($mac);

36
docs/README.txt Executable file
View File

@ -0,0 +1,36 @@
==Title==
OE Captcha
==Author==
OXID eSales AG
==Prefix==
oe
==Shop Version==
6.x
==Version==
1.0.0
==Link==
http://www.oxid-esales.com/
==Mail==
==Description==
OE Captcha Module
==Installation==
Activate the module in administration area.
==Extend==
==Modules==
==Modified original templates==
==Uninstall==
Disable the module in administration area and delete module folder.

63
metadata.php Executable file
View File

@ -0,0 +1,63 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
/**
* This file is part of OXID eSales Captcha module.
*
* TODO: license
*
* @category module
* @package captcha
* @author OXID eSales AG
* @link http://www.oxid-esales.com/
* @copyright (C) OXID eSales AG 2003-20162016
*/
/**
* Metadata version
*/
$sMetadataVersion = '1.1';
/**
* Module information
*/
$aModule = array(
'id' => 'oecaptcha',
'title' => array(
'de' => 'Simple Captcha',
'en' => 'Simple Captcha',
),
'description' => array(
'de' => 'OXID eSales Simple Captcha Module',
'en' => 'OXID eSales Simple Captcha Module',
),
'thumbnail' => 'out/pictures/picture.png',
'version' => '1.0.0',
'author' => 'OXID eSales AG',
'url' => 'http://www.oxid-esales.com/',
'email' => '',
'extend' => array('details' => 'oe/captcha/controllers/oecaptchadetails',
'contact' => 'oe/captcha/controllers/oecaptchacontact',
'invite' => 'oe/captcha/controllers/oecaptchainvite',
'pricealarm' => 'oe/captcha/controllers/oecaptchapricealarm',
'suggest' => 'oe/captcha/controllers/oecaptchasuggest'),
'files' => array(
'oecaptcha' => 'oe/captcha/core/oecaptcha.php',
'oecaptchaEvents' => 'oe/captcha/core/oecaptchaevents.php',
),
'templates' => array(),
'blocks' => array(
array('template' => 'form/contact.tpl', 'block'=>'captcha_form', 'file'=>'/views/blocks/captcha_form.tpl'),
array('template' => 'form/invite.tpl', 'block'=>'captcha_form', 'file'=>'/views/blocks/captcha_form.tpl'),
array('template' => 'form/pricealarm.tpl', 'block'=>'captcha_form', 'file'=>'/views/blocks/captcha_form.tpl'),
array('template' => 'form/suggest.tpl', 'block'=>'captcha_form', 'file'=>'/views/blocks/captcha_form.tpl'),
),
'settings' => array(
array('group' => 'main', 'name' => 'oecaptchakey', 'type' => 'str', 'value' => ''),
),
'events' => array(
'onActivate' => 'oecaptchaevents::onActivate',
'onDeactivate' => 'oecaptchaevents::onDeactivate'
),
);

BIN
out/pictures/picture.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@ -0,0 +1,40 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
abstract class CaptchaTestCase extends OxidTestCase
{
/**
* Fixture set up.
*/
protected function setUp()
{
parent::setUp();
$query = "CREATE TABLE IF NOT EXISTS `oecaptcha` (
`OXID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Captcha id',
`OXHASH` char(32) NOT NULL default '' COMMENT 'Hash',
`OXTIME` int(11) NOT NULL COMMENT 'Validation time',
`OXTIMESTAMP` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT 'Timestamp',
PRIMARY KEY (`OXID`),
KEY `OXID` (`OXID`,`OXHASH`),
KEY `OXTIME` (`OXTIME`)
) ENGINE=MEMORY AUTO_INCREMENT=1 COMMENT 'If session is not available, this is where captcha information is stored';
";
oxDb::getDb()->execute($query);
}
/**
* Fixture set up.
*/
protected function tearDown()
{
$query = "DROP TABLE `oecaptcha`";
oxDb::getDb()->execute($query);
parent::tearDown();
}
}

View File

@ -0,0 +1,59 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
require_once __DIR__ . '/../CaptchaTestCase.php';
class Unit_Core_oecaptchaEventsTest extends CaptchaTestCase
{
/**
* Set up the fixture.
*/
protected function setUp()
{
parent::setUp();
//Drop captcha table
oxDb::getDB()->execute("DROP TABLE IF EXISTS `oecaptcha`");
}
/**
* Tear down the fixture.
*/
public function tearDown()
{
oeCaptchaEvents::addCaptchaTable();
parent::tearDown();
}
/**
* Test onActivate event.
*/
public function testOnActivate()
{
oeCaptchaEvents::onActivate();
$oDbMetaDataHandler = oxNew('oxDbMetaDataHandler');
//If session is not available, table oecaptcha is where captcha information is stored
$this->assertTrue($oDbMetaDataHandler->tableExists('oecaptcha'));
}
/**
* Test onActivate event.
*/
public function testOnDeactivate()
{
oeCaptchaEvents::onDeactivate();
$oDbMetaDataHandler = oxNew('oxDbMetaDataHandler');
//If session is not available, table oecaptcha is where captcha information is stored
$this->assertFalse($oDbMetaDataHandler->tableExists('oecaptcha'));
}
}

View File

@ -0,0 +1,230 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
require_once __DIR__ . '/../CaptchaTestCase.php';
class Unit_Core_oecaptchaTest extends CaptchaTestCase
{
private $captcha = null;
/**
* Fixture set up.
*/
public function setUp()
{
parent::setUp();
$this->captcha = $this->getProxyClass('oecaptcha');
}
/**
* oeCaptcha::getText() test case
*/
public function testGetText()
{
$this->assertNull($this->captcha->getNonPublicVar('text'));
$sText = $this->captcha->getText();
$this->assertEquals($sText, $this->captcha->getNonPublicVar('text'));
$this->assertEquals(5, strlen($sText));
}
/**
* oeCaptcha::getTextHash() test case
*/
public function testGetTextHash()
{
$this->assertEquals('c4b961848aeff4d9b083fe15a56c9bd0', $this->captcha->getTextHash('test1'));
}
/**
* oeCaptcha::getHash() test case
*/
public function testGetHashNoSession()
{
$session = $this->getMock('oxSession', array('isSessionStarted'));
$session->expects($this->once())->method('isSessionStarted')->will($this->returnValue(false));
$captcha = $this->getMock('oeCaptcha', array('getSession'));
$captcha->expects($this->once())->method('getSession')->will($this->returnValue($session));
$hash = $captcha->getHash('test');
$this->assertEquals(oxDb::getDb()->getOne('select LAST_INSERT_ID()', false, false), $hash);
}
/**
* oeCaptcha::getHash() test case
* #0004286 adding case for multiple hashes
*/
public function testGetHashSession()
{
$session = $this->getMock('oxSession', array('isSessionStarted'));
$session->expects($this->exactly(2))->method('isSessionStarted')->will($this->returnValue(true));
$captcha = $this->getMock('oeCaptcha', array('getSession'));
$captcha->expects($this->exactly(2))->method('getSession')->will($this->returnValue($session));
$hash1 = $captcha->getHash('test1');
$hash2 = $captcha->getHash('test2');
$captchaHash = oxRegistry::getSession()->getVariable('captchaHashes');
$this->assertNotNull($captchaHash);
$this->assertTrue(isset($captchaHash[$hash1]));
$this->assertTrue(isset($captchaHash[$hash2]));
}
/**
* oeCaptcha::getImageUrl() test case
*/
public function testGetImageUrl()
{
$this->setConfigParam('oecaptchakey', 'someTestCaptchaKey');
$this->captcha->setNonPublicVar('text', 'test1');
$expected = $this->getConfig()->getShopUrl() . 'modules/oe/captcha/core/utils/verificationimg.php?e_mac=ox_MAsbCBYgVBoQ';
$this->assertEquals($expected, $this->captcha->getImageUrl());
}
/**
* oeCaptcha::getImageUrl() test case if sCaptcha key is not set
*/
public function testGetImageUrlFallbackKey()
{
$this->setConfigParam('oecaptchakey', '');
$this->captcha->setNonPublicVar('text', 'test1');
$expected = $this->getConfig()->getShopUrl() . 'modules/oe/captcha/core/utils/verificationimg.php?e_mac=ox_MB4FUUYlYlld';
$this->assertEquals($expected, $this->captcha->getImageUrl());
}
/**
* oeCaptcha::isImageVisible() test case
*/
public function testIsImageVisible()
{
$this->assertTrue($this->captcha->isImageVisible());
}
/**
* oeCaptcha::isImageVisible() test case
*/
public function testIsImageVisibleLowGD()
{
$this->getConfig()->setConfigParam('iUseGDVersion', 0);
$this->assertFalse($this->captcha->isImageVisible());
}
/**
* oeCaptcha::pass() test case
*/
public function testDbPassCorrect()
{
$captcha = $this->getMock('oeCaptcha', array('passFromSession'));
$captcha->expects($this->once())->method('passFromSession')->will($this->returnValue(null));
// reseting session
$session = oxNew('oxSession');
$captcha->setSession($session);
$captcha->getHash('3at8u');
$hash = oxDb::getDb()->getOne('select LAST_INSERT_ID()', false, false);
$this->assertTrue($captcha->pass('3at8u', $hash));
}
/**
* oeCaptcha::pass() test case
*/
public function testDbPassFail()
{
$captcha = $this->getMock('oeCaptcha', array('passFromSession'));
$captcha->expects($this->once())->method('passFromSession')->will($this->returnValue(null));
$this->assertFalse($captcha->pass('3at8v', 'd9a470912b222133fb913da36c0f50d0'));
}
/**
* oeCaptcha::pass() test case
* #0004286 adding case for multiple hashes
*/
public function testSessionPassCorrect()
{
$mac1 = '3at8u';
$mac2 = '3at8u';
$hash1 = 1234;
$hash2 = 1235;
$captcha = oxNew('oeCaptcha');
$hash = array(
$hash1 => array($captcha->getTextHash($mac1) => time() + 3600),
$hash2 => array($captcha->getTextHash($mac2) => time() + 3600)
);
$session = $this->getSession();
$session->setVariable('captchaHashes', $hash);
$captcha = $this->getMock('oeCaptcha', array('passFromDb'));
$captcha->expects($this->never())->method('passFromDb');
$this->assertTrue($captcha->pass($mac1, $hash1));
$this->assertEquals(1, count($session->getVariable('captchaHashes')));
$this->assertTrue($captcha->pass($mac2, $hash2));
$this->assertNull($session->getVariable('captchaHashes'));
}
/**
* oeCaptcha::pass() test case
*/
public function testSessionPassFail()
{
$this->getSession()->setVariable('captchaHashes', array('testHash' => array('testTextHash' => 132)));
$captcha = $this->getMock('oeCaptcha', array('passFromDb'));
$captcha->expects($this->never())->method('passFromDb');
$this->assertFalse($captcha->pass('3at8v', 'd9a470912b222133fb913da36c0f50d0'));
}
/**
* Test passing captcha.
*/
public function testPassCaptchaYes()
{
$captcha = $this->getMock('oeCaptcha', array('pass'));
$captcha->expects($this->once())->method('pass')->will($this->returnValue(true));
$result = $captcha->passCaptcha();
$this->assertTrue($result);
}
/**
* Test not passing captcha.
*/
public function testPassCaptchaNo()
{
$utilsView = $this->getMock('oxUtilsView', array('addErrorToDisplay'));
$utilsView->expects($this->once())->method('addErrorToDisplay')->with($this->equalTo('MESSAGE_WRONG_VERIFICATION_CODE'));
oxRegistry::set('oxUtilsView', $utilsView);
$captcha = $this->getMock('oeCaptcha', array('pass'));
$captcha->expects($this->once())->method('pass')->will($this->returnValue(false));
$result = $captcha->passCaptcha();
$this->assertFalse($result);
}
/**
* Test not passing captcha without displaying error message.
*/
public function testPassCaptchaNoWithoutDisplayMessage()
{
$utilsView = $this->getMock('oxUtilsView', array('addErrorToDisplay'));
$utilsView->expects($this->never())->method('addErrorToDisplay');
oxRegistry::set('oxUtilsView', $utilsView);
$captcha = $this->getMock('oeCaptcha', array('pass'));
$captcha->expects($this->once())->method('pass')->will($this->returnValue(false));
$result = $captcha->passCaptcha(false);
$this->assertFalse($result);
}
}

View File

@ -0,0 +1,150 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
require_once __DIR__ . '/../CaptchaTestCase.php';
/**
* Testing details class
*/
class Unit_contactTest extends CaptchaTestCase
{
/**
* Test if send mail is not executed if CAPTCHA image is not entered
* and warning message is displayed
*/
public function testSaveWithoutCaptcha()
{
oxRegistry::getSession()->deleteVariable('Errors');
$params['oxuser__oxusername'] = 'aaaa@aaa.com';
$this->setRequestParameter('editval', $params);
$contact = oxNew('Contact');
$this->assertFalse($contact->send());
//checking if warning was added to errors list
$message = oxRegistry::getLang()->translateString('MESSAGE_WRONG_VERIFICATION_CODE');
$errors = oxRegistry::getSession()->getVariable('Errors');
$error = unserialize($errors['default'][0]);
$this->assertEquals($message, $error->getOxMessage());
}
/**
* Test if send mail is not executed if user data is not entered
* and warning message is displayed
*/
public function testSaveWithoutUserData()
{
oxRegistry::getSession()->deleteVariable('Errors');
oxTestModules::addFunction('oeCaptcha', 'pass', '{return true;}');
$params['oxuser__oxusername'] = 'aaaa@aaa.com';
$this->setRequestParameter('editval', $params);
$contact = oxNew('Contact');
$this->assertFalse($contact->send());
//checking if warning was added to errors list
$message = oxRegistry::getLang()->translateString('ERROR_MESSAGE_INPUT_NOTALLFIELDS');
$errors = oxRegistry::getSession()->getVariable('Errors');
$error = unserialize($errors['default'][0]);
$this->assertEquals($message, $error->getOxMessage());
}
/**
* Test send mail
*/
public function testSave()
{
oxTestModules::addFunction('oeCaptcha', 'pass', '{return true;}');
oxTestModules::addFunction('oxemail', 'sendContactMail', '{return true;}');
$params['oxuser__oxusername'] = 'aaaa@aaa.com';
$params['oxuser__oxfname'] = 'first name';
$params['oxuser__oxlname'] = 'last name';
$this->setRequestParameter('editval', $params);
$this->setRequestParameter('c_subject', 'testSubject');
$contact = $this->getProxyClass('Contact');
$contact->send();
$this->assertEquals(1, $contact->getNonPublicVar('_blContactSendStatus'));
}
/**
* Test getting object for handling CAPTCHA image
*/
public function testGetCaptcha()
{
$contact = oxNew('Contact');
$this->assertEquals(oxNew('oeCaptcha'), $contact->getCaptcha());
}
/**
* Test case for bug #0002065: Contact-Mail shows MR or MRS instead of localized salutation
*/
public function testSendForBugtrackEntry0002065()
{
$params = array(
'oxuser__oxusername' => 'info@oxid-esales.com',
'oxuser__oxfname' => 'admin',
'oxuser__oxlname' => 'admin',
'oxuser__oxsal' => 'MR'
);
$this->setRequestParameter('editval', $params);
$this->setRequestParameter('c_message', 'message');
$this->setRequestParameter('c_subject', 'subject');
$language = oxRegistry::getLang();
$message = $language->translateString('MESSAGE_FROM') . ' ' . $language->translateString('MR') .
' admin admin(info@oxid-esales.com)<br /><br />message';
$email = $this->getMock('oxemail', array('sendContactMail'));
$email->expects($this->once())->method('sendContactMail')->with($this->equalTo('info@oxid-esales.com'),
$this->equalTo('subject'), $this->equalTo($message))->will($this->returnValue(true));
oxTestModules::addModuleObject('oxemail', $email);
$captcha = $this->getMock('oeCaptcha', array('passCaptcha'));
$captcha->expects($this->once())->method('passCaptcha')->will($this->returnValue(true));
$contact = $this->getMock('oecaptchacontact', array('getCaptcha'));
$contact->expects($this->once())->method('getCaptcha')->will($this->returnValue($captcha));
$contact->send();
}
/**
* Testing method send()
*/
public function testSendEmailNotSend()
{
$utils = $this->getMock('oxUtilsView', array('addErrorToDisplay'));
$utils->expects($this->once())->method('addErrorToDisplay')->with($this->equalTo('ERROR_MESSAGE_CHECK_EMAIL'));
oxTestModules::addModuleObject('oxUtilsView', $utils);
$params = array(
'oxuser__oxusername' => 'info@oxid-esales.com',
'oxuser__oxfname' => 'admin',
'oxuser__oxlname' => 'admin',
'oxuser__oxsal' => 'MR'
);
$this->setRequestParameter('editval', $params);
$this->setRequestParameter('c_message', 'message');
$this->setRequestParameter('c_subject', 'subject');
$email = $this->getMock('oxemail', array('sendContactMail'));
$email->expects($this->once())->method('sendContactMail')->will($this->returnValue(false));
oxTestModules::addModuleObject('oxemail', $email);
$captcha = $this->getMock('oeCaptcha', array('passCaptcha'));
$captcha->expects($this->once())->method('passCaptcha')->will($this->returnValue(true));
$contact = $this->getMock('oecaptchacontact', array('getCaptcha'));
$contact->expects($this->once())->method('getCaptcha')->will($this->returnValue($captcha));
$contact->send();
}
}

View File

@ -0,0 +1,45 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
require_once __DIR__ . '/../CaptchaTestCase.php';
/**
* Testing details class
*/
class Unit_detailsTest extends CaptchaTestCase
{
/**
* Test get Captcha.
*
* @return null
*/
public function testGetCaptcha()
{
$details = $this->getProxyClass('oecaptchadetails');
$this->assertEquals(oxNew('oeCaptcha'), $details->getCaptcha());
}
/**
* Invalid captcha test case.
*/
public function testAddmeInvalidCaptcha()
{
$captcha = $this->getMock('oeCaptcha', array('passCaptcha'));
$captcha->expects($this->once())->method('passCaptcha')->will($this->returnValue(false));
$email = $this->getMock('oxEmail', array('sendPricealarmNotification'));
$email->expects($this->never())->method('sendPricealarmNotification');
oxTestModules::addModuleObject('oxEmail', $email);
$details = $this->getMock($this->getProxyClassName('oecaptchadetails'), array('getCaptcha'));
$details->expects($this->once())->method('getCaptcha')->will($this->returnValue($captcha));
$details->addme();
$this->assertSame(2, $details->getNonPublicVar('_iPriceAlarmStatus'));
}
}

View File

@ -0,0 +1,106 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
require_once __DIR__ . '/../CaptchaTestCase.php';
class Unit_inviteTest extends OxidTestCase
{
/**
* Tear down the fixture.
*
* @return null
*/
protected function tearDown()
{
$this->cleanUpTable('oxinvitations', 'oxuserid');
parent::tearDown();
}
/**
* Testing method getCaptcha()
*
* @return null
*/
public function testGetCaptcha()
{
$invite = $this->getProxyClass('oecaptchainvite');
$this->assertEquals(oxNew('oeCaptcha'), $invite->getCaptcha());
}
/**
* Testing method send() - no captcha text
*/
public function testSendWithoutCaptcha()
{
$this->setRequestParameter('editval', array('rec_email' => 'testRecEmail@oxid-esales.com',
'send_name' => 'testSendName',
'send_email' => 'testSendEmail@oxid-esales.com',
'send_message' => 'testSendMessage',
'send_subject' => 'testSendSubject'));
$this->getConfig()->setConfigParam('blInvitationsEnabled', true);
$captcha = $this->getMock('oeCaptcha', array('passCaptcha'));
$captcha->expects($this->once())->method('passCaptcha')->will($this->returnValue(false));
$invite = $this->getMock('oecaptchainvite', array('getCaptcha', 'getUser'));
$invite->expects($this->never())->method('getUser');
$invite->expects($this->once())->method('getCaptcha')->will($this->returnValue($captcha));
$invite->send();
$this->assertFalse($invite->getInviteSendStatus());
}
/**
* Testing method send()
*/
public function testSend()
{
$this->setRequestParameter('editval', array('rec_email' => array('testRecEmail@oxid-esales.com'), 'send_name' => 'testSendName', 'send_email' => 'testSendEmail@oxid-esales.com', 'send_message' => 'testSendMessage', 'send_subject' => 'testSendSubject'));
$this->getConfig()->setConfigParam('blInvitationsEnabled', true);
$email = $this->getMock('oxEmail', array('sendInviteMail'));
$email->expects($this->once())->method('sendInviteMail')->will($this->returnValue(true));
oxTestModules::addModuleObject('oxEmail', $email);
$captcha = $this->getMock('oeCaptcha', array('passCaptcha'));
$captcha->expects($this->once())->method('passCaptcha')->will($this->returnValue(true));
$invite = $this->getMock('oecaptchainvite', array('getCaptcha', 'getUser'));
$invite->expects($this->once())->method('getCaptcha')->will($this->returnValue($captcha));
$invite->expects($this->any())->method('getUser')->will($this->returnValue(oxNew('oxUser')));
$invite->send();
$this->assertTrue($invite->getInviteSendStatus());
}
/**
* Testing method render()
*
* @return null
*/
public function testRender()
{
$this->getConfig()->setConfigParam('blInvitationsEnabled', true);
$invite = $this->getMock('invite', array('getUser'));
$invite->expects($this->any())->method('getUser')->will($this->returnValue(oxNew('oxUser')));
$this->assertEquals('page/privatesales/invite.tpl', $invite->render());
}
/**
* Testing method render() - mail was sent status
*/
public function testRenderMailWasSent()
{
$this->getConfig()->setConfigParam('blInvitationsEnabled', true);
$invite = $this->getProxyClass('invite');
$invite->setNonPublicVar('_iMailStatus', 1);
$invite->render();
$this->assertTrue($invite->getInviteSendStatus());
}
}

View File

@ -0,0 +1,111 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
require_once __DIR__ . '/../CaptchaTestCase.php';
class Unit_pricealarmTest extends CaptchaTestCase
{
/**
* Tear down the fixture.
*
* @return null
*/
protected function tearDown()
{
$this->cleanUpTable('oxpricealarm', 'oxartid');
parent::tearDown();
}
/**
* Test incorrect captcha.
*/
public function testAddmeIncorectCaptcha()
{
$priceAlarm = $this->getProxyClass('oecaptchapricealarm');
$this->setRequestParameter('c_mac', 'aa');
$this->setRequestParameter('c_mach', 'bb');
$priceAlarm->addme();
$this->assertEquals(2, $priceAlarm->getNonPublicVar('_iPriceAlarmStatus'));
$query = 'select count(oxid) from oxpricealarm';
$this->assertEquals(0, oxDb::getDb()->getOne($query));
}
/**
* Test incorrect email.
*/
public function testAddmeIncorectEmail()
{
$priceAlarm = $this->getProxyClass('oecaptchapricealarm');
oxTestModules::addFunction('oeCaptcha', 'passCaptcha', '{return true;}');
$this->setRequestParameter('pa', array('email' => 'ladyGaga'));
$priceAlarm->addme();
$this->assertEquals(0, $priceAlarm->getNonPublicVar('_iPriceAlarmStatus'));
$query = 'select count(oxid) from oxpricealarm';
$this->assertEquals(0, oxDb::getDb()->getOne($query));
}
/**
* Test all is well.
*/
public function testAddmeSavesAndSendsPriceAlarm()
{
$priceAlarm = $this->getProxyClass('pricealarm');
oxTestModules::addFunction('oeCaptcha', 'passCaptcha', '{return true;}');
oxTestModules::addFunction('oxEmail', 'sendPricealarmNotification', '{return 999;}');
$this->getSession()->setVariable('usr', 'testUserId');
$parameters['email'] = 'goodemail@ladyGagaFans.lt';
$parameters['aid'] = '_testArtId';
$parameters['price'] = '10';
$parameters['mano'] = '101';
$this->setRequestParameter('pa', $parameters);
$priceAlarm->addme();
$this->assertEquals(999, $priceAlarm->getNonPublicVar('_iPriceAlarmStatus'));
$query = 'select * from oxpricealarm';
$alarm = oxDb::getDb(oxDB::FETCH_MODE_ASSOC)->getRow($query);
$this->assertEquals($parameters['email'], $alarm['OXEMAIL']);
$this->assertEquals($parameters['aid'], $alarm['OXARTID']);
$this->assertEquals($parameters['price'], $alarm['OXPRICE']);
$this->assertEquals('testUserId', $alarm['OXUSERID']);
$this->assertEquals('EUR', $alarm['OXCURRENCY']);
$this->assertEquals(0, $alarm['OXLANG']);
}
/**
* Test saving active language.
*/
public function testAddmeSavesCurrentActiveLanguage()
{
$priceAlarm = $this->getProxyClass('pricealarm');
oxTestModules::addFunction('oeCaptcha', 'passCaptcha', '{return true;}');
oxTestModules::addFunction('oxEmail', 'sendPricealarmNotification', '{return 999;}');
$this->getSession()->setVariable('usr', 'testUserId');
$parameters['email'] = 'goodemail@ladyGagaFans.lt';
oxRegistry::getLang()->setBaseLanguage(1);
$this->setRequestParameter('pa', $parameters);
$priceAlarm->addme();
$query = 'select oxlang from oxpricealarm';
$language = oxDb::getDb(oxDB::FETCH_MODE_ASSOC)->getOne($query);
$this->assertEquals(1, $language);
}
}

View File

@ -0,0 +1,111 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
require_once __DIR__ . '/../CaptchaTestCase.php';
class Unit_suggestTest extends CaptchaTestCase
{
/**
* Tear down the fixture.
*
* @return null
*/
protected function tearDown()
{
$sDelete = "delete from oxrecommlists where oxid like 'testlist%'";
oxDb::getDB()->execute($sDelete);
$sDelete = "delete from oxobject2list where oxlistid like 'testlist%'";
oxDb::getDB()->execute($sDelete);
parent::tearDown();
}
/**
* Test getter for suggest data.
*/
public function testGetSuggestData()
{
oxTestModules::addFunction('oeCaptcha', 'passCaptcha', '{return true;}');
$this->setRequestParameter('editval', array('name' => 'test', 'value' => 'testvalue'));
$suggest = $this->getProxyClass('oecaptchasuggest');
$suggest->send();
$parameter = $suggest->getSuggestData();
$this->assertEquals('test', $parameter->name);
$this->assertEquals('testvalue', $parameter->value);
}
/**
* Test captcha getter.
*/
public function testGetCaptcha()
{
$suggest = $this->getProxyClass('oecaptchasuggest');
$this->assertEquals(oxNew('oeCaptcha'), $suggest->getCaptcha());
}
/**
* Test all is well.
*/
public function testSendPass()
{
$this->setRequestParameter(
'editval',
array(
'name' => 'test',
'value' => 'testvalue',
'rec_name' => 'test1',
'rec_email' => 'recmail@oxid.lt',
'send_name' => 'test3',
'send_email' => 'sendmail@oxid.lt',
'send_message' => 'test5',
'send_subject' => 'test6',
)
);
$email = $this->getMock('stdclass', array('sendSuggestMail'));
$email->expects($this->once())->method('sendSuggestMail')
->will($this->returnValue(1));
oxTestModules::addModuleObject('oxemail', $email);
$product = $this->getMock('oxarticle', array('getId'));
$product->expects($this->once())->method('getId')->will($this->returnValue('XProduct'));
$captcha = $this->getMock('oeCaptcha', array('passCaptcha'));
$captcha->expects($this->once())->method('passCaptcha')->will($this->returnValue(true));
$suggest = $this->getMock('oecaptchasuggest', array('getProduct', 'getCaptcha'));
$suggest->expects($this->once())->method('getProduct')->will($this->returnValue($product));
$suggest->expects($this->once())->method('getCaptcha')->will($this->returnValue($captcha));
$this->setRequestParameter('searchparam', 'searchparam&&A');
$this->setRequestParameter('searchcnid', 'searchcnid&&A');
$this->setRequestParameter('searchvendor', 'searchvendor&&A');
$this->setRequestParameter('searchmanufacturer', 'searchmanufacturer&&A');
$this->setRequestParameter('listtype', 'listtype&&A');
$expected = 'details?anid=XProduct&searchparam=searchparam%26%26A&searchcnid=searchcnid&amp;&amp;A&searchvendor=searchvendor&amp;&amp;A&searchmanufacturer=searchmanufacturer&amp;&amp;A&listtype=listtype&amp;&amp;A';
$this->assertEquals($expected, $suggest->send());
}
/**
* Test invalid captcha case.
*/
public function testSendInvalidCaptcha()
{
$captcha = $this->getMock('oeCaptcha', array('passCaptcha'));
$captcha->expects($this->once())->method('passCaptcha')->will($this->returnValue(false));
$suggest = $this->getMock('oecaptchasuggest', array('getProduct', 'getCaptcha'));
$suggest->expects($this->never())->method('getProduct');
$suggest->expects($this->once())->method('getCaptcha')->will($this->returnValue($captcha));
$this->assertFalse($suggest->send());
}
}

View File

@ -0,0 +1,17 @@
<?php
/**
*
* @category module
* @package captcha
* @author OXID eSales AG
* @link http://www.oxid-esales.com/
* @copyright (C) OXID eSales AG 2003-20162016
*/
$sLangName = 'Deutsch';
$aLang = array(
'charset' => 'UTF-8',
'MESSAGE_WRONG_VERIFICATION_CODE' => 'Der Prüfcode, den Sie eingegeben haben, ist nicht korrekt. Bitte versuchen Sie es erneut!'
);

View File

@ -0,0 +1,17 @@
<?php
/**
*
* @category module
* @package captcha
* @author OXID eSales AG
* @link http://www.oxid-esales.com/
* @copyright (C) OXID eSales AG 2003-20162016
*/
$sLangName = 'English';
$aLang = array(
'charset' => 'UTF-8',
'MESSAGE_WRONG_VERIFICATION_CODE' => "The verification code you entered is not correct. Please try again."
);

View File

@ -0,0 +1,13 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
// -------------------------------
// RESOURCE IDENTIFIER = STRING
// -------------------------------
$aLang = array(
'charset' => 'UTF-8',
'SHOP_MODULE_GROUP_main' => 'Allgemein',
'SHOP_MODULE_oecaptchakey' => 'Captcha Key',
);

View File

@ -0,0 +1,13 @@
<?php
/**
* #PHPHEADER_OECAPTCHA_LICENSE_INFORMATION#
*/
// -------------------------------
// RESOURCE IDENTIFIER = STRING
// -------------------------------
$aLang = array(
'charset' => 'UTF-8',
'SHOP_MODULE_GROUP_main' => 'General',
'SHOP_MODULE_oecaptchakey' => 'Captcha Key',
);

View File

@ -0,0 +1,18 @@
[{$smarty.block.parent}]
[{assign var="oCaptcha" value=$oView->getCaptcha()}]
<input type="hidden" name="c_mach" value="[{$oCaptcha->getHash()}]"/>
<li class="verify">
<label class="req">[{oxmultilang ident="VERIFICATION_CODE" suffix="COLON"}]</label>
[{assign var="oCaptcha" value=$oView->getCaptcha()}]
[{if $oCaptcha->isImageVisible()}]
<img src="[{$oCaptcha->getImageUrl()}]" alt="">
[{else}]
<span class="verificationCode" id="verifyTextCode">[{$oCaptcha->getText()}]</span>
[{/if}]
<input type="text" data-fieldsize="verify" name="c_mac" value="" class="js-oxValidate js-oxValidate_notEmpty">
<p class="oxValidateError">
<span class="js-oxError_notEmpty">[{oxmultilang ident="ERROR_MESSAGE_INPUT_NOTALLFIELDS"}]</span>
</p>
</li>