cakephp check password with profile update - cakephp

I am newbie to cake php and I have a problem.
When a user updates his profile iam asking to enter his password.Now I dont know how to check it with the stored password.
<?php echo $form->create('UserProfile', array('url' => array('action' => 'edit_profile', 'controller' => 'users'))); ?>
<?php
echo $form->input('nickname', array('label' => __('Display Name', true), 'class' => 'INPUT required'));
?>
<b>To save these settings, please enter your password</b><br /><br />
<?php
echo $form->input('repeat_password', array('label' => __('Password', true), 'class' => 'INPUT required','type'=>'password'));
echo $form->input('private', array('label' => __('Set Profile Private', true), 'class' => 'INPUT required'));
?>
<!-- <div id="CityList">
<?php
// echo $form->input('city', array('id' => 'citySelect', 'name' => 'data[UserProfile][city]', 'empty' => __('Please select city', true), 'label' => __('City', true), 'class' => 'INPUT required'));
?>
</div> -->
<?php echo $form->submit(__('Submit', true), array('class' => 'save_btn')) ?>`
>
In My model i have applied the following validation on repeat password.
'repeat_password' => array(
array('rule' => 'check_repeatPassword'),
array('rule' => 'notempty', 'message' => __('Required', true), 'require' => true),
array('rule' => 'alphaNumeric', 'allowEmpty' => true, 'message' => __('Password must only contain letters and numbers.', true)),
array('rule' => array('minLength', 6), 'allowEmpty' => true,
'message' => __('Password must be at least 6 characters long.', true)),
array('rule' => array('maxLength', 16), 'allowEmpty' => true,
'message' => __('Password must be at most 16 characters long.', true))
),
function check_repeatPassword($data) {
$repeatPassword = $data['repeat_passowrd'];
$passwordExists = $this->find('count', array('conditions' => array('User.repeat_password' => $repeatPassword)));
if ($passwordExists == 0) {
return false;
}
return true;
}
In My Controller I have made the following edit profile method.
function edit_profile() {
$this->loadModel('UserProfile');
$user = $this->_authenticate_user();
$id = $user['account_num'];
if (!empty($this->data)) {
$this->data['UserProfile']['account_name'] = $id;
unset($this->data['UserProfile']['country']);
unset($this->data['UserProfile']['city']);
if ($this->UserProfile->save($this->data)) {
$userInfo = $this->User->getUserInfo($id);
$this->User->reassign_session($userInfo);
$this->flashMessage(__('Your Profile has been Updated successfully', true), 'Sucmessage');
//$this->redirect(array('action' => 'profile'));
} else {
$this->flashMessage(__('Your Profile has not been updated. Please, try again.', true));
}
}
if (empty($this->data)) {
$this->data = $this->UserProfile->read(null, $id);
}
// $this->loadModel('Country');
// $countries = $this->Country->find('list');
// $this->set('countries', $countries);
$this->loadModel('Nationality');
$nationalities = $this->Nationality->find('list', array('fields' => array('name', 'name')));
$this->set('nationalities', $nationalities);
$this->pageTitle = __('Edit My Profile', true);
}
Kindly help me how to do this.Thankssssss in advance

You are not storing passwords in plain text
I cannot avoid seeing this and being amazed:
$passwordExists = $this->find('count', array(
'conditions' => array(
'User.repeat_password' => $repeatPassword
)
));
Please, please confirm that you aren't storing user passwords in plain text, and if you are stop doing so immediately and execute the following sql:
ALTER TABLE users DROP repeat_password;
Compare a hash with a hash
In the db, you should have the user's existing password stored as a one-way-hash. Assuming that's the case, to verify that the user entered their existing account password - just hash what they provided in the same way the Auth component does, and compare to the db:
function check_repeatPassword($data) {
$userId = $this->data['UserProfile']['account_name']; // from the question
$userInput = current($data);
$hashedUserInput = Security::hash($userInput, null, true);
return $this->find('count', array(
'conditions' => array(
'password' => $hashedUserInput,
'id' => $userId
)
));
}
This will confirm that the password the user entered, is the same as the one already in the db for that user.

Related

how can i make two form input are related cakephp

I would like to make this in my add.ctp.
when user choose the department, on the file form field, only shows the file with the same department that they choose
in my add.ctp
<div class="form-group">
<?php echo $this->Form->input('department', array('class' => 'form-control', 'placeholder' => 'Department', 'options' => array(
'Administrator' => 'Administrator',
'Multimedia' => 'Multimedia',
'Treasurer' => 'Treasurer',
'Marketing' => 'Marketing',
),
'empty' => '(Choose Department)',));?>
</div>
<div class="form-group">
<?php echo $this->Form->input('fail_id', array('class' => 'form-control', 'label' => 'File','placeholder' => 'File Id', 'empty' => '(Choose File)'));?>
</div>
in my controller
public function add() {
if ($this->request->is('post')) {
$this->Borrow->create();
$this->request->data['Borrow']['user_id']= $this->Auth->user('id');
if ($this->Borrow->save($this->request->data)) {
$this->Session->setFlash(__('The borrow has been saved.'), 'default', array('class' => 'alert alert-success'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The borrow could not be saved. Please, try again.'), 'default', array('class' => 'alert alert-danger'));
}
}
$users = $this->Borrow->User->find('list');
$fails = $this->Borrow->Fail->find('list');
$fails = $this->Borrow->Fail->find('list');
$this->set(compact('users', 'fails', 'fails'));
}
thanks for the kindness help.
You have to use ajax post. after user select a department you should send an ajax post with the value of department and get the related files and update second combobox.

Update Pictures In cakePHP

I have an Up which has to do a lot with pictures. I have a problem. I know might seems stupid, and even i know that im missing something, but i havent found out yet. So in few words. Let's say I have an Item. |id|name|price|condition|location|picture|
picture is the picture path that i save to DB. So when i create a new Item all the field are required. Till here everything works Fine.Now lets say i open Item x to edit. I edit only the name and the price and other i leave them as they are, and i press save, browse button, of the picture field is still required and i have to open galerry find the pic again in order to save. So my question is this: How can i do a picture upload only if i browse for the picture, but not to forget that on creation must not be empty. To Ilustrate it here is some code:
<?php
App::uses('AppModel', 'Model');
class Item extends AppModel {
public $name = 'Item';
public $primaryKey = 'id';
public $displayField = 'title';
public $validate = array(
'id' => array(
'blank' => array(
'rule' => 'blank',
'on' => 'create',
),
),
'title' => array(
'words' => array(
'rule' => array('custom', '/[0-9A-Za-z\._-]/'),
'message' => 'The Item name can only contain letters, numbers and spaces.',
),
'maxLength' => array(
'rule' => array('maxLength', 100),
'message' => 'The Item name must not be longer than 100 characters.',
),
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'The Item name must not be empty.',
),
'isUnique' => array(
'rule' => 'isUnique',
'message' => 'This Item name already exists.',
),
),
'picture' => array(
'uploadError' => array(
'rule'=>'uploadError',
'message' => 'The File Did NOT Upload. Please Try Again!',
),
'fileSize'=>array(
'rule'=>array('fileSize','<=','30MB'),
'message'=>'File Size should be less then 30MB',
),
'processMediaUpload'=>array(
'rule' =>'processMediaUpload',
'message'=>'Uploading File Failed!',
),
),
'item_location_id' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'You Must Choose a Location',
),
'numeric' => array(
'rule' => array('numeric'),
//'message' => 'Your custom message here',
),
),
'address' => array(
'words' => array(
'rule' => array('custom', '/[0-9A-Za-z\._-]/'),
'message' => 'The Item Address can only contain letters, numbers and spaces.',
),
'maxLength' => array(
'rule' => array('maxLength', 150),
'message' => 'Address can not be longer then 150 characters long',
),
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'You Should Put an Address',
),
),
);
public $belongsTo = array(
'ItemLocation' => array(
'className' => 'ItemLocation',
'foreignKey' => 'item_location_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
);
public function processMediaUpload($mediacheck = array()) {
$dir = 'img/uploads/item/media/';
if (isset($mediacheck['media_path']['name'])) {
if(is_uploaded_file($mediacheck['media_path']['tmp_name'])) {
if (trim($mediacheck['media_path']['name'])!=""){
// here we delete if the image exist and replace it.
if (file_exists(WWW_ROOT . $dir . $mediacheck['media_path']['name'])) {
unlink(WWW_ROOT . $dir . $mediacheck['media_path']['name']);
return true;
}
}
$allowedExts = array('jpeg', 'png', 'jpg', 'gif');
$extension=strtolower(end(explode(".", $mediacheck['media_path']['name'])));
if (($mediacheck['media_path']['size'] < 55000000)) {
if(in_array($extension, $allowedExts)){
if ($mediacheck['media_path']["error"] > 0) {
$this->invalidate('media_path', $mediacheck['media_path']['error']);
return false;
} else {
if (file_exists( WWW_ROOT . $dir) && is_dir( WWW_ROOT . $dir)) {
if (file_exists( WWW_ROOT . $dir . $mediacheck['media_path']['name'])) {
$this->invalidate('media_path', 'File Allredy Exists!');
return false;
} else {
move_uploaded_file($mediacheck['media_path']['tmp_name'], WWW_ROOT . $dir . mktime() . $mediacheck['media_path']['name']);
$this->data[$this->alias]['media_path'] = mktime() . $mediacheck['media_path']['name'];
return TRUE;
}
} else { // in this case the directory doesent exist so we create it
mkdir($dir, 0777, true);
move_uploaded_file($mediacheck['media_path']['tmp_name'], WWW_ROOT . $dir . mktime() . $mediacheck['media_path']['name']);
$this->data[$this->alias]['media_path'] = mktime() . $mediacheck['media_path']['name'];
return TRUE;
}
}
}else { $this->invalidate('media_path', 'Invalid File Format! '); return false;}
} else { $this->invalidate('media_path', 'File size is To big!'); return false; }
} else { $this->invalidate('media_path', 'You must upload a file before you Submit!'); return false; }
} else { $this->invalidate('media_path', 'You must upload a file before you Submit!'); return false; }
// better safe then sorry!
return false;
}
Add Form:
<div class="items form">
<?php echo $this->Form->create('Item', array('type'=>'file')); ?>
<fieldset>
<legend><?php echo __('Add New Item'); ?></legend>
<?php
echo $this->Form->input('id');
echo $this->Form->input('title');
echo $this->Form->input('item_description');
echo $this->Form->input('location_description');
echo $this->Form->input('media_path', array('label'=>'Media','type'=>'file'));
echo $this->Form->input('item_location_id', array('label'=>'Location'));
echo $this->Form->input('item_characteristic_id', array('label'=>'Characteristics'));
echo $this->Form->input('address', array('id' => 'address'));
echo "<div id=\"map_canvas\" style=\"width:98%; height:400px;\"> </div>";
echo $this->Form->input('longitude', array('id'=>'longitude', 'readonly'=>'readonly'));
echo $this->Form->input('latitude', array('id'=>'latitude', 'readonly'=>'readonly'));
echo $this->Form->input('first_seller_id');
echo $this->Form->input('second_seller_id');
echo $this->Form->input('brochure_path', array('label'=>'Broshure','type'=>'file'));
echo $this->Form->input('seo_title');
echo $this->Form->input('seo_description' , array('label' => 'SEO Description'));
echo $this->Form->input('seo_url' , array('label' => 'SEO Url'));
echo $this->Form->input('seo_keywords' , array('label' => 'SEO Keywords'));
?>
</fieldset>
Edit Form:
<div class="items form">
<?php echo $this->Form->create('Item', array('type'=>'file')); ?>
<fieldset>
<legend><?php echo __('Edit Item'); ?></legend>
<?php
$dir = "/img/uploads/item/media/";
echo $this->Form->input('id');
echo $this->Form->input('title');
echo $this->Form->input('item_description');
echo $this->Form->input('location_description');
echo $this->Form->input('media_path', array('label'=>'Media','type'=>'file'));
echo $this->Form->input('hiddenimage', array('type'=>'hidden','value'=> $this->Form->value('media_path') ));
$Image = $this->Form->value( 'media_path');
if(empty($Image) || $Image==NULL)
{$Image = "/img/uploads/noimg.jpg";}
else {$Image = $dir . $Image; }
echo $this->Html->image($Image,array('align'=>'absbottom','style'=>'max-height:100px'));
echo "<h3> Test: ". $this->Form->value('media_path') . "</h3>";
echo $this->Form->input('item_location_id', array('label'=>'Location'));
echo $this->Form->input('item_characteristic_id', array('label'=>'Characteristics'));
echo $this->Form->input('address', array('id' => 'address'));
echo "<div id=\"map_canvas\" style=\"width:98%; height:400px;\"> </div>";
echo $this->Form->input('longitude', array('id'=>'longitude', 'readonly'=>'readonly'));
echo $this->Form->input('latitude', array('id'=>'latitude', 'readonly'=>'readonly'));
echo $this->Form->input('first_seller_id');
echo $this->Form->input('second_seller_id');
echo $this->Form->input('brochure_path', array('label'=>'Broshure','type'=>'file'));
echo $this->Form->input('seo_title');
echo $this->Form->input('seo_description' , array('label' => 'SEO Description'));
echo $this->Form->input('seo_url' , array('label' => 'SEO Url'));
echo $this->Form->input('seo_keywords' , array('label' => 'SEO Keywords'));
?>
</fieldset>
Look at adding the on parameter to your rules.
'on' => 'create'
Will only trigger the validation on an insert (i.e. a new record).
If a rule has defined ‘on’ => ‘create’, the rule will only be enforced
during the creation of a new record. Likewise, if it is defined as
‘on’ => ‘update’, it will only be enforced during the updating of a
record.
In your edit action could you not just check the field and remove it if it's empty? Is that what you mean? Like:
if (empty($this->request->data['Item']['media_path'])) {
unset($this->request->data['Item']['media_path']);
}
It would probably be more complicated than that, checking to see if it's valid upload I guess, but would something like that work?

cakephp setting user_id to current user

I am working in CakePHP 2.x
Currently in my app the user can select to add something as any user. I want to force them to have thier own id as the "user_id". User_id is a foreign key and i am using ACL, Auth. I have tried to set the data in the controller by using $this->Data => $this->auth->user('id); but it doesn't seam to set the value.
Cakephp Add View:
<?php echo $this->Form->create('Asset'); ?>
<fieldset>
<legend><?php echo __('Add Asset'); ?></legend>
<?php
echo $this->Form->input('asset_name');
echo $this->Form->input('description');
echo $this->Form->input('vaule');
echo $this->Form->input('date_bought');
echo $this->Form->input('date_freehold');
echo $this->Form->input('user_id');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
cake php controller:
public function add() {
if ($this->request->is('post')) {
$this->Asset->create();
if ($this->Asset->save($this->request->data)) {
$this->data['Assets']['user_id'] = $this->Auth->user('id');
$this->Session->setFlash(__('The asset has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The asset could not be saved. Please, try again.'));
}
}
$users = $this->Asset->User->find('list');
$this->set(compact('users'));
}
Cake Php Model:
class Asset extends AppModel {
/**
* Validation rules
*
* #var array
*/
public $validate = array(
'asset_name' => array(
'notempty' => array(
'rule' => array('notempty'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'date_bought' => array(
'date' => array(
'rule' => array('date'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'user_id' => array(
'numeric' => array(
'rule' => array('numeric'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
/**
* belongsTo associations
*
* #var array
*/
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
}
Not 100% sure how or where to do this, any help would be hugely apcreciated thanks guys.
Here's how I do it, thought it might be worth posting as it's a little less code;
// in AppController
function beforeFilter() {
// setup auth here
...
$this->set('authUser', $this->Auth->user());
...
}
// in Add view's form
...
echo $this->Form->hidden('user_id', array('value'=>$authUser['id']));
...

cakephp login page doesn't go anywhere

I have tried to set up a login page, but when I try to log in, even with a wrong username/password, cake redirects to the login page (the logout function redirects correctly). Even if I plug in the wrong info, I get no error flashes at all, I don't get it. Here is my controller code:
class UsersController extends AppController {
public $name='Users';
public $layout='pagelayout';
public $uses=array('User');
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('add', 'logout', 'overview');
}
public function login() {
$this->set('title', 'Log in to your Gulf Shores 4 Less account');
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash(__('Username or password is incorrect'), 'default', array(), 'auth');
}
}
}
and here is my model:
<?php
App::uses('AuthComponent', 'Controller/Component');
class User extends AppModel {
public $name='User';
public $hasMany=array('Unit', 'Complex', 'Coupon', 'Location', 'Image', 'Charter', 'Course', 'Nightclub', 'Store');
public function beforeSave() {
if (isset($this->data[$this->alias]['password'])) {
$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
}
return true;
}
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A username is required'
)
),
'password' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'A password is required'
)
),
'role' => array(
'valid' => array(
'rule' => array('inList', array('admin', 'advertiser')),
'message' => 'Please enter a valid role',
'allowEmpty' => false
)
)
);
}
?>
Here is the code from AppController:
<?php
class AppController extends Controller {
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'users', 'action' => 'overview'),
'logoutRedirect' => array('controller' => 'pages', 'action' => 'index')
)
);
function beforeFilter() {
$this->Auth->allow('login','index', 'view', 'condos', 'houses', 'hotels_and_motels', 'print_all_coupons', 'print_coupon', 'search', 'golf', 'charters', 'events', 'nightlife', 'shopping', 'visitors_info', 'contact_us');
}
}
?>
and here is the view code:
<div class="users form">
<?php echo $this->Session->flash('auth'); ?>
<?php echo $this->Form->create('User');?>
<fieldset>
<legend><?php echo __('Please enter your username and password'); ?></legend>
<?php
echo $this->Form->input('username');
echo $this->Form->input('password');
?>
</fieldset>
<?php echo $this->Form->end(__('Login'));?>
</div>
As you can see, I pretty much copy and pasted what was in the Cakephp-2.0 manual for this. The only difference between my db table and the manual's is that my password is stored as an MD5 hash in my users table. i can't figure out where this has derailed.
Make sure that your passwords are stored using the Auth component hash. AFAIK, there is no support for 'plain' md5 passwords. The hashes Cake generates are more complex than md5.
See the documentation for info on how to hash your passwords. If you are migrating from an app that used md5 hashing, you'll have to reset all the passwords to something random for all your users.
You can try to use the following codes on your AppController.php file
AppController.php
$this->Auth->authenticate = array(
AuthComponent::ALL => array('userModel' => 'User'),
'Form' => array(
'fields' => array('username' => 'email')
)
);
$this->Auth->authorize =false;
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->fields = array('username' => 'email', 'password' => 'password');
$this->Auth->loginRedirect = array('controller' => 'media', 'action' => 'index/');
$this->Auth->logoutRedirect = '/logout';
$this->Auth->loginError = 'Invalid e-mail / password combination. Please try again';

Checking password length problem for registration in CakePHP

I'm trying to write a base user registration page and my problem is on checking password length string. I've read of various problem and solutions on that but I still in troubles.
This is what I've wrote:
class UsersController extends AppController {
function register () {
if (!empty ($this->data)) {
if ($this->data['User']['password'] == $this->Auth->password($this->data['User']['password_confirm'])) {
if ($this->User->save($this->data)) {
$this->Session->setFlash('All ok');
$this->redirect(array('action', 'login'));
}
} else {
$this->Session->setFlash('Password mismatch');
$this->redirect(array('action', 'register'));
}
}
}
}
Then the user model:
var $validate = array (
'username' => array (
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'required' => true,
'message' => 'Alphanumeric chars only'
),
'between' => array(
'rule' => array('between', 1, 24),
'message' => 'Username between 1 and 24 chars'
)
),
'password' => array (
'between' => array(
'rule' => array('between', 7, 25),
'message' => 'Password between 8 and 24 chars'
)
)
);
File register.ctp
<?php
echo $this->Form->create('User');
echo $this->Form->input('username');
echo $this->Form->input('password');
echo $this->Form->input('password_confirm', array('type' => 'password'));
echo $this->Form->end('Register account');
?>
The password and password_confirm checking works perfect, if I write different passwords I get the error, if the password are equal, I get a password length error, where I'm wrong?
log:
2011-03-29 23:20:41 Error: Array
(
[User] => Array
(
[username] => tonino
[password] => ae4f47749b697085b2f7322383fa7b14c79e06f6
[password_confirm] => passwordtest
)
)
I've forgot to say my password is SHA1 hashed, so how I can check if an user write a too long password?
Passwords are hashed automatically by the AuthComponent. All the validation you're doing is done on the password "ae4f47749b697085b2f7322383fa7b14c79e06f6", not "passwordtest", which is why it fails validation. You need to do the validation on the password_confirm field, not the password field.
See here for an example of a somewhat transparent solution.

Resources