From 97a0f7dcfdcf4a5263c1cc6c19160a0868abb5f2 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 12 Dec 2014 18:28:38 +0100 Subject: Rework config module class structure. Still some TODOs though.... --- apis/update.inc.php | 13 ++ inc/configmodule.inc.php | 99 ---------------- inc/configmodule/adauth.inc.php | 124 +++++++++++++++++++ inc/configmodule/branding.inc.php | 44 +++++++ inc/configmodule/customodule.inc.php | 16 +++ inc/configmodules.inc.php | 94 +++++++++++++++ inc/database.inc.php | 6 +- inc/trigger.inc.php | 32 +---- install/content.sql | 2 +- lang/de/messages-hardcoded.json | 6 +- lang/en/messages-hardcoded.json | 6 +- lang/pt/messages-hardcoded.json | 5 - modules/session.inc.php | 34 +++--- modules/sysconfig.inc.php | 58 ++------- modules/sysconfig/addconfig.inc.php | 2 +- modules/sysconfig/addmodule.inc.php | 2 +- modules/sysconfig/addmodule_ad.inc.php | 142 ---------------------- modules/sysconfig/addmodule_adauth.inc.php | 145 +++++++++++++++++++++++ modules/sysconfig/addmodule_branding.inc.php | 4 +- modules/sysconfig/addmodule_custom.inc.php | 140 ---------------------- modules/sysconfig/addmodule_custommodule.inc.php | 136 +++++++++++++++++++++ modules/translation.inc.php | 2 +- modules/webinterface.inc.php | 2 +- templates/main-menu.html | 11 +- templates/sysconfig/ad-checkconnection.html | 9 +- templates/sysconfig/ad-finish.html | 2 +- templates/sysconfig/start.html | 2 +- 27 files changed, 626 insertions(+), 512 deletions(-) delete mode 100644 inc/configmodule.inc.php create mode 100644 inc/configmodule/adauth.inc.php create mode 100644 inc/configmodule/branding.inc.php create mode 100644 inc/configmodule/customodule.inc.php create mode 100644 inc/configmodules.inc.php delete mode 100644 modules/sysconfig/addmodule_ad.inc.php create mode 100644 modules/sysconfig/addmodule_adauth.inc.php delete mode 100644 modules/sysconfig/addmodule_custom.inc.php create mode 100644 modules/sysconfig/addmodule_custommodule.inc.php diff --git a/apis/update.inc.php b/apis/update.inc.php index 9c0cf740..878dc47f 100644 --- a/apis/update.inc.php +++ b/apis/update.inc.php @@ -185,3 +185,16 @@ function update_6() } return true; } + +// ####################### +// ##### 2014-12-12 +// Rename config modules, add "has changed" column to modules +function update_7() +{ + if (!tableHasColumn('configtgz_module', 'haschanged')) + Database::exec("ALTER TABLE configtgz_module ADD `haschanged` TINYINT DEFAULT '0'"); + Database::exec("UPDATE configtgz_module SET moduletype = 'Branding' WHERE moduletype = 'BRANDING'"); + Database::exec("UPDATE configtgz_module SET moduletype = 'AdAuth' WHERE moduletype = 'AD_AUTH'"); + Database::exec("UPDATE configtgz_module SET moduletype = 'CustomModule' WHERE moduletype = 'custom'"); + return true; +} diff --git a/inc/configmodule.inc.php b/inc/configmodule.inc.php deleted file mode 100644 index 1788a53a..00000000 --- a/inc/configmodule.inc.php +++ /dev/null @@ -1,99 +0,0 @@ - $title)); - $id = Database::lastInsertId(); - if (!is_numeric($id)) Util::traceError('Inserting new AD config to DB did not yield a numeric insert id'); - // Entry created, now try to get a free port for the proxy - $res = Database::simpleQuery("SELECT moduleid, contents FROM configtgz_module WHERE moduletype = 'AD_AUTH'"); - $ports = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - if ($row['moduleid'] == $id) { - // ... - } else { - $data = json_decode($row['contents'], true); - if (isset($data['proxyport'])) $ports[] = $data['proxyport']; - } - } - $port = 3300; - while (in_array($port, $ports)) { - $port++; - } - // Port determined, carry on... - $ownEntry = array( - 'server' => $server, - 'searchbase' => $searchbase, - 'binddn' => $binddn, - 'bindpw' => $bindpw, - 'home' => $home, - 'proxyport' => $port - ); - $data = json_encode($ownEntry); - if ($data === false) Util::traceError('Serializing the AD data failed.'); - $moduleTgz = CONFIG_TGZ_LIST_DIR . '/modules/AD_AUTH_id_' . $id . '.' . mt_rand() . '.tgz'; - Database::exec("UPDATE configtgz_module SET filepath = :filename, contents = :contents WHERE moduleid = :id LIMIT 1", array( - 'id' => $id, - 'filename' => $moduleTgz, - 'contents' => $data - )); - Database::exec("UNLOCK TABLES"); - // Add archive file name to array before returning it - $ownEntry['moduleid'] = $id; - $ownEntry['filename'] = $moduleTgz; - return $ownEntry; - } - - /** - * Get all existing AD proxy configs. - * - * @return array array of ad configs in DB with fields: - * moduleid, filename, server, searchbase, binddn, bindpw, home, proxyport - */ - public static function getAdConfigs() - { - $res = Database::simpleQuery("SELECT moduleid, filepath, contents FROM configtgz_module WHERE moduletype = 'AD_AUTH'"); - $mods = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $data = json_decode($row['contents'], true); - $data['moduleid'] = $row['moduleid']; - $data['filename'] = $row['filepath']; - $mods[] = $data; - } - return $mods; - } - - public static function insertBrandingModule($title, $archive) - { - Database::exec("INSERT INTO configtgz_module (title, moduletype, filepath, contents) " - . " VALUES (:title, 'BRANDING', '', '')", array('title' => $title)); - $id = Database::lastInsertId(); - if (!is_numeric($id)) Util::traceError('Inserting new Branding Module into DB did not yield a numeric insert id'); - // Move tgz - $moduleTgz = CONFIG_TGZ_LIST_DIR . '/modules/BRANDING_id_' . $id . '.' . mt_rand() . '.tgz'; - $task = Taskmanager::submit('MoveFile', array( - 'source' => $archive, - 'destination' => $moduleTgz - )); - $task = Taskmanager::waitComplete($task, 3000); - if (Taskmanager::isFailed($task) || $task['statusCode'] !== TASK_FINISHED) { - Taskmanager::addErrorMessage($task); - Database::exec("DELETE FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array( - 'moduleid' => $id - )); - return false; - } - // Update with path - Database::exec("UPDATE configtgz_module SET filepath = :filename WHERE moduleid = :id LIMIT 1", array( - 'id' => $id, - 'filename' => $moduleTgz - )); - return true; - } - -} diff --git a/inc/configmodule/adauth.inc.php b/inc/configmodule/adauth.inc.php new file mode 100644 index 00000000..c0d4860c --- /dev/null +++ b/inc/configmodule/adauth.inc.php @@ -0,0 +1,124 @@ + $title, 'modid' => self::MODID)); + $id = Database::lastInsertId(); + if (!is_numeric($id)) Util::traceError('Inserting new AD config to DB did not yield a numeric insert id'); + // Entry created, now try to get a free port for the proxy + $res = Database::simpleQuery("SELECT moduleid, contents FROM configtgz_module WHERE moduletype = :modid", array( + 'modid' => self::MODID + )); + $ports = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if ($row['moduleid'] == $id) { + // ... + } else { + $data = json_decode($row['contents'], true); + if (isset($data['proxyport'])) $ports[] = $data['proxyport']; + } + } + $port = 3300; + while (in_array($port, $ports)) { + $port++; + } + // Port determined, carry on... + $ownEntry = array( + 'server' => $server, + 'searchbase' => $searchbase, + 'binddn' => $binddn, + 'bindpw' => $bindpw, + 'home' => $home, + 'proxyport' => $port + ); + $data = json_encode($ownEntry); + if ($data === false) Util::traceError('Serializing the AD data failed.'); + $moduleTgz = CONFIG_TGZ_LIST_DIR . '/modules/AD_AUTH_id_' . $id . '.' . mt_rand() . '.tgz'; + Database::exec("UPDATE configtgz_module SET filepath = :filename, contents = :contents WHERE moduleid = :id LIMIT 1", array( + 'id' => $id, + 'filename' => $moduleTgz, + 'contents' => $data + )); + Database::exec("UNLOCK TABLES"); + // Add archive file name to array before returning it + $ownEntry['moduleid'] = $id; + $ownEntry['filename'] = $moduleTgz; + return $ownEntry; + } + + /** + * To be called if the server ip changes, as it's embedded in the AD module configs. + * This will then recreate all AD tgz modules. + */ + private static function rebuildAll($parent = NULL) + { + // Stop all running instances of ldadp + $task = Taskmanager::submit('LdadpLauncher', array( + 'parentTask' => $parent, + 'failOnParentFail' => false, + 'ids' => array() + )); + $ads = self::getAll(); + if (empty($ads)) // Nothing to do + return false; + + if (isset($task['id'])) + $parent = $task['id']; + foreach ($ads as $ad) { + $ad['parentTask'] = $parent; + $ad['failOnParentFail'] = false; + $ad['proxyip'] = Property::getServerIp(); + $task = Taskmanager::submit('CreateAdConfig', $ad); + if (isset($task['id'])) + $parent = $task['id']; + } + Trigger::ldadp($parent); + return $parent; + } + + /** + * Get all existing AD proxy configs. + * + * @return array array of ad configs in DB with fields: + * moduleid, filename, server, searchbase, binddn, bindpw, home, proxyport + */ + public static function getAll() + { + $res = Database::simpleQuery("SELECT moduleid, filepath, contents FROM configtgz_module WHERE moduletype = :modid", array( + 'modid' => self::MODID + )); + $mods = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $data = json_decode($row['contents'], true); + $data['moduleid'] = $row['moduleid']; + $data['filename'] = $row['filepath']; + $mods[] = $data; + } + return $mods; + } + + // ############## Callbacks ############################# + + /** + * Server IP changed - rebuild all AD modules. + */ + public function event_serverIpChanged() + { + self::rebuildAll(); + } + +} diff --git a/inc/configmodule/branding.inc.php b/inc/configmodule/branding.inc.php new file mode 100644 index 00000000..f293fda6 --- /dev/null +++ b/inc/configmodule/branding.inc.php @@ -0,0 +1,44 @@ + $title, 'modid' => self::MODID)); + $id = Database::lastInsertId(); + if (!is_numeric($id)) + Util::traceError('Inserting new Branding Module into DB did not yield a numeric insert id'); + // Move tgz + $moduleTgz = CONFIG_TGZ_LIST_DIR . '/modules/BRANDING_id_' . $id . '.' . mt_rand() . '.tgz'; + $task = Taskmanager::submit('MoveFile', array( + 'source' => $archive, + 'destination' => $moduleTgz + )); + $task = Taskmanager::waitComplete($task, 3000); + if (Taskmanager::isFailed($task) || $task['statusCode'] !== TASK_FINISHED) { + Taskmanager::addErrorMessage($task); + Database::exec("DELETE FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array( + 'moduleid' => $id + )); + return false; + } + // Update with path + Database::exec("UPDATE configtgz_module SET filepath = :filename WHERE moduleid = :id LIMIT 1", array( + 'id' => $id, + 'filename' => $moduleTgz + )); + return true; + } + +} diff --git a/inc/configmodule/customodule.inc.php b/inc/configmodule/customodule.inc.php new file mode 100644 index 00000000..89f0aca6 --- /dev/null +++ b/inc/configmodule/customodule.inc.php @@ -0,0 +1,16 @@ + $title, + 'description' => $description, + 'group' => $group, + 'unique' => $unique, + 'sortOrder' => $sortOrder, + 'moduleClass' => $moduleClass, + 'wizardClass' => $wizardClass + ); + } + + /** + * Will be called if the server's IP address changes. The event will be propagated + * to all config module classes so action can be taken if appropriate. + */ + public static function serverIpChanged() + { + self::loadDb(); + foreach (self::$moduleTypes as $module) { + $instance = new $module['moduleClass']; + $instance->event_serverIpChanged(); + } + } + +} + +/** + * Base class for config modules + */ +abstract class ConfigModule +{ + + public function event_serverIpChanged() + { + + } + +} diff --git a/inc/database.inc.php b/inc/database.inc.php index 85bee4b1..2c535d04 100644 --- a/inc/database.inc.php +++ b/inc/database.inc.php @@ -7,6 +7,10 @@ class Database { + /** + * + * @var \PDO Database handle + */ private static $dbh = false; private static $statements = array(); @@ -16,7 +20,7 @@ class Database */ public static function getExpectedSchemaVersion() { - return 7; + return 8; } public static function needSchemaUpdate() diff --git a/inc/trigger.inc.php b/inc/trigger.inc.php index a5a149c8..38b25540 100644 --- a/inc/trigger.inc.php +++ b/inc/trigger.inc.php @@ -83,10 +83,11 @@ class Trigger */ public static function ldadp($parent = NULL) { + // TODO: Fetch list from ConfigModule_AdAuth (call loadDb first) $res = Database::simpleQuery("SELECT moduleid, configtgz.filepath FROM configtgz_module" . " INNER JOIN configtgz_x_module USING (moduleid)" . " INNER JOIN configtgz USING (configid)" - . " WHERE moduletype = 'AD_AUTH'"); + . " WHERE moduletype = 'AdAuth'"); // TODO: Multiconfig support $id = array(); while ($row = $res->fetch(PDO::FETCH_ASSOC)) { @@ -105,35 +106,6 @@ class Trigger return $task['id']; } - /** - * To be called if the server ip changes, as it's embedded in the AD module configs. - * This will then recreate all AD tgz modules. - */ - public static function rebuildAdModules($parent = NULL) - { - $task = Taskmanager::submit('LdadpLauncher', array( - 'parentTask' => $parent, - 'failOnParentFail' => false, - 'ids' => array() - )); // Stop all running instances - $ads = ConfigModule::getAdConfigs(); - if (empty($ads)) - return false; - - if (isset($task['id'])) - $parent = $task['id']; - foreach ($ads as $ad) { - $ad['parentTask'] = $parent; - $ad['failOnParentFail'] = false; - $ad['proxyip'] = Property::getServerIp(); - $task = Taskmanager::submit('CreateAdConfig', $ad); - if (isset($task['id'])) - $parent = $task['id']; - } - Trigger::ldadp($parent); - return $parent; - } - /** * Mount the VM store into the server. * diff --git a/install/content.sql b/install/content.sql index d5ba99b0..10028c5a 100644 --- a/install/content.sql +++ b/install/content.sql @@ -1,2 +1,2 @@ -INSERT INTO property (name, dateline, value) VALUES ('webif-version', 0, 7); +INSERT INTO property (name, dateline, value) VALUES ('webif-version', 0, 8); diff --git a/lang/de/messages-hardcoded.json b/lang/de/messages-hardcoded.json index cdb7edce..6a0c0629 100644 --- a/lang/de/messages-hardcoded.json +++ b/lang/de/messages-hardcoded.json @@ -1,16 +1,11 @@ { "lang_adAuthentication": "Active Directory Authentifizierung", - "lang_adModule": "Mit diesem Modul ist die Anmeldung an den Client PCs mit den Benutzerkonten eines Active Directory m\u00f6glich. Je nach Konfiguration ist auch die Nutzung eines Benutzerverzeichnisses auf dem Client m\u00f6glich.", "lang_addCustomModule": "Generisches Modul hinzuf\u00fcgen", - "lang_addCustomModuleInfo": "Mit einem Erweiterten Modul ist es m\u00f6glich, beliebige Dateien zum Grundsystem hinzuzuf\u00fcgen 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\u00e4sst. Das Hinzuf\u00fcgen eines Erweiterten Moduls erfordert in der Regel zumindest grundlegende Systemkenntnisse im Linuxbereich.", - "lang_authentication": "Authentifizierung", "lang_configurationCompilation": "Konfiguration zusammenstellen", "lang_contentOf": "Inhalt von \u0022", "lang_createUser": "Benutzer anlegen", "lang_days": "Tag(e)", - "lang_generic": "Generisch", "lang_hours": "Stunde(n)", - "lang_institutionLogo": "Logo der Einrichtung", "lang_location": "Lokalisierung", "lang_login": "Anmelden", "lang_moduleAdd": "Modul hinzuf\u00fcgen", @@ -18,6 +13,7 @@ "lang_specificLogo": "Einrichtungsspezifisches Logo", "lang_titleBackup": "Sichern und Wiederherstellen", "lang_titleEventLog": "Ereignisprotokoll", + "lang_titleWebinterface": "Webschnittstelle", "lang_unknwonTaskManager": "Unbekannter Taskmanager-Fehler", "today": "Heute", "yesterday": "Gestern" diff --git a/lang/en/messages-hardcoded.json b/lang/en/messages-hardcoded.json index 808b81d2..33f28fcf 100644 --- a/lang/en/messages-hardcoded.json +++ b/lang/en/messages-hardcoded.json @@ -1,16 +1,11 @@ { "lang_adAuthentication": "Active Directory Authentication", - "lang_adModule": "This module makes possible the application to the client PCs with the user accounts of an Active Directory. Depending on the configuration, the use of a user directory on the client is possible.", "lang_addCustomModule": "Add generic module", - "lang_addCustomModuleInfo": "With an extended module it is possible to add any files to the basic system that uses this module, for example to use specific configuration files, which can not be created with one of the other Wizards. Adding an Extended module usually requires at least basic knowledge of the Linux system.", - "lang_authentication": "Authentication", "lang_configurationCompilation": "Compile configuration", "lang_contentOf": "Content of \u0022", "lang_createUser": "Create User", "lang_days": "Day(s)", - "lang_generic": "Generic", "lang_hours": "Hour(s)", - "lang_institutionLogo": "Institution Logo", "lang_location": "Location", "lang_login": "Login", "lang_moduleAdd": "Add Module", @@ -18,6 +13,7 @@ "lang_specificLogo": "Institution Specific Logo", "lang_titleBackup": "Save and Restore", "lang_titleEventLog": "Event log", + "lang_titleWebinterface": "Web Interface", "lang_unknwonTaskManager": "Unknown Task Manager error", "today": "Today", "yesterday": "Yesterday" diff --git a/lang/pt/messages-hardcoded.json b/lang/pt/messages-hardcoded.json index 07ffc5d6..3341dedd 100644 --- a/lang/pt/messages-hardcoded.json +++ b/lang/pt/messages-hardcoded.json @@ -1,15 +1,10 @@ { "lang_adAuthentication": "Autentica\u00e7\u00e3o do Active Directory", - "lang_adModule": "Este m\u00f3dulo possibilita a aplica\u00e7\u00e3o para os computadores clientes com as contas de usu\u00e1rio de um Active Directory. Dependendo da configura\u00e7\u00e3o, o uso de um diret\u00f3rio de usu\u00e1rio no cliente \u00e9 poss\u00edvel.", - "lang_addCustomModuleInfo": "Com um m\u00f3dulo estendido, \u00e9 poss\u00edvel adicionar os arquivos para o sistema b\u00e1sico que usa este m\u00f3dulo, por exemplo, para usar arquivos de configura\u00e7\u00e3o espec\u00edficas, que n\u00e3o podem ser criados com um dos outros assistentes. Adicionar um m\u00f3dulo estendido normalmente exige pelo menos um conhecimento b\u00e1sico do sistema Linux.", - "lang_authentication": "Autentica\u00e7\u00e3o", "lang_configurationCompilation": "Compilar configura\u00e7\u00e3o", "lang_contentOf": "Conte\u00fado de \u0022", "lang_createUser": "Criar Usu\u00e1rio", "lang_days": "Dia(s)", - "lang_generic": "Gen\u00e9rico", "lang_hours": "Hora(s)", - "lang_institutionLogo": "Logotipo da Institui\u00e7\u00e3o", "lang_location": "Localiza\u00e7\u00e3o", "lang_login": "Entrar", "lang_moduleAdd": "Adicionar M\u00f3dulo", diff --git a/modules/session.inc.php b/modules/session.inc.php index 42963e63..5b9bc7fc 100644 --- a/modules/session.inc.php +++ b/modules/session.inc.php @@ -2,43 +2,37 @@ class Page_Session extends Page { - + protected function doPreprocess() { - if (!isset($_REQUEST['action'])) Util::traceError('No action on module init'); - User::load(); - if (isset($_POST['action']) && $_POST['action'] === 'login') { + if (Request::post('action') === 'login') { // Login - see if already logged in - if (User::isLoggedIn()) { + if (User::isLoggedIn()) // and then just redirect Util::redirect('?do=Main'); - } // Else, try to log in - if (User::login($_POST['user'], $_POST['pass'])) { + if (User::login(Request::post('user'), Request::post('pass'))) Util::redirect('?do=Main'); - } - // Login credentials wrong + // Login credentials wrong - delay and show error message sleep(1); 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::post('action') === 'logout') { + // Log user out (or do nothing if not logged in) + User::logout(); + Util::redirect('?do=Main'); } + + if (User::isLoggedIn()) + Util::redirect('?do=Main'); } protected function doRender() { - if ($_REQUEST['action'] === 'login') { - Render::setTitle(Dictionary::translate('lang_login')); - Render::addTemplate('page-login'); - return; - } + Render::setTitle(Dictionary::translate('lang_login')); + Render::addTemplate('page-login'); } } diff --git a/modules/sysconfig.inc.php b/modules/sysconfig.inc.php index 6bb96c80..134f3143 100644 --- a/modules/sysconfig.inc.php +++ b/modules/sysconfig.inc.php @@ -3,45 +3,6 @@ class Page_SysConfig extends Page { - /** - * Holds all the known configuration modules, with title, description, start class for their wizard, etc. - * @var array - */ - protected static $moduleTypes = array(); - - /** - * Add a known configuration module. Every addmoule_* file should call this - * for its module provided. - * - * @param string $id Internal identifier for the module - * @param string $startClass Class to start wizard for creating such a module - * @param string $title Title of this module type - * @param string $description Description for this module type - * @param string $group Title for group this module type belongs to - * @param bool $unique Can only one such module be added to a config? - * @param int $sortOrder Lower comes first, alphabetical ordering otherwiese - */ - public static function addModule($id, $startClass, $title, $description, $group, $unique, $sortOrder = 0) - { - self::$moduleTypes[$id] = array( - 'startClass' => $startClass, - 'title' => $title, - 'description' => $description, - 'group' => $group, - 'unique' => $unique, - 'sortOrder' => $sortOrder - ); - } - - /** - * - * @return array All registered module types - */ - public static function getModuleTypes() - { - return self::$moduleTypes; - } - protected function doPreprocess() { User::load(); @@ -53,12 +14,6 @@ class Page_SysConfig extends Page $action = Request::any('action', 'list'); - // Load all addmodule classes, as they populate the $moduleTypes array - require_once 'modules/sysconfig/addmodule.inc.php'; - foreach (glob('modules/sysconfig/addmodule_*.inc.php') as $file) { - require_once $file; - } - // Action: "addmodule" (upload new module) if ($action === 'addmodule') { $this->initAddModule(); @@ -316,21 +271,24 @@ class Page_SysConfig extends Page private function initAddModule() { + ConfigModules::loadDb(); + require_once 'modules/sysconfig/addmodule.inc.php'; $step = Request::any('step', 0); - if ($step === 0) + if ($step === 0) { $step = 'AddModule_Start'; + } elseif (!class_exists($step) && preg_match('/^([a-zA-Z0-9]+)_/', $step, $out)) { + require_once 'modules/sysconfig/addmodule_' . strtolower($out[1]) . '.inc.php'; + } AddModule_Base::setStep($step); } private function initAddConfig() { + ConfigModules::loadDb(); + require_once 'modules/sysconfig/addconfig.inc.php'; $step = Request::any('step', 0); if ($step === 0) $step = 'AddConfig_Start'; - require_once 'modules/sysconfig/addconfig.inc.php'; - foreach (glob('modules/sysconfig/addconfig_*.inc.php') as $file) { - require_once $file; - } AddConfig_Base::setStep($step); } diff --git a/modules/sysconfig/addconfig.inc.php b/modules/sysconfig/addconfig.inc.php index 1e2e870a..0f35095f 100644 --- a/modules/sysconfig/addconfig.inc.php +++ b/modules/sysconfig/addconfig.inc.php @@ -108,7 +108,7 @@ class AddConfig_Start extends AddConfig_Base protected function renderInternal() { - $mods = Page_SysConfig::getModuleTypes(); + $mods = ConfigModules::getList(); $res = Database::simpleQuery("SELECT moduleid, title, moduletype, filepath FROM configtgz_module" . " ORDER BY title ASC"); while ($row = $res->fetch(PDO::FETCH_ASSOC)) { diff --git a/modules/sysconfig/addmodule.inc.php b/modules/sysconfig/addmodule.inc.php index 1191570d..7fa5b5b9 100644 --- a/modules/sysconfig/addmodule.inc.php +++ b/modules/sysconfig/addmodule.inc.php @@ -109,7 +109,7 @@ class AddModule_Start extends AddModule_Base protected function renderInternal() { $title = $order = array(); - $mods = Page_SysConfig::getModuleTypes(); + $mods = ConfigModules::getList(); foreach ($mods as $module) { $title[] = $module['title']; $order[] = $module['sortOrder']; diff --git a/modules/sysconfig/addmodule_ad.inc.php b/modules/sysconfig/addmodule_ad.inc.php deleted file mode 100644 index d43c9129..00000000 --- a/modules/sysconfig/addmodule_ad.inc.php +++ /dev/null @@ -1,142 +0,0 @@ - 'AdModule_CheckConnection', - 'title' => Request::post('title'), - 'server' => Request::post('server'), - 'searchbase' => Request::post('searchbase'), - 'binddn' => Request::post('binddn'), - 'bindpw' => Request::post('bindpw'), - 'home' => Request::post('home') - )); - } - -} - -class AdModule_CheckConnection extends AddModule_Base -{ - - private $taskIds; - private $originalBindDn; - - protected function preprocessInternal() - { - $server = Request::post('server'); - $searchbase = Request::post('searchbase', ''); - $binddn = Request::post('binddn'); - $bindpw = Request::post('bindpw'); - if (empty($server) || empty($binddn)) { - Message::addError('empty-field'); - AddModule_Base::setStep('AdModule_Start'); // Continues with AdModule_Start for render() - return; - } - $parent = null; - $this->originalBindDn = ''; - if (preg_match('#^\w+[/\\\\](\w+)$#', $binddn, $out)) { - $user = $out[1]; - $this->originalBindDn = str_replace('/', '\\', $binddn); - $selfSearch = Taskmanager::submit('LdapSearch', array( - 'server' => $server, - 'searchbase' => $searchbase, - 'binddn' => $this->originalBindDn, - 'bindpw' => $bindpw, - 'username' => $user - )); - if (!isset($selfSearch['id'])) { - AddModule_Base::setStep('AdModule_Start'); // Continues with AdModule_Start for render() - return; - } - $parent = $selfSearch['id']; - } - $ldapSearch = Taskmanager::submit('LdapSearch', array( - 'parentTask' => $parent, - 'server' => $server, - 'searchbase' => $searchbase, - 'binddn' => $binddn, - 'bindpw' => $bindpw - )); - if (!isset($ldapSearch['id'])) { - AddModule_Base::setStep('AdModule_Start'); // Continues with AdModule_Start for render() - return; - } - $this->taskIds = array( - 'tm-search' => $ldapSearch['id'] - ); - if (isset($selfSearch['id'])) - $this->taskIds['self-search'] = $selfSearch['id']; - } - - protected function renderInternal() - { - Render::addDialog(Dictionary::translate('lang_adAuthentication'), false, 'sysconfig/ad-checkconnection', array_merge($this->taskIds, array( - 'title' => Request::post('title'), - 'server' => Request::post('server'), - 'searchbase' => Request::post('searchbase'), - 'binddn' => Request::post('binddn'), - 'bindpw' => Request::post('bindpw'), - 'home' => Request::post('home'), - 'originalbinddn' => $this->originalBindDn, - 'step' => 'AdModule_Finish' - )) - ); - } - -} - -class AdModule_Finish extends AddModule_Base -{ - - private $taskIds; - - protected function preprocessInternal() - { - $binddn = Request::post('binddn'); - $searchbase = Request::post('searchbase'); - if (empty($searchbase)) { - $originalBindDn = str_replace('\\', '/', trim(Request::post('originalbinddn'))); - if (!preg_match('#^([^/]+)/[^/]+$#', $originalBindDn, $out)) { - Message::addError('value-invalid', 'binddn', $originalBindDn); - Util::redirect('?do=SysConfig&action=addmodule&step=AdModule_Start'); - } - $i = mb_stripos($binddn, '=' . $out[1] . ','); - if ($i === false) { - Message::addError('value-invalid', 'binddn', $out[1]); - Util::redirect('?do=SysConfig&action=addmodule&step=AdModule_Start'); - } - $searchbase = mb_substr($binddn, $i + 1); - } - $title = Request::post('title'); - if (empty($title)) - $title = 'AD: ' . Request::post('server'); - $config = ConfigModule::insertAdConfig($title, Request::post('server'), $searchbase, $binddn, Request::post('bindpw', ''), Request::post('home', '')); - $config['proxyip'] = Property::getServerIp(); - $tgz = Taskmanager::submit('CreateAdConfig', $config); - if (!isset($tgz['id'])) { - AddModule_Base::setStep('AdModule_Start'); // Continues with AdModule_Start for render() - return; - } - $this->taskIds = array( - 'tm-config' => $tgz['id'], - ); - } - - protected function renderInternal() - { - Render::addDialog(Dictionary::translate('lang_adAuthentication'), false, 'sysconfig/ad-finish', $this->taskIds); - } - -} diff --git a/modules/sysconfig/addmodule_adauth.inc.php b/modules/sysconfig/addmodule_adauth.inc.php new file mode 100644 index 00000000..4873d505 --- /dev/null +++ b/modules/sysconfig/addmodule_adauth.inc.php @@ -0,0 +1,145 @@ + 'AdAuth_CheckConnection', + 'title' => Request::post('title'), + 'server' => Request::post('server'), + 'searchbase' => Request::post('searchbase'), + 'binddn' => Request::post('binddn'), + 'bindpw' => Request::post('bindpw'), + 'home' => Request::post('home') + )); + } + +} + +class AdAuth_CheckConnection extends AddModule_Base +{ + + private $taskIds; + private $originalBindDn; + + protected function preprocessInternal() + { + $server = Request::post('server'); + $searchbase = Request::post('searchbase', ''); + $binddn = Request::post('binddn'); + $bindpw = Request::post('bindpw'); + if (empty($server) || empty($binddn)) { + Message::addError('empty-field'); + AddModule_Base::setStep('AdAuth_Start'); // Continues with AdAuth_Start for render() + return; + } + $parent = null; + $this->originalBindDn = ''; + if (preg_match('#^\w+[/\\\\](\w+)$#', $binddn, $out)) { + $user = $out[1]; + $this->originalBindDn = str_replace('/', '\\', $binddn); + $selfSearch = Taskmanager::submit('LdapSearch', array( + 'server' => $server, + 'searchbase' => $searchbase, + 'binddn' => $this->originalBindDn, + 'bindpw' => $bindpw, + 'username' => $user + )); + if (!isset($selfSearch['id'])) { + AddModule_Base::setStep('AdAuth_Start'); // Continues with AdAuth_Start for render() + return; + } + $parent = $selfSearch['id']; + } + $ldapSearch = Taskmanager::submit('LdapSearch', array( + 'parentTask' => $parent, + 'server' => $server, + 'searchbase' => $searchbase, + 'binddn' => $binddn, + 'bindpw' => $bindpw + )); + if (!isset($ldapSearch['id'])) { + AddModule_Base::setStep('AdAuth_Start'); // Continues with AdAuth_Start for render() + return; + } + $this->taskIds = array( + 'tm-search' => $ldapSearch['id'] + ); + if (isset($selfSearch['id'])) + $this->taskIds['self-search'] = $selfSearch['id']; + } + + protected function renderInternal() + { + Render::addDialog(Dictionary::translate('lang_adAuthentication'), false, 'sysconfig/ad-checkconnection', array_merge($this->taskIds, array( + 'title' => Request::post('title'), + 'server' => Request::post('server'), + 'searchbase' => Request::post('searchbase'), + 'binddn' => Request::post('binddn'), + 'bindpw' => Request::post('bindpw'), + 'home' => Request::post('home'), + 'originalbinddn' => $this->originalBindDn, + 'step' => 'AdAuth_Finish' + )) + ); + } + +} + +class AdAuth_Finish extends AddModule_Base +{ + + private $taskIds; + + protected function preprocessInternal() + { + $binddn = Request::post('binddn'); + $searchbase = Request::post('searchbase'); + if (empty($searchbase)) { + // If no search base was given, determine it from the dn + $originalBindDn = str_replace('\\', '/', trim(Request::post('originalbinddn'))); + if (!preg_match('#^([^/]+)/[^/]+$#', $originalBindDn, $out)) { + Message::addError('value-invalid', 'binddn', $originalBindDn); + Util::redirect('?do=SysConfig&action=addmodule&step=AdAuth_Start'); + } // $out[1] is the domain + // Find the domain in the dn + $i = mb_stripos($binddn, '=' . $out[1] . ','); + if ($i === false) { + Message::addError('value-invalid', 'binddn', $out[1]); + Util::redirect('?do=SysConfig&action=addmodule&step=AdAuth_Start'); + } + // Now find ',' before it so we get the key + $i = mb_strrpos(mb_substr($binddn, 0, $i), ','); + if ($i === false) + $i = -1; + $searchbase = mb_substr($binddn, $i + 1); + } + $title = Request::post('title'); + if (empty($title)) + $title = 'AD: ' . Request::post('server'); + $config = ConfigModule_AdAuth::insert($title, Request::post('server'), $searchbase, $binddn, Request::post('bindpw', ''), Request::post('home', '')); + $config['proxyip'] = Property::getServerIp(); + $tgz = Taskmanager::submit('CreateAdConfig', $config); + if (!isset($tgz['id'])) { + AddModule_Base::setStep('AdAuth_Start'); // Continues with AdAuth_Start for render() + return; + } + $this->taskIds = array( + 'tm-config' => $tgz['id'], + ); + } + + protected function renderInternal() + { + Render::addDialog(Dictionary::translate('lang_adAuthentication'), false, 'sysconfig/ad-finish', $this->taskIds); + } + +} diff --git a/modules/sysconfig/addmodule_branding.inc.php b/modules/sysconfig/addmodule_branding.inc.php index 9612bedb..a6c16d9d 100644 --- a/modules/sysconfig/addmodule_branding.inc.php +++ b/modules/sysconfig/addmodule_branding.inc.php @@ -4,8 +4,6 @@ * Wizard for including a branding logo. */ -Page_SysConfig::addModule('BRANDING', 'Branding_Start', Dictionary::translate('lang_institutionLogo'), Dictionary::translate('lang_institutionLogo'), 'Branding', true); - class Branding_Start extends AddModule_Base { @@ -199,7 +197,7 @@ class Branding_Finish extends AddModule_Base Message::addError('missing-file'); Util::redirect('?do=SysConfig&action=addmodule&step=Branding_Start'); } - if (!ConfigModule::insertBrandingModule($title, $tgz)) + if (!ConfigModule_Branding::insert($title, $tgz)) Util::redirect('?do=SysConfig&action=addmodule&step=Branding_Start'); Session::set('logo_tgz', false); Session::save(); diff --git a/modules/sysconfig/addmodule_custom.inc.php b/modules/sysconfig/addmodule_custom.inc.php deleted file mode 100644 index f79313e8..00000000 --- a/modules/sysconfig/addmodule_custom.inc.php +++ /dev/null @@ -1,140 +0,0 @@ - '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', Util::uploadErrorString($_FILES['modulefile']['error'])); - Util::redirect('?do=SysConfig'); - } - $tempfile = '/tmp/bwlp-' . mt_rand(1, 100000) . '-' . crc32($_SERVER['REMOTE_HOST']) . '.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(Dictionary::translate('lang_addCustomModule'), 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-' . Util::sanitizeFilename($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, filepath, 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/sysconfig/addmodule_custommodule.inc.php b/modules/sysconfig/addmodule_custommodule.inc.php new file mode 100644 index 00000000..66ba33a5 --- /dev/null +++ b/modules/sysconfig/addmodule_custommodule.inc.php @@ -0,0 +1,136 @@ + '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', Util::uploadErrorString($_FILES['modulefile']['error'])); + Util::redirect('?do=SysConfig'); + } + $tempfile = '/tmp/bwlp-' . mt_rand(1, 100000) . '-' . crc32($_SERVER['REMOTE_HOST']) . '.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(Dictionary::translate('lang_addCustomModule'), 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-' . Util::sanitizeFilename($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, filepath, 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/translation.inc.php b/modules/translation.inc.php index 85524d92..4dc2f515 100644 --- a/modules/translation.inc.php +++ b/modules/translation.inc.php @@ -271,7 +271,7 @@ class Page_Translation extends Page */ private function loadHardcodedStringEditArray() { - $tags = $this->loadTagsFromPhp('/Dictionary\s*::\s*translate\s*\(\s*[\'"](.*?)[\'"]\s*\)/i'); + $tags = $this->loadTagsFromPhp('/Dictionary\s*::\s*translate\s*\(\s*[\'"]([^\'"]*?)[\'"]\s*\)/i'); if ($tags === false) return false; return $this->buildTranslationTable('messages-hardcoded', $tags); diff --git a/modules/webinterface.inc.php b/modules/webinterface.inc.php index fcaf923b..f3780277 100644 --- a/modules/webinterface.inc.php +++ b/modules/webinterface.inc.php @@ -48,7 +48,7 @@ class Page_WebInterface extends Page protected function doRender() { - Render::setTitle(Dictionary::translate('title-webinterface')); + Render::setTitle(Dictionary::translate('lang_titleWebinterface')); if (Request::get('show') === 'httpsupdate') { Render::addTemplate('webinterface/httpd-restart', array('taskid' => Session::get('https-id'))); } diff --git a/templates/main-menu.html b/templates/main-menu.html index 937b171c..77d5d5ee 100644 --- a/templates/main-menu.html +++ b/templates/main-menu.html @@ -37,7 +37,7 @@