davadmin/admin/users.php
Jan Dittberner 7bffc8bf97 addresses #1
directories are working
users still have dependencies to database code
2007-11-21 23:00:58 +00:00

309 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');
function getGroups($username) {
$groupdata = file($GLOBALS['davconfig']['group.file']);
$retval = array();
foreach ($groupdata as $line) {
$colonpos = strpos($line, ":");
if ($colonpos > 0) {
$groupname = trim(substr($line, 0, $colonpos - 1));
$users = explode(" ", substr($line, $colonpos + 1));
foreach ($users as $user) {
if (trim($user) == $username) {
array_push($retval, $groupname);
}
}
}
}
return $retval;
}
/**
* Gets XML encoded data for a user.
*
* @param int $uid user id
* @return XML string
*/
function getUserData($uid) {
if (!(is_numeric($uid) && array_key_exists($uid, $GLOBALS['namemap']))) {
errorAsXml(sprintf(_("Invalid user id %s"), $uid));
}
$row = $GLOBALS['namemap'][$uid];
$groups = getGroups($row['username']);
$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>0</loggedin></userdata>',
$uid, $row['username'], $row['firstname'],
$row['lastname'], implode(", ", $groups));
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;
}
function createDigest($username, $realm, $password) {
return sprintf("%s:%s:%s", $username, $realm,
md5(sprintf("%s:%s:%s", $username, $realm, $password)));
}
/**
* 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");
$smarty->assign("users", $namemap);
$smarty->display("users.html");
}
?>