DBMarcos99
DBMarcos99

Reputation: 465

Allow user to change password Cakephp 2

I've looked over various approaches, and various questions published on this subject, but with no luck. In my case, the controller code "appears" to work, and the message flashes up "Your changes have been saved", but the password database field is unchanged. Is there something I am missing?

Controller code

public function changepass($id = null) {
    $this->layout = 'profile_page';
    //$this->request->data['User']['id'] = $this->Session->read('Auth.User.id');

    $user = $this->User->find('first', array( 
        'conditions' => array('User.id' => $this->Auth->user('id'))
    ));     // 'User.id' => $id
    $this->set('user',$user);


    if ($this->request->is('post') || $this->request->is('put'))
    {   
        $this->User->saveField('password', AuthComponent::password($this->request->data['User']['newpass']));
        // $this->User->saveField('password', $this->data['User']['password']);
        // $this->data['User']['password']= $this->request->data['User']['newpass'];

        if ($this->User->save($this->request->data))
        {   
            $this->Session->setFlash(__('Your password has been changed!'));
            $this->redirect(array('controller'=>'articles','action'=>'index'));
        }
        else
        {
            $this->Session->setFlash(__('Whoops! Something went wrong... try again?'));
            $this->redirect(array('controller'=>'users','action'=>'changepass'));
        }
    }
    $this->request->data = $this->User->read(null, $id);
    unset($this->request->data['User']['password']); // tried commenting out
}

Model

public function beforeSave($options = array()) {
    if (isset($this->data[$this->alias]['password'])) {
        $this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
        if (isset($this->data[$this->alias]['newpass'])) {
            $this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['newpass']);
        }
    }
    return true;
}

Of course later I'd put in existing password check, and confirm new password check, but i need to get the existing password update basic approach working.

Many thanks in advance for any light you can shed on this,

I think I've sussed this. First, major bloop on my part - in my view I'd put echo $this->Form->create('User', array('action' => 'edit')); -- of course change action to 'changepass'

New Controller code:

    public function changepass ($id = null) {
    $this->layout = 'profile_page';
    $this->User->id = $id;
    if (!$this->User->exists()) {
        throw new NotFoundException(__('Invalid user'));
    }
            //debug($this->request->data);

    if ($this->request->is('post') || $this->request->is('put')) {
        $this->data['User']['password']= $this->request->data['User']['newpass'];
        if ($this->User->save($this->request->data)) {
            $this->Session->setFlash(__('Your password changes have been saved'));
             $this->redirect(array('controller' => 'articles', 'action' => 'index'));
        } else {
            $this->Session->setFlash(__('The profile could not be saved. Please, try again.'));
         }
    } else {
                if ($this->Auth->user('id')!= $id) {
        $this->Session->setFlash('You are not allowed that operation!');
        $this->redirect(array('controller' => 'articles', 'action' => 'index'));
        }

        $this->request->data = $this->User->read(null, $id);  
        debug($this->request->data);
        unset($this->request->data['User']['password']);
    }
}

Model - tidied up as per advice from eboletaire

    public function beforeSave($options = array()) {
    if (isset($this->data[$this->alias]['password'])) {
        $this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']); 
    }
    if (isset($this->data[$this->alias]['newpass'])) {
        $this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['newpass']);
    }

return true;
}  

Upvotes: 1

Views: 4459

Answers (2)

Daniel
Daniel

Reputation: 445

if ($this->request->is('post') || $this->request->is('put')) {
    $this->data['User']['password']= $this->request->data['User']['newpass'];
    if ($this->User->save($this->request->data)) {

Should be

if ($this->request->is('post') || $this->request->is('put')) {
    $this->data['User']['id'] = $id;
    $this->data['User']['password']= $this->request->data['User']['newpass'];
    if ($this->User->save($this->data)) {

Watch out for $this->data vs $this->request->data.

Upvotes: 3

elboletaire
elboletaire

Reputation: 5367

First of all, you are saving the password twice. Remove/comment this line:

$this->User->saveField('password', AuthComponent::password($this->request->data['User']['newpass']));

Anyway, I think the problem is in your model. Check out your beforeSave method. Why are you setting password first with field password and then with field newpass???

PD. Cleaning up your code I've also seen that maybe the second if should be outside the first one.

Upvotes: 1

Related Questions