[pLog-svn] r2361 - in plog/branches/plog-1.0.2: class/data class/data/captcha class/summary/action class/summary/view imgs imgs/authimage templates/summary

oscar at devel.plogworld.net oscar at devel.plogworld.net
Mon Jul 25 13:22:19 GMT 2005


Author: oscar
Date: 2005-07-25 13:22:19 +0000 (Mon, 25 Jul 2005)
New Revision: 2361

Added:
   plog/branches/plog-1.0.2/class/data/captcha/
   plog/branches/plog-1.0.2/class/data/captcha/captcha.class.php
   plog/branches/plog-1.0.2/class/summary/view/summaryusercreationview.class.php
   plog/branches/plog-1.0.2/imgs/authimage/
   plog/branches/plog-1.0.2/imgs/authimage/marble.gif
   plog/branches/plog-1.0.2/imgs/authimage/ocean.gif
   plog/branches/plog-1.0.2/imgs/authimage/pine.gif
   plog/branches/plog-1.0.2/imgs/authimage/rain.gif
   plog/branches/plog-1.0.2/imgs/authimage/sky.gif
   plog/branches/plog-1.0.2/imgs/authimage/transparent.gif
Modified:
   plog/branches/plog-1.0.2/class/summary/action/doreadagreement.class.php
   plog/branches/plog-1.0.2/class/summary/action/dousercreation.class.php
   plog/branches/plog-1.0.2/class/summary/action/douserregister.class.php
   plog/branches/plog-1.0.2/templates/summary/registerstep1.template
Log:
added a "captcha" image to the regsitration process, in the step where the user is created. The image creation
code is almost the same as Mark's AuthImage plugin but reworked it a bit in order to be self-contained. This
feature will be disabled and hidden by default, but I have implemented it now so that people can stop
bugging me for a while... We'll add the locale strings and the configuration option in 1.1 but in the meantime
you can set the value 'use_captcha_auth' to '1' in the plog_config table to get this to work.


