Here is the script template.inc script
<?php
class Template {
var $content;
var $filename = "";
function Template($filename) {
$this->filename = $filename;
$this->content = array();
$this->content["name"] = "main";
$this->content["body"] = $this->loadfile($this->filename);
$this->content["blocks"] = array();
$this->content["values"] = array();
$this->parse(&$this->content);
}
function showStructure() {
print "<ul>";
$this->_showStructure(&$this->content);
print "</ul>";
}
function _showStructure(&$content) {
print "<li>name: ".$content["name"]."</li>";
print "<li>body: ".htmlentities($content["body"])."</li>";
print "<li>blocks:";
print "<ul>";
reset ($content["blocks"]);
while (list($blockname, $block) = each($content["blocks"])) {
for ($i = 0; $i < count($block); $i++) {
$this->_showStructure($block[$i]);
}
}
print "</ul>";
print "</li>";
}
function parse(&$content) {
while (eregi("<!--\ startBlock\(([^)]+)\)\ -->", $content["body"], $m)) {
$name = $m[1];
$block = array();
$block["name"] = $name;
$block["blocks"] = array();
$block["used"] = 0;
$block["values"] = array();
$reg = "<!--\ startBlock\(".$name."\)\ -->(.*)<!--\ endBlock\(".$name."\)\ -->";
if (!eregi($reg, $content["body"], $m)) {
$this->error("block `".$name."' does not have startBlock() AND endBlock().");
}
$block["body"] = $m[1];
$content["body"] = eregi_replace($reg, "{".$name."}", $content["body"]);
$content["blocks"][$name] = array();
$this->parse(&$block);
$content["blocks"][$name][0] = $block;
}
}
function toString() {
return $this->_toString(&$this->content, 0);
}
function _toString(&$content, $count) {
global $HTTP_SERVER_VARS;
$txt = $content["body"];
reset($content["values"]);
while (list($key, $val) = each($content["values"])) {
if (!is_numeric($key)) {
$txt = eregi_replace("{".$key."}", $val, $txt);
}
}
$txt = eregi_replace("{sid}", session_id(), $txt);
$txt = eregi_replace("{script}", $HTTP_SERVER_VARS["SCRIPT_NAME"], $txt);
while (eregi("{url

[^}]+)}", $txt, $m)) {
$txt = eregi_replace("{url:".$m[1]."}", urlencode($content["values"][$m[1]]), $txt);
}
while (eregi("{format

[^:]+)

[^}]+)}", $txt, $m)) {
$txt = eregi_replace("{format:".$m[1].":".$m[2]."}", sprintf($m[2], $content["values"][$m[1]]), $txt);
}
while (eregi("{date

[^:]+)

[^}]+)}", $txt, $m)) {
$txt = eregi_replace("{date:".$m[1].":".$m[2]."}", date($m[2], $content["values"][$m[1]]), $txt);
}
while (eregi("{ifEq

[^:]+)

[^:]+)

[^}]+)}", $txt, $m)) {
if ($content["values"][$m[1]] == $m[2]) {
$txt = eregi_replace("{ifEq:".$m[1].":".$m[2]."

[^}]+)}", "\\1", $txt);
} else {
$txt = eregi_replace("{ifEq:".$m[1].":".$m[2]."

[^}]+)}", "", $txt);
}
}
while (eregi("{ifNe

[^:]+)

[^:]*)

