From 93b405ab9f69538546165c75a301c0c57a5359cf Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Tue, 26 Jul 2016 00:16:17 +0200 Subject: User authentication mechanism --- classes/BusinessAdmin.php | 46 +++++++++++++ classes/constants.php | 5 +- classes/user.php | 172 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 classes/user.php (limited to 'classes') diff --git a/classes/BusinessAdmin.php b/classes/BusinessAdmin.php index dc1f3e7..ce332ee 100644 --- a/classes/BusinessAdmin.php +++ b/classes/BusinessAdmin.php @@ -29,6 +29,52 @@ class BusinessAdmin { // Getters and setters //------------------------------------------------------------------------------ + /** + * Get all user ids + * + * @see BusinessAdmin::getUsers() This funtion returns instances of the user class instead of just the ids + * + * @param PDO $pdo The PDO class for database connection + * @param string[] $where An array of WHERE clauses that will be AND-ed into a prepared statement + * @param mixed[] $variables An array of variables that should go into the prepared statement + * + * @throws PDOException Is something went wrong with the database + * + * @return int[] The ids + */ + public static function getUserIds($pdo, $where = [], $variables = []) { + $ids = []; + $users = $pdo->prepare("SELECT `id` FROM `".constants::db_prefix."user`" . ((count($where) > 0) ? (" WHERE (" . implode(') AND (', $where) . ")") : "")); + $users->execute($variables); + $users = $users->fetchAll(PDO::FETCH_ASSOC); + foreach ($users as $user) { + $ids[] = $user['id']; + } + return $ids; + } + + /** + * Get all users + * + * @see BusinessAdmin::getUserIds() This function returns just the ids of the users, and not instances of the user class + * + * @param PDO $pdo The PDO class for database connection + * @param string[] $where An array of WHERE clauses that will be AND-ed into a prepared statement + * @param mixed[] $variables An array of variables that should go into the prepared statement + * + * @throws PDOException If something went wrong with the database + * + * @return user[] An array indexed by id of instances of the user class + */ + public static function getUsers($pdo, $where = [], $variables = []) { + $ids = self::getUserIds($pdo, $where, $variables); + $users = []; + foreach ($ids as $id) { + $users[$id] = new user($pdo, $id); + } + return $users; + } + /** * Get all client ids * diff --git a/classes/constants.php b/classes/constants.php index d16bde4..77f47b0 100644 --- a/classes/constants.php +++ b/classes/constants.php @@ -69,6 +69,9 @@ class constants { /** @const fa_valuta see http://fontawesome.io/icons/#currency; the fa- postfix for valuta */ const fa_valuta = 'eur'; + /** @const password_cost for the password_hash function. Run install?password_cost to benchmark your system */ + const password_cost = 10; + /** @const version Version of BusinessAdmin. Don't change this yourself! */ - const version = '0.3'; + const version = '0.4'; } diff --git a/classes/user.php b/classes/user.php new file mode 100644 index 0000000..261fa3d --- /dev/null +++ b/classes/user.php @@ -0,0 +1,172 @@ +. + */ + +/** + * An interface to the user table in the database + */ +class user { + /** + * @var pdo $pdo The PDO class for database communication + * @var int $id The id of the user + * @var string $username The username of the user + * @var string $password The (hashed) password of the user + */ + protected $pdo, $id, $username, $password; + + /** + * Hash a password + * + * @param string $password The password to be hashed + * @param int $cost The password cost + * + * @return string The hashed password + */ + public static function hash($password, $cost=null) { + return password_hash( + $password, + PASSWORD_DEFAULT, + ['cost' => is_null($cost) ? constants::password_cost : $cost] + ); + } + + /** + * Create a new instance + * + * @param PDO $pdo The PDO class, to access the database + * @param int $id The id of the user to fetch + * + * @throws PDOException If something went wrong with the database + * @throws Exception If the user could not be found + */ + public function __construct($pdo, $id) { + $this->pdo = $pdo; + + $stmt = $this->pdo->prepare("SELECT * FROM `".constants::db_prefix."user` WHERE `id`=?"); + $stmt->execute(array($id)); + if ($stmt->rowCount() == 0) { + throw new Exception("The user with id '$id' could not be found."); + } + $user = $stmt->fetch(PDO::FETCH_ASSOC); + + $this->id = $user['id']; + $this->username = $user['username']; + $this->password = $user['password']; + } + + //------------------------------------------------------------------------------ + // Getters and setters + //------------------------------------------------------------------------------ + + /** + * Get the ID of the user + * + * @return int The ID + */ + public function getId() { + return $this->id; + } + + /** + * Get the username of the user + * + * @return string The username + */ + public function getUsername() { + return $this->username; + } + + /** + * Set the username of the user + * + * @param string $username The new username for the user + * + * @throws PDOException If something went wrong with the database + * + * @return bool True on succes, false on failure + */ + public function setName($username) { + $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."user` SET `username`=? WHERE `id`=?"); + $stmt->execute(array($username, $this->id)); + if ($stmt->rowCount() == 1) { + $this->username = $username; + return true; + } else { + return false; + } + } + + /** + * Set the password of the user + * + * @param string $password The new password for the user + * + * @throws PDOException If something went wrong with the database + * + * @return bool True on succes, false on failure + */ + public function setPassword($password) { + $password = self::hash($password); + $stmt = $this->pdo->prepare("UPDATE `".constants::db_prefix."user` SET `password`=? WHERE `id`=?"); + $stmt->execute(array($password, $this->id)); + if ($stmt->rowCount() == 1) { + $this->password = $password; + return true; + } else { + return false; + } + } + + //------------------------------------------------------------------------------ + // Other functions + //------------------------------------------------------------------------------ + + /** + * Verify a password + * + * @param string $password The password to verify + * + * @return bool True iff the password can be accepted + */ + public function verifyPassword($password) { + return password_verify($password, $this->password); + } + + /** + * Remove this user from the database + * + * If this doesn't succeed (i.e. false is returned), that means the user was removed manually or by another instance of this class + * + * @throws PDOException If something went wrong with the database + * + * @return bool True on success, false on failure + */ + public function delete() { + $stmt = $this->pdo->prepare("DELETE FROM `".constants::db_prefix."user` WHERE `id`=?"); + $stmt->execute(array($this->id)); + if ($stmt->rowCount() != 1) { + return false; + } else { + return true; + } + } +} -- cgit v1.2.3