Added: plog/branches/plog-1.0.2/class/data/captcha/captcha.class.php
===================================================================
--- plog/branches/plog-1.0.2/class/data/captcha/captcha.class.php	2005-07-25 11:31:02 UTC (rev 2360)
+++ plog/branches/plog-1.0.2/class/data/captcha/captcha.class.php	2005-07-25 13:22:19 UTC (rev 2361)
@@ -0,0 +1,148 @@
+<?php
+
+	include_once( PLOG_CLASS_PATH."class/object/object.class.php" );
+	
+	/**
+	 * default expiration time for old images, 1h
+	 */
+	define( "CAPTCHA_DEFAULT_EXPIRATION_TIME", 3600 );
+	
+	/**
+	 * background folder and background default image
+	 */
+	define( "CAPTCHA_BACKGROUND_FOLDER", PLOG_CLASS_PATH."imgs/authimage/" );
+	define( "CAPTCHA_BACKGROUND_FILE", "sky.gif" );
+	/**
+	 * change this to your default key, used for the "encryption"
+	 */	
+	define( "CAPTCHA_DEFAULT_KEY", "default-key" );
+	/**
+	 * where you would like to store the images
+	 */
+	define( "CAPTCHA_CACHE_FOLDER", "./tmp" );
+	/** 
+	 * default length of the code
+	 */
+	define( "CAPTCHA_DEFAULT_CODE_LENGTH", 6 );
+	
+	/**
+	 * Class to generate CAPTCHA images, based on Mark Wu's AuthImage plugin.
+	 *
+	 * Usage:
+	 * <pre>
+	 *  $auth = new Captcha();
+	 *  $auth->generate();
+	 *  ...
+	 *  if( $auth->validate( $_POST["authImage"] )) {
+	 *     // validation ok!
+	 *  }
+	 *  else {
+	 *    // error in validation!
+	 *  }
+	 * </pre>
+	 */
+	class Captcha extends Object
+	{
+		function Captcha()
+		{
+			$this->Object();
+			
+			$this->key = CAPTCHA_DEFAULT_KEY;
+			$this->cacheFolder = CAPTCHA_CACHE_FOLDER;
+			$this->expiredTime = CAPTCHA_DEFAULT_EXPIRATION_TIME;
+			$this->length = CAPTCHA_DEFAULT_CODE_LENGTH;
+		}
+		
+        /**
+         * @private
+         */
+        function encrypt($string, $key) {
+            $plainText = $string.$key;
+            $encodeText = md5($plainText);
+            return $encodeText;
+        }
+        
+        /**
+         * @private
+         */
+        function generateCode() {
+            $code = "";
+            for($i=0; $i < $this->length; $i++) $code .= rand(0,9);
+            return $code;
+        }		
+		
+		/**
+		 * generates a new image and returns the url
+		 *
+		 * @return a url to the captcha image
+		 */
+		function generate()
+		{
+            // Delete those cached authimage files that never used
+            $this->purgeOld($this->expiredTime);
+            
+            $code = $this->generateCode();
+            $encrypt = $this->encrypt($code, $this->key);
+            $background = CAPTCHA_BACKGROUND_FOLDER.CAPTCHA_BACKGROUND_FILE;
+            $tempFile = $this->cacheFolder."/".$encrypt.".gif";
+
+            if(function_exists ( 'imagecreatefromgif' )){
+                $image = @imagecreatefromgif($background) or die("Cannot Initialize new GD image stream");
+			}
+			else if(function_exists ( 'imagecreatefrompng' )){
+                $image = @imagecreatefrompng($background) or die("Cannot Initialize new GD image stream"); 
+            } 
+            else {
+			  die("Server doesn't support GIF or PNG creation. Sorry.");
+            }           
+            
+            $textColor = imageColorAllocate($image, 0x00, 0x00, 0x00);
+            ImageString($image, 5, 7, 2, $code, $textColor);
+
+            if ( !function_exists ( 'ImageGIF' ) ) {
+                ImagePNG($image, $tempFile);
+            } else {            
+                ImageGIF($image, $tempFile);
+            }
+            
+            // Now chmod it so it can be deleted later by the user
+            chmod($tempFile, 0666);       
+            
+			return( $tempFile );
+		}
+		
+		/**
+		 * checks whether the given code validates with any of the authimages
+		 * previously generated
+		 *
+		 * @param code The code
+		 * @return True if the code is valid or false otherwise
+		 */
+		function validate( $code )
+		{
+			include_once( PLOG_CLASS_PATH."class/file/file.class.php" );
+            $encrypt = $this->encrypt($code, $this->key);
+            $tempFile = $this->cacheFolder."/".$encrypt.".gif";
+           	$result = File::exists( $tempFile );
+
+			return( $result );
+		}
+		
+		/**
+		 * Removes the old captcha images that are not needed anymre
+		 *Ê@private
+		 */
+		function purgeOld( $expireTime = CAPTCHA_DEFAULT_EXPIRATION_TIME )
+		{
+			include_once( PLOG_CLASS_PATH."class/misc/glob.class.php" );
+			$files = Glob::myGlob( $this->cacheFolder, "*.gif" );
+			if( $files ) {
+				foreach( $files as $file ) {
+					$diff = time() - filectime( $file );
+					if ($diff > $expireTime) 
+						unlink( $file );
+				}
+			}
+		}
+	}
+?>
\ No newline at end of file

Modified: plog/branches/plog-1.0.2/class/summary/action/doreadagreement.class.php
===================================================================
--- plog/branches/plog-1.0.2/class/summary/action/doreadagreement.class.php	2005-07-25 11:31:02 UTC (rev 2360)
+++ plog/branches/plog-1.0.2/class/summary/action/doreadagreement.class.php	2005-07-25 13:22:19 UTC (rev 2361)
@@ -10,12 +10,13 @@
 	{
         function perform()
         {
-    		if( $this->_config->getValue( "summary_show_agreement" ))
+    		if( $this->_config->getValue( "summary_show_agreement" )) {
     		    $this->_view = new SummaryView( "registerstep0" );
-	    	else
-		    	$this->_view = new SummaryView( "registerstep1" );
-
-            $this->setCommonData();
+	            $this->setCommonData();    		    
+	        }
+	    	else {
+	    		SummaryController::setForwardAction( "RegisterStep1" );
+		    }
         }
     }	 
 ?>

Modified: plog/branches/plog-1.0.2/class/summary/action/dousercreation.class.php
===================================================================
--- plog/branches/plog-1.0.2/class/summary/action/dousercreation.class.php	2005-07-25 11:31:02 UTC (rev 2360)
+++ plog/branches/plog-1.0.2/class/summary/action/dousercreation.class.php	2005-07-25 13:22:19 UTC (rev 2361)
@@ -7,6 +7,7 @@
     include_once( PLOG_CLASS_PATH."class/data/validator/passwordvalidator.class.php" );    
     include_once( PLOG_CLASS_PATH."class/dao/users.class.php" );
     include_once( PLOG_CLASS_PATH."class/summary/view/doblogregistrationview.class.php" );