[^}]+)}", $txt, $m)) {
if ($content["values"][$m[1]] != $m[2]) {
$txt = eregi_replace("{ifNe:".$m[1].":".$m[2]."

[^}]+)}", "\\1", $txt);
} else {
$txt = eregi_replace("{ifNe:".$m[1].":".$m[2]."

[^}]+)}", "", $txt);
}
}
while (eregi("{ifSet

[^:]+)

[^}]+)}", $txt, $m)) {
if ($content["values"][$m[1]] != "" && $content["values"][$m[1]] != "0") {
$txt = eregi_replace("{ifSet:".$m[1]."

[^}]+)}", "\\1", $txt);
} else {
$txt = eregi_replace("{ifSet:".$m[1]."

[^}]+)}", "", $txt);
}
}
while (eregi("{ifNotSet

[^:]+)

[^}]+)}", $txt, $m)) {
if ($content["values"][$m[1]] == "" || $content["values"][$m[1]] == "0") {
$txt = eregi_replace("{ifNotSet:".$m[1]."

[^}]+)}", "\\1", $txt);
} else {
$txt = eregi_replace("{ifNotSet:".$m[1]."

[^}]+)}", "", $txt);
}
}
if (eregi("{ifNotFirst

[^}]+)}", $txt, $m)) {
if ($count == 0) {
$txt = eregi_replace("{ifNotFirst:".$m[1]."}", "", $txt);
} else {
$txt = eregi_replace("{ifNotFirst:".$m[1]."}", $m[1], $txt);
}
}
if (eregi("{ifOddPosition

[^}]+)}", $txt, $m)) {
if ($count % 2 == 1) {
$txt = eregi_replace("{ifOddPosition:".$m[1]."}", $m[1], $txt);
} else {
$txt = eregi_replace("{ifOddPosition:".$m[1]."}", "", $txt);
}
}
if (eregi("{ifEvenPosition

[^}]+)}", $txt, $m)) {
if ($count % 2 == 0) {
$txt = eregi_replace("{ifEvenPosition:".$m[1]."}", $m[1], $txt);
} else {
$txt = eregi_replace("{ifEvenPosition:".$m[1]."}", "", $txt);
}
}
$txt = eregi_replace("{count:1}", "".($count+1), $txt);
$txt = eregi_replace("{count:0}", "".($count), $txt);
reset ($content["blocks"]);
while (list($blockname, $block) = each($content["blocks"])) {
if (!is_numeric($blockname)) {
$rep = "";
for ($i = 0; $i < count($block); $i++) {
if ($block[$i]["used"]) {
$rep .= $this->_toString($block[$i], $i);
}
}
$txt = eregi_replace("{".$blockname."}", $rep, $txt);
}
}
return $txt;
}
function setVar($variable, $value) {
if (is_array($value)) {
if ($variable == "") {
$path = "";
} else {
$path = $variable.".";
}
reset($value);
while (list($var, $val) = each($value)) {
$this->_setVar($this->content, $path.$var, $val);
}
} else {
$value = $value."";
$this->_setVar($this->content, $variable, $value);
}
}
function _setVar(&$content, $variable, $value) {
if (eregi("([^\.]+)\.(.*)", $variable, $m)) {
$parent = $m[1];
$var = $m[2];
$content["used"] = 1;
$i = count($content["blocks"][$parent])-1;
if (isset($content["blocks"][$parent])) {
$this->_setVar($content["blocks"][$parent][$i], $var, $value);
}
} else {
$content["used"] = 1;
$content["values"][$variable] = $value;
}
}
function gotoNext($variable) {
$this->_gotoNext(&$this->content, $variable);
}
function _gotoNext(&$content, $variable) {
if (eregi("([^\.]+)\.(.*)", $variable, $m)) {
$parent = $m[1];
$var = $m[2];
$i = count($content["blocks"][$parent])-1;
$this->_gotoNext(&$content["blocks"][$parent][$i], $var);
} else {
$i = count($content["blocks"][$variable]);
if (count($content["blocks"][$variable][$i-1]["values"]) > 0) {
$content["blocks"][$variable][$i] = $this->_copyStructure($content["blocks"][$variable][$i-1]);
}
}
}
function &_copyStructure($content) {
$newcontent = array();
$newcontent["name"] = $content["name"];
$newcontent["body"] = $content["body"];
$newcontent["values"] = array();
$newcontent["blocks"] = array();
$newcontent["used"] = 0;
reset($content["blocks"]);
while (list($key, $value) = each($content["blocks"])) {
$newcontent["blocks"][$key] = array();
$newcontent["blocks"][$key][0] = $this->_copyStructure($content["blocks"][$key][0]);
}
return $newcontent;
}
function loadfile($filename) {
return implode("", file($filename));
}
function error($message) {
die($this->filename.": ".$message);
}
}
**** Then this is authman.inc
<?php
require($PHP_PATH."Template.inc");
require($PHP_PATH."UserManagement.inc");
class AuthManager {
var $um;
var $version = "0.1";
function AuthManager($dir = "") {
global $HTTP_SERVER_VARS;
if ($dir != "" && $dir[0] == "/") {
$dir = realpath($dir);
} else {
$dir = dirname(realpath($HTTP_SERVER_VARS["SCRIPT_FILENAME"]));
}
$userfile = "";
$groupfile = "";
while ($userfile == "" || $groupfile == "") {
if (file_exists($dir."/.htaccess")) {
$filename = $dir."/.htaccess";
if (is_readable($filename)) {
$f = file($filename);
while (list($ln, $l) = each($f)) {
if ($userfile == "" && eregi("authuserfile[\ \t]+([^\ \t\n]+)[\ \t\n]", $l, $m)) {
$userfile = $m[1];
}
if ($groupfile == "" && eregi("authgroupfile[\ \t]+([^\ \t\n]+)[\ \t\n]", $l, $m)) {
$groupfile = $m[1];
}
}
} else {
die($filename." is not readable.");
}
}
if ($dir == "/") {
break;
} else {
$dir = realpath($dir."/..");
}
}
if ($userfile == "") {
die("No users file found in your .htaccess files.");
}
if ($groupfile == "") {
die("No groups file found in your .htaccess files.");
}
$this->um = new UserManagement($userfile, $groupfile);
$this->main();
}
function main() {
global $HTTP_GET_VARS;
global $HTTP_POST_VARS;
if (isset($HTTP_GET_VARS["cmd"])) {
$cmd = $HTTP_GET_VARS["cmd"];
} else if (isset($HTTP_POST_VARS["cmd"])) {
$cmd = $HTTP_POST_VARS["cmd"];
} else {
$cmd = "list";
}
switch ($cmd) {
case "about":
$this->showAbout();
break;
case "list":
$this->showList();
break;
case "edituser":
$login = $HTTP_GET_VARS["user"];
$this->um->getUserGroups($login);
$this->editUser($login, $groups, $login);
break;
case "newuser":
$this->newUser();
break;
case "saveuser":
$this->saveUser();
break;
case "deleteuser":
$this->deleteUser();
break;
case "editgroup":
$group = $HTTP_GET_VARS["group"];
$this->editGroup($group, $group);
break;
case "newgroup":
$this->newGroup();
break;
case "savegroup":
$this->saveGroup();
break;
case "deletegroup":
$this->deleteGroup();
break;
case "addmember":
$this->addMember();
break;
case "deletemember":
$this->deleteMember();
break;
default:
die("Unknown command $cmd.");
}
}
function addMember() {
global $HTTP_GET_VARS;
$this->um->addMember($HTTP_GET_VARS["user"], $HTTP_GET_VARS["group"]);
$this->um->close();
$this->showList();
}
function deleteMember() {
global $HTTP_GET_VARS;
$this->um->deleteMember($HTTP_GET_VARS["user"], $HTTP_GET_VARS["group"]);
$this->um->close();
$this->showList();
}
function showAbout() {
$tpl = new Template("templates/main.ihtml");
$tpl->setVar("main", "AuthManager ".$this->version);
print $tpl->toString();
}
function showList() {
$t = new Template("templates/list.ihtml");
$users = $this->um->getUsers();
sort($users);
$groups = $this->um->getGroups();
sort($groups);
$t->setVar("groupnumber", 3*count($groups));
for ($i = 0; $i < count($groups); $i++) {
$t->gotoNext("group");
$t->setVar("group.name", $groups[$i]);
}
for ($i = 0; $i < count($users); $i++) {
$t->gotoNext("user");
$t->setVar("user.login", $users[$i]);
for ($j = 0; $j < count($groups); $j++) {
$t->gotoNext("user.ugroup");
if ($this->um->isMember($users[$i], $groups[$j])) {
$t->setVar("user.ugroup.status", 1);
} else {
$t->setVar("user.ugroup.status", 0);
}
$t->setVar("user.ugroup.name", $groups[$j]);
$t->setVar("user.ugroup.user", $users[$i]);
}
}
$tpl = new Template("templates/main.ihtml");
$tpl->setVar("main", $t->toString());
print $tpl->toString();
}
function newUser() {
$this->editUser("", array(), "");
}
function editUser($login = "", $groups = "", $oldlogin) {
global $HTTP_GET_VARS;
if ($groups == "") {
$groups = array();
}
$t = new Template("templates/edituser.ihtml");
$t->setVar("login", $login);
$t->setVar("oldlogin", $oldlogin);
$g = $this->um->getGroups();
for ($i = 0; $i < count($g); $i++) {
$t->gotoNext("group");
$t->setVar("group.name", $g[$i]);
if ($this->um->isMember($login, $g[$i])) {
$t->setVar("group.active", 1);
} else {
$t->setVar("group.active", 0);
}
}
$tpl = new Template("templates/main.ihtml");
$tpl->setVar("main", $t->toString());
print $tpl->toString();
}
function saveUser() {
global $HTTP_POST_VARS;
if (isset($HTTP_POST_VARS["cancel"])) {
$this->showList();
return;
}
$login = trim($HTTP_POST_VARS["login"]);
$oldlogin = trim($HTTP_POST_VARS["oldlogin"]);
$password = trim($HTTP_POST_VARS["password"]);
$groups = array();
$g = $this->um->getGroups();
for ($i = 0; $i < count($g); $i++) {
if (isset($HTTP_POST_VARS["group"][$g[$i]])) {
$groups[] = $g[$i];
}
}
if ($login == "" || ($oldlogin == "" && $password == "")) {
$this->editUser($login, $groups, $oldlogin);
return;
}
if ($oldlogin != "") {
$oldpassword = $this->um->getPassword($oldlogin);
$this->um->deleteUser($oldlogin);
}
$this->um->deleteUser($login);
if ($password != "") {
$this->um->addUser($login, crypt($password));
} else {
$this->um->addUser($login, $oldpassword);
}
for ($i = 0; $i < count($groups); $i++) {
$this->um->addMember($login, $groups[$i]);
}
$this->um->close();
$this->showList();
}
function deleteUser() {
global $HTTP_GET_VARS;
$this->um->deleteUser($HTTP_GET_VARS["user"]);
$this->um->close();
$this->showList();
}
function newGroup() {
$this->editGroup("", "");
}
function editGroup($group, $oldgroup) {
$t = new Template("templates/editgroup.ihtml");
$t->setVar("group", $group);
$t->setVar("oldgroup", $oldgroup);
$tpl = new Template("templates/main.ihtml");
$tpl->setVar("main", $t->toString());
print $tpl->toString();
}
function saveGroup() {
global $HTTP_POST_VARS;
if (isset($HTTP_POST_VARS["cancel"])) {
$this->showList();
return;
}
$group = trim($HTTP_POST_VARS["group"]);
$oldgroup = trim($HTTP_POST_VARS["oldgroup"]);
if ($group == "") {
$this->editGroup($group, $oldgroup);
return;
}
if ($oldgroup != "") {
$this->um->deleteGroup($oldgroup);
}
$this->um->deleteGroup($group);
$this->um->addGroup($group);
$this->um->close();
$this->showList();
}
function deleteGroup() {
global $HTTP_GET_VARS;
$this->um->deleteGroup($HTTP_GET_VARS["group"]);
$this->um->close();
$this->showList();
}
}
?>
****** and this is usermanagement.inc
<?php
class UserManagement {
var $userfile = "";
var $groupfile = "";
var $users;
var $groups;
var $changed = 0;
function UserManagement($userfile, $groupfile) {
if (!file_exists($userfile) && !is_writable(dirname($userfile))) {
die("File $userfile does not exist and the directory containing it is not writable.");
}
if (!is_readable($userfile)) {
die("File $userfile is not readable.");
}
if (!file_exists($groupfile) && !is_writable(dirname($groupfile))) {
die("File $groupfile does not exist and the directory containing it is not writable.");
}
if (!is_readable($groupfile)) {
die("File $groupfile is not readable.");
}
$this->userfile = $userfile;
$this->groupfile = $groupfile;
$this->open();
}
function open() {
$this->users = array();
$this->groups = array();
if (file_exists($this->userfile)) {
$f = file($this->userfile);
for ($ln = 0; $ln < count($f); $ln++) {
$tok = explode(":", ereg_replace("^([^#])#.*$", "\\1", trim($f[$ln])));
if (count($tok) >= 2) {
$this->users[] = array("username" => $tok[0], "password" => $tok[1], "groups" => array());
}
}
}
if (file_exists($this->groupfile)) {
$groups = array();
$f = file($this->groupfile);
for ($i = 0; $i < count($f); $i++) {
$tok = explode(":", ereg_replace("^([^#])#.*$", "\\1", trim($f[$i])));
if (count($tok) >= 2) {
$u = explode(" ", $tok[1]);
$users = array();
for ($j = 0; $j < count($u); $j++) {
$users[$u[$j]] = 1;
}
$groups[$tok[0]] = $users;
}
}
$this->groups = array_keys($groups);
for ($i = 0; $i < count($this->users); $i++) {
$user = $this->users[$i]["username"];
for ($j = 0; $j < count($this->groups); $j++) {
$group = $this->groups[$j];
if (isset($groups[$group][$user])) {
$this->users[$i]["groups"][$group] = 1;
} else {
$this->users[$i]["groups"][$group] = 0;
}
}
}
}
}
/**
* Saves the new password and group files if necessary.
*/
function close() {
if ($this->changed != 0) {
$usercontent = "";
for ($i = 0; $i < count($this->users); $i++) {
$usercontent .= sprintf("%s:%s\n", $this->users[$i]["username"], $this->users[$i]["password"]);
}
$groups = $this->getGroups();
$groupcontent = "";
for ($i = 0; $i < count($groups); $i++) {
$users = array();
for ($j = 0; $j < count($this->users); $j++) {
if ($this->users[$j]["groups"][$groups[$i]] == 1) {
$users[] = $this->users[$j]["username"];
}
}
$groupcontent .= sprintf("%s: %s\n", $groups[$i], implode(" ", $users));
}
$this->replaceFile($this->userfile, $usercontent);
$this->replaceFile($this->groupfile, $groupcontent);
}
}
function replaceFile($filename, $contents) {
$fd = fopen($filename.".new", "w");
if ($fd == false) {
die("Unable to create new file $filename.new");
}
fwrite($fd, $contents);
fclose($fd);
if (false == rename($filename.".new", $filename)) {
die("Unable to rename $filename.new to $filename");
}
}
/**
* Returns the names of all groups.
*
* @return Names of the groups.
*/
function getGroups() {
return $this->groups;
}
/**
* Returns the names of all users.
*
* @return Names of the users.
*/
function getUsers() {
$users = array();
for ($i = 0; $i < count($this->users); $i++) {
$users[] = $this->users[$i]["username"];
}
return $users;
}
/**
* Returns an array with the names of the groups a user is member of.
*
* @param $username Name of the user.
* @return Array containing the names of the groups.
*/
function getUserGroups($username) {
$groupnames = $this->getGroups();
for ($i = 0; $i < count($this->users); $i++) {
if ($this->users[$i]["username"] == $username) {
$groups = array();
for ($j = 0; $j < count($groupnames); $j++) {
if ($this->users[$i]["groups"][$groupnames[$j]] == 1) {
$groups[] = $groupnames[$j];
}
}
return $groups;
}
}
return array();
}
/**
* Returns the crypted password of a user.
*
* @param $username The name of the user.
* @return The crypted password.
*/
function getPassword($username) {
for ($i = 0; $i < count($this->users); $i++) {
if ($this->users[$i]["username"] == $username) {
return $this->users[$i]["password"];
}
}
return "";
}
/**
* Adds the group "groupname" to the list of groups.
*
* @param $groupname Name of the group to add.
*/
function addGroup($groupname) {
$this->changed = 1;
$this->groups[] = $groupname;
for ($i = 0; $i < count($this->users); $i++) {
$this->users[$i]["groups"][$groupname] = 0;
}
}
/**
* Removes a group from the list of groups.
*
* @param $groupname Name of the group to remove.
*/
function deleteGroup($groupname) {
$this->changed = 1;
$g = array();
for ($i = 0; $i < count($this->groups); $i++) {
if ($this->groups[$i] != $groupname) {
$g[] = $this->groups[$i];
}
}
$this->groups = $g;
for ($i = 0; $i < count($this->users); $i++) {
unset($this->users[$i]["groups"][$groupname]);
}
}
/**
* Deletes the user "username" from the list of users.
*
* @param $username Name of the user to delete.
*/
function deleteUser($username) {
$this->changed = 1;
$u = array();
for ($i = 0; $i < count($this->users); $i++) {
if ($this->users[$i]["username"] != $username) {
$u[] = $this->users[$i];
}
}
$this->users = $u;
}
/**
* Adds a user to the list of users.
*
* @param $username Name of the user to add.
* @param $password Crypted password of the user.
*/
function addUser($username, $password) {
$this->changed = 1;
$this->users[] = array("username" => $username, "password" => $password, "groups" => array());
}
/**
* Adds a user to a group.
*
* @param $username Name of the user to add.
* @param $groupname Name of the group.
*/
function addMember($username, $groupname) {
$this->changed = 1;
for ($i = 0; $i < count($this->users); $i++) {
if ($this->users[$i]["username"] == $username) {
$this->users[$i]["groups"][$groupname] = 1;
return;
}
}
}
/**
* Removes a user from a group.
*
* @param $username Name of the user to remove.
* @param $groupname Name of the group.
*/
function deleteMember($username, $groupname) {
$this->changed = 1;
for ($i = 0; $i < count($this->users); $i++) {
if ($this->users[$i]["username"] == $username) {
$this->users[$i]["groups"][$groupname] = 0;
return;
}
}
}
/**
* Checks if a user is member of a group.
*
* @param $username Name of the user.
* @param $groupname Name of the group.
* @return 1 if the user is member of the group, 0 otherwise.
*/
function isMember($username, $groupname) {
for ($i = 0; $i < count($this->users); $i++) {
if ($this->users[$i]["username"] == $username) {
return $this->users[$i]["groups"][$groupname];
}
}
return 0;
}
/**
* Returns a string representation of this object.
*/
function toString() {
$s = "";
$users = $this->getUsers();
for ($i = 0; $i < count($users); $i++) {
$s .= sprintf("%s: ", $users[$i]);
$groups = $this->getUserGroups($users[$i]);
$s .= implode(", ", $groups);
$s .= "\n";
}
return $s;
}
}
?>