Files
DomFramework/src/Userssql.php
2022-11-25 21:21:30 +01:00

294 lines
9.8 KiB
PHP

<?php
/** DomFramework
* @package domframework
* @author Dominique Fournier <dominique@fournier38.fr>
* @license BSD
*/
namespace Domframework;
/** 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;
/** The user needed to connect to database */
private $username;
/** The password needed to connect to database */
private $password;
/** The optional drivers need by the database */
private $driver_options;
/** The db connector */
private $db;
/** The table to store the information */
public $table = "authusers";
/** The tableprefix text to prepend to table name (Should finish by _)
Just allow chars ! */
public $tableprefix = "";
/** The email field in the database */
public $fieldEmail = "email";
/** The firstname field in the database */
public $fieldFirstname = "firstname";
/** The lastname field in the database */
public $fieldLastname = "lastname";
/** The password field in the database */
public $fieldPassword = "password";
/** The lastchange field in the database */
public $fieldLastchange = "lastchange";
/** The constructor. Save the parameters to connect to the database
* @param string $dsn The DSN to connect
* @param string|null $username The username to connect
* @param string|null $password The password to connect
* @param array|null $driver_options The optional drivers parameters
*/
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)
* @param string $email The email to add
* @param string $firstname The firstname to add
* @param string $lastname The lastname to add
* @param string|null $password The password of the user
*/
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
* @param string $email The email to remove
*/
public function deluser($email)
{
if ($this->db === null) {
$this->connect();
}
$this->checkEmail($email);
return $this->db->delete($email);
}
/** Update a user
* @param string $oldemail The old email to modify
* @param string $newemail The new email to save
* @param string $firstname The firstname of the user
* @param string $lastname The lastname of the 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
* @param string $email The email to authenticate
* @param string $password The user password (not crypted !)
*/
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;
}
}