From 94bc27f7d4cfa55a163e0231538398c3e4057c3e Mon Sep 17 00:00:00 2001 From: Dominique Fournier Date: Sat, 12 Sep 2015 15:26:16 +0000 Subject: [PATCH] users/usersSQL : Add users storage in SQL and the users abstraction class git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@2276 bf3deb0d-5f1a-0410-827f-c0cc1f45334c --- users.php | 144 +++++++++++++++++++++++++++++++++++ userssql.php | 208 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 352 insertions(+) create mode 100644 users.php create mode 100644 userssql.php diff --git a/users.php b/users.php new file mode 100644 index 0000000..7d474b6 --- /dev/null +++ b/users.php @@ -0,0 +1,144 @@ += 128) + throw new Exception (dgettext("domframework", + "Invalid password provided : too long"), + 500); + return true; + } + + /** Crypt the password with the best algorithm available */ + public function cryptPasswd ($password) + { + if (! function_exists ("openssl_random_pseudo_bytes")) + throw new Exception (dgettext("domframework", + "No PHP support for openssl_random_pseudo_bytes"), + 500); + $cost = 11; + $salt = substr (base64_encode (openssl_random_pseudo_bytes (17)), 0, 22); + $salt = str_replace ("+", ".", $salt); + $param = '$'.implode ('$', array( + "2y", //select the most secure version of blowfish (>=PHP 5.3.7) + str_pad ($cost, 2, "0", STR_PAD_LEFT), //add the cost in two digits + $salt //add the salt + )); + //now do the actual hashing + return crypt ($password, $param); + } + + /** Check if the password is enough complex + Return True if the password is enough complex */ + public function passwdComplexity ($password) + { + } +} diff --git a/userssql.php b/userssql.php new file mode 100644 index 0000000..2fc049f --- /dev/null +++ b/userssql.php @@ -0,0 +1,208 @@ + */ + +require_once ("domframework/dblayer.php"); +require_once ("domframework/users.php"); + +/** Store the users in SQL database. Manage the creation of the users, + modification, delete, password management*/ +class userssql extends users +{ + /** The database connector */ + private $dsn; + private $username; + private $password; + private $driver_options; + /** The db connector */ + private $db; + + /** The table to store the informations */ + public $table = "authusers"; + /** The tableprefix text to prepend to table name (Should finish by _) + Just allow chars ! */ + public $tableprefix = ""; + + /** the fields */ + public $fieldEmail = "email"; + public $fieldFirstname = "firstname"; + public $fieldLastname = "lastname"; + public $fieldPassword = "password"; + public $fieldLastchange = "lastchange"; + + public function __construct ($dsn, $username=null, $password=null, + $driver_options=null) + { + $this->dsn = $dsn; + $this->username = $username; + $this->password = $password; + $this->driver_options = $driver_options; + } + + /** Connect to the storage */ + public function connect () + { + if ($this->table === null) + throw new Exception (dgettext("domframework","No SQL table defined"), + 500); + if ($this->fieldEmail === null) + throw new Exception (dgettext("domframework", + "No fieldIdentifier defined"), 500); + if ($this->fieldPassword === null) + throw new Exception (dgettext("domframework", + "No fieldPassword defined"), 500); + if ($this->fieldLastname === null) + throw new Exception (dgettext("domframework", + "No fieldLastname defined"), 500); + if ($this->fieldFirstname === null) + throw new Exception (dgettext("domframework", + "No fieldFirstname defined"), 500); + if ($this->fieldLastchange === null) + throw new Exception (dgettext("domframework", + "No fieldLastchange defined"), 500); + $this->db = new dblayer ($this->dsn, $this->username, $this->password, + $this->driver_options); + $this->db->table = $this->table; + $this->db->fields = array ( + $this->fieldEmail=>array ("varchar", "255", "not null"), + $this->fieldFirstname=>array ("varchar", "255", "not null"), + $this->fieldLastname=>array ("varchar", "255"), + $this->fieldPassword=>array ("varchar", "255"), + $this->fieldLastchange=>array ("datetime")); + $this->db->primary = $this->fieldEmail; + $this->db->unique = array ($this->fieldEmail); + $this->db->tableprefix = $this->tableprefix; + } + + /** Initialise the storage + Create the structure of data needed to the class */ + public function initStorage () + { + if ($this->db === null) + $this->connect (); + return $this->db->createTable (); + } + + /** Create a new user + If the password is not provided, create a default passwd (can be disable + password) */ + public function adduser ($email, $firstname, $lastname, $password=null) + { + if ($this->db === null) + $this->connect (); + $this->checkEmail ($email); + $this->checkFirstname ($firstname); + $this->checkLastname ($lastname); + if ($password !== null) + { + $this->checkPassword ($password); + $password = $this->cryptPasswd ($password); + } + return $this->db->insert (array ($this->fieldEmail=>$email, + $this->fieldFirstname=>$firstname, + $this->fieldLastname=>$lastname, + $this->fieldPassword=>$password)); + } + + /** Delete a user */ + public function deluser ($email) + { + if ($this->db === null) + $this->connect (); + $this->checkEmail ($email); + return $this->db->delete ($email); + } + + /** Update a user */ + public function updateuser ($oldemail, $newemail, $firstname, $lastname) + { + if ($this->db === null) + $this->connect (); + $this->checkEmail ($oldemail); + $this->checkEmail ($newemail); + $this->checkFirstname ($firstname); + $this->checkLastname ($lastname); + return $this->db->update ($oldemail, + array ($this->fieldEmail=>$newemail, + $this->fieldFirstname=>$firstname, + $this->fieldLastname=>$lastname)); + } + + /** List the users */ + public function listusers () + { + if ($this->db === null) + $this->connect (); + return $this->db->read (null, array ($this->fieldEmail, + $this->fieldFirstname, + $this->fieldLastname)); + } + + /** Change password + @param string $email the user email to change the password + @param string $oldpassword The old password (to check if the user have the + rights to change the password) + @param string $newpassword The new password to be recorded */ + public function changepassword ($email, $oldpassword, $newpassword) + { + if ($this->db === null) + $this->connect (); + $this->checkEmail ($email); + $this->checkPassword ($oldpassword); + $this->checkPassword ($newpassword); + if ($this->checkValidPassword ($email, $oldpassword) !== true) + throw new Exception (dgettext("domframework", + "Bad old password provided"), 401); + $cryptedPassword = $this->cryptPasswd ($newpassword); + return $this->db->update ($email, + array ($this->fieldPassword=>$cryptedPassword, + $this->fieldLastchange=> + date ("Y-m-d H:i:s", time()))); + } + + /** Overwrite password (without oldpassword check) + Must be reserved to the administrators. For the users, use changepassword + method + @param string $email the user email to change the password + @param string $newpassword The new password to be recorded */ + public function overwritepassword ($email, $newpassword) + { + if ($this->db === null) + $this->connect (); + $this->checkEmail ($email); + $this->checkPassword ($newpassword); + $data = $this->db->read (array (array ($this->fieldEmail, $email)), + array ($this->fieldPassword)); + if (count ($data) === 0) + throw new Exception (dgettext("domframework", + "No information found for this email"), 404); + $cryptedPassword = $this->cryptPasswd ($newpassword); + return $this->db->update ($email, + array ($this->fieldPassword=>$cryptedPassword, + $this->fieldLastchange=> + date ("Y-m-d H:i:s", time()))); + } + + /** Check if the provided password is correctely associated to the email user + */ + public function checkValidPassword ($email, $password) + { + if ($this->db === null) + $this->connect (); + $this->checkEmail ($email); + $this->checkPassword ($password); + $data = $this->db->read (array (array ($this->fieldEmail, $email)), + array ($this->fieldPassword)); + if (count ($data) === 0) + throw new Exception (dgettext("domframework", + "No information found for this email"), 404); + if (! isset ($data[0][$this->fieldPassword])) + throw new Exception (dgettext("domframework", + "No password available for this email"), 404); + $cryptedPassword = $data[0][$this->fieldPassword]; + if (crypt ($password, $cryptedPassword) !== $cryptedPassword) + return false; + return true; + } +}