+	include_once( PLOG_CLASS_PATH."class/summary/view/summaryusercreationview.class.php" );    
 
     /**
      * starts the user and blog registration process
@@ -23,8 +24,12 @@
 			$this->registerFieldValidator( "userPassword", new PasswordValidator());
 			$this->registerFieldValidator( "userPasswordCheck", new PasswordValidator());
 			$this->registerFieldValidator( "userEmail", new EmailValidator());
+            $this->_config =& Config::getConfig();
+            if( $this->_config->getValue( "use_captcha_auth" )) {
+				$this->registerFieldValidator( "userAuth", new StringValidator());
+			}
 			$this->registerField( "userFullName" );
-			$view = new SummaryView( "registerstep1" );
+			$view = new SummaryUserCreationView();
 			$view->setErrorMessage( $this->_locale->tr("error_adding_user" ));
 			$this->setValidationErrorView( $view );
 		}	
@@ -38,11 +43,12 @@
             $this->confirmPassword = $tf->filterAllHTML($this->_request->getValue( "userPasswordCheck" ));
             $this->userEmail = $tf->filterAllHTML($this->_request->getValue( "userEmail" ));
 			$this->userFullName = $tf->filterAllHTML($this->_request->getValue( "userFullName" ));
+			$this->captcha = $this->_request->getValue( "userAuth" );
 			
 			// check if there is already a user with the same username and quit if so
 			$users = new Users();
 			if( $users->userExists( $this->userName )) {
-				$this->_view = new SummaryView( "registerstep1" );
+				$this->_view = new SummaryUserCreationView();
 				//$this->_form->hasRun( true );
 				$this->_form->setFieldValidationStatus( "userName", false );
 				$this->setCommonData( true );
@@ -50,27 +56,39 @@
 			}
 
             // check if this email account has registered and quit if so, but only if the configuration
-		// says that we should only allow one blog per email account
-		if( $this->_config->getValue( "force_one_blog_per_email_account" )) {
-            if( $users->emailExists($this->userEmail)) {
-				$this->_view = new SummaryView( "registerstep1" );
-				//$this->_form->hasRun( true );
-				$this->_form->setFieldValidationStatus( "userEmail", false );
-				$this->setCommonData( true );
-				return false;
-            }
-		}
+			// says that we should only allow one blog per email account
+			if( $this->_config->getValue( "force_one_blog_per_email_account" )) {
+        	    if( $users->emailExists($this->userEmail)) {
+					$this->_view = new SummaryUserCreationView();
+					//$this->_form->hasRun( true );
+					$this->_form->setFieldValidationStatus( "userEmail", false );
+					$this->setCommonData( true );
+					return false;
+            	}
+			}
 			
 			// check if the passwords match, and stop processing if so too
             if( $this->userPassword != $this->confirmPassword ) {
-	            $this->_view = new SummaryView( "registerstep1" );
+	            $this->_view = new SummaryUserCreationView();
                 $this->_view->setErrorMessage( $this->_locale->tr("error_passwords_dont_match"));
 				$this->_form->setFieldValidationStatus( "userPasswordCheck", false );                
                 $this->setCommonData( true );
                 return false;
             }			
+            
+            // check if the captcha matches
+            if( $this->_config->getValue( "use_captcha_auth")) {
+            	include_once( PLOG_CLASS_PATH."class/data/captcha/captcha.class.php" );
+            	$captcha = new Captcha();
+            	if( !$captcha->validate( $this->captcha )) {
+		            $this->_view = new SummaryUserCreationView();
+    	            $this->_view->setErrorMessage( $this->_locale->tr("error_invalid_auth_code"));
+					$this->_form->setFieldValidationStatus( "userAuth", false );                
+            	    $this->setCommonData( true );
+                	return false;            	
+            	}
+            }
 
-
             // if everything went fine, then proceed
             $this->_view = new doBlogRegistrationView();
             $this->setValues();

Modified: plog/branches/plog-1.0.2/class/summary/action/douserregister.class.php
===================================================================
--- plog/branches/plog-1.0.2/class/summary/action/douserregister.class.php	2005-07-25 11:31:02 UTC (rev 2360)
+++ plog/branches/plog-1.0.2/class/summary/action/douserregister.class.php	2005-07-25 13:22:19 UTC (rev 2361)
@@ -1,6 +1,7 @@
 <?php
 
 	include_once( PLOG_CLASS_PATH."class/summary/action/registeraction.class.php" );
+	include_once( PLOG_CLASS_PATH."class/summary/view/summaryusercreationview.class.php" );
 
 	/**
 	 * shows a form so that users can register
@@ -9,8 +10,8 @@
 	{
         function perform()
         {
-            $this->_view = new SummaryView( "registerstep1" );
-            $this->setCommonData();
+           $this->_view = new SummaryUserCreationView();
+           $this->setCommonData();
         }
     }	 
 ?>

Added: plog/branches/plog-1.0.2/class/summary/view/summaryusercreationview.class.php
===================================================================
--- plog/branches/plog-1.0.2/class/summary/view/summaryusercreationview.class.php	2005-07-25 11:31:02 UTC (rev 2360)
+++ plog/branches/plog-1.0.2/class/summary/view/summaryusercreationview.class.php	2005-07-25 13:22:19 UTC (rev 2361)
@@ -0,0 +1,32 @@
+<?php
+	include_once( PLOG_CLASS_PATH."class/config/config.class.php" );
+
+	class SummaryUserCreationView extends SummaryView
+	{
+		function SummaryUserCreationView()
+		{
+			$this->SummaryView( "registerstep1" );
+		}
+		
+		function render()
+		{			
+    		$config =& Config::getConfig();
+    		// check whether we should also display one of those authentication images
+    		if( $config->getValue( "use_captcha_auth" )) {
+    			// generate a file with the captcha class
+    			include_once( PLOG_CLASS_PATH."class/data/captcha/captcha.class.php" );
+    			$captcha = new Captcha();
+    			$captchaFile = $captcha->generate();
+    			// and then build a full url based on it...
+    			$url = $config->getValue( "base_url" )."/".$captchaFile;
+    			$this->setValue( "userAuthImgPath", $url );
+    			$this->setValue( "useCaptchaAuth", true );
+    		}
+    		else {
+    			$this->setValue( "useCaptchaAuth", false );	    		
+    		}
+    		
+			parent::render();    		
+		}
+	}
+?>
\ No newline at end of file

Added: plog/branches/plog-1.0.2/imgs/authimage/marble.gif
===================================================================
(Binary files differ)


Property changes on: plog/branches/plog-1.0.2/imgs/authimage/marble.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: plog/branches/plog-1.0.2/imgs/authimage/ocean.gif
===================================================================
(Binary files differ)


Property changes on: plog/branches/plog-1.0.2/imgs/authimage/ocean.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: plog/branches/plog-1.0.2/imgs/authimage/pine.gif
===================================================================
(Binary files differ)


Property changes on: plog/branches/plog-1.0.2/imgs/authimage/pine.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: plog/branches/plog-1.0.2/imgs/authimage/rain.gif
===================================================================
(Binary files differ)


Property changes on: plog/branches/plog-1.0.2/imgs/authimage/rain.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: plog/branches/plog-1.0.2/imgs/authimage/sky.gif
===================================================================
(Binary files differ)


Property changes on: plog/branches/plog-1.0.2/imgs/authimage/sky.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: plog/branches/plog-1.0.2/imgs/authimage/transparent.gif
===================================================================
(Binary files differ)


Property changes on: plog/branches/plog-1.0.2/imgs/authimage/transparent.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: plog/branches/plog-1.0.2/templates/summary/registerstep1.template
===================================================================
--- plog/branches/plog-1.0.2/templates/summary/registerstep1.template	2005-07-25 11:31:02 UTC (rev 2360)
+++ plog/branches/plog-1.0.2/templates/summary/registerstep1.template	2005-07-25 13:22:19 UTC (rev 2361)
@@ -33,9 +33,19 @@
             <label for="userPasswordCheck">{$locale->tr("email")}</label>
 			<span class="required">*</span>
 			<div class="formHelp">{$locale->tr("email_help")}</div>
-            <input type="text" name="userEmail" id="userEmail" value="{$userEmail}"/>
+            <input type="text" name="userEmail" id="userEmail" value="{$userEmail}" />
             {include file="summary/validate.template" field=userEmail message=$locale->tr("error_incorrect_email_address")}
         </div>
+        {if $useCaptchaAuth}
+        <div class="field">
+            <label for="userAuth">{$locale->tr("auth_img")}</label>
+            <span class="required">*</span>
+            <div class="formHelp">{$locale->tr("auth_img_help")}</div>
+            <img src="{$userAuthImgPath}" alt="CAPTCHA" />
+            <input type="text" name="userAuth" id="userAuth" value="" />
+            {include file="summary/validate.template" field=userAuth message=$locale->tr("error_incorrect_auth_img")}
+        </div>
+        {/if}
     </fieldset>
     <div class="buttons">
       <input type="submit"  value="{$locale->tr("register_next")} &raquo;" name="Register"/>




More information about the pLog-svn mailing list