From d1875fd32e0aa7a093544b5decd0b43499424d4f Mon Sep 17 00:00:00 2001
From: xue <>
Date: Thu, 30 Aug 2007 15:40:24 +0000
Subject: further enhanced TCaptcha.
---
.../protected/pages/Controls/Captcha.page | 6 +-
.../pages/Controls/Samples/TCaptcha/Home.page | 4 +-
.../source/prado/validator/validation3.js | 13 +--
framework/Web/UI/WebControls/TCaptcha.php | 107 ++++++++++++++++++---
framework/Web/UI/WebControls/TCaptchaValidator.php | 11 ++-
framework/Web/UI/WebControls/assets/captcha.php | 4 +
6 files changed, 121 insertions(+), 24 deletions(-)
diff --git a/demos/quickstart/protected/pages/Controls/Captcha.page b/demos/quickstart/protected/pages/Controls/Captcha.page
index 244a3adc..a0af13e5 100644
--- a/demos/quickstart/protected/pages/Controls/Captcha.page
+++ b/demos/quickstart/protected/pages/Controls/Captcha.page
@@ -16,7 +16,11 @@ The token generated by TCaptcha can be configured in several ways. To s
-To specify the appearance of the generated token image, set TokenImageTheme to be an integer between 0 and 31. You may try the following example to see how this value affects the generated token image. The size of the generated token image is determined by TokenFontSize. In particular, the image width is proportional to the font size. You may also set Width to scale the generated image to your desired size, but the scaled image may not look good.
+The validation of the token is related with two properties: TestLimit (defaults to 5 times) and TokenExpiry (defaults to 600 seconds). The former specifies how many times a token can be tested with on the server side, and the latter says when a generated token will expire. If the validation fails in any of the two scenarios, a new token will be automatically generated.
+
+
+
+To specify the appearance of the generated token image, set TokenImageTheme to be an integer between 0 and 31. You may try the following example to see how this value affects the generated token image. The size of the generated token image is determined by TokenFontSize. In particular, the image width is proportional to the font size. You may also set Width to scale the generated image to your desired size, but the scaled image may not look good. By setting ChangingTokenBackground to true, the image background of the token will be variating even though the token is the same during postbacks.
diff --git a/framework/Web/Javascripts/source/prado/validator/validation3.js b/framework/Web/Javascripts/source/prado/validator/validation3.js
index 3d43a5f3..62d6e718 100644
--- a/framework/Web/Javascripts/source/prado/validator/validation3.js
+++ b/framework/Web/Javascripts/source/prado/validator/validation3.js
@@ -1388,14 +1388,11 @@ Prado.WebUI.TCaptchaValidator = Class.extend(Prado.WebUI.TBaseValidator,
*/
evaluateIsValid : function()
{
- var a = this.getValidationValue();
- if (a.length <= 0)
- return false;
- var b = this.options.TokenHash;
- if (this.options.CaseSensitive)
- return(this.crc32(a) == b);
- else
- return(this.crc32(a.toUpperCase()) == b);
+ var a = this.getValidationValue();
+ var h = 0;
+ for(var i = a.length-1; i >= 0; --i)
+ h += a.charCodeAt(i);
+ return h == this.options.TokenHash;
},
crc32 : function(str)
diff --git a/framework/Web/UI/WebControls/TCaptcha.php b/framework/Web/UI/WebControls/TCaptcha.php
index bff04236..48e57b9e 100644
--- a/framework/Web/UI/WebControls/TCaptcha.php
+++ b/framework/Web/UI/WebControls/TCaptcha.php
@@ -24,12 +24,18 @@ Prado::using('System.Web.UI.WebControls.TImage');
* generated and can be configured in several ways. To specify the length of characters
* in the token, set {@link setMinTokenLength MinTokenLength} and {@link setMaxTokenLength MaxTokenLength}.
* To use case-insensitive comparison and generate upper-case-only token, set {@link setCaseSensitive CaseSensitive}
- * to false. More advanced users can try to set {@link setTokenAlphabet TokenAlphabet}, which
+ * to false. Advanced users can try to set {@link setTokenAlphabet TokenAlphabet}, which
* specifies what characters can appear in tokens.
*
+ * The validation of the token is related with two properties: {@link setTestLimit TestLimit}
+ * and {@link setTokenExpiry TokenExpiry}. The former specifies how many times a token can
+ * be tested with on the server side, and the latter says when a generated token will expire.
+ *
* To specify the appearance of the generated token image, set {@link setTokenImageTheme TokenImageTheme}
* to be an integer between 0 and 31. And to adjust the generated image size, set {@link setTokenFontSize TokenFontSize}
* (you may also set {@link TWebControl::setWidth Width}, but the scaled image may not look good.)
+ * By setting {@link setChangingTokenBackground ChangingTokenBackground} to true, the image background
+ * of the token will be variating even though the token is the same during postbacks.
*
* Upon postback, user input can be validated by calling {@link validate()}.
* The {@link TCaptchaValidator} control can also be used to do validation, which provides
@@ -53,9 +59,10 @@ Prado::using('System.Web.UI.WebControls.TImage');
*/
class TCaptcha extends TImage
{
- const MIN_TOKEN_LENGTH=4;
+ const MIN_TOKEN_LENGTH=2;
const MAX_TOKEN_LENGTH=40;
private $_privateKey;
+ private $_validated=false;
/**
* Checks the requirements needed for using TCaptcha.
@@ -119,11 +126,11 @@ class TCaptcha extends TImage
}
/**
- * @return integer the minimum length of the token. Defaults to 5.
+ * @return integer the minimum length of the token. Defaults to 4.
*/
public function getMinTokenLength()
{
- return $this->getViewState('MinTokenLength',5);
+ return $this->getViewState('MinTokenLength',4);
}
/**
@@ -133,17 +140,17 @@ class TCaptcha extends TImage
{
$length=TPropertyValue::ensureInteger($value);
if($length>=self::MIN_TOKEN_LENGTH && $length<=self::MAX_TOKEN_LENGTH)
- $this->setViewState('MinTokenLength',$length,5);
+ $this->setViewState('MinTokenLength',$length,4);
else
throw new TConfigurationException('captcha_mintokenlength_invalid',self::MIN_TOKEN_LENGTH,self::MAX_TOKEN_LENGTH);
}
/**
- * @return integer the maximum length of the token. Defaults to 8.
+ * @return integer the maximum length of the token. Defaults to 6.
*/
public function getMaxTokenLength()
{
- return $this->getViewState('MaxTokenLength',8);
+ return $this->getViewState('MaxTokenLength',6);
}
/**
@@ -153,7 +160,7 @@ class TCaptcha extends TImage
{
$length=TPropertyValue::ensureInteger($value);
if($length>=self::MIN_TOKEN_LENGTH && $length<=self::MAX_TOKEN_LENGTH)
- $this->setViewState('MaxTokenLength',$length,8);
+ $this->setViewState('MaxTokenLength',$length,6);
else
throw new TConfigurationException('captcha_maxtokenlength_invalid',self::MIN_TOKEN_LENGTH,self::MAX_TOKEN_LENGTH);
}
@@ -192,6 +199,65 @@ class TCaptcha extends TImage
$this->setViewState('TokenAlphabet',$value,'234578adefhijmnrtABDEFGHJLMNRT');
}
+ /**
+ * @return integer the number of seconds that a generated token will remain valid. Defaults to 600 seconds (10 minutes).
+ */
+ public function getTokenExpiry()
+ {
+ return $this->getViewState('TokenExpiry',600);
+ }
+
+ /**
+ * @param integer the number of seconds that a generated token will remain valid. A value smaller than 1 means the token will not expire.
+ */
+ public function setTokenExpiry($value)
+ {
+ $this->setViewState('TokenExpiry',TPropertyValue::ensureInteger($value),600);
+ }
+
+ /**
+ * @return boolean whether the background of the token image should be variated during postbacks. Defaults to false.
+ */
+ public function getChangingTokenBackground()
+ {
+ return $this->getViewState('ChangingTokenBackground',false);
+ }
+
+ /**
+ * @param boolean whether the background of the token image should be variated during postbacks.
+ */
+ public function setChangingTokenBackground($value)
+ {
+ $this->setViewState('ChangingTokenBackground',TPropertyValue::ensureBoolean($value),false);
+ }
+
+ /**
+ * @return integer how many times a generated token can be tested. Defaults to 5.
+ */
+ public function getTestLimit()
+ {
+ return $this->getViewState('TestLimit',5);
+ }
+
+ /**
+ * @param integer how many times a generated token can be tested. For unlimited tests, set it to 0.
+ */
+ public function setTestLimit($value)
+ {
+ $this->setViewState('TestLimit',TPropertyValue::ensureInteger($value),5);
+ }
+
+ /**
+ * @return boolean whether the currently generated token has expired.
+ */
+ public function getIsTokenExpired()
+ {
+ if(($expiry=$this->getTokenExpiry())>0 && ($start=$this->getViewState('TokenGenerated',0))>0)
+ return $expiry+$start