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.
Related
I have a simple registration form and complete model validation.
public function add() {
// Has any form data been POSTed?
if ($this->request->is('post')) {
$this->User->set($this->request->data); //echo '<pre>'; print_r($this->data);exit;
if($this->User->validates()){
if ($this->User->save($this->request->data)) {
// Set a session flash message and redirect.
$this->Session->setFlash('User Saved!');
return $this->redirect('/users');
}
}
}
}
Modal validation code is below
class User extends AppModel {
public $validate = array(
'username' => array(
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'required' => true,
'message' => 'Alphabets and numbers only'
),
'between' => array(
'rule' => array('between', 5, 15),
'message' => 'Between 5 to 15 characters'
)
),
'password' => array(
'rule' => array('minLength', '8'),
'message' => 'Minimum 8 characters long'
),
'email' => 'email',
'born' => array(
'rule' => 'date',
'message' => 'Enter a valid date',
'allowEmpty' => true
)
);
}
The problem is that when i delete html fields using firebug and submit form it save data with blank entries . i think its a big problem i am facing because it not good practice to save blank entry and i want to stop it by the hacker or any one.
please help.
Add the validation rule 'notEmpty' for all fields which shouldn't be blank entries in the database.
Reference: cookbook
I am agree with semmelbroesel13
please use notEmpty rules as:
'rule' => array('notempty')
Updated:
Please try below code and check whats the query exactly
public function add() {
// Has any form data been POSTed?
if ($this->request->is('post')) {
$this->User->set($this->request->data); //echo '<pre>'; print_r($this->data);exit;
if($this->User->validates()){
if ($this->User->save($this->request->data)) {
$log=$this->User->getDataSource()->getLog(false, false);
echo "<pre>";print_r($log);exit;
// Set a session flash message and redirect.
$this->Session->setFlash('User Saved!');
return $this->redirect('/users');
}
}
}
}
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?
I just need a bit of help with identifying the email of the user which is also the username in the database, I used the 'isUnique' in the model but for some reason it is not giving an error message and it still registers the user please can someone give me a bit of help here is the code...
MODEL
App::uses('AuthComponent','Controller/Component');
class User extends AppModel {
public $validate = array(
'email' => 'email',
'email' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Please enter a valid email address for username',
'unique' => array(
'rule' => 'isUnique',
'message' => 'Please enter another email, this one is already taken'
)
)
),
'password' => array(
'required'=> array(
'rule' => array('notEmpty'),
'message' => 'Please enter a valid password',
'rule' => array('minLength','8'),
'message' => 'Please enter minimum 8 characters'
)
)
);
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
}
return true;
}
}
**CONTROLLER**
<?php
class usersController extends AppController
{
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('add');
}
var $name = 'Users';
public function add()
{
if (!empty($this ->data))
{
$this->User->create();
if ($this->User->save($this->data))
{
$this->Session->setFlash('Thank you for registering');
$this->redirect(array('action'=>'index'));
}
else
{
// Make the password fields blank
unset($this->data['User']['password']);
unset($this->data['User']['confirm_password']);
$this->Session->setFlash('An error occurred, try again!');
}
}
}
function index()
{
}
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirectUrl());
}
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
public function logout() {
return $this->redirect($this->Auth->logout());
}
}
VIEW
<h2>End a problem registration</h2>
<p>Please fill out details to register</p>
<?php
echo $this->Form->Create('User',array('action' => 'add'));
echo $this->Form->input('title');
echo $this->Form->input('name');
echo $this->Form->input('surname');
echo $this->Form->input('email');
echo $this->Form->input('password');
echo $this->Form->input('password');
echo $this->Form->end('Register');
Your array declarations for your validation rules are wrong.
They have the wrong "level", thus making them invalid.
E.g. email key is used twice.
Please correct them according to the documentation - and using correct 1 tab indentation.
This will make them both correct and readable and easily prevents the mistake you made above.
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.
Can Cake Php Validation clear input field value
var $validate = array(
'name' => array(
'isUnique' => array (
'rule' => 'isUnique',
'message' => 'This Person name already exists.'
)
)
);
If error persist in validation, I want to clear name field value. Is it possible to do so with cake php validation itself ?
You can do it with a custom validation rule if you wanted.
var $validate = array(
'name' => array(
'isUnique' => array (
'rule' => 'ifNotUniqueClear', // use custom rule defined below
'message' => 'This Person name already exists.'
)
)
);
function ifNotUniqueClear(&$data) {
$field = key($data);
// see if the record exists
$user = $this->find('first', array(
'conditions' => array(
$field => $data[$field]
),
'recursive' => -1
));
if ($user) {
// unset or empty it, your choice
unset($this->data[$this->alias][$field]);
return false;
}
return true;
}