Reputation: 9691
I just ran into a problem while developing a login system. I build a class that handles login for multiple users. I also created an admin area for the admin user. He will be able to add new users, to change his password, delete users, etc.
For now I managed to make the add new user and change the password part. The problem I have now it's about the change password part.
I have a table with this structure :
TABLE user
id int(11) AUTO INCREMENT
admin int(11) DEFAULT 0
username varchar(256)
password varchar(256)
The admin from the table defines the type of user, 0 is for normal user and 1 for admin user who can do what I described in above.
I have the following function to change the userpassword :
public function changeUserPassword($cusrn,$oldPass,$newPass,$newPassConfirm) {
if(strlen($newPass) < 4) {
$error = true;
$message['error'] = true;
$message['message'] = "The Password is to short";
return json_encode($message);
}
elseif($newPass != $newPassConfirm) {
$error = true;
$message['error'] = true;
$message['message'] = "Confirmed Password doesn't match";
return json_encode($message);
}
elseif(!(ALLOW_SPECIAL_CHARACTERS == true) && preg_match('/[\'^£$%&*()}{@#~?><>,|=_+¬-]/', $newPass)) {
$error = true;
$message['error'] = true;
$message['message'] = "Special characters are not allowed";
return json_encode($message);
}
elseif(!(ALLOW_NUMBERS == true) && preg_match('#\d#',$newPass)) {
$error = true;
$message['error'] = true;
$message['message'] = "Numbers are not allowed";
return json_encode($message);
}
elseif(!isset($error)) {
$oldPass = hash_hmac('sha512',$oldPass,$this -> salt($cusrn,$oldPass));
$newPass = hash_hmac('sha512',$newPass,$this -> salt($cusrn,$newPass));
$sql = 'SELECT username,password FROM user WHERE username = ? AND password = ?';
if($stmt = $this->conn->prepare($sql)) {
$stmt->bind_param('ss',$cusrn,$newPass);
$stmt->execute();
$stmt->bind_result($usrn,$passw);
if($stmt->fetch()) {
if( $cusrn == $usrn ) {
if(!(strcmp($oldPass,$passw) == false)) {
$error = true;
$message['error'] = true;
$message['message'] = "The current Password is incorrect";
return json_encode($message);
}
elseif (!(strcmp($oldPass,$newPass) == false)) {
$stmt->close();
$sql = "UPDATE user SET password = ? WHERE username = '$usrn' LIMIT 1";
if($stmt = $this->conn->prepare($sql)) {
$stmt->bind_param('s',$newPass);
$stmt->execute();
$stmt->close();
$error = false;
$message['error'] = false;
$message['message'] = "Password successfuly changed";
return json_encode($message);
}
else {
$error = true;
$message['error'] = true;
$message['message'] = "Cannot connect to database for updating";
return json_encode($message);
}
}
else {
$error = true;
$message['error'] = true;
$message['message'] = "New Password must not match the old one";
return json_encode($message);
}
}
else {
$error = true;
$message['error'] = true;
$message['message'] = "The current Username is incorrect";
return json_encode($message);
}
}
else {
$error = true;
$message['error'] = true;
$message['message'] = "Cannot fetch data from the database";
return json_encode($message);
}
}
else {
$error = true;
$message['error'] = true;
$message['message'] = "Cannot prepare database connection";
return json_encode($message);
}
}
else {
$error = true;
$message['error'] = true;
$message['message'] = "Check the PHP syntax | Something went wrong";
return json_encode($message);
}
}
The problem I have is that if I try to input a certain username it either throws me this :
"Cannot fetch data from the database"
or it keeps telling me this :
"The current Username is incorrect"
even if the username is correct. Though it works for the last row it exists in the table, I mean it works for the username that is placed on the last row in the table.
I'm certain I'm doing something wrong and I'm asking you what could be that wrong thig I'm doing ?
Upvotes: 0
Views: 222
Reputation: 91734
Your code is hard to read, but one error I can see is where you select your user:
$sql = 'SELECT username,password FROM user WHERE username = ? AND password = ?';
if($stmt = $this->conn->prepare($sql)) {
$stmt->bind_param('ss',$cusrn,$newPass);
You are using the new password to select a user before you have changed it, so that will fail / you will not find a user.
By the way, if you want your admin to be able to change passwords of different users, you need to exclude the admin user from some of the password comparison functions.
For example (assuming you set your admin user in a session):
if(!(strcmp($oldPass,$passw) == false) || $_SESSION['admin_user']) {
Upvotes: 3