Cameron
Cameron

Reputation: 28843

CakePHP Password reset not changing password

I have the following function in a CakePHP 1.3 app that takes a token and allows the user to change their password. Everything seems to work fine except that the password doesn't actually get changed :/ Any ideas what the problem is?

function admin_changepassword ( $token = null )
    {
        // If has a token or form has been submitted
        if (!empty($token) || !(empty($this->data)))
        {   
            $user = $this->User->find('first',array("MD5(User.email + '".Configure::read('Security.salt')."')"=>$token));

            if (empty($user))
            { 
                $this->redirect(array('admin'=>false,'controller'=>'pages','action'=>'display','home'));
                $this->Session->setFlash('Invalid token'); 
            }
            else
            {
                $this->set('user',$user);
                if (!empty($this->data['User']['password']))
                { 
                    $user['User']['password'] = $this->data['User']['password']; 
                    $this->User->save($this->data); 
                    $this->Session->setFlash('Your password has been changed! Please log in.'); 
                    $this->redirect(array('admin'=>true,'controller' => 'users', 'action' => 'login'));
                }   
            }
        }
        else
        {
            $this->redirect(array('admin'=>false,'controller'=>'home','action'=>'display','home'));
            $this->Session->setFlash('No token');
        }
    }

Upvotes: 0

Views: 1521

Answers (3)

rajankz
rajankz

Reputation: 664

This is an old thread, but it might help someone

function changePwd(){
     $this->User->id = $this->data->['User']['id']; //assuming this is set
     //check if the password fields are empty
     //check if the password fields match (password and confirm password one)

    //convert password 
    $this->request->data['User']['password'] = $this->Auth->password($this->data['User']['password'] );

    //saveField worked for me
    if($this->User->saveField('password',$this->request->data['User']['password'])){
        $this->Session->setFlash('Password changed successfully.','flashSuccess');
    }else{ ....
}

Upvotes: 0

Ross
Ross

Reputation: 17987

OK upon some testing, your problem is as I initially suggested in my comment.

You aren't setting the id of your user, so:

$this->User->save($this->data);

is not updating the password, it is adding a new row to your database.

You need to specify the ID of the user's to update.

$user = $this->User->find('first',array("MD5(User.email + 
                            '".Configure::read('Security.salt')."')"=>$token));

// this line is redundant 
$user['User']['password'] = $this->data['User']['password'];  


$this->User->id = $user['User']['id']; // set user id
$this->User->save($this->data);  //  save it

If you check your users table I suspect you will find there are lots of empty records with the "changed" password. My testing agrees with the cake manual.

Upvotes: 1

Ross
Ross

Reputation: 17987

Personally I'd do something like this; but I'm assuming your user is actually logged in, using the auth component or similar. Untested; but logic looks like it should work to me.

<?php
function admin_changepassword ($token = NULL) {
    // bail out early if there is no token set, and always set the flash before redirecting.
    if($token==NULL) {
        $this->Session->setFlash('No token');
        $this->redirect(array('admin'=>false,'controller'=>'home','action'=>'display','home'));
    }

    // this is an admin action; the user already be logged in right?
    $this->User->id = $this->Auth->user('id');
    $user_password = $this->User->field('password');

    // does the token match the hashed password, and did they enter a new password?
    if($token==md5($user_password . Configure::read('Security.salt')) && !empty($this->data['User']['password'])) {
        $this->User->saveField('password', $this->data['User']['password']);    
        $this->Session->setFlash('Your password has been changed! Please log in.'); 
        $this->redirect(array('admin'=>true,'controller' => 'users', 'action' => 'login'));
    }

    // somethings gone wrong/password was not updated
    $this->Session->setFlash('Your password was not changed.'); 
    $this->redirect(array('admin'=>false,'controller'=>'home','action'=>'display','home'));
}

Upvotes: 1

Related Questions