Changeset 2174

Show
Ignore:
Timestamp:
08/29/2007 10:22:42 AM
Author:
xue
Message:

added TCaptcha.Alphabet and added options to CAPTCHA generator.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/framework/Web/UI/WebControls/TCaptcha.php

    r2171 r2174  
    4040        const MIN_TOKEN_LENGTH=4; 
    4141        const MAX_TOKEN_LENGTH=40; 
     42        private $_privateKey; 
    4243 
    4344        public function onInit($param) 
     
    104105 
    105106        /** 
     107         * @return string the characters that may appear in the token. Defaults to '234578adefhijmnrtABDEFGHJLMNQRT'. 
     108         */ 
     109        public function getTokenAlphabet() 
     110        { 
     111                return $this->getViewState('TokenAlphabet','234578adefhijmnrtABDEFGHJLMNQRT'); 
     112        } 
     113 
     114        /** 
     115         * @param string the characters that may appear in the token. At least 2 characters must be specified. 
     116         */ 
     117        public function setTokenAlphabet($value) 
     118        { 
     119                if(strlen($value)<2) 
     120                        throw new TConfigurationException('captcha_tokenalphabet_invalid'); 
     121                $this->setViewState('TokenAlphabet',$value,'234578adefhijmnrtABDEFGHJLMNQRT'); 
     122        } 
     123 
     124        /** 
    106125         * @return string the public key used for generating the token. A random one will be generated and returned if this is not set. 
    107126         */ 
     
    129148        public function getToken() 
    130149        { 
    131                 return $this->generateToken($this->getPublicKey(),$this->getPrivateKey(),$this->getTokenLength(),$this->getCaseSensitive()); 
    132         } 
    133  
     150                return $this->generateToken($this->getPublicKey(),$this->getPrivateKey(),$this->getTokenAlphabet(),$this->getTokenLength(),$this->getCaseSensitive()); 
     151        } 
     152 
     153        /** 
     154         * @return integer the length of the token to be generated. 
     155         */ 
    134156        protected function getTokenLength() 
    135157        { 
     
    154176        public function getPrivateKey() 
    155177        { 
    156                 $fileName=$this->generatePrivateKeyFile(); 
    157                 $content=file_get_contents($fileName); 
    158                 $matches=array(); 
    159                 if(preg_match("/privateKey='(.*?)'/ms",$content,$matches)>0) 
    160                         return $matches[1]; 
    161                 else 
    162                         throw new TConfigurationException('captcha_private_unknown'); 
     178                if($this->_privateKey===null) 
     179                { 
     180                        $fileName=$this->generatePrivateKeyFile(); 
     181                        $content=file_get_contents($fileName); 
     182                        $matches=array(); 
     183                        if(preg_match("/privateKey='(.*?)'/ms",$content,$matches)>0) 
     184                                $this->_privateKey=$matches[1]; 
     185                        else 
     186                                throw new TConfigurationException('captcha_privatekey_unknown'); 
     187                } 
     188                return $this->_privateKey; 
    163189        } 
    164190 
     
    194220                if(!$this->getViewState('TokenGenerated',false)) 
    195221                { 
    196                         $token=$this->getToken(); 
    197                         $tokenLength=strlen($token); 
    198222                        $manager=$this->getApplication()->getAssetManager(); 
    199223                        $manager->publishFilePath($this->getFontFile()); 
    200224                        $url=$manager->publishFilePath($this->getCaptchaScriptFile()); 
    201                         $url.='?pk='.urlencode($this->getPublicKey()); 
    202                         $url.='&amp;length='.$tokenLength; 
    203                         $url.='&amp;case='.($this->getCaseSensitive()?'1':'0'); 
     225                        $url.='?options='.urlencode($this->getTokenImageOptions()); 
    204226                        $this->setImageUrl($url); 
    205                         $this->generatePrivateKeyFile(); 
    206227 
    207228                        $this->setViewState('TokenGenerated',true); 
    208229                } 
     230        } 
     231 
     232        /** 
     233         * @return string the options to be passed to the token image generator 
     234         */ 
     235        protected function getTokenImageOptions() 
     236        { 
     237                $privateKey=$this->getPrivateKey();  // call this method to ensure private key is generated 
     238                $token=$this->getToken(); 
     239                $options=array(); 
     240                $options['publicKey']=$this->getPublicKey(); 
     241                $options['tokenLength']=strlen($token); 
     242                $options['caseSensitive']=$this->getCaseSensitive(); 
     243                $options['alphabet']=$this->getTokenAlphabet(); 
     244                $str=serialize($options); 
     245                return base64_encode(md5($privateKey.$str).$str); 
    209246        } 
    210247 
     
    259296         * @return string the token generated. 
    260297         */ 
    261         protected function generateToken($publicKey,$privateKey,$tokenLength,$caseSensitive) 
    262         { 
    263                 $token=substr($this->hash2string(md5($publicKey.$privateKey)).$this->hash2string(md5($privateKey.$publicKey)),0,$tokenLength); 
     298        protected function generateToken($publicKey,$privateKey,$alphabet,$tokenLength,$caseSensitive) 
     299        { 
     300                $token=substr($this->hash2string(md5($publicKey.$privateKey),$alphabet).$this->hash2string(md5($privateKey.$publicKey),$alphabet),0,$tokenLength); 
    264301                return $caseSensitive?$token:strtoupper($token); 
    265302        } 
     
    290327        } 
    291328 
     329        /** 
     330         * Checks the requirements needed for generating CAPTCHA images. 
     331         */ 
    292332        protected function checkRequirements() 
    293333        { 
  • trunk/framework/Web/UI/WebControls/assets/captcha.php

    r2170 r2174  
    11<?php 
     2/** 
     3 * CAPTCHA generator script. 
     4 * 
     5 * @author Qiang Xue <qiang.xue@gmail.com> 
     6 * @link http://www.pradosoft.com/ 
     7 * @copyright Copyright &copy; 2005-2007 PradoSoft 
     8 * @license http://www.pradosoft.com/license/ 
     9 * @version $Id: $ 
     10 * @package System.Web.UI.WebControls.assets 
     11 */ 
    212 
    3 if(isset($_GET['pk']) && strlen($_GET['pk'])>=6 && isset($_GET['length']) && (int)$_GET['length']>=4 && isset($_GET['case'])) 
     13require_once(dirname(__FILE__).'/captcha_key.php'); 
     14 
     15$token='error'; 
     16if(isset($_GET['options'])) 
    417{ 
    5         require_once(dirname(__FILE__).'/captcha_key.php'); 
    6         $publicKey=$_GET['pk']; 
    7         $tokenLength=(int)$_GET['length']; 
    8         $caseSensitive=!empty($_GET['case']); 
    9         $token=generateToken($publicKey,$privateKey,$tokenLength,$caseSensitive); 
     18        $str=base64_decode($_GET['options']); 
     19        if(strlen($str)>32) 
     20        { 
     21                $hash=substr($str,0,32); 
     22                $str=substr($str,32); 
     23                if(md5($privateKey.$str)===$hash) 
     24                { 
     25                        $options=unserialize($str); 
     26                        $publicKey=$options['publicKey']; 
     27                        $tokenLength=$options['tokenLength']; 
     28                        $caseSensitive=$options['caseSensitive']; 
     29                        $alphabet=$options['alphabet']; 
     30                        $token=generateToken($publicKey,$privateKey,$alphabet,$tokenLength,$caseSensitive); 
     31                } 
     32        } 
    1033} 
    11 else 
    12         $token='error'; 
    1334 
    1435displayToken($token); 
    1536 
    16 function generateToken($publicKey,$privateKey,$tokenLength,$caseSensitive) 
     37function generateToken($publicKey,$privateKey,$alphabet,$tokenLength,$caseSensitive) 
    1738{ 
    18         $token=substr(hash2string(md5($publicKey.$privateKey)).hash2string(md5($privateKey.$publicKey)),0,$tokenLength); 
     39        $token=substr(hash2string(md5($publicKey.$privateKey),$alphabet).hash2string(md5($privateKey.$publicKey),$alphabet),0,$tokenLength); 
    1940        return $caseSensitive?$token:strtoupper($token); 
    2041} 
     
    7798    } 
    7899    imagefilter($image,IMG_FILTER_GAUSSIAN_BLUR); 
     100 
    79101        imagepng($image); 
    80102        imagedestroy($image);