Welcome Guest, Not a member yet? Register   Sign In
Form Validation Callback for Matching Password
#1

[eluser]RMinor[/eluser]
I am trying to validate a form that administrators will use to change their passwords. I am salting and using sha1() on the password when I store it in the database. When an administrator is changing their password I am checking that the password they enter as their old one is actually correct. For this I need to pass in their id and the entered password value. How do I do this using the form validation callback feature and multiple input parameters to it?

Controller
Code:
/**
  * Default method for this controller
  */
public function index()
{
  // Retrieve page information
  $data['page_info'] = $this->Global_model->pageInfo($this->_page);
  // Retrieve the administrator's id value from teh session
  $admin_id = $this->session->userdata('admin_id');
  // Load the form helper
  $this->load->helper('form');
  // Check if the submit button was pressed
  if ($this->input->post('submit')) {
   // Load the form validation library
   $this->load->library('form_validation');
   // Set form validation rules
   $this->form_validation->set_rules('old_password', 'Old Password', 'trim|required|callback_password_matches');
   $this->form_validation->set_rules('new_password', 'New Password', 'trim|required');
   $this->form_validation->set_rules('confirm_password', 'Confirm Password', 'trim|required|matches[new_password]');
   // Run form validation
   if($this->form_validation->run() == FALSE) {} else {
    // Retrieve the administrator's email address
    $email = $this->Administrator_model->getEmail($admin_id);
    // Assign input to variables
    $old_password = $this->input->post('old_password');
    $new_password = $this->input->post('new_password');
    // Attempt to change password
    if ($this->Administrator_model->changePassword($email, $old_password, $new_password)) {
     $data['success'] = TRUE;
    } else {
     $data['success'] = FALSE;
    }
   }
  }
  $this->load->view('employer/change-password_view', $data);
}

/**
  * Method to perform a password match during form validation
  * @param string $email
  * @param string $passowrd
  * @return boolean
  */
public function password_matches($id, $passowrd)
{
  if (!$this->User_model->passwordMatches($id, $password)) {
   $this->form_validation->set_message('password_matches', 'The password you entered does not match your old password.');
   return FALSE;
  } else {
   return TRUE;
  }
  
}

Model
Code:
/**
  * Method to determine if a password matches what is stored in the database
  * @param integer $id
  * @param string $password
  * @return boolean
  */
public function passwordMatches($id, $password)
{
  $query = $this->db->query("SELECT admin_salt
   FROM admin
   WHERE admin_id = ?", array($id));
  if ($query->num_rows() == 1) {
   $result = $query->row_array();
   $salt = $result['admin_salt'];
  }
  $hashed_password = sha1($salt . $password);
  $query = $this->db->query("SELECT admin_id
   FROM admin
   WHERE admin_id = ?
   AND admin_password = ?", array(
    $id,
    $hashed_password
   ));
  if ($query->num_rows() == 1) {
   return TRUE;
  }
  return FALSE;
}
#2

[eluser]CroNiX[/eluser]
Code:
$this->form_validation->set_rules('old_password', 'Old Password', "trim|required|callback_password_matches[$admin_id]");

The first value passed to your callback will always be the form field value, any additional values can be passed within brackets (see above) and will be received as the 2nd parameter of the callback.

Code:
public function password_matches($submitted_value, $admin_id)
{
  //load your admin by id, validate current password.
  if (password_wrong)
  {
    $this->form_validation->set_message('password_matches', 'The password you supplied does not match your existing password.');
    return FALSE;
  }

  //check to see if the new password matches the reentered new password...
  if ($submitted_value !== $this->input->post('confirmation_password'))
  {
    $this->form_validation->set_message('password_matches', 'The confirmation password does not match.');
    return FALSE;
  }

  //passed...
  return TRUE;
}
#3

[eluser]RMinor[/eluser]
Cool, I did not know that. Thanks for the help. Something like this should be in the user guide, unless I just missed it.
#4

[eluser]CroNiX[/eluser]
http://ellislab.com/codeigniter/user-gui...#callbacks
Quote:To invoke a callback just put the function name in a rule, with "callback_" as the rule prefix. If you need to receive an extra parameter in your callback function, just add it normally after the function name between square brackets, as in: "callback_foo[bar]", then it will be passed as the second argument of your callback function.




Theme © iAndrew 2016 - Forum software by © MyBB