registration requires CAPTCHA
authorCalin-Andrei Burloiu <calin.burloiu@gmail.com>
Fri, 4 Nov 2011 16:48:13 +0000 (18:48 +0200)
committerCalin-Andrei Burloiu <calin.burloiu@gmail.com>
Fri, 4 Nov 2011 16:48:13 +0000 (18:48 +0200)
14 files changed:
application/config/captcha.php
application/config/form_validation.php
application/controllers/user.php
application/language/english/form_validation_lang.php
application/language/english/ui_lang.php
application/libraries/Captcha.php
application/views/user/profile_view.php
application/views/user/register_view.php
img/captcha/index.html [new file with mode: 0644]
img/index.html [new file with mode: 0644]
img/index.php [new file with mode: 0644]
js/index.html [new file with mode: 0644]
nbproject/netbeans_ci_code_completion.php
system/helpers/captcha_helper.php

index fe117d1..806d0dd 100644 (file)
@@ -1,6 +1,7 @@
 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 
 $config['captcha_params'] = array(
+       'expiration' => 900,
        'img_path' => './img/captcha/',
-       'img_url' => site_url('img/captcha/')
+       'img_url' => site_url('img/captcha/') . '/'
 );
\ No newline at end of file
index 042d5f7..67ed55c 100644 (file)
@@ -83,6 +83,11 @@ $config = array(
                        'field'=>'locality',
                        'label'=>'lang:user_locality',
                        'rules'=>'trim|ucwords|xss_clean|prep_for_form'
+               ),
+               array(
+                       'field'=>'captcha',
+                       'label'=>'lang:captcha',
+                       'rules'=>'callback__required_by_register|callback__check_captcha'
                )
        ),
        'activate'=> array(
index 810069d..fad3ddf 100644 (file)
@@ -26,7 +26,7 @@ class User extends CI_Controller {
        
        public function test($user_id = 1)
        {
-//             echo ($this->users_model->get_userdata('calin.burloiu') ? 'd' : 'n');
+               echo extension_loaded('gd') ? 'gd' : 'nu';
        }
        
        // DEBUG
@@ -45,6 +45,13 @@ class User extends CI_Controller {
                        
                $this->session->sess_destroy();
        }
+       
+       public function ajax_get_captcha()
+       {
+               $this->load->library('captcha');
+               $captcha = $this->captcha->get_captcha();
+               echo $captcha['image'];
+       }
 
        /**
        * Login a user and then redirect it to the last page which must be encoded
@@ -215,6 +222,7 @@ class User extends CI_Controller {
                if (! $b_validation)
                {
                        // Edit account data if logged in, otherwise register.
+                       // ** ACCOUNT
                        if ($user_id)
                        {
                                $userdata = $this->users_model->get_userdata(intval($user_id));
@@ -222,11 +230,18 @@ class User extends CI_Controller {
                                        $userdata['autogen_username'] =
                                                substr($userdata['username'], 8);
                                $selected_menu = 'account';
+                               $captcha = FALSE;
                        }
+                       // ** REGISTER
                        else
                        {
                                $userdata = FALSE;
                                $selected_menu = 'register';
+                               
+                               // CAPTCHA
+                               $this->load->library('captcha');
+                               $captcha = $this->captcha->get_captcha();
+                               $captcha = $captcha['image'];
                        }
                        
                        $params = array('title' =>
@@ -246,7 +261,7 @@ class User extends CI_Controller {
                        
                        $main_params['content'] = $this->load->view('user/register_view', 
                                array('userdata'=> $userdata, 'redirect'=> $redirect,
-                                       'error_upload'=> $error_upload),
+                                       'error_upload'=> $error_upload, 'captcha'=> $captcha),
                                TRUE);
                        $main_params['side'] = $this->load->view('side_default', NULL, TRUE);
                        $this->load->view('main', $main_params);
@@ -712,6 +727,13 @@ class User extends CI_Controller {
                return TRUE;
        }
        
+       public function _check_captcha($word)
+       {
+               $this->load->library('captcha');
+               
+               return $this->captcha->check_captcha($word);
+       }
+       
        public function _internal_account($username)
        {
                $userdata = $this->users_model->get_userdata($username, 'auth_src');
index 59d8352..b8b6d29 100644 (file)
@@ -12,6 +12,7 @@ $lang['_valid_date']                          = 'Invalid %s! Use the specified format or leave the fie
 $lang['_valid_old_password']           = 'Wrong %s.';
 $lang['_change_password_cond']         = 'If you want to change your password complete all three password related fields.';
 $lang['_required_by_register']         = 'The %s field is required.';
+$lang['_check_captcha']                                = 'The text entered does not match the text from the previous image. Try again with this image.';
 
 // Account Activation
 $lang['_valid_activation_code']                = 'Invalid activation code. You must provide 16 hexa characters.';
index bd290ad..4d6d3dc 100644 (file)
@@ -65,5 +65,9 @@ $lang['ui_msg_repeated_action_restriction'] = 'You can only perform this action
 
 $lang['ui_chars_left'] = 'characters left';
 
+$lang['ui_captcha'] = 'CAPTCHA';
+$lang['ui_captcha_instructions'] = 'Please insert the text from the image below in order to demonstrate that you are a human:';
+$lang['ui_change_captcha'] = 'Change CAPTCHA image';
+
 /* End of file ui_lang.php */
 /* Location: ./application/language/english/ui_lang.php */
\ No newline at end of file
index fc41471..6950a9c 100644 (file)
@@ -1,67 +1,95 @@
 <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 
 
+/**
+ * A library which simplifies the insertion and verification of CATCHAs.
+ * 
+ * @author Călin-Andrei Burloiu
+ * @category Library
+ */
 class Captcha {
        
        private $ci = NULL;
        private $db;
        private $params = NULL;
        
-       public function __construct()
+       public function __construct($params = NULL)
        {
                $this->ci =& get_instance();
                $this->ci->config->load('captcha');
                $this->ci->load->library('Singleton_db');
                $this->db = $this->ci->singleton_db->connect();
                
-               $this->params = $this->ci->config->item('captcha_params');
+               // Configuration parameters.
+               if (!$params)
+               {
+                       $this->params = $this->ci->config->item('captcha_params');
+               }
+               else
+                       $this->params = $params;
                
                if (!$this->params)
                        die('Cannot load CAPTCHA config file.');
        }
        
+       public function get_params()
+       {
+               return $this->params;
+       }
+
+       public function set_params($params)
+       {
+               $this->params = $params;
+       }
+
        /**
-        * Generates a CAPTCHA image and returns an HTML image tag for it.
+        * Generates a CAPTCHA image and returns an array of associative data
+        * about the image.
         * 
         * @param string $word
-        * @return string
+        * @return array
         */
-       public function get_captcha_tag($word = NULL)
+       public function get_captcha($word = NULL)
        {
-               $this->load->helper('captcha');
+               $this->ci->load->helper('captcha');
                
                if ($word)
-                       $this->params['word'] = $word;
+                       $this->params['captcha_params']['word'] = $word;
 
-               $cap = create_captcha($this->params);
+               // Creating the CAPTCHA.
+               $cap = create_captcha($this->params['captcha_params']);
 
                $data = array(
                        'captcha_time' => $cap['time'],
-                       'ip_address' => $this->input->ip_address(),
+                       'ip_address' => $this->ci->input->ip_address(),
                        'word' => $cap['word']
                        );
 
+               // Remember in DB the CAPTCHA - user mapping.
                $str_query = $this->db->insert_string('captcha', $data);
                $this->db->query($str_query);
 
-               return $cap['image'];
+               return $cap;
        }
        
        /**
         * Check againt the DB if the word(s) entered by the user ($word) matches
         * the CAPTCHA and if the CAPTCHA did not expired.
+        * 
+        * @param string $word
+        * @return boolean
         */
        public function check_captcha($word)
        {
                // First, delete old captchas
-               $expiration_limit = (!$this->params['expiration']
-                               ? 7200 : $this->params['expiration']);
+               $expiration_limit = (!$this->params['captcha_params']['expiration']
+                               ? 7200 : $this->params['captcha_params']['expiration']);
                $expiration = time() - $expiration_limit; // Two hour limit
                $this->db->query("DELETE FROM captcha WHERE captcha_time < ".$expiration);
                // TODO also delete the CAPTCHA image file
 
                // Then see if a captcha exists:
                $sql = "SELECT COUNT(*) AS count FROM captcha WHERE word = ? AND ip_address = ? AND captcha_time > ?";
-               $binds = array($word, $this->input->ip_address(), $expiration);
+               $binds = array($word, $this->ci->input->ip_address(), $expiration);
                $query = $this->db->query($sql, $binds);
                $row = $query->row();
 
index d831658..1382317 100644 (file)
                                <th><?php echo $this->lang->line('user_last_name'). ': ' ?></th>
                                <td><?php echo $userdata['last_name'] ?></td>
                        </tr>
+                       
+                       <tr>
+                               <th><?php echo $this->lang->line('user_sex'). ': ' ?></th>
+                               <td><?php
+                                       echo ($userdata['sex']
+                                                       ? $this->lang->line('user_sex_female')
+                                                       : $this->lang->line('user_sex_male') ) ?></td>
+                       </tr>
 
                        <tr>
                                <th><?php echo $this->lang->line('user_birth_date'). ': ' ?></th>
index e038dfc..aeb6dc5 100644 (file)
@@ -17,11 +17,6 @@ else
        echo form_open_multipart("user/account/$redirect");
 ?>
 
-<!--<?php if ($userdata): ?>
-<input type="hidden" name="user-id" value="<?php echo $userdata['id'] ?>" />
-<input type="hidden" name="username" value="<?php echo $userdata['username'] ?>" />
-<?php endif ?>-->
-
 <table class="form">
        <tr>
                <td></td>
@@ -44,7 +39,6 @@ else
                <th><?php echo $this->lang->line('user_username'). ' : ' ?></th>
                <td>
                        &nbsp;<em><?php echo $userdata['username'] ?></em>
-                       <!--<input type="hidden" name="username" value="<?php echo $userdata['username'] ?>" />-->
                </td>
          <?php endif ?>
        </tr>
@@ -201,6 +195,23 @@ else
        
        <tr><td></td><td>&nbsp;</td></tr>
        
+  <?php if (! $userdata): ?>
+       <tr>
+               <th><?php echo $this->lang->line('ui_captcha'). ' <span class="required">*</span> : ' ?></th>
+               <td>
+                       <div><?php echo $this->lang->line('ui_captcha_instructions') ?></div>
+                       <div><span id="container-captcha"><?php echo $captcha ?></span>
+                               <input type="button" id="button-change-captcha"
+                                          value="<?php echo $this->lang->line('ui_change_captcha') ?>" />
+                       </div>
+                       <p><input type="text" name="captcha" size="16" value="" /></p>
+               </td>
+       </tr>
+       <tr><td></td><td><?php echo form_error('captcha') ?></td></tr>
+       
+       <tr><td></td><td>&nbsp;</td></tr>
+  <?php endif ?>
+       
        <tr>
                <td></td>
                <td>
@@ -225,5 +236,11 @@ else
                        buttonImage: "<?php echo site_url('img/calendar.gif') ?>",
                        buttonImageOnly: true
                });
+               
+               $('#button-change-captcha')
+                       .click(function() {
+                               $('#container-captcha')
+                                       .load('<?php echo site_url('user/ajax_get_captcha') ?>');
+                       });
        });
 </script>
