davadmin/admin/users.php
2007-08-28 08:18:04 +00:00

317 lines
10 KiB
PHP

<?php
/**
* User administration code.
*
* @author Jan Dittberner <jan@dittberner.info>
* @version $Id$
* @license GPL
* @package WebDAVAdmin
*
* Copyright (c) 2007 Jan Dittberner
*
* This file is part of WebDAVAdmin.
*
* This program 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 2 of the
* License, or (at your option) any later version.
*
* This program 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
/** Include common code. */
include_once('common.inc.php');
/**
* Gets XML encoded data for a user.
*
* @param int $uid user id
* @return XML string
*/
function getUserData($uid) {
if (!is_numeric($uid)) {
errorAsXml(sprintf(_("Invalid user id %s"), $uid));
}
try {
$currentuser = $_SERVER['PHP_AUTH_USER'];
$dbh = new PDO($GLOBALS['dsn'], $GLOBALS['dbuser'], $GLOBALS['dbpass']);
$sth = $dbh->prepare("SELECT groupname FROM dav_group, dav_password WHERE dav_group.username=dav_password.username AND dav_password.uid=:uid");
if (!$sth->execute(array(':uid' => $uid))) {
statementErrorAsXml($sth);
}
$groups = array();
while ($grouprow = $sth->fetch(PDO::FETCH_ASSOC)) {
array_push($groups, $grouprow['groupname']);
}
$sth = $dbh->prepare("SELECT username, firstname, lastname FROM dav_password WHERE uid=:uid");
if (!$sth->execute(array(':uid' => $uid))) {
statementErrorAsXml($sth);
}
$row = $sth->fetch(PDO::FETCH_ASSOC);
$retval = sprintf('<?xml version="1.0" encoding="utf8"?><userdata><uid>%d</uid><username>%s</username><firstname>%s</firstname><lastname>%s</lastname><groups>%s</groups><loggedin>%d</loggedin></userdata>',
$uid, $row['username'], $row['firstname'],
$row['lastname'], implode(", ", $groups),
($currentuser == $row['username']) ? 1 : 0);
$dbh = null;
} catch (PDOException $e) {
errorAsXml($e->getMessage());
}
header("Content-Type: text/xml; charset=UTF-8");
return $retval;
}
/**
* Gets XML encoded data for a deleted user.
*
* @param int $uid user id
* @return XML string
*/
function getDeletedUserData($uid) {
if (!is_numeric($uid)) {
errorAsXml(sprintf(_("Invalid user id %s"), $uid));
}
return sprintf('<?xml version="1.0" encoding="utf8"?><userdata><uid>%d</uid></userdata>', $uid);
}
/**
* Validates the given user data array for correctness.
*
* @param array &$userdata reference to an user data array
* @param boolean $forinsert if this is true the check skips field
* that will be created during insert
* @return an array with validation error messages or an empty array
*/
function validateUserData(&$userdata, $forinsert) {
$errormsgs = array();
// normalize the user data array
foreach ($userdata as $key => $value) {
$userdata[$key] = trim($value);
}
if (!$forinsert) {
if (!is_numeric($userdata['uid'])) {
array_push($errormsgs, _("Uid must be numeric."));
}
if (!empty($userdata['password']) && strlen($userdata['password']) < 8) {
array_push($errormsgs, _("Password must be at least 8 characters long."));
}
} else {
if (!preg_match('/^[a-zA-Z0-9]{2,}$/', $userdata['username'])) {
array_push($errormsgs, _("Username must be at least 2 characters long and must contain letters and digits only."));
}
if (empty($userdata['password']) || strlen($userdata['password']) < 8) {
array_push($errormsgs, _("Password must be at least 8 characters long."));
}
}
if (empty($userdata['firstname'])) {
$userdata['firstname'] = null;
}
if (empty($userdata['lastname'])) {
$userdata['lastname'] = null;
}
if (!preg_match('/^([0-9a-zA-z]+[,\s]*)+$/', $userdata['groups'])) {
array_push($errormsgs, _('Groups must be a list of group names separated by commas. Group names must consist of letters and digits.'));
}
return $errormsgs;
}
/**
* Updates the data of a user in the database.
*
* @param array &$userdata reference to a user data array
*/
function updateUser(&$userdata) {
$validation = validateUserData($userdata, false);
if (!empty($validation)) {
errorAsXml(implode("\n", $validation));
}
try {
$dbh = new PDO($GLOBALS['dsn'], $GLOBALS['dbuser'], $GLOBALS['dbpass']);
$dbh->beginTransaction();
if ($userdata['password']) {
$sth = $dbh->prepare("UPDATE dav_password SET firstname=:firstname, lastname=:lastname, password=md5(:password) WHERE uid=:uid");
if (!$sth->execute(array(':firstname' => $userdata['firstname'],
':lastname' => $userdata['lastname'],
':password' => $userdata['password'],
':uid' => $userdata['uid']))) {
$dbh->rollback();
statementErrorAsXml($sth);
}
} else {
$sth = $dbh->prepare("UPDATE dav_password SET firstname=:firstname, lastname=:lastname WHERE uid=:uid");
if (!$sth->execute(array(':firstname' => $userdata['firstname'],
':lastname' => $userdata['lastname'],
':uid' => $userdata['uid']))) {
$dbh->rollback();
statementErrorAsXml($sth);
}
}
if ($userdata['groups']) {
$groups = array();
$sth = $dbh->prepare("DELETE FROM dav_group WHERE username=:username");
if (!$sth->execute(array(':username' => $userdata['username']))) {
$dbh->rollback();
statementErrorAsXml($sth);
}
$sth = $dbh->prepare("INSERT INTO dav_group (username, groupname) VALUES (:username, :groupname)");
foreach (explode(",", $userdata['groups']) as $group) {
$group = trim($group);
if (!in_array($group, $groups)) {
array_push($groups, $group);
if (!$sth->execute(array(':username' => $userdata['username'],
':groupname' => $group))) {
$dbh->rollback();
statementErrorAsXml($sth);
}
$sth->closeCursor();
}
}
}
$dbh->commit();
$dbh = null;
} catch (PDOException $e) {
errorAsXml($e->getMessage());
}
}
/**
* Inserts a new user and its group assignments into the database.
*
* @param array &$userdata reference to an user data array
*/
function insertUser(&$userdata) {
$validation = validateUserData($userdata, true);
if (!empty($validation)) {
errorAsXml(implode("\n", $validation));
}
try {
$dbh = new PDO($GLOBALS['dsn'], $GLOBALS['dbuser'], $GLOBALS['dbpass']);
$dbh->beginTransaction();
$sth = $dbh->prepare("INSERT INTO dav_password (username, firstname, lastname, password) VALUES (:username, :firstname, :lastname, md5(:password))");
if (!$sth->execute(array(':username' => $userdata['username'],
':firstname' => $userdata['firstname'],
':lastname' => $userdata['lastname'],
':password' => $userdata['password']))) {
$dbh->rollback();
statementErrorAsXml($sth);
}
$uid = $dbh->lastInsertId('dav_password_uid_seq');
$groups = array();
$sth = $dbh->prepare("INSERT INTO dav_group (username, groupname) VALUES (:username, :groupname)");
foreach (split(",", $userdata['groups']) as $group) {
$group = trim($group);
if (!in_array($group, $groups)) {
array_push($groups, $group);
if (!$sth->execute(array(':username' => $userdata['username'],
':groupname' => $group))) {
$dbh->rollback();
statementErrorAsXml($sth);
}
$sth->closeCursor();
}
}
$dbh->commit();
$dbh = null;
} catch (PDOException $e) {
errorAsXml($e->getMessage);
}
return $uid;
}
/**
* Delete the user with the given user id and its group assignments
* from the database.
*
* @param int $uid user id
*/
function deleteUser($uid) {
if (!is_numeric($uid)) {
errorAsXml(sprintf(_("Invalid user id %s"), $uid));
}
try {
$dbh = new PDO($GLOBALS['dsn'], $GLOBALS['dbuser'], $GLOBALS['dbpass']);
$dbh->beginTransaction();
$query = $dbh->prepare("DELETE FROM dav_group WHERE username IN (SELECT username FROM dav_password WHERE uid=:uid)");
if (!$query->execute(array(':uid' => $uid))) {
$dbh->rollback();
statementErrorAsXml($query);
}
$query = $dbh->prepare("DELETE FROM dav_password WHERE uid=:uid");
if (!$query->execute(array(':uid' => $uid))) {
$dbh->rollback();
statementErrorAsXml($query);
}
$dbh->commit();
$dbh = null;
} catch (PDOException $e) {
errorAsXml($e->getMessage());
}
}
if ($_GET) {
if ($_GET['method']) {
switch ($_GET['method']) {
case 'getuserdata':
if ($_GET['uid']) {
print getUserData($_GET['uid']);
}
break;
default:
errorAsXml(sprintf(_("Unexpected values %s!"), serialize($_GET)));
}
} else {
invalidCall();
}
} elseif ($_POST) {
if ($_POST['method']) {
switch ($_POST['method']) {
case 'submituser':
if ($_POST['uid']) {
updateUser($_POST);
print getUserData($_POST['uid']);
} else {
print getUserData(insertUser($_POST));
}
break;
case 'deleteuser':
if ($_POST['uid']) {
deleteUser($_POST['uid']);
print getDeletedUserData($_POST['uid']);
} else {
errorAsXml(sprintf(_("Unexpected values %s!"), serialize($_POST)));
}
break;
default:
errorAsXml(sprintf(_("Unexpected values %s!"), serialize($_POST)));
}
} else {
invalidCall();
}
} else {
$currentuser = $_SERVER['PHP_AUTH_USER'];
header("Content-Type: text/html; charset=UTF-8");
try {
$dbh = new PDO($dsn, $dbuser, $dbpass);
$query = $dbh->prepare("SELECT uid, username, firstname, lastname FROM dav_password ORDER BY username");
$query->execute();
$rows = $query->fetchall(PDO::FETCH_ASSOC);
foreach ($rows as $key => $value) {
$value['loggedin'] = ($value['username'] == $currentuser);
$rows[$key] = $value;
}
$smarty->assign("users", $rows);
$smarty->display("users.html");
} catch (PDOException $e) {
errorAsHtml($e->getMessage());
}
}
?>