Skip to content

Commit

Permalink
Merge pull request #168 from devplanete/patch-6
Browse files Browse the repository at this point in the history
Update Login.php - PDO support
  • Loading branch information
panique committed Aug 20, 2013
2 parents e8b7c99 + fdf1f65 commit 5d53d24
Showing 1 changed file with 89 additions and 71 deletions.
160 changes: 89 additions & 71 deletions 2-advanced/classes/Login.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,16 @@ public function __construct()
private function databaseConnection()
{
// connection already opened
if ($this->db_connection != null)
if ($this->db_connection != null) {
return true;
else {
// create a database connection, using the constants from config/db.php (which we loaded in index.php)
$this->db_connection = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);

// if no connection errors (= working database connection)
if (!$this->db_connection->connect_errno) {
} else {
// create a database connection, using the constants from config/config.php
try {
$this->db_connection = new PDO('mysql:host='. DB_HOST .';dbname='. DB_NAME, DB_USER, DB_PASS);
return true;
// otherwise, database connection failed
} else {

// If an error is catched, database connection failed
} catch (PDOException $e) {
$this->errors[] = "Database connection problem.";
return false;
}
Expand All @@ -149,16 +148,15 @@ private function loginWithPostData()
// if database connection opened
if ($this->databaseConnection()) {

// escape the POST stuff
$this->user_name = $this->db_connection->real_escape_string($_POST['user_name']);
// database query, getting all the info of the selected user
$checklogin = $this->db_connection->query("SELECT user_id, user_name, user_email, user_password_hash, user_active FROM users WHERE user_name = '".$this->user_name."';");
$checklogin = $this->db_connection->prepare('SELECT user_id, user_name, user_email, user_password_hash, user_active FROM users WHERE user_name = :user_name');
$checklogin->bindValue(':user_name', trim($_POST['user_name']), PDO::PARAM_STR);
$checklogin->execute();
// get result row (as an object)
$result_row = $checklogin->fetchObject();

// if this user exists
if ($checklogin->num_rows == 1) {

// get result row (as an object)
$result_row = $checklogin->fetch_object();
if (isset($result_row->user_id)) {

// using PHP 5.5's password_verify() function to check if the provided passwords fits to the hash of that user's password
if (password_verify($_POST['user_password'], $result_row->user_password_hash)) {
Expand All @@ -173,6 +171,7 @@ private function loginWithPostData()

// declare user id, set the login status to true
$this->user_id = $result_row->user_id;
$this->user_name = $result_row->user_name;
$this->user_is_logged_in = true;

// OPTIONAL: recalculate the user's password hash
Expand All @@ -188,9 +187,12 @@ private function loginWithPostData()
$this->user_password_hash = password_hash($_POST['user_password'], PASSWORD_DEFAULT, array('cost' => HASH_COST_FACTOR));

// TODO: this should be put into another method !?
$this->db_connection->query("UPDATE users SET user_password_hash = '$this->user_password_hash' WHERE user_id = '$this->user_id';");
$query_update = $this->db_connection->prepare('UPDATE users SET user_password_hash = :user_password_hash WHERE user_id = :user_id');
$query_update->bindValue(':user_password_hash', $this->user_password_hash, PDO::PARAM_STR);
$query_update->bindValue(':user_id', $this->user_id, PDO::PARAM_INT);
$query_update->execute();

if ($this->db_connection->affected_rows == 0) {
if ($query_update->rowCount() == 0) {

// writing new hash was successful. you should now output this to the user ;)

Expand Down Expand Up @@ -274,23 +276,29 @@ public function editUserName()
if ($this->databaseConnection()) {

// escapin' this
$this->user_name = $this->db_connection->real_escape_string(htmlentities($_POST['user_name'], ENT_QUOTES));
$this->user_name = substr($this->user_name, 0, 64); // TODO: is this really necessary ?
$this->user_id = $this->db_connection->real_escape_string($_SESSION['user_id']); // TODO: is this really necessary ?
$this->user_name = substr(trim($_POST['user_name']), 0, 64);
$this->user_id = intval($_SESSION['user_id']);

// check if new username already exists
$query_check_user_name = $this->db_connection->query("SELECT * FROM users WHERE user_name = '".$this->user_name."';");
$query_check_user_name = $this->db_connection->prepare('SELECT user_id FROM users WHERE user_name = :user_name');
$query_check_user_name->bindValue(':user_name', $this->user_name, PDO::PARAM_STR);
$query_check_user_name->execute();
// get result row (as an object)
$result_row = $query_check_user_name->fetchObject();

if ($query_check_user_name->num_rows == 1) {
if (isset($result_row->user_id)) {

$this->errors[] = "Sorry, that username is already taken. Please choose another one.";

} else {

// write user's new data into database
$query_edit_user_name = $this->db_connection->query("UPDATE users SET user_name = '$this->user_name' WHERE user_id = '$this->user_id';");
$query_edit_user_name = $this->db_connection->prepare('UPDATE users SET user_name = :user_name WHERE user_id = :user_id');
$query_edit_user_name->bindValue(':user_name', $this->user_name, PDO::PARAM_STR);
$query_edit_user_name->bindValue(':user_id', $this->user_id, PDO::PARAM_INT);
$query_edit_user_name->execute();

if ($query_edit_user_name) {
if ($query_edit_user_name->rowCount()) {

$_SESSION['user_name'] = $this->user_name;
$this->messages[] = "Your username has been changed successfully. New username is " . $this->user_name . ".";
Expand Down Expand Up @@ -328,17 +336,18 @@ public function editUserEmail()
// if database connection opened
if ($this->databaseConnection()) {

// escapin' this
$this->user_email = $this->db_connection->real_escape_string(htmlentities($_POST['user_email'], ENT_QUOTES));
// prevent database flooding
$this->user_email = substr($this->user_email, 0, 64);
$this->user_email = substr(trim($_POST['user_email']), 0, 64);
// not really necessary, but just in case...
$this->user_id = $this->db_connection->real_escape_string($_SESSION['user_id']);
$this->user_id = intval($_SESSION['user_id']);

// write users new data into database
$query_edit_user_email = $this->db_connection->query("UPDATE users SET user_email = '$this->user_email' WHERE user_id = '$this->user_id';");
$query_edit_user_email = $this->db_connection->prepare('UPDATE users SET user_email = :user_email WHERE user_id = :user_id');
$query_edit_user_email->bindValue(':user_email', $this->user_email, PDO::PARAM_STR);
$query_edit_user_email->bindValue(':user_id', $this->user_id, PDO::PARAM_INT);
$query_edit_user_email->execute();

if ($query_edit_user_email) {
if ($query_edit_user_email->rowCount()) {

$_SESSION['user_email'] = $this->user_email;
$this->messages[] = "Your email address has been changed successfully. New email address is " . $this->user_email . ".";
Expand Down Expand Up @@ -383,13 +392,14 @@ public function editUserPassword()
if ($this->databaseConnection()) {

// database query, getting hash of currently logged in user (to check with just provided password)
$check_for_right_password = $this->db_connection->query("SELECT user_password_hash FROM users WHERE user_id = '".$_SESSION['user_id']."';");
$check_for_right_password = $this->db_connection->prepare('SELECT user_password_hash FROM users WHERE user_id = :user_id');
$check_for_right_password->bindValue(':user_id', $_SESSION['user_id'], PDO::PARAM_INT);
$check_for_right_password->execute();
// get result row (as an object)
$result_row = $check_for_right_password->fetchObject();

// if this user exists
if ($check_for_right_password->num_rows == 1) {

// get result row (as an object)
$result_row = $check_for_right_password->fetch_object();
if (isset($result_row->user_password_hash)) {

// using PHP 5.5's password_verify() function to check if the provided passwords fits to the hash of that user's password
if (password_verify($_POST['user_password_old'], $result_row->user_password_hash)) {
Expand All @@ -405,10 +415,13 @@ public function editUserPassword()
$this->user_password_hash = password_hash($_POST['user_password_new'], PASSWORD_DEFAULT, array('cost' => $this->hash_cost_factor));

// write users new hash into database
$this->db_connection->query("UPDATE users SET user_password_hash = '$this->user_password_hash' WHERE user_id = '".$_SESSION['user_id']."';");
$query_update = $this->db_connection->prepare('UPDATE users SET user_password_hash = :user_password_hash WHERE user_id = :user_id');
$query_update->bindValue(':user_password_hash', $this->user_password_hash, PDO::PARAM_STR);
$query_update->bindValue(':user_id', $_SESSION['user_id'], PDO::PARAM_INT);
$query_update->execute();

// check if exactly one row was successfully changed:
if ($this->db_connection->affected_rows == 1) {
if ($query_update->rowCount()) {

$this->messages[] = "Password sucessfully changed!";

Expand Down Expand Up @@ -469,26 +482,30 @@ public function setPasswordResetDatabaseToken()
if ($this->databaseConnection()) {

// TODO: this is not totally clean, as this is just the form provided username
$this->user_name = $this->db_connection->real_escape_string(htmlentities($_POST['user_name'], ENT_QUOTES));
$query_get_user_data = $this->db_connection->query("SELECT user_id, user_email FROM users WHERE user_name = '".$this->user_name."';");
$this->user_name = trim($_POST['user_name']); //$this->db_connection->real_escape_string(htmlentities($_POST['user_name'], ENT_QUOTES));
$query_get_user_data = $this->db_connection->prepare('SELECT user_id, user_email FROM users WHERE user_name = :user_name');
$query_get_user_data->bindValue(':user_name', $this->user_name, PDO::PARAM_STR);
$query_get_user_data->execute();
// get result row (as an object)
$result_row = $query_get_user_data->fetchObject();

// if this user exists
if ($query_get_user_data->num_rows == 1) {

// get result row (as an object)
$result_user_row = $query_get_user_data->fetch_object();
if (isset($result_row->user_id)) {

// database query:
$this->db_connection->query("UPDATE users
SET user_password_reset_hash = '".$this->user_password_reset_hash."',
user_password_reset_timestamp = '".$temporary_timestamp."'
WHERE user_name = '".$this->user_name."';");
$query_update = $this->db_connection->prepare('UPDATE users SET user_password_reset_hash = :user_password_reset_hash,
user_password_reset_timestamp = :user_password_reset_timestamp
WHERE user_name = :user_name');
$query_update->bindValue(':user_password_reset_hash', $this->user_password_reset_hash, PDO::PARAM_STR);
$query_update->bindValue(':user_password_reset_timestamp', $temporary_timestamp, PDO::PARAM_INT);
$query_update->bindValue(':user_name', $this->user_name, PDO::PARAM_STR);
$query_update->execute();

// check if exactly one row was successfully changed:
if ($this->db_connection->affected_rows == 1) {
if ($query_update->rowCount() == 1) {

// define email
$this->user_email = $result_user_row->user_email;
$this->user_email = $result_row->user_email;

return true;

Expand Down Expand Up @@ -576,23 +593,23 @@ public function checkIfEmailVerificationCodeIsValid()
if ($this->databaseConnection()) {

// TODO: this is not totally clean, as this is just the form provided username
$this->user_name = $this->db_connection->real_escape_string(htmlentities($_GET['user_name'], ENT_QUOTES));
$this->user_password_reset_hash = $this->db_connection->real_escape_string(htmlentities($_GET['verification_code'], ENT_QUOTES));
$this->user_name = trim($_GET['user_name']);
$this->user_password_reset_hash = $_GET['verification_code'];

$query_get_user_data = $this->db_connection->query("SELECT user_id, user_password_reset_timestamp
FROM users
WHERE user_name = '".$this->user_name."'
&& user_password_reset_hash = '".$this->user_password_reset_hash."';");
$query_get_user_data = $this->db_connection->prepare('SELECT user_id, user_password_reset_timestamp FROM users
WHERE user_name = :user_name AND user_password_reset_hash = :user_password_reset_hash');
$query_get_user_data->bindValue(':user_name', $this->user_name, PDO::PARAM_STR);
$query_get_user_data->bindValue(':user_password_reset_hash', $this->user_password_reset_hash, PDO::PARAM_STR);
$query_get_user_data->execute();
// get result row (as an object)
$result_row = $query_get_user_data->fetchObject();

// if this user exists
if ($query_get_user_data->num_rows == 1) {

// get result row (as an object)
$result_user_row = $query_get_user_data->fetch_object();
if (isset($result_row->user_id)) {

$timestamp_one_hour_ago = time() - 3600; // 3600 seconds are 1 hour

if ($result_user_row->user_password_reset_timestamp > $timestamp_one_hour_ago) {
if ($result_row->user_password_reset_timestamp > $timestamp_one_hour_ago) {

// set the marker to true, making it possible to show the password reset edit form view
$this->password_reset_link_is_valid = true;
Expand Down Expand Up @@ -639,9 +656,9 @@ public function editNewPassword()
if ($this->databaseConnection()) {

// escapin' this, additionally removing everything that could be (html/javascript-) code
$this->user_name = $this->db_connection->real_escape_string(htmlentities($_POST['user_name'], ENT_QUOTES));
$this->user_password_reset_hash = $this->db_connection->real_escape_string(htmlentities($_POST['user_password_reset_hash'], ENT_QUOTES));
$this->user_name = trim($_POST['user_name']);
$this->user_password_reset_hash = $_POST['user_password_reset_hash'];

// no need to escape as this is only used in the hash function
$this->user_password = $_POST['user_password_new'];

Expand All @@ -656,15 +673,16 @@ public function editNewPassword()
$this->user_password_hash = password_hash($this->user_password, PASSWORD_DEFAULT, array('cost' => $this->hash_cost_factor));

// write users new hash into database
$this->db_connection->query("UPDATE users
SET user_password_hash = '$this->user_password_hash',
user_password_reset_hash = NULL,
user_password_reset_timestamp = NULL
WHERE user_name = '".$this->user_name."'
&& user_password_reset_hash = '".$this->user_password_reset_hash."';");
$query_update = $this->db_connection->prepare('UPDATE users SET user_password_hash = :user_password_hash,
user_password_reset_hash = NULL, user_password_reset_timestamp = NULL
WHERE user_name = :user_name AND user_password_reset_hash = :user_password_reset_hash');
$query_update->bindValue(':user_password_hash', $this->user_password_hash, PDO::PARAM_STR);
$query_update->bindValue(':user_password_reset_hash', $this->user_password_reset_hash, PDO::PARAM_STR);
$query_update->bindValue(':user_name', $this->user_name, PDO::PARAM_STR);
$query_update->execute();

// check if exactly one row was successfully changed:
if ($this->db_connection->affected_rows == 1) {
if ($query_update->rowCount() == 1) {

$this->password_reset_was_successful = true;
$this->messages[] = "Password sucessfully changed!";
Expand Down

0 comments on commit 5d53d24

Please sign in to comment.