From c79a62443b72506b46566b219e0e7be6359054f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81ro=CC=82me=20Schneider?= Date: Mon, 12 Mar 2012 13:20:49 +0100 Subject: [PATCH] Added first implementation of admin web interface --- .gitignore | 1 + CoreVersions/Baikal_0.1/BaikalAdmin.php | 75 +++++++++++++++ CoreVersions/Baikal_0.1/BaikalTools.php | 46 +++++++++ CoreVersions/Baikal_0.1/Bootstrap.php | 7 +- CoreVersions/Baikal_0.1/Frameworks/Tabulator | 1 + .../Versions/Tabulator.0.0.1/Colorize.php | 63 ++++++++++++ .../Tabulator.0.0.1/Tabulator.cli.php | 81 ++++++++++++++++ .../Tabulator.0.0.1/Tabulator.html.php | 50 ++++++++++ .../Versions/Tabulator.0.0.1/Tabulator.php | 79 +++++++++++++++ .../Tabulator.0.0.1/TabulatorColumn.php | 96 +++++++++++++++++++ CoreVersions/Baikal_0.1/WWWRoot/admin.php | 39 ++++++++ Specific/config.php | 5 +- html/admin.php | 1 + 13 files changed, 541 insertions(+), 3 deletions(-) create mode 100644 .gitignore create mode 100644 CoreVersions/Baikal_0.1/BaikalAdmin.php create mode 100644 CoreVersions/Baikal_0.1/BaikalTools.php create mode 120000 CoreVersions/Baikal_0.1/Frameworks/Tabulator create mode 100644 CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/Colorize.php create mode 100644 CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/Tabulator.cli.php create mode 100644 CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/Tabulator.html.php create mode 100644 CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/Tabulator.php create mode 100644 CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/TabulatorColumn.php create mode 100644 CoreVersions/Baikal_0.1/WWWRoot/admin.php create mode 120000 html/admin.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4f0a495 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +Specific/ENABLE_ADMIN diff --git a/CoreVersions/Baikal_0.1/BaikalAdmin.php b/CoreVersions/Baikal_0.1/BaikalAdmin.php new file mode 100644 index 0000000..09e433c --- /dev/null +++ b/CoreVersions/Baikal_0.1/BaikalAdmin.php @@ -0,0 +1,75 @@ + +* All rights reserved +* +* http://baikal.codr.fr +* +* This script is part of the Baïkal Server project. The Baïkal +* Server project 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. +* +* The GNU General Public License can be found at +* http://www.gnu.org/copyleft/gpl.html. +* +* 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. +* +* This copyright notice MUST APPEAR in all copies of the script! +***************************************************************/ + +require_once(BAIKAL_PATH_FRAMEWORKS . "Tabulator/Tabulator.html.php"); + +class BaikalAdmin { + + static function assertEnabled() { + if(!defined("BAIKAL_ADMIN_ENABLED") || BAIKAL_ADMIN_ENABLED !== TRUE) { + die("

Baïkal Admin is disabled.

To enable it, set BAIKAL_ADMIN_ENABLED to TRUE in Specific/config.php"); + } + + $bLocked = TRUE; + $sEnableFile = BAIKAL_PATH_SPECIFIC . "ENABLE_ADMIN"; + if(file_exists($sEnableFile)) { + + clearstatcache(); + $iTime = intval(filemtime($sEnableFile)); + if((time() - $iTime) < 3600) { + // file has been created more than an hour ago + // delete and declare locked + + $bLocked = FALSE; + } else { + if(!@unlink($sEnableFile)) { + die("

Baïkal Admin is locked.

To unlock it, delete and re-create an empty file named ENABLE_ADMIN in Specific/config.php"); + } + } + } + + if($bLocked) { + die("

Baïkal Admin is locked.

