diff options
30 files changed, 815 insertions, 562 deletions
diff --git a/inc/user.inc.php b/inc/user.inc.php index b333c7e4..19d17753 100644 --- a/inc/user.inc.php +++ b/inc/user.inc.php @@ -25,6 +25,9 @@ class User public static function load() { + if (self::isLoggedIn()) { + return true; + } if (Session::load()) { $uid = Session::get('uid'); if ($uid === false || $uid < 1) self::logout(); @@ -50,7 +53,7 @@ class User public static function logout() { Session::delete(); - Header('Location: ?do=main&fromlogout'); + Header('Location: ?do=Main&fromlogout'); exit(0); } @@ -1,51 +1,89 @@ <?php +/** + * Page class which all "modules" must be extending from + */ +abstract class Page +{ + protected function doPreprocess() {} + protected function doRender() {} + protected function doAjax() {} + public static function preprocess() { self::$instance->doPreprocess(); } + public static function render() { self::$instance->doRender(); } + public static function ajax() { self::$instance->doAjax(); } + /** + * + * @var \Page + */ + private static $instance = false; + public static function set($name) + { + $name = preg_replace('/[^A-Za-z]/', '', $name); + $modulePath = 'modules/' . strtolower($name) . '.inc.php'; + if (!file_exists($modulePath)) { + Util::traceError('Invalid module file: ' . $modulePath); + } + require_once $modulePath; + $className = 'Page_' . $name; + if (!class_exists($className) || get_parent_class($className) !== 'Page') { + Util::traceError('Module not found: ' . $name); + } + self::$instance = new $className(); + } +} + +// Error reporting (hopefully goind to stderr, not being printed on pages) error_reporting(E_ALL); +// Set variable if this is an ajax request +$isAsync = (isset($_REQUEST['async'])) + || (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'); + // Autoload classes from ./inc which adhere to naming scheme <lowercasename>.inc.php function slxAutoloader($class) { $file = 'inc/' . preg_replace('/[^a-z0-9]/', '', mb_strtolower($class)) . '.inc.php'; if (!file_exists($file)) return; require_once $file; } - spl_autoload_register('slxAutoloader'); -if (empty($_REQUEST['do'])) { - // No specific module - set default - $moduleName = 'main'; -} else { - $moduleName = preg_replace('/[^a-z]/', '', $_REQUEST['do']); -} +// Now determine which module to run +Page::set(empty($_REQUEST['do']) ? 'Main' : $_REQUEST['do']); -$modulePath = 'modules/' . $moduleName . '.inc.php'; - -if (!file_exists($modulePath)) { - Util::traceError('Invalid module: ' . $moduleName); +// Deserialize any messages to display +if (!$isAsync && isset($_REQUEST['message'])) { + Message::fromRequest(); } -// Deserialize any messages -if (isset($_REQUEST['message'])) { - Message::fromRequest(); +// CSRF/XSS check +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + User::load(); + if (!Util::verifyToken()) { + if ($isAsync) { + die('CSRF/XSS? Missing token in POST request!'); + } else { + Util::redirect('?do=Main'); + } + } } -// CSRF/XSS -if ($_SERVER['REQUEST_METHOD'] === 'POST' && !Util::verifyToken()) { - Util::redirect('?do=' . $moduleName); +// AJAX Stuff? Just do so. Otherwise, run preprocessing +if ($isAsync) { + Page::ajax(); + exit(0); } -// Load module - it will execute pre-processing, or act upon request parameters -require_once($modulePath); -unset($modulePath); +// Normal mode - preprocess first.... +Page::preprocess(); -// Main menu +// Generate Main menu $menu = new Menu; Render::addTemplate('main-menu', $menu); Message::renderList(); -// Render module. If the module wants to output anything, it will be done here -render_module(); +// Render page. If the module wants to output anything, it will be done here... +Page::render(); if (defined('CONFIG_DEBUG') && CONFIG_DEBUG) { Message::addWarning('debug-mode'); @@ -53,4 +91,3 @@ if (defined('CONFIG_DEBUG') && CONFIG_DEBUG) { // Send page to client. Render::output(); - diff --git a/modules/adduser.inc.php b/modules/adduser.inc.php index f152643b..6a5faf3a 100644 --- a/modules/adduser.inc.php +++ b/modules/adduser.inc.php @@ -6,13 +6,13 @@ if (isset($_POST['action']) && $_POST['action'] === 'adduser') { // Check required fields if (empty($_POST['user']) || empty($_POST['pass1']) || empty($_POST['pass2']) || empty($_POST['fullname']) || empty($_POST['phone']) || empty($_POST['email'])) { Message::addError('empty-field'); - Util::redirect('?do=adduser'); + Util::redirect('?do=AddUser'); } elseif ($_POST['pass1'] !== $_POST['pass2']) { Message::addError('password-mismatch'); - Util::redirect('?do=adduser'); + Util::redirect('?do=AddUser'); } elseif (Database::queryFirst('SELECT userid FROM user LIMIT 1') !== false) { Message::addError('adduser-disabled'); - Util::redirect('?do=session&action=login'); + Util::redirect('?do=Session&action=login'); } else { $data = array( 'user' => $_POST['user'], @@ -31,7 +31,7 @@ if (isset($_POST['action']) && $_POST['action'] === 'adduser') { Database::exec('UPDATE user SET permissions = 1'); } Message::addInfo('adduser-success'); - Util::redirect('?do=session&action=login'); + Util::redirect('?do=Session&action=login'); } } diff --git a/modules/baseconfig.inc.php b/modules/baseconfig.inc.php index 80dc6cd5..99e7f1bb 100644 --- a/modules/baseconfig.inc.php +++ b/modules/baseconfig.inc.php @@ -1,94 +1,97 @@ <?php -User::load(); - -// Determine if we're setting global, distro or pool -$qry_extra = array(); -if (isset($_REQUEST['distroid'])) { - // TODO: Everything - $qry_extra[] = array( - 'name' => 'distroid', - 'value' => (int)$_REQUEST['distroid'], - 'table' => 'setting_distro', - ); - if (isset($_REQUEST['poolid'])) { - $qry_extra[] = array( - 'name' => 'poolid', - 'value' => (int)$_REQUEST['poolid'], - 'table' => 'setting_pool', - ); - } -} +class Page_BaseConfig extends Page +{ + private $qry_extra = array(); + protected function doPreprocess() + { + User::load(); -if (isset($_POST['setting']) && is_array($_POST['setting'])) { - if (User::hasPermission('superadmin')) { - if (Util::verifyToken()) { - // Build variables for specific sub-settings - $qry_insert = ''; - $qry_values = ''; - foreach ($qry_extra as $item) { - $qry_insert = ', ' . $item['name']; - $qry_values = ', :' . $item['name']; + // Determine if we're setting global, distro or pool + if (isset($_REQUEST['distroid'])) { + // TODO: Everything + $this->qry_extra[] = array( + 'name' => 'distroid', + 'value' => (int)$_REQUEST['distroid'], + 'table' => 'setting_distro', + ); + if (isset($_REQUEST['poolid'])) { + $this->qry_extra[] = array( + 'name' => 'poolid', + 'value' => (int)$_REQUEST['poolid'], + 'table' => 'setting_pool', + ); } - // Load all existing config options to validate input - $res = Database::simpleQuery('SELECT setting, validator FROM setting'); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $key = $row['setting']; - $validator = $row['validator']; - $input = (isset($_POST['setting'][$key]) ? $_POST['setting'][$key] : ''); - // Validate data first! - $value = Validator::validate($validator, $input); - if ($value === false) { - Message::addWarning('value-invalid', $key, $input); - continue; + } + + if (isset($_POST['setting']) && is_array($_POST['setting'])) { + if (User::hasPermission('superadmin')) { + // Build variables for specific sub-settings + $qry_insert = ''; + $qry_values = ''; + foreach ($this->qry_extra as $item) { + $qry_insert = ', ' . $item['name']; + $qry_values = ', :' . $item['name']; } - // Now put into DB - Database::exec("INSERT INTO setting_global (setting, value $qry_insert) - VALUES (:key, :value $qry_values) - ON DUPLICATE KEY UPDATE value = :value", - $qry_extra + array( - 'key' => $key, - 'value' => $value, - ) - ); + // Load all existing config options to validate input + $res = Database::simpleQuery('SELECT setting, validator FROM setting'); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $key = $row['setting']; + $validator = $row['validator']; + $input = (isset($_POST['setting'][$key]) ? $_POST['setting'][$key] : ''); + // Validate data first! + $value = Validator::validate($validator, $input); + if ($value === false) { + Message::addWarning('value-invalid', $key, $input); + continue; + } + // Now put into DB + Database::exec("INSERT INTO setting_global (setting, value $qry_insert) + VALUES (:key, :value $qry_values) + ON DUPLICATE KEY UPDATE value = :value", + $this->qry_extra + array( + 'key' => $key, + 'value' => $value, + ) + ); + } + Message::addSuccess('settings-updated'); + Util::redirect('?do=BaseConfig'); } - Message::addSuccess('settings-updated'); - Util::redirect('?do=baseconfig'); } } -} -function render_module() -{ - if (!User::hasPermission('superadmin')) { - Message::addError('no-permission'); - return; - } - // Build left joins for specific settings - global $qry_extra; - $joins = ''; - foreach ($qry_extra as $item) { - $joins .= " LEFT JOIN ${item['table']} "; - } - // List global config option - $settings = array(); - $res = Database::simpleQuery('SELECT cat_setting.name AS category_name, setting.setting, setting.defaultvalue, setting.permissions, setting.description, tbl.value - FROM setting - INNER JOIN cat_setting USING (catid) - LEFT JOIN setting_global AS tbl USING (setting) - ORDER BY cat_setting.sortval ASC, setting.setting ASC'); // TODO: Add setting groups and sort order - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $row['description'] = Util::markup($row['description']); - if (is_null($row['value'])) $row['value'] = $row['defaultvalue']; - $row['big'] = false; - $settings[$row['category_name']]['settings'][] = $row; - $settings[$row['category_name']]['category_name'] = $row['category_name']; + protected function doRender() + { + if (!User::hasPermission('superadmin')) { + Message::addError('no-permission'); + return; + } + // Build left joins for specific settings + $joins = ''; + foreach ($this->qry_extra as $item) { + $joins .= " LEFT JOIN {$item['table']} "; + } + // List global config option + $settings = array(); + $res = Database::simpleQuery('SELECT cat_setting.name AS category_name, setting.setting, setting.defaultvalue, setting.permissions, setting.description, tbl.value + FROM setting + INNER JOIN cat_setting USING (catid) + LEFT JOIN setting_global AS tbl USING (setting) + ORDER BY cat_setting.sortval ASC, setting.setting ASC'); // TODO: Add setting groups and sort order + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $row['description'] = Util::markup($row['description']); + if (is_null($row['value'])) $row['value'] = $row['defaultvalue']; + $row['big'] = false; + $settings[$row['category_name']]['settings'][] = $row; + $settings[$row['category_name']]['category_name'] = $row['category_name']; + } + $settings = array_values($settings); + Render::addTemplate('page-baseconfig', array( + 'categories' => $settings, + 'token' => Session::get('token'), + )); } - $settings = array_values($settings); - Render::addTemplate('page-baseconfig', array( - 'categories' => $settings, - 'token' => Session::get('token'), - )); -} +} diff --git a/modules/ipxe.inc.php b/modules/ipxe.inc.php index 869f4c72..d479bd15 100644 --- a/modules/ipxe.inc.php +++ b/modules/ipxe.inc.php @@ -1,35 +1,40 @@ <?php -User::load(); +class Page_iPxe extends Page +{ -if (!User::hasPermission('superadmin')) { - Message::addError('no-permission'); - Util::redirect('?do=main'); -} + protected function doPreprocess() + { + User::load(); + + if (!User::hasPermission('superadmin')) { + Message::addError('no-permission'); + Util::redirect('?do=Main'); + } -if (isset($_POST['action'])) { - if ($_POST['action'] === 'compile') { - if (!Util::verifyToken()) { - Util::redirect('?do=main'); + if (isset($_POST['action'])) { + if ($_POST['action'] === 'compile') { + if (!Util::verifyToken()) { + Util::redirect('?do=Main'); + } + } } } -} -function render_module() -{ - $ips = array(); - $current = CONFIG_IPXE_DIR . '/last-ip'; - if (file_exists($current)) $current = file_get_contents($current); - exec('/bin/ip a', $retval); - foreach ($retval as $ip) { - if (preg_match('#inet (\d+\.\d+\.\d+\.\d+)/\d+.*scope#', $ip, $out) && $out[1] !== '127.0.0.1') { - $ips[] = array( - 'ip' => $out[1], - 'current' => ($out[1] == $current) - ); + protected function doRender() + { + $ips = array(); + $current = CONFIG_IPXE_DIR . '/last-ip'; + if (file_exists($current)) $current = file_get_contents($current); + exec('/bin/ip a', $retval); + foreach ($retval as $ip) { + if (preg_match('#inet (\d+\.\d+\.\d+\.\d+)/\d+.*scope#', $ip, $out) && $out[1] !== '127.0.0.1') { + $ips[] = array( + 'ip' => $out[1], + 'current' => ($out[1] == $current) + ); + } } + Render::addTemplate('page-ipxe', array('ips' => $ips, 'token' => Session::get('token'))); } - Render::addTemplate('page-ipxe', array('ips' => $ips, 'token' => Session::get('token'))); } - - diff --git a/modules/main.inc.php b/modules/main.inc.php index 24f519c6..3b35ad53 100644 --- a/modules/main.inc.php +++ b/modules/main.inc.php @@ -1,27 +1,34 @@ <?php -User::load(); - -function render_module() +class Page_Main extends Page { - // Render::setTitle('abc'); - - if (!User::isLoggedIn()) { - Render::addTemplate('page-main-guest'); - return; + + protected function doPreprocess() + { + User::load(); } - // Logged in here - $ipxe = true; - $file = CONFIG_IPXE_DIR . '/last-ip'; - if (file_exists($file)) { - $last = file_get_contents($file); - exec('/bin/ip a', $ips); - foreach ($ips as $ip) { - if (preg_match("#inet $last/\d+.*scope#", $ip)) $ipxe = false; + + protected function doRender() + { + // Render::setTitle('abc'); + + if (!User::isLoggedIn()) { + Render::addTemplate('page-main-guest'); + return; } + // Logged in here + $ipxe = true; + $file = CONFIG_IPXE_DIR . '/last-ip'; + if (file_exists($file)) { + $last = file_get_contents($file); + exec('/bin/ip a', $ips); + foreach ($ips as $ip) { + if (preg_match("#inet $last/\d+.*scope#", $ip)) $ipxe = false; + } + } + $sysconfig = !file_exists(CONFIG_HTTP_DIR . '/default/config.tgz'); + $minilinux = !file_exists(CONFIG_HTTP_DIR . '/default/kernel') || !file_exists(CONFIG_HTTP_DIR . '/default/initramfs-stage31') || !file_exists(CONFIG_HTTP_DIR . '/default/stage32.sqfs'); + Render::addTemplate('page-main', array('user' => User::getName(), 'ipxe' => $ipxe, 'sysconfig' => $sysconfig, 'minilinux' => $minilinux)); } - $sysconfig = !file_exists(CONFIG_HTTP_DIR . '/default/config.tgz'); - $minilinux = !file_exists(CONFIG_HTTP_DIR . '/default/kernel') || !file_exists(CONFIG_HTTP_DIR . '/default/initramfs-stage31') || !file_exists(CONFIG_HTTP_DIR . '/default/stage32.sqfs'); - Render::addTemplate('page-main', array('user' => User::getName(), 'ipxe' => $ipxe, 'sysconfig' => $sysconfig, 'minilinux' => $minilinux)); -} +} diff --git a/modules/minilinux.inc.php b/modules/minilinux.inc.php index 72af0eb4..6e68a34e 100644 --- a/modules/minilinux.inc.php +++ b/modules/minilinux.inc.php @@ -1,88 +1,97 @@ <?php -User::load(); +class Page_MiniLinux extends Page +{ -if (!User::hasPermission('superadmin')) { - Message::addError('no-permission'); - Util::redirect('?do=main'); -} + protected function doPreprocess() + { + User::load(); -function render_module() -{ - $files = array(); - mkdir(CONFIG_HTTP_DIR . "/default", 0755, true); - checkFile($files, 'kernel'); - checkFile($files, 'initramfs-stage31'); - checkFile($files, 'stage32.sqfs'); - checkFile($files, 'vmware.sqfs'); - checkFile($files, 'nvidia_libs.sqfs'); - Render::addTemplate('page-minilinux', array('files' => $files, 'token' => Session::get('token'))); -} + if (!User::hasPermission('superadmin')) { + Message::addError('no-permission'); + Util::redirect('?do=Main'); + } + } -function checkFile(&$files, $name) -{ - static $someId = 0; - $remote = CONFIG_REMOTE_ML . "/${name}.md5"; - $localTarget = CONFIG_HTTP_DIR . "/default/${name}"; - $local = "${localTarget}.md5"; - $localLock = "${localTarget}.lck"; + protected function doRender() + { + $files = array(); + mkdir(CONFIG_HTTP_DIR . "/default", 0755, true); + $this->checkFile($files, 'kernel'); + $this->checkFile($files, 'initramfs-stage31'); + $this->checkFile($files, 'stage32.sqfs'); + $this->checkFile($files, 'vmware.sqfs'); + $this->checkFile($files, 'nvidia_libs.sqfs'); + Render::addTemplate('page-minilinux', array( + 'files' => $files, + 'token' => Session::get('token') + )); + } - // Maybe already in progress? - if (file_exists($localLock)) { - $data = explode(' ', file_get_contents($localLock)); - if (count($data) == 2) { - $pid = (int)$data[0]; - if (posix_kill($pid, 0)) { - $files[] = array( - 'file' => $name, - 'id' => 'id' . $someId++, - 'pid' => $pid, - 'progress' => $data[1] - ); - return true; - } else { + private function checkFile(&$files, $name) + { + static $someId = 0; + $remote = CONFIG_REMOTE_ML . "/${name}.md5"; + $localTarget = CONFIG_HTTP_DIR . "/default/${name}"; + $local = "${localTarget}.md5"; + $localLock = "${localTarget}.lck"; + + // Maybe already in progress? + if (file_exists($localLock)) { + $data = explode(' ', file_get_contents($localLock)); + if (count($data) == 2) { + $pid = (int)$data[0]; + if (posix_kill($pid, 0)) { + $files[] = array( + 'file' => $name, + 'id' => 'id' . $someId++, + 'pid' => $pid, + 'progress' => $data[1] + ); + return true; + } else { + unlink($localLock); + } + } else { unlink($localLock); - } - } else { - unlink($localLock); - } - } + } + } - // Not in progress, normal display - if (!file_exists($local) || filemtime($local) + 300 < time()) { - if (file_exists($localTarget)) { - $existingMd5 = md5_file($localTarget); + // Not in progress, normal display + if (!file_exists($local) || filemtime($local) + 300 < time()) { + if (file_exists($localTarget)) { + $existingMd5 = md5_file($localTarget); + } else { + $existingMd5 = '<missing>'; + } + if (file_put_contents($local, $existingMd5) === false) { + @unlink($local); + Message::addWarning('error-write', $local); + } } else { - $existingMd5 = '<missing>'; + $existingMd5 = file_get_contents($local); } - if (file_put_contents($local, $existingMd5) === false) { - @unlink($local); - Message::addWarning('error-write', $local); + $existingMd5 = strtolower(preg_replace('/[^0-9a-f]/is', '', $existingMd5)); + $remoteMd5 = Util::download($remote, 3, $code); + $remoteMd5 = strtolower(preg_replace('/[^0-9a-f]/is', '', $remoteMd5)); + if ($code != 200) { + Message::addError('remote-timeout', $remote, $code); + return false; } - } else { - $existingMd5 = file_get_contents($local); - } - $existingMd5 = strtolower(preg_replace('/[^0-9a-f]/is', '', $existingMd5)); - $remoteMd5 = Util::download($remote, 3, $code); - $remoteMd5 = strtolower(preg_replace('/[^0-9a-f]/is', '', $remoteMd5)); - if ($code != 200) { - Message::addError('remote-timeout', $remote, $code); - return false; - } - if ($existingMd5 === $remoteMd5) { - // Up to date + if ($existingMd5 === $remoteMd5) { + // Up to date + $files[] = array( + 'file' => $name, + 'id' => 'id' . $someId++, + ); + return true; + } + // New version on server $files[] = array( - 'file' => $name, - 'id' => 'id' . $someId++, + 'file' => $name, + 'id' => 'id' . $someId++, + 'update' => true ); return true; } - // New version on server - $files[] = array( - 'file' => $name, - 'id' => 'id' . $someId++, - 'update' => true - ); - return true; } - diff --git a/modules/session.inc.php b/modules/session.inc.php index 456ff6b8..aa7719ab 100644 --- a/modules/session.inc.php +++ b/modules/session.inc.php @@ -1,36 +1,43 @@ <?php -if (!isset($_REQUEST['action'])) Util::traceError('No action on module init'); +class Page_Session extends Page +{ + + protected function doPreprocess() + { + if (!isset($_REQUEST['action'])) Util::traceError('No action on module init'); -User::load(); + User::load(); -if (isset($_POST['action']) && $_POST['action'] === 'login') { - // Login - see if already logged in - if (User::isLoggedIn()) { - Util::redirect('?do=main'); - } - // Else, try to log in - if (User::login($_POST['user'], $_POST['pass'])) { - Util::redirect('?do=main'); - } - // Login credentials wrong - Message::addError('loginfail'); -} + if (isset($_POST['action']) && $_POST['action'] === 'login') { + // Login - see if already logged in + if (User::isLoggedIn()) { + Util::redirect('?do=Main'); + } + // Else, try to log in + if (User::login($_POST['user'], $_POST['pass'])) { + Util::redirect('?do=Main'); + } + // Login credentials wrong + Message::addError('loginfail'); + } -if ($_REQUEST['action'] === 'logout') { - if (Util::verifyToken()) { - // Log user out (or do nothing if not logged in) - User::logout(); - Util::redirect('?do=main'); + if ($_REQUEST['action'] === 'logout') { + if (Util::verifyToken()) { + // Log user out (or do nothing if not logged in) + User::logout(); + Util::redirect('?do=Main'); + } + } } -} -function render_module() -{ - if ($_REQUEST['action'] === 'login') { - Render::setTitle('Anmelden'); - Render::addTemplate('page-login'); - return; + protected function doRender() + { + if ($_REQUEST['action'] === 'login') { + Render::setTitle('Anmelden'); + Render::addTemplate('page-login'); + return; + } } -} +} diff --git a/modules/sysconfig.inc.php b/modules/sysconfig.inc.php index faa26787..28fc6a50 100644 --- a/modules/sysconfig.inc.php +++ b/modules/sysconfig.inc.php @@ -1,107 +1,87 @@ <?php -/* -@include_once('Archive/Tar.php'); -if (!class_exists('Archive_Tar')) { - Message::addError('Broken php installation: pear extension Archive_Tar missing!'); - Util::redirect('?do=main'); -} - */ +class Page_SysConfig extends Page +{ -User::load(); + protected function doPreprocess() + { + User::load(); -// Read request vars -$action = Request::any('action', 'list'); -$step = Request::any('step', 0); -$nextStep = $step + 1; + // Read request vars + $action = Request::any('action', 'list'); + $step = Request::any('step', 0); -// Action: "addmodule" (upload new module) -if ($action === 'addmodule') { - require_once 'modules/sysconfig/addmodule.inc.php'; - $handler = AddModule_Base::get($step); - $handler->preprocess(); -} + // Action: "addmodule" (upload new module) + if ($action === 'addmodule') { + if ($step === 0) $step = 'AddModule_Start'; + require_once 'modules/sysconfig/addmodule.inc.php'; + foreach (glob('modules/sysconfig/addmodule_*.inc.php') as $file) { + require_once $file; + } + AddModule_Base::setStep($step); + AddModule_Base::preprocess(); + } -// Action "activate" (set sysconfig as active) -if ($action === 'activate') { - if (!User::hasPermission('superadmin')) { - Message::addError('no-permission'); - Util::redirect('?do=sysconfig'); - } - if (!isset($_REQUEST['file'])) { - Message::addError('missing-file'); - Util::redirect('?do=sysconfig'); + // Action "activate" (set sysconfig as active) + if ($action === 'activate') { + if (!User::hasPermission('superadmin')) { + Message::addError('no-permission'); + Util::redirect('?do=SysConfig'); + } + if (!isset($_REQUEST['file'])) { + Message::addError('missing-file'); + Util::redirect('?do=SysConfig'); + } + $file = preg_replace('/[^a-z0-9\-_\.]/', '', $_REQUEST['file']); + $path = CONFIG_TGZ_LIST_DIR . '/' . $file; + if (!file_exists($path)) { + Message::addError('invalid-file', $file); + Util::redirect('?do=SysConfig'); + } + mkdir(CONFIG_HTTP_DIR . '/default', 0755, true); + $linkname = CONFIG_HTTP_DIR . '/default/config.tgz'; + @unlink($linkname); + if (file_exists($linkname)) Util::traceError('Could not delete old config.tgz link!'); + if (!symlink($path, $linkname)) Util::traceError("Could not symlink to $path at $linkname!"); + Message::addSuccess('config-activated'); + Util::redirect('?do=SysConfig'); + } } - $file = preg_replace('/[^a-z0-9\-_\.]/', '', $_REQUEST['file']); - $path = CONFIG_TGZ_LIST_DIR . '/' . $file; - if (!file_exists($path)) { - Message::addError('invalid-file', $file); - Util::redirect('?do=sysconfig'); - } - mkdir(CONFIG_HTTP_DIR . '/default', 0755, true); - $linkname = CONFIG_HTTP_DIR . '/default/config.tgz'; - @unlink($linkname); - if (file_exists($linkname)) Util::traceError('Could not delete old config.tgz link!'); - if (!symlink($path, $linkname)) Util::traceError("Could not symlink to $path at $linkname!"); - Message::addSuccess('config-activated'); - Util::redirect('?do=sysconfig'); -} -/** - * Render module; called by main script when this module page should render - * its content. - */ -function render_module() -{ - global $action, $handler; - switch ($action) { - case 'addmodule': - $handler->render(); - break; - case 'list': - rr_list_configs(); - break; - default: - Message::addError('invalid-action', $_REQUEST['action']); - break; + /** + * Render module; called by main script when this module page should render + * its content. + */ + protected function doRender() + { + $action = Request::any('action', 'list'); + switch ($action) { + case 'addmodule': + AddModule_Base::render(); + break; + case 'list': + $this->rr_list_configs(); + break; + default: + Message::addError('invalid-action', $action); + break; + } } -} -function rr_list_configs() -{ - if (!User::hasPermission('superadmin')) { - Message::addError('no-permission'); - return; - } - $res = Database::simpleQuery("SELECT title FROM configtgz_module ORDER BY title ASC"); - $modules = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $modules[] = array( - 'module' => $row['title'] - ); + private function rr_list_configs() + { + if (!User::hasPermission('superadmin')) { + Message::addError('no-permission'); + return; + } + $res = Database::simpleQuery("SELECT title FROM configtgz_module ORDER BY title ASC"); + $modules = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $modules[] = array( + 'module' => $row['title'] + ); + } + Render::addTemplate('page-sysconfig-main', array('modules' => $modules, 'token' => Session::get('token'))); } - Render::addTemplate('page-sysconfig-main', array('modules' => $modules, 'token' => Session::get('token'))); -} -function rr_list_remote_configs() -{ - if (!User::hasPermission('superadmin')) { - Message::addError('no-permission'); - return; - } - $data = Util::download(CONFIG_REMOTE_TGZ . '/list.php', 4, $code); - if ($code !== 200) { - Message::addError('remote-timeout', CONFIG_REMOTE_TGZ . '/list.php', $code); - return; - } - $list = json_decode($data, true); - if (!is_array($list)) { - Message::addError('remote-parse-failed', $data); - return; - } - $id = 0; - foreach ($list as &$item) { - $item['id'] = 'download' . (++$id); - } - Render::addTemplate('page-remote-tgz-list', array('files' => $list)); } diff --git a/modules/sysconfig/addmodule.inc.php b/modules/sysconfig/addmodule.inc.php index aca2f762..924f18fa 100644 --- a/modules/sysconfig/addmodule.inc.php +++ b/modules/sysconfig/addmodule.inc.php @@ -8,30 +8,47 @@ abstract class AddModule_Base { /** + * Holds all the known configuration modules, with title, description, start class for their wizard, etc. + * @var array + */ + protected static $moduleTypes = array(); + + /** + * Holds the instance for the currently executing step + * @var \AddModule_Base + */ + private static $instance = false; + + public static function addModule($id, $startClass, $title, $description, $sortOrder = 0) + { + self::$moduleTypes[] = array( + 'startClass' => $startClass, + 'title' => $title, + 'description' => $description, + 'sortOrder' => $sortOrder + ); + } + + /** * * @param type $step * @return \AddModule_Base */ - public static function get($step) + public static function setStep($step) { - switch ($step) { - case 0: // Upload form - return new AddModule_UploadForm(); - case 1: // Handle config module uploading - return new AddModule_ProcessUpload(); - case 2: // ? - return new AddModule_CompressModule(); + if (empty($step) || !class_exists($step) || get_parent_class($step) !== 'AddModule_Base') { + Message::addError('invalid-action', $step); + Util::redirect('?do=SysConfig'); } - Message::addError('invalid-action', $step); - Util::redirect('?do=sysconfig'); + self::$instance = new $step(); } - + protected function tmError() { Message::addError('taskmanager-error'); - Util::redirect('?do=sysconfig'); + Util::redirect('?do=SysConfig'); } - + protected function taskError($status) { if (isset($status['data']['error'])) { @@ -42,7 +59,7 @@ abstract class AddModule_Base $error = 'Unbekannter Taskmanager-Fehler'; // TODO: No text } Message::addError('task-error', $error); - Util::redirect('?do=sysconfig'); + Util::redirect('?do=SysConfig'); } /** @@ -51,146 +68,53 @@ abstract class AddModule_Base * early if something is wrong, or you received post * data etc. */ - public function preprocess() + protected function preprocessInternal() { // void } /** - * Do page rendering + * Do page rendering. */ - public function render() + protected function renderInternal() { // void } - -} - -class AddModule_UploadForm extends AddModule_Base -{ - - public function render() - { - global $nextStep; - Session::set('mod_temp', false); - Render::addDialog('Eigenes Modul hinzufügen', false, 'sysconfig/custom-upload', array('step' => $nextStep)); - } - -} - -/** - * Some file has just been uploaded. Try to store it, then try to unpack/analyze it. - * If this succeeds, we proceed to the next step where we present the user our findings - * and ask what to do with this. - */ -class AddModule_ProcessUpload extends AddModule_Base -{ - private $taskId = false; - - public function preprocess() + public static function preprocess() { - if (!isset($_FILES['modulefile'])) { - Message::addError('missing-file'); - return; + if (self::$instance === false) { + Util::traceError('No step instance yet'); } - if ($_FILES['modulefile']['error'] != UPLOAD_ERR_OK) { - Message::addError('upload-failed', $_FILE['modulefile']['name']); - return; - } - $tempfile = $_FILES['modulefile']['tmp_name'] . '.tmp'; - if (!move_uploaded_file($_FILES['modulefile']['tmp_name'], $tempfile)) { - Message:addError('error-write', $tempfile); - return; - } - $this->taskId = 'tgzmod' . mt_rand() . '-' . microtime(true); - Taskmanager::submit('ListArchive', array( - 'id' => $this->taskId, - 'file' => $tempfile - ), true); - Session::set('mod_temp', $tempfile); + self::$instance->preprocessInternal(); } - public function render() + public static function render() { - $status = Taskmanager::waitComplete($this->taskId); - Taskmanager::release($this->taskId); - $tempfile = Session::get('mod_temp'); - if (!isset($status['statusCode'])) { - unlink($tempfile); - $this->tmError(); - } - if ($status['statusCode'] != TASK_FINISHED) { - unlink($tempfile); - $this->taskError($status); - } - // Sort files for better display - $dirs = array(); - foreach ($status['data']['entries'] as $file) { - if ($file['isdir']) continue; - $dirs[dirname($file['name'])][] = $file; - } - ksort($dirs); - $list = array(); - foreach ($dirs as $dir => $files) { - $list[] = array( - 'name' => $dir, - 'isdir' => true - ); - sort($files); - foreach ($files as $file) { - $file['size'] = Util::readableFileSize($file['size']); - $list[] = $file; - } + if (self::$instance === false) { + Util::traceError('No step instance yet'); } - global $nextStep; - Render::addDialog('Eigenes Modul hinzufügen', false, 'sysconfig/custom-fileselect', array( - 'step' => $nextStep, - 'files' => $list, - )); - Session::save(); + self::$instance->renderInternal(); } } -class AddModule_CompressModule extends AddModule_Base +/** + * Start dialog for adding module. Here the user + * selects which kind of module they want to add. + */ +class AddModule_Start extends AddModule_Base { - - private $taskId = false; - - public function preprocess() + + protected function renderInternal() { - $title = Request::post('title'); - $tempfile = Session::get('mod_temp'); - if (empty($title) || empty($tempfile) || !file_exists($tempfile)) { - Message::addError('empty-field'); - return; + $title = $order = array(); + foreach (AddModule_Base::$moduleTypes as $module) { + $title[] = $module['title']; + $order[] = $module['sortOrder']; } - // Recompress using task manager - $this->taskId = 'tgzmod' . mt_rand() . '-' . microtime(true); - $destFile = CONFIG_TGZ_LIST_DIR . '/modules/mod-' . preg_replace('/[^a-z0-9_\-]+/is', '_', $title) . '-' . microtime(true) . '.tgz'; - Taskmanager::submit('RecompressArchive', array( - 'id' => $this->taskId, - 'inputFiles' => array($tempfile), - 'outputFile' => $destFile - ), true); - $status = Taskmanager::waitComplete($this->taskId); - unlink($tempfile); - if (!isset($status['statusCode'])) { - $this->tmError(); - } - if ($status['statusCode'] != TASK_FINISHED) { - $this->taskError($status); - } - // Seems ok, create entry in DB - $ret = Database::exec("INSERT INTO configtgz_module (title, moduletype, filename, contents) VALUES (:title, 'custom', :file, '')", - array('title' => $title, 'file' => $destFile)); - if ($ret === false) { - unlink($destFile); - Util::traceError("Could not insert module into Database"); - } - Message::addSuccess('module-added'); - Util::redirect('?do=sysconfig'); + array_multisort($order, SORT_ASC, $title, SORT_ASC, self::$moduleTypes); + Render::addDialog('Modul hinzufügen', false, 'sysconfig/start', array('modules' => self::$moduleTypes)); } - + } diff --git a/modules/sysconfig/addmodule_ad.inc.php b/modules/sysconfig/addmodule_ad.inc.php new file mode 100644 index 00000000..abc55df5 --- /dev/null +++ b/modules/sysconfig/addmodule_ad.inc.php @@ -0,0 +1,57 @@ +<?php + +/* + * Wizard for setting up active directory integration for authentication. + */ + +AddModule_Base::addModule('active_directory', 'AdModule_Start', 'Active Directory Authentifizierung', + 'Mit diesem Modul ist die Anmeldung an den Client PCs mit den Benutzerkonten eines Active Directory' + . ' möglich. Je nach Konfiguration ist auch die Nutzung eines Benutzerverzeichnisses auf dem Client möglich.' +); + +class AdModule_Start extends AddModule_Base +{ + + protected function renderInternal() + { + Session::set('ad_stuff', false); + Render::addDialog('Active Directory Authentifizierung', false, 'sysconfig/ad-start', array( + 'step' => 'AdModule_CheckConnection', + 'server' => Request::post('server'), + 'searchbase' => Request::post('searchbase'), + 'binddn' => Request::post('binddn'), + 'bindpw' => Request::post('bindpw'), + )); + } + +} + +class AdModule_CheckConnection extends AddModule_Base +{ + + private $taskId = false; + + protected function preprocessInternal() + { + $server = Request::post('server'); + $searchbase = Request::post('searchbase'); + $binddn = Request::post('binddn'); + $bindpw = Request::post('bindpw'); + if (empty($server) || empty($searchbase) || empty($binddn)) { + Message::addError('empty-field'); + AddModule_Base::setStep('AdModule_Start'); + return; + } + $this->taskId = 'ad_' . mt_rand() . '-' . microtime(true); + Taskmanager::submit('LdapSearch', array( + 'id' => $this->taskId, + 'uri' => '' + ), true); + } + + protected function renderInternal() + { + Message::addInfo('missing-file'); + } + +}
\ No newline at end of file diff --git a/modules/sysconfig/addmodule_custom.inc.php b/modules/sysconfig/addmodule_custom.inc.php new file mode 100644 index 00000000..ec2c8af7 --- /dev/null +++ b/modules/sysconfig/addmodule_custom.inc.php @@ -0,0 +1,142 @@ +<?php + +/* + * Wizard for adding a custom module. A custom module is a plain archive that gets + * included into a config.tgz the way itz is. No handling, sanity checks or anything + * fancy is happening. + */ + +AddModule_Base::addModule('custom', 'CustomModule_UploadForm', 'Erweitertes Modul', + 'Mit einem Erweiterten Modul ist es möglich, beliebige Dateien zum Grundsystem hinzuzufügen.' + . ' Nutzen Sie dieses Modul, um z.B. spezielle Konfigurationsdateien auf den Client PCs zu' + . ' verwenden, die sich nicht mit einem der anderen Wizards erstellen lässt.' + . ' Das Hinzufügen eines Erweiterten Moduls erfordert in der Regel zumindest grundlegende' + . ' Systemkenntnisse im Linuxbereich.', 100 +); + +class CustomModule_UploadForm extends AddModule_Base +{ + + protected function renderInternal() + { + Session::set('mod_temp', false); + Render::addDialog('Eigenes Modul hinzufügen', false, 'sysconfig/custom-upload', array('step' => 'CustomModule_ProcessUpload')); + } + +} + +/** + * Some file has just been uploaded. Try to store it, then try to unpack/analyze it. + * If this succeeds, we proceed to the next step where we present the user our findings + * and ask what to do with this. + */ +class CustomModule_ProcessUpload extends AddModule_Base +{ + + private $taskId = false; + + protected function preprocessInternal() + { + if (!isset($_FILES['modulefile'])) { + Message::addError('missing-file'); + Util::redirect('?do=SysConfig'); + } + if ($_FILES['modulefile']['error'] != UPLOAD_ERR_OK) { + Message::addError('upload-failed', $_FILES['modulefile']['name']); + Util::redirect('?do=SysConfig'); + } + $tempfile = $_FILES['modulefile']['tmp_name'] . '.tmp'; + if (!move_uploaded_file($_FILES['modulefile']['tmp_name'], $tempfile)) { + Message:addError('error-write', $tempfile); + Util::redirect('?do=SysConfig'); + } + $this->taskId = 'tgzmod' . mt_rand() . '-' . microtime(true); + Taskmanager::submit('ListArchive', array( + 'id' => $this->taskId, + 'file' => $tempfile + ), true); + Session::set('mod_temp', $tempfile); + } + + protected function renderInternal() + { + $status = Taskmanager::waitComplete($this->taskId); + Taskmanager::release($this->taskId); + $tempfile = Session::get('mod_temp'); + if (!isset($status['statusCode'])) { + unlink($tempfile); + $this->tmError(); + } + if ($status['statusCode'] != TASK_FINISHED) { + unlink($tempfile); + $this->taskError($status); + } + // Sort files for better display + $dirs = array(); + foreach ($status['data']['entries'] as $file) { + if ($file['isdir']) continue; + $dirs[dirname($file['name'])][] = $file; + } + ksort($dirs); + $list = array(); + foreach ($dirs as $dir => $files) { + $list[] = array( + 'name' => $dir, + 'isdir' => true + ); + sort($files); + foreach ($files as $file) { + $file['size'] = Util::readableFileSize($file['size']); + $list[] = $file; + } + } + Render::addDialog('Eigenes Modul hinzufügen', false, 'sysconfig/custom-fileselect', array( + 'step' => 'CustomModule_CompressModule', + 'files' => $list, + )); + Session::save(); + } + +} + +class CustomModule_CompressModule extends AddModule_Base +{ + + private $taskId = false; + + protected function preprocessInternal() + { + $title = Request::post('title'); + $tempfile = Session::get('mod_temp'); + if (empty($title) || empty($tempfile) || !file_exists($tempfile)) { + Message::addError('empty-field'); + return; + } + // Recompress using task manager + $this->taskId = 'tgzmod' . mt_rand() . '-' . microtime(true); + $destFile = CONFIG_TGZ_LIST_DIR . '/modules/mod-' . preg_replace('/[^a-z0-9_\-]+/is', '_', $title) . '-' . microtime(true) . '.tgz'; + Taskmanager::submit('RecompressArchive', array( + 'id' => $this->taskId, + 'inputFiles' => array($tempfile), + 'outputFile' => $destFile + ), true); + $status = Taskmanager::waitComplete($this->taskId); + unlink($tempfile); + if (!isset($status['statusCode'])) { + $this->tmError(); + } + if ($status['statusCode'] != TASK_FINISHED) { + $this->taskError($status); + } + // Seems ok, create entry in DB + $ret = Database::exec("INSERT INTO configtgz_module (title, moduletype, filename, contents) VALUES (:title, 'custom', :file, '')", + array('title' => $title, 'file' => $destFile)); + if ($ret === false) { + unlink($destFile); + Util::traceError("Could not insert module into Database"); + } + Message::addSuccess('module-added'); + Util::redirect('?do=SysConfig'); + } + +} diff --git a/modules/syslog.inc.php b/modules/syslog.inc.php index 62c94edf..2c54b8f4 100644 --- a/modules/syslog.inc.php +++ b/modules/syslog.inc.php @@ -1,64 +1,69 @@ <?php -require_once('inc/paginate.inc.php'); - -User::load(); +class Page_SysLog extends Page +{ -if (!User::isLoggedIn()) { - Util::redirect('?do=main'); -} + protected function doPreprocess() + { + User::load(); -function render_module() -{ - Render::setTitle('Client Log'); - - if (isset($_GET['filter'])) { - $filter = $_GET['filter']; - $not = isset($_GET['not']) ? 'NOT' : ''; - } elseif (isset($_POST['filter'])) { - $filter = $_POST['filter']; - $not = isset($_POST['not']) ? 'NOT' : ''; - Session::set('log_filter', $filter); - Session::set('log_not', $not); - Session::save(); - } else { - $filter = Session::get('log_filter'); - $not = Session::get('log_not') ? 'NOT' : ''; - } - if (!empty($filter)) { - $filterList = explode(',', $filter); - $whereClause = array(); - foreach ($filterList as $filterItem) { - $filterItem = preg_replace('/[^a-z0-9_\-]/', '', trim($filterItem)); - if (empty($filterItem) || in_array($filterItem, $whereClause)) continue; - $whereClause[] = "'$filterItem'"; + if (!User::isLoggedIn()) { + Util::redirect('?do=Main'); } - if (!empty($whereClause)) $whereClause = ' WHERE logtypeid ' . $not . ' IN (' . implode(', ', $whereClause) . ')'; } - if (!isset($whereClause) || empty($whereClause)) $whereClause = ''; - $today = date('d.m.Y'); - $yesterday = date('d.m.Y', time() - 86400); - $lines = array(); - $paginate = new Paginate("SELECT logid, dateline, logtypeid, clientip, description, extra FROM clientlog $whereClause ORDER BY logid DESC", 50); - $res = $paginate->exec(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $day = date('d.m.Y', $row['dateline']); - // TODO: No output strings in source files! - if ($day === $today) { - $day = 'Heute'; - } elseif ($day === $yesterday) { - $day = 'Gestern'; + protected function doRender() + { + Render::setTitle('Client Log'); + + if (isset($_GET['filter'])) { + $filter = $_GET['filter']; + $not = isset($_GET['not']) ? 'NOT' : ''; + } elseif (isset($_POST['filter'])) { + $filter = $_POST['filter']; + $not = isset($_POST['not']) ? 'NOT' : ''; + Session::set('log_filter', $filter); + Session::set('log_not', $not); + Session::save(); + } else { + $filter = Session::get('log_filter'); + $not = Session::get('log_not') ? 'NOT' : ''; } - $row['date'] = $day . date(' H:i', $row['dateline']); - $lines[] = $row; + if (!empty($filter)) { + $filterList = explode(',', $filter); + $whereClause = array(); + foreach ($filterList as $filterItem) { + $filterItem = preg_replace('/[^a-z0-9_\-]/', '', trim($filterItem)); + if (empty($filterItem) || in_array($filterItem, $whereClause)) continue; + $whereClause[] = "'$filterItem'"; + } + if (!empty($whereClause)) $whereClause = ' WHERE logtypeid ' . $not . ' IN (' . implode(', ', $whereClause) . ')'; + } + if (!isset($whereClause) || empty($whereClause)) $whereClause = ''; + + $today = date('d.m.Y'); + $yesterday = date('d.m.Y', time() - 86400); + $lines = array(); + $paginate = new Paginate("SELECT logid, dateline, logtypeid, clientip, description, extra FROM clientlog $whereClause ORDER BY logid DESC", 50); + $res = $paginate->exec(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $day = date('d.m.Y', $row['dateline']); + // TODO: No output strings in source files! + if ($day === $today) { + $day = 'Heute'; + } elseif ($day === $yesterday) { + $day = 'Gestern'; + } + $row['date'] = $day . date(' H:i', $row['dateline']); + $lines[] = $row; + } + + $paginate->render('page-syslog', array( + 'token' => Session::get('token'), + 'filter' => $filter, + 'not' => $not, + 'list' => $lines + )); } - - $paginate->render('page-syslog', array( - 'token' => Session::get('token'), - 'filter' => $filter, - 'not' => $not, - 'list' => $lines - )); -} +} diff --git a/style/default.css b/style/default.css index 98ecadd6..c1e5684a 100644 --- a/style/default.css +++ b/style/default.css @@ -50,6 +50,16 @@ body { font-style: italic; } +.slx-ga { + min-width: 7em; +} + +.slx-dialog { + width: 100%; + min-width: 600px; + max-width: 820px; +} + .bootstrap-tagsinput { width: 100%; margin: 0px; diff --git a/templates/dialog-generic.html b/templates/dialog-generic.html index 5e875e8b..929400a5 100644 --- a/templates/dialog-generic.html +++ b/templates/dialog-generic.html @@ -1,5 +1,5 @@ <div class="container"> - <div class="modal-dialog"> + <div class="modal-dialog slx-dialog"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title">{{title}}</h4> diff --git a/templates/main-menu.html b/templates/main-menu.html index 4a912f46..733f901f 100644 --- a/templates/main-menu.html +++ b/templates/main-menu.html @@ -7,19 +7,19 @@ <span class="icon-bar"></span> <span class="icon-bar"></span> </button> - <a class="navbar-brand" href="?do=main">OpenSLX Admin</a> + <a class="navbar-brand" href="?do=Main">OpenSLX Admin</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="#about">Hilfe</a></li> - <li><a href="?do=syslog">Client Logs</a></li> + <li><a href="?do=SysLog">Client Logs</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">Einstellungen<b class="caret"></b></a> <ul class="dropdown-menu"> - <li><a href="?do=minilinux">MiniLinux</a></li> - <li><a href="?do=baseconfig">KonfigurationsVariablen</a></li> - <li><a href="?do=sysconfig">SystemKonfiguration</a></li> - <li><a href="?do=ipxe">iPXE</a></li> + <li><a href="?do=MiniLinux">MiniLinux</a></li> + <li><a href="?do=BaseConfig">KonfigurationsVariablen</a></li> + <li><a href="?do=SysConfig">SystemKonfiguration</a></li> + <li><a href="?do=iPxe">iPXE</a></li> <li class="divider"></li> <li class="dropdown-header">Nav header</li> <li><a href="#">1</a></li> diff --git a/templates/menu-login.html b/templates/menu-login.html index c5ee6a2a..89b22adf 100644 --- a/templates/menu-login.html +++ b/templates/menu-login.html @@ -1 +1 @@ -<li><a href="?do=session&action=login">Anmelden</a></li> +<li><a href="?do=Session&action=login">Anmelden</a></li> diff --git a/templates/menu-logout.html b/templates/menu-logout.html index 68cf4671..17e53985 100644 --- a/templates/menu-logout.html +++ b/templates/menu-logout.html @@ -1 +1 @@ -<li><a href="?do=session&action=logout&token={{{token}}}"><b>{{user}}</b> (abmelden)</a></li> +<li><a href="?do=Session&action=logout&token={{{token}}}"><b>{{user}}</b> (abmelden)</a></li> diff --git a/templates/page-adduser.html b/templates/page-adduser.html index 8fca8610..cd317457 100644 --- a/templates/page-adduser.html +++ b/templates/page-adduser.html @@ -1,5 +1,5 @@ <div class="container"> - <form class="form-adduser" action="?do=adduser" method="post"> + <form class="form-adduser" action="?do=AddUser" method="post"> <h2 class="form-signin-heading">Benutzer anlegen</h2> <div class="row"> <div class="col-md-4">Benutzerkennung</div> diff --git a/templates/page-baseconfig.html b/templates/page-baseconfig.html index 2dbe4736..e8511fb2 100644 --- a/templates/page-baseconfig.html +++ b/templates/page-baseconfig.html @@ -1,6 +1,6 @@ <div class="container"> <h1>Basiskonfiguration</h1> - <form action="?do=baseconfig" method="post"> + <form action="?do=BaseConfig" method="post"> {{#categories}} <div class="panel panel-default"> <div class="panel-heading">{{category_name}}</div> diff --git a/templates/page-login.html b/templates/page-login.html index c09db8ae..9696e31d 100644 --- a/templates/page-login.html +++ b/templates/page-login.html @@ -1,5 +1,5 @@ <div class="container"> - <form class="form-signin" action="?do=session" method="post"> + <form class="form-signin" action="?do=Session" method="post"> <h2 class="form-signin-heading">Anmeldung</h2> <input type="text" name="user" class="form-control" placeholder="Benutzerkennung" autofocus> <input type="password" name="pass" class="form-control" placeholder="Passwort"> @@ -7,7 +7,7 @@ <input type="checkbox" name="remember" value="remember-me"> Angemeldet bleiben </label> <button class="btn btn-lg btn-primary btn-block" type="submit">Anmelden</button> - <a class="btn btn-lg btn-primary btn-block" href="?do=adduser">Registrieren</a> + <a class="btn btn-lg btn-primary btn-block" href="?do=AddUser">Registrieren</a> <input type="hidden" name="action" value="login"> </form> </div> diff --git a/templates/page-main-guest.html b/templates/page-main-guest.html index f580e9f5..8867ccf8 100644 --- a/templates/page-main-guest.html +++ b/templates/page-main-guest.html @@ -1,5 +1,5 @@ <div class="jumbotron"> <h1>Willkommen</h1> <p>Dies ist das Administrations-Interface der lokalen bwLehrpool-Installation. Bitte authentifizieren Sie sich, um Einstellungen vorzunehmen.</p> - <p><a href="?do=session&action=login" class="btn btn-primary btn-lg">Anmelden »</a></p> + <p><a href="?do=Session&action=login" class="btn btn-primary btn-lg">Anmelden »</a></p> </div> diff --git a/templates/page-main.html b/templates/page-main.html index 6d35b9f3..9ca60fbc 100644 --- a/templates/page-main.html +++ b/templates/page-main.html @@ -4,19 +4,19 @@ {{#ipxe}} <div class="alert alert-warning"> <p>Das iPXE-Modul des Servers ist veraltet oder nicht vorhanden.</p> - <a class="btn btn-large btn-primary" href="?do=ipxe">iPXE compilieren</a> + <a class="btn btn-large btn-primary" href="?do=iPxe">iPXE compilieren</a> </div> {{/ipxe}} {{#minilinux}} <div class="alert alert-warning"> <p>Wichtige Dateien der MiniLinux-Installation fehlen.</p> - <a class="btn btn-large btn-primary" href="?do=minilinux">MiniLinux herunterladen</a> + <a class="btn btn-large btn-primary" href="?do=MiniLinux">MiniLinux herunterladen</a> </div> {{/minilinux}} {{#sysconfig}} <div class="alert alert-warning"> <p>Es wurde noch keine Systemkonfiguration ausgewählt..</p> - <a class="btn btn-large btn-primary" href="?do=sysconfig">Systemkonfiguration festlegen</a> + <a class="btn btn-large btn-primary" href="?do=SysConfig">Systemkonfiguration festlegen</a> </div> {{/sysconfig}} </div> diff --git a/templates/page-remote-tgz-list.html b/templates/page-remote-tgz-list.html index ef4435db..8ea80673 100644 --- a/templates/page-remote-tgz-list.html +++ b/templates/page-remote-tgz-list.html @@ -1,6 +1,6 @@ <ol class="breadcrumb"> - <li><a href="?do=main">Start</a></li> - <li><a href="?do=sysconfig">SystemKonfiguration</a></li> + <li><a href="?do=Main">Start</a></li> + <li><a href="?do=SysConfig">SystemKonfiguration</a></li> <li class="active">Zentral verfügbare Konfigurationen</li> </ol> <div class="container"> diff --git a/templates/page-sysconfig-main.html b/templates/page-sysconfig-main.html index c160fd0b..32b3a6bd 100644 --- a/templates/page-sysconfig-main.html +++ b/templates/page-sysconfig-main.html @@ -1,5 +1,5 @@ <ol class="breadcrumb"> - <li><a href="?do=main">Start</a></li> + <li><a href="?do=Main">Start</a></li> <li class="active">SystemKonfiguration</li> </ol> <div class="container"> @@ -14,7 +14,7 @@ <td class=col-md-8">{{file}}</td> <td class="col-md-4"> {{^current}} - <a class="btn btn-primary" href="?do=sysconfig&action=activate&file={{file}}&token={{token}}">Aktivieren</a> + <a class="btn btn-primary" href="?do=SysConfig&action=activate&file={{file}}&token={{token}}">Aktivieren</a> {{/current}} {{#current}} <span class="btn btn-success">Bereits aktiv</span> @@ -40,8 +40,8 @@ <tr> <td>{{module}}</td> <td nowrap> - <a class="btn btn-default btn-xs">Bearbeiten</a> - <a class="btn btn-danger btn-xs">Löschen</a> + <a class="btn btn-default btn-xs"><span class="glyphicon glyphicon-edit"></span> Bearbeiten</a> + <a class="btn btn-danger btn-xs"><span class="glyphicon glyphicon-trash"></span> Löschen</a> </td> </tr> {{/modules}} @@ -50,7 +50,7 @@ <div class="alert alert-warning">Keine Konfigurationsmodule gefunden!</div> {{/modules}} <div class="panel-body"> - <a class="btn btn-primary" href="?do=sysconfig&action=addmodule">Neues Modul erstellen</a> + <a class="btn btn-primary" href="?do=SysConfig&action=addmodule">Neues Modul erstellen</a> </div> </div> </div> diff --git a/templates/page-syslog.html b/templates/page-syslog.html index c16d8da1..eb2f4caa 100644 --- a/templates/page-syslog.html +++ b/templates/page-syslog.html @@ -1,6 +1,7 @@ <div class="container"> <h1>Client Log</h1> - <form method="post" action="?do=syslog"> + <form method="post" action="?do=SysLog"> + <input type="hidden" name="token" value="{{token}}"> <div class="input-group"> <span class="input-group-addon">Filter</span> <input id="filterstring" type="text" placeholder="event-id" value="{{filter}}" name="filter" data-role="tagsinput" /> diff --git a/templates/sysconfig/ad-start.html b/templates/sysconfig/ad-start.html new file mode 100644 index 00000000..0ce4bbf3 --- /dev/null +++ b/templates/sysconfig/ad-start.html @@ -0,0 +1,51 @@ +<p> + Zum Einrichten der Benutzerauthentifizierung über ein Active Directory wird neben der Adresse + des anzusprechenden Servers ein dedizierter Benutzer im AD benötigt, über welchen das AD angesprochen wird. + <br> + Dieser Benutzer benötigt keine besonderen Rechte, Sie können diesem Benutzer zur Sicherheit auch die + Rechte zum Anmelden entziehen. Der Benutzer muss lediglich ausreichende Berechtigungen haben, um einen + LDAP-Bind am AD durchzuführen, und nach Benutzern zu suchen. + <br> + Im Folgenden muss der <strong>Distinguished Name</strong> des Benutzers angegeben werden. Diesen können Sie ermitteln, + indem Sie das Kommandozeilenprogramm <strong>dsquery</strong> auf einem Domain Controller wie folgt aufrufen: +</p> +<pre>dsquery user -name "Benutzername"</pre> +<p> + Nach Eingabe aller benötigten Daten wird im nächsten Schritt überprüft, ob die Kommunikation mit + dem AD möglich ist. +</p> + +<form role="form" method="post" action="?do=SysConfig&action=addmodule&step={{step}}"> + <div class="input-group"> + <span class="input-group-addon slx-ga">Server</span> + <input name="server" value="{{server}}" type="text" class="form-control" placeholder="dc0.institution.example.com"> + <span class="input-group-btn"> + <button class="btn btn-default" type="button"><span class="glyphicon glyphicon-question-sign"></span></button> + </span> + </div> + <div class="input-group"> + <span class="input-group-addon slx-ga">Suchbasis</span> + <input name="searchbase" value="{{searchbase}}" type="text" class="form-control" placeholder="dc=windows,dc=hs-beispiel,dc=de"> + <span class="input-group-btn"> + <button class="btn btn-default" type="button"><span class="glyphicon glyphicon-question-sign"></span></button> + </span> + </div> + <div class="input-group"> + <span class="input-group-addon slx-ga">Bind DN</span> + <input name="binddn" value="{{binddn}}" type="text" class="form-control" placeholder="CN=bwlehrpool user,OU=Benutzer,OU=Gruppe XYZ,DC=windows,DC=hs-beispiel,DC=de"> + <span class="input-group-btn"> + <button class="btn btn-default" type="button"><span class="glyphicon glyphicon-question-sign"></span></button> + </span> + </div> + <div class="input-group"> + <span class="input-group-addon slx-ga">Passwort</span> + <input name="bindpw" value="{{bindpw}}" type="text" class="form-control" placeholder="Paswort von 'bwlehrpool user'"> + <span class="input-group-btn"> + <button class="btn btn-default" type="button"><span class="glyphicon glyphicon-question-sign"></span></button> + </span> + </div> + <br> + <div class="pull-right"> + <button type="submit" class="btn btn-primary">Weiter »</button> + </div> +</form>
\ No newline at end of file diff --git a/templates/sysconfig/custom-fileselect.html b/templates/sysconfig/custom-fileselect.html index c61edc7f..5a0a26f3 100644 --- a/templates/sysconfig/custom-fileselect.html +++ b/templates/sysconfig/custom-fileselect.html @@ -1,4 +1,4 @@ -<form role="form" method="post" action="?do=sysconfig&action=addmodule&step={{step}}"> +<form role="form" method="post" action="?do=SysConfig&action=addmodule&step={{step}}"> <input type="hidden" name="modid" value="{{modid}}"> <div class="input-group"> <span class="input-group-addon">Modulname</span> diff --git a/templates/sysconfig/custom-upload.html b/templates/sysconfig/custom-upload.html index 2c0ff723..c5a43522 100644 --- a/templates/sysconfig/custom-upload.html +++ b/templates/sysconfig/custom-upload.html @@ -6,7 +6,7 @@ <p>Beispiel: Enthält das hochgeladene Archiv eine Datei <strong>etc/beispiel.conf</strong>, so wird auf einem gebooteten Client diese Datei als <strong>/etc/beispiel.conf</strong> zu finden sein.</p> -<form role="form" enctype="multipart/form-data" method="post" action="?do=sysconfig&action=addmodule&step={{step}}"> +<form role="form" enctype="multipart/form-data" method="post" action="?do=SysConfig&action=addmodule&step={{step}}"> <div class="input-group"> <span class="input-group-addon">Archiv</span> <input class="form-control" type="file" name="modulefile"> diff --git a/templates/sysconfig/start.html b/templates/sysconfig/start.html new file mode 100644 index 00000000..68777329 --- /dev/null +++ b/templates/sysconfig/start.html @@ -0,0 +1,12 @@ +<p>Bitte wählen Sie aus, welche Art Konfigurationsmodul Sie erstellen möchten.</p> + +{{#modules}} +<div class="panel panel-default"> + <div class="panel-heading"> + {{title}} <a href="?do=SysConfig&action=addmodule&step={{startClass}}" class="pull-right btn btn-primary btn-xs"><span class="glyphicon glyphicon-plus"></span> Hinzufügen</a> + </div> + <div class="panel-body"> + {{description}} + </div> +</div> +{{/modules}} |