\ No newline at end of file
diff --git a/img/captcha/index.html b/img/captcha/index.html
new file mode 100644 (file)
index 0000000..c942a79
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+<head>
+       <title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/img/index.html b/img/index.html
new file mode 100644 (file)
index 0000000..c942a79
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+<head>
+       <title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/img/index.php b/img/index.php
new file mode 100644 (file)
index 0000000..6e67c2d
--- /dev/null
@@ -0,0 +1,204 @@
+<?php
+
+/*
+ *---------------------------------------------------------------
+ * APPLICATION ENVIRONMENT
+ *---------------------------------------------------------------
+ *
+ * You can load different configurations depending on your
+ * current environment. Setting the environment also influences
+ * things like logging and error reporting.
+ *
+ * This can be set to anything, but default usage is:
+ *
+ *     development
+ *     testing
+ *     production
+ *
+ * NOTE: If you change these, also change the error_reporting() code below
+ *
+ */
+       define('ENVIRONMENT', 'development');
+/*
+ *---------------------------------------------------------------
+ * ERROR REPORTING
+ *---------------------------------------------------------------
+ *
+ * Different environments will require different levels of error reporting.
+ * By default development will show errors but testing and live will hide them.
+ */
+
+if (defined('ENVIRONMENT'))
+{
+       switch (ENVIRONMENT)
+       {
+               case 'development':
+                       error_reporting(E_ALL);
+               break;
+       
+               case 'testing':
+               case 'production':
+                       error_reporting(0);
+               break;
+
+               default:
+                       exit('The application environment is not set correctly.');
+       }
+}
+
+/*
+ *---------------------------------------------------------------
+ * SYSTEM FOLDER NAME
+ *---------------------------------------------------------------
+ *
+ * This variable must contain the name of your "system" folder.
+ * Include the path if the folder is not in the same  directory
+ * as this file.
+ *
+ */
+       $system_path = 'system';
+
+/*
+ *---------------------------------------------------------------
+ * APPLICATION FOLDER NAME
+ *---------------------------------------------------------------
+ *
+ * If you want this front controller to use a different "application"
+ * folder then the default one you can set its name here. The folder
+ * can also be renamed or relocated anywhere on your server.  If
+ * you do, use a full server path. For more info please see the user guide:
+ * http://codeigniter.com/user_guide/general/managing_apps.html
+ *
+ * NO TRAILING SLASH!
+ *
+ */
+       $application_folder = 'application';
+
+/*
+ * --------------------------------------------------------------------
+ * DEFAULT CONTROLLER
+ * --------------------------------------------------------------------
+ *
+ * Normally you will set your default controller in the routes.php file.
+ * You can, however, force a custom routing by hard-coding a
+ * specific controller class/function here.  For most applications, you
+ * WILL NOT set your routing here, but it's an option for those
+ * special instances where you might want to override the standard
+ * routing in a specific front controller that shares a common CI installation.
+ *
+ * IMPORTANT:  If you set the routing here, NO OTHER controller will be
+ * callable. In essence, this preference limits your application to ONE
+ * specific controller.  Leave the function name blank if you need
+ * to call functions dynamically via the URI.
+ *
+ * Un-comment the $routing array below to use this feature
+ *
+ */
+       // The directory name, relative to the "controllers" folder.  Leave blank
+       // if your controller is not in a sub-folder within the "controllers" folder
+       // $routing['directory'] = '';
+
+       // The controller class file name.  Example:  Mycontroller.php
+       // $routing['controller'] = '';
+
+       // The controller function you wish to be called.
+       // $routing['function'] = '';
+
+
+/*
+ * -------------------------------------------------------------------
+ *  CUSTOM CONFIG VALUES
+ * -------------------------------------------------------------------
+ *
+ * The $assign_to_config array below will be passed dynamically to the
+ * config class when initialized. This allows you to set custom config
+ * items or override any default config values found in the config.php file.
+ * This can be handy as it permits you to share one application between
+ * multiple front controller files, with each file containing different
+ * config values.
+ *
+ * Un-comment the $assign_to_config array below to use this feature
+ *
+ */
+       // $assign_to_config['name_of_config_item'] = 'value of config item';
+
+
+
+// --------------------------------------------------------------------
+// END OF USER CONFIGURABLE SETTINGS.  DO NOT EDIT BELOW THIS LINE
+// --------------------------------------------------------------------
+
+/*
+ * ---------------------------------------------------------------
+ *  Resolve the system path for increased reliability
+ * ---------------------------------------------------------------
+ */
+
+       // Set the current directory correctly for CLI requests
+       if (defined('STDIN'))
+       {
+               chdir(dirname(__FILE__));
+       }
+
+       if (realpath($system_path) !== FALSE)
+       {
+               $system_path = realpath($system_path).'/';
+       }
+
+       // ensure there's a trailing slash
+       $system_path = rtrim($system_path, '/').'/';
+
+       // Is the system path correct?
+       if ( ! is_dir($system_path))
+       {
+               exit("Your system folder path does not appear to be set correctly. Please open the following file and correct this: ".pathinfo(__FILE__, PATHINFO_BASENAME));
+       }
+
+/*
+ * -------------------------------------------------------------------
+ *  Now that we know the path, set the main path constants
+ * -------------------------------------------------------------------
+ */
+       // The name of THIS file
+       define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME));
+
+       // The PHP file extension
+       define('EXT', '.php');
+
+       // Path to the system folder
+       define('BASEPATH', str_replace("\\", "/", $system_path));
+
+       // Path to the front controller (this file)
+       define('FCPATH', str_replace(SELF, '', __FILE__));
+
+       // Name of the "system folder"
+       define('SYSDIR', trim(strrchr(trim(BASEPATH, '/'), '/'), '/'));
+
+
+       // The path to the "application" folder
+       if (is_dir($application_folder))
+       {
+               define('APPPATH', $application_folder.'/');
+       }
+       else
+       {
+               if ( ! is_dir(BASEPATH.$application_folder.'/'))
+               {
+                       exit("Your application folder path does not appear to be set correctly. Please open the following file and correct this: ".SELF);
+               }
+
+               define('APPPATH', BASEPATH.$application_folder.'/');
+       }
+
+/*
+ * --------------------------------------------------------------------
+ * LOAD THE BOOTSTRAP FILE
+ * --------------------------------------------------------------------
+ *
+ * And away we go...
+ *
+ */
+require_once BASEPATH.'core/CodeIgniter'.EXT;
+
+/* End of file index.php */
+/* Location: ./index.php */
\ No newline at end of file
diff --git a/js/index.html b/js/index.html
new file mode 100644 (file)
index 0000000..c942a79
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+<head>
+       <title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>
\ No newline at end of file
index fbdf075..c667c58 100644 (file)
@@ -38,6 +38,7 @@
  * @property CI_Zip $zip
  * 
  * 
+ * @property Captcha $captcha
  * @property Html_head_params $html_head_params
  * @property Image $image
  * @property Openid $openid
@@ -89,6 +90,7 @@ class CI_Model
  * @property CI_Zip $zip
  * 
  * 
+ * @property Captcha $captcha
  * @property Html_head_params $html_head_params
  * @property Image $image
  * @property Openid $openid
index 19ec0c7..deacdb4 100644 (file)
@@ -77,7 +77,7 @@ if ( ! function_exists('create_captcha'))
                {
                        return FALSE;
                }
-
+               
                // -----------------------------------
                // Remove old images
                // -----------------------------------
@@ -235,7 +235,7 @@ if ( ! function_exists('create_captcha'))
                $img = "<img src=\"$img_url$img_name\" width=\"$img_width\" height=\"$img_height\" style=\"border:0;\" alt=\" \" />";
 
                ImageDestroy($im);
-
+               
                return array('word' => $word, 'time' => $now, 'image' => $img);
        }
 }