To unlock it, create an empty file named ENABLE_ADMIN in Specific/config.php"); + } else { + // update filemtime + @touch($sEnableFile); + } + } + + static function displayUsers() { + $aUsers = BaikalTools::getUsers(); + + $oTabulator = new TabulatorHtml(); + $oTabulator->addColumn(self::makeColumn("id", "Id", "numeric")); + $oTabulator->addColumn(self::makeColumn("username", "Username")); + $oTabulator->render($aUsers); + } + + function &makeColumn($sName, $sHeader = "", $sType = "text") { + $oColumn = new TabulatorColumnHtml($sName, $sHeader, $sType); + return $oColumn; + } +} \ No newline at end of file diff --git a/CoreVersions/Baikal_0.1/BaikalTools.php b/CoreVersions/Baikal_0.1/BaikalTools.php new file mode 100644 index 0000000..bd79b21 --- /dev/null +++ b/CoreVersions/Baikal_0.1/BaikalTools.php @@ -0,0 +1,46 @@ + +* All rights reserved +* +* http://baikal.codr.fr +* +* This script is part of the Baïkal Server project. The Baïkal +* Server project 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. +* +* The GNU General Public License can be found at +* http://www.gnu.org/copyleft/gpl.html. +* +* 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. +* +* This copyright notice MUST APPEAR in all copies of the script! +***************************************************************/ + +class BaikalTools { + public static function &db() { + return $GLOBALS["pdo"]; + } + + public static function getUsers() { + + $aUsers = array(); + + # Fetching user + $stmt = BaikalTools::db()->prepare("SELECT * FROM users"); + $stmt->execute(); + while(($user = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_FIRST)) !== FALSE) { + $aUsers[] = $user; + } + + reset($aUsers); + return $aUsers; + } +} \ No newline at end of file diff --git a/CoreVersions/Baikal_0.1/Bootstrap.php b/CoreVersions/Baikal_0.1/Bootstrap.php index 2391dad..c91ccdd 100644 --- a/CoreVersions/Baikal_0.1/Bootstrap.php +++ b/CoreVersions/Baikal_0.1/Bootstrap.php @@ -58,6 +58,7 @@ if(@file_exists($sTemp) && (@is_dir($sTemp . "Core") || @is_link($sTemp . "Core" define("BAIKAL_PATH_CORE", BAIKAL_PATH_ROOT . "Core/"); define("BAIKAL_PATH_SPECIFIC", BAIKAL_PATH_ROOT . "Specific/"); +define("BAIKAL_PATH_FRAMEWORKS", BAIKAL_PATH_CORE . "Frameworks/"); require_once(BAIKAL_PATH_SPECIFIC . "config.php"); @@ -72,15 +73,17 @@ if(!file_exists(BAIKAL_SQLITE_FILE)) { $pdo = new PDO('sqlite:' . BAIKAL_SQLITE_FILE); $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); +$bShouldCheckEnv = ((!defined("BAIKAL_CONTEXT_CLI") || BAIKAL_CONTEXT_CLI === FALSE) && (!defined("BAIKAL_CONTEXT_ADMIN") || BAIKAL_CONTEXT_ADMIN === FALSE)); + # Check if at least one user exists -if(!defined("BAIKAL_CONTEXT_CLI") || BAIKAL_CONTEXT_CLI === FALSE) { +if($bShouldCheckEnv === TRUE) { if(($iNbUsers = intval($pdo->query('SELECT count(*) FROM users')->fetchColumn())) === 0) { die("No users are defined.
To create a user, you can use the helper Core/Scripts/adduser.php (requires command line access)"); } } -if(!defined("BAIKAL_CONTEXT_CLI") || BAIKAL_CONTEXT_CLI === FALSE) { +if($bShouldCheckEnv === TRUE) { # Mapping PHP errors to exceptions function exception_error_handler($errno, $errstr, $errfile, $errline) { throw new ErrorException($errstr, 0, $errno, $errfile, $errline); diff --git a/CoreVersions/Baikal_0.1/Frameworks/Tabulator b/CoreVersions/Baikal_0.1/Frameworks/Tabulator new file mode 120000 index 0000000..0b866b4 --- /dev/null +++ b/CoreVersions/Baikal_0.1/Frameworks/Tabulator @@ -0,0 +1 @@ +Versions/Tabulator.0.0.1 \ No newline at end of file diff --git a/CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/Colorize.php b/CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/Colorize.php new file mode 100644 index 0000000..0d817db --- /dev/null +++ b/CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/Colorize.php @@ -0,0 +1,63 @@ + "1;30", + "dark_gray" => "1;30", + "blue" => "0;34", + "light_blue" => "1;34", + "green" => "0;32", + "light_green" => "1;32", + "cyan" => "0;36", + "light_cyan" => "1;36", + "red" => "0;31", + "light_red" => "1;31", + "purple" => "0;35", + "light_purple" => "1;35", + "brown" => "0;33", + "yellow" => "1;33", + "light_gray" => "0;37", + "white" => "1;37" + ); + + private static $background_colors = array( + "black" => "40", + "red" => "41", + "green" => "42", + "yellow" => "43", + "blue" => "44", + "magenta" => "45", + "cyan" => "46", + "light_gray" => "47" + ); + + // Returns colored string + public function getColoredString($string, $foreground_color = null, $background_color = null) { + $colored_string = ""; + + // Check if given foreground color found + if (isset(self::$foreground_colors[$foreground_color])) { + $colored_string .= "\033[" . self::$foreground_colors[$foreground_color] . "m"; + } + // Check if given background color found + if (isset(self::$background_colors[$background_color])) { + $colored_string .= "\033[" . self::$background_colors[$background_color] . "m"; + } + + // Add string and end coloring + $colored_string .= $string . "\033[0m"; + + return $colored_string; + } + + // Returns all foreground color names + public function getForegroundColors() { + return array_keys(self::$foreground_colors); + } + + // Returns all background color names + public function getBackgroundColors() { + return array_keys(self::$background_colors); + } +} \ No newline at end of file diff --git a/CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/Tabulator.cli.php b/CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/Tabulator.cli.php new file mode 100644 index 0000000..256b314 --- /dev/null +++ b/CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/Tabulator.cli.php @@ -0,0 +1,81 @@ + $this->iLen) { + $this->iLen = $iLen; + } + } + + protected function wrap($sString) { + if($this->getType() === "numeric") { + $sPadType = STR_PAD_LEFT; + } else { + $sPadType = STR_PAD_RIGHT; + } + + return $this->mb_str_pad($sString, $this->iLen, " ", $sPadType); + } + + public function renderUnderline() { + return $this->wrap(str_repeat("-", $this->iLen)); + } + + protected function mb_str_pad($input, $pad_length, $pad_string=' ', $pad_type=STR_PAD_RIGHT) { + $diff = intval(mb_strlen($input, "latin1") - mb_strlen($input, "utf8")); + return str_pad($input, $pad_length+$diff, $pad_string, $pad_type); + } +} + +class TabulatorCli extends Tabulator { + + public function getSep() { + return " "; + } + + public function repeatHeadersEvery() { + return 10; + } + + protected function wrapHeaders($sHeaders) { + + $aHeaderUnderline = array(); + reset($this->aColumns); + while(list($sName,) = each($this->aColumns)) { + $aHeaderUnderline[] = $this->aColumns[$sName]->renderUnderline(); + } + + $sHeaders = Colorize::getColoredString($sHeaders, "white", "red"); + #$sUnderline = Colorize::getColoredString(implode($this->getSep(), $aHeaderUnderline), "white", "red"); + + #return "\n" . $sHeaders . "\n" . $sUnderline . "\n"; + return "\n" . $sHeaders . "\n"; + } + + protected function wrapValues($sValues, $iRowNum) { + if(($iRowNum % 2) === 0) { + return Colorize::getColoredString($sValues, "light_gray") . "\n"; + } + + return $sValues . "\n"; + } + + function renderOpen() { + return ""; + } + + function renderClose() { + return ""; + } +} diff --git a/CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/Tabulator.html.php b/CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/Tabulator.html.php new file mode 100644 index 0000000..49780ab --- /dev/null +++ b/CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/Tabulator.html.php @@ -0,0 +1,50 @@ +getType(), array("numeric", "duration"))) { + $sAlign = "right"; + } else { + $sAlign = "left"; + } + + return "getName() . " align-" . $sAlign . "\">" . $sString . ""; + } + + public function renderUnderline() { + return $this->wrap(str_repeat("-", $this->iLen)); + } +} + +class TabulatorHtml extends Tabulator { + + public function getSep() { + return ""; + } + + protected function wrapHeaders($sHeaders) { + return "" . $sHeaders . ""; + } + + protected function wrapValues($sValues, $iRowNum) { + $sClass = (($iRowNum % 2) === 0) ? "even" : "odd"; + return "" . $sValues . ""; + } + + function renderOpen() { + return ""; + } + + function renderClose() { + return "
"; + } + + public function repeatHeadersEvery() { + return 30; + } +} diff --git a/CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/Tabulator.php b/CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/Tabulator.php new file mode 100644 index 0000000..3c002e7 --- /dev/null +++ b/CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/Tabulator.php @@ -0,0 +1,79 @@ +aColumns[$oColumn->getName()] = $oColumn; + } + + public function hasColumn($sName) { + return array_key_exists($sName, $this->aColumns); + } + + public function &getColumn($sName) { + return $this->aColumns[$sName]; + } + + protected function renderHeader() { + + $aHeaderLine = array(); + + # on rend les entêtes + reset($this->aColumns); + while(list($sName,) = each($this->aColumns)) { + $aHeaderLine[] = $this->aColumns[$sName]->renderHeader(); + } + + return $this->wrapHeaders(implode($this->getSep(), $aHeaderLine)); + } + + protected function renderValues() { + $aRes = array(); + + for($k = 0; $k < $this->iNbValues; $k++) { + $aLine = array(); + reset($this->aColumns); + while(list($sName,) = each($this->aColumns)) { + $aLine[] = $this->aColumns[$sName]->renderValueAtIndex($k); + } + + $aRes[] = $this->wrapValues(implode($this->getSep(), $aLine), $k); + + if((($k+1) % $this->repeatHeadersEvery()) === 0 && ($k+1 < $this->iNbValues)) { + $aRes[] = $this->renderHeader(); + } + } + + return implode("", $aRes) . "\n"; + } + + public function render($aValues) { + + $this->iNbValues = count($aValues); + + reset($aValues); + while(list($iRow,) = each($aValues)) { + reset($aValues[$iRow]); + while(list($sColumnName,) = each($aValues[$iRow])) { + if($this->hasColumn($sColumnName)) { + $this->getColumn($sColumnName)->addValue($aValues[$iRow][$sColumnName]); + } + } + } + + echo $this->renderOpen(); + echo $this->renderHeader(); + echo $this->renderValues(); + echo $this->renderClose(); + } + + abstract protected function getSep(); + abstract protected function wrapHeaders($sHeaders); + abstract protected function wrapValues($sValues, $iRowNum); + abstract protected function renderOpen(); + abstract protected function renderClose(); + abstract protected function repeatHeadersEvery(); +} \ No newline at end of file diff --git a/CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/TabulatorColumn.php b/CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/TabulatorColumn.php new file mode 100644 index 0000000..ad6fca4 --- /dev/null +++ b/CoreVersions/Baikal_0.1/Frameworks/Versions/Tabulator.0.0.1/TabulatorColumn.php @@ -0,0 +1,96 @@ +sHeader = $sHeader; + $this->iLen = mb_strlen($sHeader, "utf8"); + $this->sName = $sName; + $this->sType = $sType; + } + + public function getName() { + return $this->sName; + } + + public function getHeader() { + return $this->sHeader; + } + + public function getType() { + return $this->sType; + } + + public function getValueAtIndex($iIndex) { + if($this->getType() === "duration") { + return $this->humanDuration( + $this->aValues[$iIndex] * 60 + ); + } + + return $this->aValues[$iIndex]; + } + + public function addValue($sValue) { + $this->aValues[] = $sValue; + } + + public function renderValueAtIndex($iIndex) { + return $this->wrap($this->getValueAtIndex($iIndex)); + } + + public function renderHeader() { + $sString = $this->getHeader(); + + if(array_key_exists("headerinnerwrap", $this->aCallbacks)) { + $sString = call_user_func($this->aCallbacks["headerinnerwrap"], $this, $sString); + } + + return $this->wrapHeader($sString); + } + + public function humanDuration($iSeconds) { + + $units = array( +# "w" => 7*24*3600, +# "j" => 24*3600, + "h" => 3600, + "m" => 60, + "s" => 1, + ); + + // specifically handle zero + if($iSeconds == 0) { + return "0 second"; + } + + $s = ""; + + foreach ( $units as $name => $divisor ) { + if ( $quot = intval($iSeconds / $divisor) ) { + $s .= $quot . $name; + #$s .= (abs($quot) > 1 ? "s" : "") . ""; + $iSeconds -= $quot * $divisor; + } + } + + return $s; + #return substr($s, 0, -2); + } + + public function setHeaderInnerWrapCallback($aCallback) { + $this->aCallbacks["headerinnerwrap"] = $aCallback; + } + + protected function wrapHeader($sString) { + return $this->wrap($sString); + } + + abstract protected function wrap($sString); + abstract public function renderUnderline(); +} \ No newline at end of file diff --git a/CoreVersions/Baikal_0.1/WWWRoot/admin.php b/CoreVersions/Baikal_0.1/WWWRoot/admin.php new file mode 100644 index 0000000..5ee0268 --- /dev/null +++ b/CoreVersions/Baikal_0.1/WWWRoot/admin.php @@ -0,0 +1,39 @@ + +* All rights reserved +* +* http://baikal.codr.fr +* +* This script is part of the Baïkal Server project. The Baïkal +* Server project 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. +* +* The GNU General Public License can be found at +* http://www.gnu.org/copyleft/gpl.html. +* +* 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. +* +* This copyright notice MUST APPEAR in all copies of the script! +***************************************************************/ + +ini_set("display_errors", 1); +error_reporting(E_ALL); +define("BAIKAL_CONTEXT", TRUE); +define("BAIKAL_CONTEXT_ADMIN", TRUE); +require_once("../Core/Bootstrap.php"); +require_once(BAIKAL_PATH_CORE . "BaikalAdmin.php"); +require_once(BAIKAL_PATH_CORE . "BaikalTools.php"); + +BaikalAdmin::assertEnabled(); + +echo "

Baïkal Admin

"; + +BaikalAdmin::displayUsers(); \ No newline at end of file diff --git a/Specific/config.php b/Specific/config.php index c04a451..5fef1a0 100755 --- a/Specific/config.php +++ b/Specific/config.php @@ -11,6 +11,9 @@ define("BAIKAL_TIMEZONE", "Europe/Paris"); # WEB absolute URI define("BAIKAL_BASEURI", "http://dav.mydomain.com/"); +# WEB absolute URI +define("BAIKAL_ADMIN_ENABLED", TRUE); + ############################################################################## # In this section: Optional configuration: you *may* customize these settings @@ -34,7 +37,7 @@ define("BAIKAL_CAL_ENABLED", TRUE); # # PATH to SabreDAV -define("BAIKAL_PATH_SABREDAV", BAIKAL_PATH_CORE . "Frameworks/SabreDAV/lib/Sabre/"); +define("BAIKAL_PATH_SABREDAV", BAIKAL_PATH_FRAMEWORKS . "SabreDAV/lib/Sabre/"); # If you change this value, you'll have to re-generate passwords for all your users define("BAIKAL_AUTH_REALM", "BaikalDAV"); diff --git a/html/admin.php b/html/admin.php new file mode 120000 index 0000000..66bc44e --- /dev/null +++ b/html/admin.php @@ -0,0 +1 @@ +../Core/WWWRoot/admin.php \ No newline at end of file