*
* AuthUser account self-registration and management using database (mysqli)
*
* For more information, please see the online documentation at
* http://www.pmwiki.org/wiki/Cookbook/UserAdmin
*
* This script is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
$RecipeInfo['UserAdmin']['Version'] = '2015-04-29';
SDV($AuthUserFunctions['useradmindb'], 'AuthUserDbase');
function AuthUserDbase($pagename, $id, $pw, $pwlist)
{
global $UserAdmin;
#echo "AUD(pagename=$pagename, id=$id, pw=$pw, pwlist=$pwlist): Entering.
\n";
#echo "DEBUG: UserAdmin=
".print_r($UserAdmin,true)."
\n";
$row = $UserAdmin->ReadUser($id);
#echo "DEBUG: row=".print_r($row,true)."
\n";
#echo "DEBUG: crypt($pw, $row[userpwhash])="._crypt($pw, $row['userpwhash'])."
\n";
if (!empty($row['userpwhash']) && (_crypt($pw, $row['userpwhash']) == $row['userpwhash']))
return true;
return false;
}
# If this is uncommented then we can't log in
#if (strncmp($action, 'user', 4)) return;
require_once('useradmin-core.php');
class UserAdminDbase extends UserAdmin {
var $pdo; // database connection
var $dbprefix = '';
function __construct($dsn, $user, $pass, $opts=null, $prefix='')
{
try {
$this->pdo = new PDO($dsn, $user, $pass, $opts);
} catch (PDOException $e) {
$this->dblog( "Connection failed: ".$e->getMessage(), true);
}
if ($prefix)
$this->dbprefix = $prefix;
}
function dblog($msg, $fatal=true)
{
echo $msg;
if ($fatal) exit;
}
/* check that the db structure has been created */
/*
$sql = "SHOW TABLES LIKE '{$this->dbconfig['prefix']}uadb'";
$result = $conn->query($sql);
if ($result && $result->num_rows > 0) {
$this->conn = $conn;
return $conn;
}
echo "ERROR: Database is not yet set up for UserAdmin Dbase.
\n";
exit(1);
*/
function dbtablename($tbl)
{
if ($this->dbprefix)
$tbl = $this->dbprefix.$tbl;
return $tbl;
}
function dbprepare($sql)
{
if (!$result = $this->pdo->prepare($sql)) {
$errmsg = "DB ERROR: Cannot prepare. SQL=<$sql> error({$this->conn->errno})=$this->conn->error\n";
$this->dberror($errmsg);
}
return $result;
}
function dbquery($sql)
{
if (!$this->dbconnect())
exit; // this shouldn't ever really happen
if (!($stmt = $this->conn->query($sql)) || $this->conn->errno) {
$errmsg = "DB ERROR: Cannot query. SQL=<$sql> error({$this->conn->errno})=$this->conn->error\n";
$this->dberror($errmsg);
}
return $stmt;
}
function dbfetch($result)
{
$rtn = mysqli_fetch_assoc($result);
if ($this->conn->errno) {
$errmsg = "DB ERROR: Cannot fetch. error({$this->conn->errno})=$this->conn->error\n";
$this->dberror($errmsg);
}
return $rtn;
}
function dberror($msg)
{
# This would be a good place for logging
die($msg);
}
function ReadUser($username, $readgroup=false)
{
$sql = "SELECT *
FROM ".$this->dbtablename('users')."
WHERE username = :username ";
try {
$stmt = $this->pdo->prepare($sql);
$stmt->execute(array(':username'=>$username));
} catch (PDOException $e) {
$this->dblog("ReadUser(): Error: SQL=$sql ERROR=".$e->getMessage());
}
$row = $stmt->fetch(PDO::FETCH_ASSOC);
# If I do this "union" of results then WriteUser() doesn't know where the read came from
#if (!$row) $row = parent::ReadUser($username, $readgroup);
return $row;
}
function WriteUser($username, $data, $csum='', $auth='read')
{
$row = $this->ReadUser($username);
if ($row) {
# UPDATE
$sql = "UPDATE ".$this->dbtablename('users')." SET ";
$sep = '';
$bindvars = array();
foreach ($data as $k=>$v) {
if ($k == 'username') continue;
$sql .= "$sep$k=:$k";
$bindvars[":$k"] = $v;
$sep = ',';
}
$sql .= " WHERE username = :username ";
$bindvars[':username'] = $username; // needed for the WHERE clause
} else {
# INSERT
$sql = "INSERT INTO ".$this->dbtablename('users')." (username";
$vals= "VALUES (:username";
$bindvars=array(':username'=>$username);
foreach ($data as $k=>$v) {
if ($k == 'username') continue; // already put in above
$sql .= ", $k";
$vals.= ", :$k";
$bindvars[":$k"] = $v;
}
$sql .= ") ".$vals.")";
}
try {
$stmt = $this->pdo->prepare($sql);
$stmt->execute($bindvars);
} catch (PDOException $e) {
$this->dblog("WriteUser(): Error SQL=$sql ERROR=".$e->getMessage());
}
return true;
}
function ListUsers($pat=NULL)
{
$sql = "SELECT *
FROM ".$this->dbtablename('users');
if ($pat)
$sql .= " WHERE username = :username";
try {
$stmt = $this->pdo->prepare($sql);
if ($pat) $bindvals = array(':username'=>$pat); // do we really need a "pattern" or is username enuf?
else $bindvals = null;
$stmt->execute($bindvals);
} catch (PDOException $e) {
$this->dblog("ListUsers(): Error SQL=$sql ERROR=".$e->getMessage());
}
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $rows;
}
function HandleInstall($pagename)
{
if (!$this->Superuser($pagename)) {
echo "You do not have the necessary privileges. Aborting.
\n";
exit(1);
}
/*************************
* DATABASE STRUCTURE:
*************************/
$prefix = $this->dbprefix;
$db_create_queries = array(
"CREATE TABLE IF NOT EXISTS `${prefix}users` (
`username` varchar(50) NOT NULL,
`userpwhash` varchar(100) NOT NULL,
`useremail` varchar(250) NOT NULL,
`userrealname` varchar(250) DEFAULT NULL,
`userfname` varchar(150) DEFAULT NULL,
`userlname` varchar(150) DEFAULT NULL,
`userkey` varchar(100) DEFAULT NULL,
`userkeyreason` varchar(100) DEFAULT NULL,
`userkeytime` int(15) DEFAULT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8",
"CREATE TABLE IF NOT EXISTS `${prefix}groups` (
`groupname` varchar(50) NOT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`groupname`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8",
"CREATE TABLE IF NOT EXISTS `${prefix}group_members` (
`groupname` varchar(50) NOT NULL,
`username` varchar(50) NOT NULL,
`admin` tinyint(1) NOT NULL DEFAULT '0',
`user_is_group` tinyint(1) NOT NULL DEFAULT '0',
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`groupname`,`username`),
KEY `groupname` (`groupname`),
KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8",
"CREATE TABLE IF NOT EXISTS `${prefix}uadb` (
`do_I_exist` varchar(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8",
);
try {
foreach ($db_create_queries as $sql)
$this->pdo->exec($sql);
} catch (PDOException $e) {
$this->dblog("HandleInstall(): ERROR: SQL=$sql ".$e->getMessage());
}
echo "Success. Database Tables Created
\n";
}
}
# This should be called from config.php (or farmconfig.php) AFTER including this file
#SDV($UserAdmin, new UserAdminDbase('host', 'user', 'pass', 'dbname'));