I have a sit developed in cakephp, and I have a page to edit user.
My user table has many field and one of this is password in md5.
The user can modify all its fields and password but if he leave blank this field I have t take from the database the old password and save it.
But return me error on save on the password field.
This is my action into the controller:
if ($this->request->is ('post')){
$this->User->id = $this->request->data['User']['id'];
if($this->request->data['User']['password'] == ''){
$user = $this->User->find('first',array('conditions'=>array('User.id' => $this->request->data['User']['id'])));
$this->request->data['User']['password'] = md5($user['User']['password']);
$this->request->data['User']['password_confirm'] = md5($user['User']['password']);
}
if ($this->User->save($this->request->data)) {
$this->redirect (array ('action'=>'index'));
}
else{
debug($this->User->validationErrors);
$this->Session->write('flash_element','error');
$this->Session->setFlash ('Errore di salvataggio dello user.');
}
}
And this is the method beforeSave into the UserModel:
public function beforeSave(){
if (isset($this->data['User']['password'])){
$this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
}
}
The problem is when I try to save return me error on the field password lie is inappropriate type.
If I print the field password before save I see something like: ***** but if I print the variable md5($user['User']['password']) return me the right value of password crypted.
Thanks
IMO, don't have the "password" field where the user edits his profile information.
You can have 2 forms on the page, where the second one is a change password form. This way, if the user changes their "first name" (which is in the first form) for example, your code does not have to check or do anything with their password.
After seeing many different frameworks, and creating systems myself, I can't say I recall anything where I have seen in the "wild" something handled like your doing. You are doing an extra step by getting their old password and "putting it back" just so you don't lose their password in the database when they want to change their profile details.
If its for security, you can make them "confirm" their password so it must match before changing the profile details.
Having the "password" box on the "edit profile" form is just bad code logic.
First comment, there is nothing wrong using md5 but I would use sha1.
Second, you can use only one form, not 2.
Then, in your controller you just need to check if user entered a new password, which you are already doing, if the field is empty then you unset that field, so cake won't update that field.
if ($this->request->is ('post')){
$this->User->id = $this->request->data['User']['id'];
if ($this->request->data['User']['password'] == '') {
unset($this->request->data['User']['password'], $this->request->data['User']['password_confirm']);
}
if ($this->User->save($this->request->data)) {
$this->redirect (array ('action'=>'index'));
}
else{
debug($this->User->validationErrors);
$this->Session->write('flash_element','error');
$this->Session->setFlash ('Errore di salvataggio dello user.');
}
}
By the way, I would change this
$this->User->id = $this->request->data['User']['id'];
For something like
$this->request->data['User']['id'] = $this->Session->read('Auth.id');
in order to prevent data tampering, but due I don't know if you are keeping the user id in a session I didn't write it in the example code
Related
I want to create an account activation where after registering, a link would be sent to an administrator (or one) email whereby the admin just has to click that link to activate that account.
I have the registration and login working. I'm using MySQL Workbench and have a "flag" or rather just a field in my accounts table (named user_login) to tell whether the account is enabled or disabled, which is disabled by default after registration.
I am stuck and sending a link through email, I'm not sure where to begin. That link that I want to send would contain a random string and would be sent to the admin, say abc/123/random?stringis=1234. Then the admin would just have to open his email and click on the string and then that specific user's account would be activated. I found this and this but that's just for how to send a link through email.
I don't have an idea on the logic. Do I create a function whereby the link would go directly to the function and from there, it would change the value in my table to enabled or whatever I call it so that the user's account is counted as activated? Do I need to create a new field to match the random generated string then?
Main idea is I'm trying to do like those typical sites whereby a link would be sent to the user to activate the account once he/she clicks it in the email, but this time just to a specific email which is the admin's.
EDIT:
In controller
public function activate_user($activation_code)
{
$result = $this->home_model->activate($activation_code);
if($result != FALSE)
{
echo "You have activated :".$result[0]->user_id.".";
}
else
{
echo "Activation failed, something went wrong.";
}
}
In Model:
public function activate($activation_link)
{
$this->db->select('*');
$this->db->from('user_login');
$this->db->where('activation_link', $activation_link);
$query = $this->db->get();
if($query->num_rows() == 1)
{
return $query->result();
}
else
{
return FALSE;
}
}
First
Database
add two column
activation_token{varchar|255}
activation_time{datetime}
After registration Success
add some randome has into activation_token(md5 or sha1(up to you))
add time if registration using Current timestamp(now())
Link
link should be
I strongly prefer userid in activation url
because it's remove the link duplication.
http://sitename.com/activation/{user_id}/{hash}
in controller
public function activation($user_id,$hash)
{
$timeOfexpiration = 3600;
$data = $this->model->get_data($id,$hash);
if(!$data)
{
return false
}
//if user found
//check expiration of linke
//like
if($data['activation_time']+$timeOfexpiration < now())
{
return true;
}
else
{
return false;
}
}
for that you need to add one more field in table called activation_linkwhen user register in site then generate random string and store that in activation_link and send link to the user so once user back then check the link and activate that user.
I'm trying to make my first Moodle auth extension where I want to confirm and login users directly after signup.
I've changed the user_signup function in the "email" auth plugin like this:
\core\event\user_created::create_from_userid($user->id)->trigger();
$DB->set_field("user", "confirmed", 1, array("id"=>$user->id));
$user = get_complete_user_data('username', $username);
$DB->set_field("user", "firstaccess", time(), array("id"=>$user->id));
$DB->set_field("user", "lastlogin", 0, array("id"=>$user->id));
update_user_login_times($user);
complete_user_login($user);
redirect("$CFG->wwwroot/enrol/index.php?id=2");
It works so far as the user gets signed up and confirmed. But as for the login I get the following error:
core\session\manager::login_user() must be an instance of stdClass, boolean given
I might be acting stupid here, but I don't know how I could login the new user here. Any help would be very much apprechiated. Thanks!
After Creating user account get username and password that you have entered and then implement like this.
if ($user = authenticate_user_login($username, $password)) {
/// Let's get them all set up.
complete_user_login($user);
redirect($CFG->wwwroot . 'URL you want');
}
I have the following code:
MODEL:
function check_account($account_details){
$query = $this->db->get_where('admin', array('username' => $account_details['username'] ,
'password' => $account_details['password']) )->result_array();
if(!empty($query)){
return 'Admin';
}
else{
$query2 = $this->db->get_where('user_mst', array('username' => $account_details['username'],
'password' => $account_details['password']) )->result_array();
if(!empty($query2)){
return 'User';
}
else return FALSE;
}
}
I only posted my model because view only consist of input fields for username and password and in the controller it only retrieves the data inputted and passed on to the function in the model. The above code snippet is the function which was called by the controller.
I only have 1 log in page, it checks first if the account inputted exists in the admin table, if not, then checks if it exists in the user table. IF the account inputted does not belong to the 2 tables, it returns false.
I checked admin table first because accounts in the admin belongs to the minority. whereas in the user will be most of the majority accounts. For example, if i have 5 admin accounts and 1000 user accounts.
Instead of checking if the account inputted is one of those 1000 it firsts checks if it belongs to the 5 in the admin table.
Hope my explanation is clear or at least understandable.
My question is, when i input say, SampleAccount as username even though in the database its all in small caps it still returns as though its the same.
SampleAccount(inputted) = sampleaccount(database) - should not return in the query.
Also, i would like to read some professional's opinion on how im checking the account, or should i just make 2 login pages for both user and admins.
foreach($query as $arr => $result){
if($account_details['username'] == $result['username']){
echo ' equal';
}
else echo ' not equal';
}
If inputted is UseRname and in the database it is Username then this is ideal.
But is there anyway, to add this in the query itself?
get_where(); like limit, etc.
bro you had big mistake make 1 table but make coulmn name it role
check if 1 user 2 admin
function premission_check($role){
switch($role){
case 1 :
return 'user';
break;
case 2 :
return 'admin';
break;
default :
return 'bad role'
break;
}}
I can not update the value in the database. Here's the code:
if($user = User::model()->findByAttributes(array('username'=>$verification->username)))
{
// Generating 8 random symbols for new password
$new_password = substr(str_shuffle(str_repeat("0123456789abcdefghijklmnopqrstuvwxyz", 8)), 0, 8);
// Transfering password to MD5 hash with salt!
$new_password = md5('salt'.$new_password);
$user->password = $new_password;
if($user->save())
{...
The debugger shows that the value and get it replaced (password), but when you save
if($user->save())
{
Gives false and resets to the most recent line of code:
$this->render('forget');
Questions:
How to find out what happened and why did not update the value?
How to find the error (error code, ...)?
As your last comment, If you have no repeat_password field into your table, add it by hand in your model. (User model). (Actually there is no need to have this field in your table.)
public $repeat_password
Then, define rules for the field. (for example, required and so on...)
To get validation error you can do like below:
CVarDumper::dump($model->getErrors(),56789,true);
When a user enters his login information and hits submit, i want to check if the user already exists or not.
So, i have the following two questions
1. Which hook is needed to be implemented , for the case when user hits the submit button on the login form. I need the username entered by the user.
2. How to check if a user already exists in drupal or not programmatically ?
Some sample code would be really appreciated.
Please help.
Thank You.
Drupal 7 provides a function to get a user object by name :
$user = user_load_by_name($name);
if(!$user){
// User doesn't exist
}
else {
// User exists
}
http://api.drupal.org/api/drupal/modules%21user%21user.module/function/user_load_by_name/7
This can be done with hook_form_alter:
function module_(&$form, &$form_state, $form_id) {
$user_login_forms = array('user_login', 'user_login_block');
if (in_array($form_id, $user_login_forms)) {
$form['#validate'][] = 'my_validate_function';
}
}
function my_validate_function(&$form, &$form_state) {
$name = $form_state['values']['name'];
// Drupal 6:
if (!db_result(db_query("SELECT COUNT(*) FROM {users} WHERE name = '%s';", $name))) {
// User doesn't exist
}
// Drupal 7:
if (!db_query("SELECT COUNT(*) FROM {users} WHERE name = :name;", array(':name' => $name))->fetchField()) {
// User doesn't exist
}
}
It's better to query the DB directly in this case than than using user_load as it hooks into other modules as well.
In Drupal 7, substitute for this in the validation function:
if (!db_query("SELECT COUNT(*) FROM {users} WHERE name = :name", array(':name' => $name))->fetchField()) {
// User doesn't exist
}
I realize this is almost 2 years old, but user_authenticate does this nicely.
$existing_user = user_authenticate($name,$password);
if($existing_user)
// user exists
else
// user doesn't exist
Hope this helps someone else.
You can try to look on these 2 modules for inspiration: friendly_register and username_check.