diff options
author | xue <> | 2007-08-29 15:22:42 +0000 |
---|---|---|
committer | xue <> | 2007-08-29 15:22:42 +0000 |
commit | 9d13a92291fad0a5a5fd46179149654cb357c9d0 (patch) | |
tree | d97b6bc3b7c9f50bdb19bbdfadfe058fe2ae0932 | |
parent | 30795649ead5b7212cad32f9d5a9ca6152beba27 (diff) |
added TCaptcha.Alphabet and added options to CAPTCHA generator.
-rw-r--r-- | framework/Web/UI/WebControls/TCaptcha.php | 72 | ||||
-rw-r--r-- | framework/Web/UI/WebControls/assets/captcha.php | 42 |
2 files changed, 88 insertions, 26 deletions
diff --git a/framework/Web/UI/WebControls/TCaptcha.php b/framework/Web/UI/WebControls/TCaptcha.php index 9f4cee08..17e9ad34 100644 --- a/framework/Web/UI/WebControls/TCaptcha.php +++ b/framework/Web/UI/WebControls/TCaptcha.php @@ -39,6 +39,7 @@ class TCaptcha extends TImage {
const MIN_TOKEN_LENGTH=4;
const MAX_TOKEN_LENGTH=40;
+ private $_privateKey;
public function onInit($param)
{
@@ -103,6 +104,24 @@ class TCaptcha extends TImage }
/**
+ * @return string the characters that may appear in the token. Defaults to '234578adefhijmnrtABDEFGHJLMNQRT'.
+ */
+ public function getTokenAlphabet()
+ {
+ return $this->getViewState('TokenAlphabet','234578adefhijmnrtABDEFGHJLMNQRT');
+ }
+
+ /**
+ * @param string the characters that may appear in the token. At least 2 characters must be specified.
+ */
+ public function setTokenAlphabet($value)
+ {
+ if(strlen($value)<2)
+ throw new TConfigurationException('captcha_tokenalphabet_invalid');
+ $this->setViewState('TokenAlphabet',$value,'234578adefhijmnrtABDEFGHJLMNQRT');
+ }
+
+ /**
* @return string the public key used for generating the token. A random one will be generated and returned if this is not set.
*/
public function getPublicKey()
@@ -128,9 +147,12 @@ class TCaptcha extends TImage */
public function getToken()
{
- return $this->generateToken($this->getPublicKey(),$this->getPrivateKey(),$this->getTokenLength(),$this->getCaseSensitive());
+ return $this->generateToken($this->getPublicKey(),$this->getPrivateKey(),$this->getTokenAlphabet(),$this->getTokenLength(),$this->getCaseSensitive());
}
+ /**
+ * @return integer the length of the token to be generated.
+ */
protected function getTokenLength()
{
if(($tokenLength=$this->getViewState('TokenLength'))===null)
@@ -153,13 +175,17 @@ class TCaptcha extends TImage */
public function getPrivateKey()
{
- $fileName=$this->generatePrivateKeyFile();
- $content=file_get_contents($fileName);
- $matches=array();
- if(preg_match("/privateKey='(.*?)'/ms",$content,$matches)>0)
- return $matches[1];
- else
- throw new TConfigurationException('captcha_private_unknown');
+ if($this->_privateKey===null)
+ {
+ $fileName=$this->generatePrivateKeyFile();
+ $content=file_get_contents($fileName);
+ $matches=array();
+ if(preg_match("/privateKey='(.*?)'/ms",$content,$matches)>0)
+ $this->_privateKey=$matches[1];
+ else
+ throw new TConfigurationException('captcha_privatekey_unknown');
+ }
+ return $this->_privateKey;
}
/**
@@ -193,22 +219,33 @@ class TCaptcha extends TImage parent::onPreRender($param);
if(!$this->getViewState('TokenGenerated',false))
{
- $token=$this->getToken();
- $tokenLength=strlen($token);
$manager=$this->getApplication()->getAssetManager();
$manager->publishFilePath($this->getFontFile());
$url=$manager->publishFilePath($this->getCaptchaScriptFile());
- $url.='?pk='.urlencode($this->getPublicKey());
- $url.='&length='.$tokenLength;
- $url.='&case='.($this->getCaseSensitive()?'1':'0');
+ $url.='?options='.urlencode($this->getTokenImageOptions());
$this->setImageUrl($url);
- $this->generatePrivateKeyFile();
$this->setViewState('TokenGenerated',true);
}
}
/**
+ * @return string the options to be passed to the token image generator
+ */
+ protected function getTokenImageOptions()
+ {
+ $privateKey=$this->getPrivateKey(); // call this method to ensure private key is generated
+ $token=$this->getToken();
+ $options=array();
+ $options['publicKey']=$this->getPublicKey();
+ $options['tokenLength']=strlen($token);
+ $options['caseSensitive']=$this->getCaseSensitive();
+ $options['alphabet']=$this->getTokenAlphabet();
+ $str=serialize($options);
+ return base64_encode(md5($privateKey.$str).$str);
+ }
+
+ /**
* @return string the file path of the PHP script generating the token image
*/
protected function getCaptchaScriptFile()
@@ -258,9 +295,9 @@ class TCaptcha extends TImage * @param boolean whether the token is case sensitive
* @return string the token generated.
*/
- protected function generateToken($publicKey,$privateKey,$tokenLength,$caseSensitive)
+ protected function generateToken($publicKey,$privateKey,$alphabet,$tokenLength,$caseSensitive)
{
- $token=substr($this->hash2string(md5($publicKey.$privateKey)).$this->hash2string(md5($privateKey.$publicKey)),0,$tokenLength);
+ $token=substr($this->hash2string(md5($publicKey.$privateKey),$alphabet).$this->hash2string(md5($privateKey.$publicKey),$alphabet),0,$tokenLength);
return $caseSensitive?$token:strtoupper($token);
}
@@ -289,6 +326,9 @@ class TCaptcha extends TImage return $result;
}
+ /**
+ * Checks the requirements needed for generating CAPTCHA images.
+ */
protected function checkRequirements()
{
if(!extension_loaded('gd'))
diff --git a/framework/Web/UI/WebControls/assets/captcha.php b/framework/Web/UI/WebControls/assets/captcha.php index a722772b..3941eb44 100644 --- a/framework/Web/UI/WebControls/assets/captcha.php +++ b/framework/Web/UI/WebControls/assets/captcha.php @@ -1,21 +1,42 @@ <?php
+/**
+ * CAPTCHA generator script.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright © 2005-2007 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Id: $
+ * @package System.Web.UI.WebControls.assets
+ */
-if(isset($_GET['pk']) && strlen($_GET['pk'])>=6 && isset($_GET['length']) && (int)$_GET['length']>=4 && isset($_GET['case']))
+require_once(dirname(__FILE__).'/captcha_key.php');
+
+$token='error';
+if(isset($_GET['options']))
{
- require_once(dirname(__FILE__).'/captcha_key.php');
- $publicKey=$_GET['pk'];
- $tokenLength=(int)$_GET['length'];
- $caseSensitive=!empty($_GET['case']);
- $token=generateToken($publicKey,$privateKey,$tokenLength,$caseSensitive);
+ $str=base64_decode($_GET['options']);
+ if(strlen($str)>32)
+ {
+ $hash=substr($str,0,32);
+ $str=substr($str,32);
+ if(md5($privateKey.$str)===$hash)
+ {
+ $options=unserialize($str);
+ $publicKey=$options['publicKey'];
+ $tokenLength=$options['tokenLength'];
+ $caseSensitive=$options['caseSensitive'];
+ $alphabet=$options['alphabet'];
+ $token=generateToken($publicKey,$privateKey,$alphabet,$tokenLength,$caseSensitive);
+ }
+ }
}
-else
- $token='error';
displayToken($token);
-function generateToken($publicKey,$privateKey,$tokenLength,$caseSensitive)
+function generateToken($publicKey,$privateKey,$alphabet,$tokenLength,$caseSensitive)
{
- $token=substr(hash2string(md5($publicKey.$privateKey)).hash2string(md5($privateKey.$publicKey)),0,$tokenLength);
+ $token=substr(hash2string(md5($publicKey.$privateKey),$alphabet).hash2string(md5($privateKey.$publicKey),$alphabet),0,$tokenLength);
return $caseSensitive?$token:strtoupper($token);
}
@@ -76,6 +97,7 @@ function displayToken($token) imagecolordeallocate($image, $col);
}
imagefilter($image,IMG_FILTER_GAUSSIAN_BLUR);
+
imagepng($image);
imagedestroy($image);
}
|