summaryrefslogtreecommitdiffstats
path: root/inc
diff options
context:
space:
mode:
authorSimon Rettberg2016-05-11 19:00:30 +0200
committerSimon Rettberg2016-05-11 19:00:30 +0200
commit1cc1c2ed092c46eb35893c1d85accb24cf43d7f9 (patch)
tree95c1302f4a1ae441e174a1dca64133e2873f8297 /inc
parentAdd PhpStorm prefs (diff)
downloadslx-admin-1cc1c2ed092c46eb35893c1d85accb24cf43d7f9.tar.gz
slx-admin-1cc1c2ed092c46eb35893c1d85accb24cf43d7f9.tar.xz
slx-admin-1cc1c2ed092c46eb35893c1d85accb24cf43d7f9.zip
Still working in modularization cleanup and refinement
Diffstat (limited to 'inc')
-rw-r--r--inc/configmodule.inc.php515
-rw-r--r--inc/configmodule/adauth.inc.php74
-rw-r--r--inc/configmodule/branding.inc.php55
-rw-r--r--inc/configmodule/customodule.inc.php55
-rw-r--r--inc/configmodule/ldapauth.inc.php76
-rw-r--r--inc/configmodule/sshconfig.inc.php63
-rw-r--r--inc/configtgz.inc.php317
-rw-r--r--inc/database.inc.php1
-rw-r--r--inc/message.inc.php4
-rw-r--r--inc/module.inc.php5
-rw-r--r--inc/property.inc.php1
-rw-r--r--inc/render.inc.php52
-rw-r--r--inc/request.inc.php5
-rw-r--r--inc/session.inc.php1
-rw-r--r--inc/taskmanagercallback.inc.php8
-rw-r--r--inc/up_json_encode.php4
-rw-r--r--inc/validator.inc.php1
17 files changed, 55 insertions, 1182 deletions
diff --git a/inc/configmodule.inc.php b/inc/configmodule.inc.php
deleted file mode 100644
index 909136ee..00000000
--- a/inc/configmodule.inc.php
+++ /dev/null
@@ -1,515 +0,0 @@
-<?php
-
-/**
- * Base class for config modules
- */
-abstract class ConfigModule
-{
-
- /**
- * @var array list of known module types
- */
- private static $moduleTypes = false;
-
- private $moduleId = 0;
- private $moduleArchive = false;
- private $moduleTitle = false;
- private $currentVersion = 0;
- protected $moduleData = false;
-
- /**
- * Load all known config module types. This is done
- * by including *.inc.php from inc/configmodule/. The
- * files there should in turn call ConfigModule::registerModule()
- * to register themselves.
- */
- public static function loadDb()
- {
- if (self::$moduleTypes !== false)
- return;
- self::$moduleTypes = array();
- foreach (glob('inc/configmodule/*.inc.php') as $file) {
- require_once $file;
- }
- }
-
- /**
- * Get all known config module types.
- *
- * @return array list of modules
- */
- public static function getList()
- {
- self::loadDb();
- return self::$moduleTypes;
- }
-
- /**
- * Add a known configuration module. Every inc/configmodule/*.inc.php should call this.
- *
- * @param string $id Identifier for the module.
- * The module class must be called ConfigModule_{$id}, the wizard start class {$id}_Start.
- * The wizard's classes should be located in modules/sysconfig/addmodule_{$id_lowercase}.inc.php
- * @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 registerModule($id, $title, $description, $group, $unique, $sortOrder = 0)
- {
- if (isset(self::$moduleTypes[$id]))
- Util::traceError("Config Module $id already registered!");
- $moduleClass = 'ConfigModule_' . $id;
- $wizardClass = $id . '_Start';
- if (!class_exists($moduleClass))
- Util::traceError("Class $moduleClass does not exist!");
- if (get_parent_class($moduleClass) !== 'ConfigModule')
- Util::traceError("$moduleClass does not have ConfigModule as its parent!");
- self::$moduleTypes[$id] = array(
- 'title' => $title,
- 'description' => $description,
- 'group' => $group,
- 'unique' => $unique,
- 'sortOrder' => $sortOrder,
- 'moduleClass' => $moduleClass,
- 'wizardClass' => $wizardClass
- );
- }
-
- /**
- * Get fresh instance of ConfigModule subclass for given module type.
- *
- * @param string $moduleType name of module type
- * @return \ConfigModule module instance
- */
- public static function getInstance($moduleType)
- {
- self::loadDb();
- if (!isset(self::$moduleTypes[$moduleType]))
- return false;
- return new self::$moduleTypes[$moduleType]['moduleClass'];
- }
-
- /**
- * Get module instance from id.
- *
- * @param int $moduleId module id to get
- * @return ConfigModule The requested module from DB, or false on error
- */
- public static function get($moduleId)
- {
- $ret = Database::queryFirst("SELECT title, moduletype, filepath, contents, version FROM configtgz_module "
- . " WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleId));
- if ($ret === false)
- return false;
- $instance = self::getInstance($ret['moduletype']);
- if ($instance === false)
- return false;
- $instance->currentVersion = $ret['version'];
- $instance->moduleArchive = $ret['filepath'];
- $instance->moduleData = json_decode($ret['contents'], true);
- $instance->moduleId = $moduleId;
- $instance->moduleTitle = $ret['title'];
- return $instance;
- }
-
- /**
- * Get module instances from module type.
- *
- * @param int $moduleType module type to get
- * @return array The requested modules from DB, or false on error
- */
- public static function getAll($moduleType = false)
- {
- if ($moduleType === false) {
- $ret = Database::simpleQuery("SELECT moduleid, title, moduletype, filepath, contents, version FROM configtgz_module");
- } else {
- $ret = Database::simpleQuery("SELECT moduleid, title, moduletype, filepath, contents, version FROM configtgz_module "
- . " WHERE moduletype = :moduletype", array('moduletype' => $moduleType));
- }
- if ($ret === false)
- return false;
- $list = array();
- while ($row = $ret->fetch(PDO::FETCH_ASSOC)) {
- $instance = self::getInstance($row['moduletype']);
- if ($instance === false)
- return false;
- $instance->currentVersion = $row['version'];
- $instance->moduleArchive = $row['filepath'];
- $instance->moduleData = json_decode($row['contents'], true);
- $instance->moduleId = $row['moduleid'];
- $instance->moduleTitle = $row['title'];
- $list[] = $instance;
- }
- return $list;
- }
-
- /**
- * Get the module version.
- *
- * @return int module version
- */
- protected abstract function moduleVersion();
-
- /**
- * Validate the module's configuration.
- *
- * @return boolean ok or not
- */
- protected abstract function validateConfig();
-
- /**
- * Set module specific data.
- *
- * @param string $key key, name or id of data being set
- * @param mixed $value Module specific data
- * @return boolean true if data was successfully set, false otherwise (i.e. invalid data being set)
- */
- public abstract function setData($key, $value);
-
- /**
- * Get module specific data.
- * Can be overridden by modules.
- *
- * @param string $key key, name or id of data to get, or false to get the raw moduleData array
- * @return mixed Module specific data
- */
- public function getData($key)
- {
- if ($key === false)
- return $this->moduleData;
- if (!is_array($this->moduleData) || !isset($this->moduleData[$key]))
- return false;
- return $this->moduleData[$key];
- }
-
- /**
- * Module specific version of generate.
- *
- * @param string $tgz File name of tgz module to write final output to
- * @param string $parent Parent task of this task
- * @return array|boolean true if generation is completed immediately,
- * a task struct if some task needs to be run for generation,
- * false on error
- */
- protected abstract function generateInternal($tgz, $parent);
-
- private final function createFileName()
- {
- return CONFIG_TGZ_LIST_DIR . '/modules/'
- . $this->moduleType() . '_id-' . $this->moduleId . '__' . mt_rand() . '-' . time() . '.tgz';
- }
-
- /**
- * Get module id (in db)
- *
- * @return int id
- */
- public final function id()
- {
- return $this->moduleId;
- }
-
- /**
- * Get module title.
- *
- * @return string
- */
- public final function title()
- {
- return $this->moduleTitle;
- }
-
- /**
- * Get module archive file name.
- *
- * @return string tgz file absolute path
- */
- public final function archive()
- {
- return $this->moduleArchive;
- }
-
- /**
- * Get the module type.
- *
- * @return string module type
- */
- public final function moduleType()
- {
- $name = get_class($this);
- if ($name === false)
- Util::traceError('ConfigModule::moduleType: get_class($this) returned false!');
- // ConfigModule_*
- if (!preg_match('/^ConfigModule_(\w+)$/', $name, $out))
- Util::traceError('ConfigModule::moduleType: get_class($this) returned "' . $name . '"');
- return $out[1];
- }
-
- /**
- * Insert this config module into DB. Only
- * valid if the object was created using the creating constructor,
- * not if the instance was created using a database entry (static get method).
- *
- * @param string $title display name of the module
- * @return boolean true if inserted successfully, false if module config is invalid
- */
- public final function insert($title)
- {
- if ($this->moduleId !== 0)
- Util::traceError('ConfigModule::insert called when moduleId != 0');
- if (!$this->validateConfig())
- return false;
- $this->moduleTitle = $title;
- // Insert
- Database::exec("INSERT INTO configtgz_module (title, moduletype, filepath, contents, version, status) "
- . " VALUES (:title, :type, '', :contents, :version, :status)", array(
- 'title' => $title,
- 'type' => $this->moduleType(),
- 'contents' => json_encode($this->moduleData),
- 'version' => 0,
- 'status' => 'MISSING'
- ));
- $this->moduleId = Database::lastInsertId();
- if (!is_numeric($this->moduleId))
- Util::traceError('Inserting new config module into DB did not yield a numeric insert id');
- $this->moduleArchive = $this->createFileName();
- Database::exec("UPDATE configtgz_module SET filepath = :path WHERE moduleid = :moduleid LIMIT 1", array(
- 'path' => $this->moduleArchive,
- 'moduleid' => $this->moduleId
- ));
- return true;
- }
-
- /**
- * Update the given module in database. This will not regenerate
- * the module's tgz.
- *
- * @return boolean true on success, false otherwise
- */
- public final function update($title)
- {
- if ($this->moduleId === 0)
- Util::traceError('ConfigModule::update called when moduleId == 0');
- if (empty($title))
- $title = $this->moduleTitle;
- if (!$this->validateConfig())
- return false;
- // Update
- Database::exec("UPDATE configtgz_module SET title = :title, contents = :contents, status = :status "
- . " WHERE moduleid = :moduleid LIMIT 1", array(
- 'moduleid' => $this->moduleId,
- 'title' => $title,
- 'contents' => json_encode($this->moduleData),
- 'status' => 'OUTDATED'
- ));
- return true;
- }
-
- /**
- * Generate the module's tgz, don't wait for completion.
- * Updating the database etc. will happen later through a callback.
- *
- * @param boolean $deleteOnError if true, the db entry will be deleted if generation failed
- * @param string $parent Parent task of this task
- * @param int $timeoutMs maximum time in milliseconds we wait for completion
- * @return string|boolean task id if deferred generation was started,
- * true if generation succeeded (without using a task or within $timeoutMs)
- * false on error
- */
- public final function generate($deleteOnError, $parent = NULL, $timeoutMs = 0)
- {
- if ($this->moduleId === 0 || $this->moduleTitle === false)
- Util::traceError('ConfigModule::generateAsync called on uninitialized/uninserted module!');
- $tmpTgz = '/tmp/bwlp-id-' . $this->moduleId . '_' . mt_rand() . '_' . time() . '.tgz';
- $ret = $this->generateInternal($tmpTgz, $parent);
- // Wait for generation if requested
- if ($timeoutMs > 0 && isset($ret['id']) && !Taskmanager::isFinished($ret))
- $ret = Taskmanager::waitComplete($ret, $timeoutMs);
- if ($ret === true || (isset($ret['statusCode']) && $ret['statusCode'] === TASK_FINISHED)) {
- // Already Finished
- if (file_exists($this->moduleArchive) && !file_exists($tmpTgz))
- $tmpTgz = false; // If generateInternal succeeded and there's no tmpTgz, it means the file didn't have to be updated
- return $this->markUpdated($tmpTgz);
- }
- if (!is_array($ret) || !isset($ret['id']) || Taskmanager::isFailed($ret)) {
- if (is_array($ret)) // Failed
- Taskmanager::addErrorMessage($ret);
- if ($deleteOnError)
- $this->delete();
- else
- $this->markFailed();
- return false;
- }
- // Still running, add callback
- TaskmanagerCallback::addCallback($ret, 'cbConfModCreated', array(
- 'moduleid' => $this->moduleId,
- 'deleteOnError' => $deleteOnError,
- 'tmpTgz' => $tmpTgz
- ));
- return $ret['id'];
- }
-
- /**
- * Delete the module.
- */
- public final function delete()
- {
- if ($this->moduleId === 0)
- Util::traceError('ConfigModule::delete called with invalid module id!');
- $ret = Database::exec("DELETE FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array(
- 'moduleid' => $this->moduleId
- ), true) !== false;
- if ($ret !== false) {
- if ($this->moduleArchive)
- Taskmanager::submit('DeleteFile', array('file' => $this->moduleArchive), true);
- $this->moduleId = 0;
- $this->moduleData = false;
- $this->moduleTitle = false;
- $this->moduleArchive = false;
- }
- return $ret;
- }
-
- private final function markUpdated($tmpTgz)
- {
- if ($this->moduleId === 0)
- Util::traceError('ConfigModule::markUpdated called with invalid module id!');
- if ($this->moduleArchive === false)
- $this->moduleArchive = $this->createFileName();
- // Move file
- if ($tmpTgz === false) {
- if (!file_exists($this->moduleArchive)) {
- EventLog::failure('ConfigModule::markUpdated for "' . $this->moduleTitle . '" called with no tmpTgz and no existing tgz!');
- $this->markFailed();
- return false;
- }
- } else {
- $task = Taskmanager::submit('MoveFile', array(
- 'source' => $tmpTgz,
- 'destination' => $this->moduleArchive
- ));
- $task = Taskmanager::waitComplete($task, 5000);
- if (Taskmanager::isFailed($task) || !Taskmanager::isFinished($task)) {
- if (!API && !AJAX)
- Taskmanager::addErrorMessage($task);
- else
- EventLog::failure('Could not move ' . $tmpTgz . ' to ' . $this->moduleArchive . ' while generating "' . $this->moduleTitle . '"');
- $this->markFailed();
- return false;
- }
- }
- // Update DB entry
- $retval = Database::exec("UPDATE configtgz_module SET filepath = :filename, version = :version, status = 'OK' WHERE moduleid = :id LIMIT 1", array(
- 'id' => $this->moduleId,
- 'filename' => $this->moduleArchive,
- 'version' => $this->moduleVersion()
- )) !== false;
- // Update related config.tgzs
- $configs = ConfigTgz::getAllForModule($this->moduleId);
- foreach ($configs as $config) {
- $config->markOutdated();
- $config->generate();
- }
- return $retval;
- }
-
- private final function markFailed()
- {
- if ($this->moduleId === 0)
- Util::traceError('ConfigModule::markFailed called with invalid module id!');
- if ($this->moduleArchive === false)
- $this->moduleArchive = $this->createFileName();
- if (!file_exists($this->moduleArchive))
- $status = 'MISSING';
- else
- $status = 'OUTDATED';
- return Database::exec("UPDATE configtgz_module SET filepath = :filename, status = :status WHERE moduleid = :id LIMIT 1", array(
- 'id' => $this->moduleId,
- 'filename' => $this->moduleArchive,
- 'status' => $status
- )) !== false;
- }
-
- ################# Callbacks ##############
-
- /**
- * Event callback for when the server ip changed.
- * Override this if you need to handle this, otherwise
- * the base implementation does nothing.
- */
- public function event_serverIpChanged()
- {
- // Do::Nothing()
- }
-
- ##################### STATIC CALLBACKS #####################
-
- /**
- * 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();
- $list = self::getAll();
- foreach ($list as $mod) {
- $mod->event_serverIpChanged();
- }
- }
-
- /**
- * Called when (re)generating a config module failed, so we can
- * update the status in the DB and add a server log entry.
- *
- * @param array $task
- * @param array $args contains 'moduleid' and optionally 'deleteOnError' and 'tmpTgz'
- */
- public static function generateFailed($task, $args)
- {
- if (!isset($args['moduleid']) || !is_numeric($args['moduleid'])) {
- EventLog::warning('Ignoring generateFailed event as it has no moduleid assigned.');
- return;
- }
- $module = self::get($args['moduleid']);
- if ($module === false) {
- EventLog::warning('generateFailed callback for module id ' . $args['moduleid'] . ', but no instance could be generated.');
- return;
- }
- if (isset($task['data']['error']))
- $error = $task['data']['error'];
- elseif (isset($task['data']['messages']))
- $error = $task['data']['messages'];
- else
- $error = '';
- EventLog::failure("Generating module '" . $module->moduleTitle . "' failed.", $error);
- if ($args['deleteOnError'])
- $module->delete();
- else
- $module->markFailed();
- }
-
- /**
- * (Re)generating a config module succeeded. Update db entry.
- *
- * @param array $args contains 'moduleid' and optionally 'deleteOnError' and 'tmpTgz'
- */
- public static function generateSucceeded($args)
- {
- if (!isset($args['moduleid']) || !is_numeric($args['moduleid'])) {
- EventLog::warning('Ignoring generateSucceeded event as it has no moduleid assigned.');
- return;
- }
- $module = self::get($args['moduleid']);
- if ($module === false) {
- EventLog::warning('generateSucceeded callback for module id ' . $args['moduleid'] . ', but no instance could be generated.');
- return;
- }
- if (isset($args['tmpTgz']))
- $module->markUpdated($args['tmpTgz']);
- else
- $module->markUpdated(false);
- }
-
-}
diff --git a/inc/configmodule/adauth.inc.php b/inc/configmodule/adauth.inc.php
deleted file mode 100644
index efc8afd7..00000000
--- a/inc/configmodule/adauth.inc.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-
-ConfigModule::registerModule(
- 'AdAuth', // ID
- Dictionary::translate('config-module', 'adAuth_title'), // Title
- Dictionary::translate('config-module', 'adAuth_description'), // Description
- Dictionary::translate('config-module', 'group_authentication'), // Group
- true // Only one per config?
-);
-
-class ConfigModule_AdAuth extends ConfigModule
-{
-
- const VERSION = 1;
-
- private static $REQUIRED_FIELDS = array('server', 'searchbase', 'binddn');
- private static $OPTIONAL_FIELDS = array('bindpw', 'home', 'ssl', 'fingerprint', 'certificate', 'homeattr');
-
- protected function generateInternal($tgz, $parent)
- {
- Trigger::ldadp($this->id(), $parent);
- $config = $this->moduleData;
- if (isset($config['certificate']) && !is_string($config['certificate'])) {
- unset($config['certificate']);
- }
- if (preg_match('/^([^\:]+)\:(\d+)$/', $config['server'], $out)) {
- $config['server'] = $out[1];
- $config['adport'] = $out[2];
- } else {
- if (isset($config['certificate'])) {
- $config['adport'] = 636;
- } else {
- $config['adport'] = 389;
- }
- }
- $config['parentTask'] = $parent;
- $config['failOnParentFail'] = false;
- $config['proxyip'] = Property::getServerIp();
- $config['proxyport'] = 3100 + $this->id();
- $config['filename'] = $tgz;
- $config['moduleid'] = $this->id();
- return Taskmanager::submit('CreateLdapConfig', $config);
- }
-
- protected function moduleVersion()
- {
- return self::VERSION;
- }
-
- protected function validateConfig()
- {
- // Check if required fields are filled
- return Util::hasAllKeys($this->moduleData, self::$REQUIRED_FIELDS);
- }
-
- public function setData($key, $value)
- {
- if (!in_array($key, self::$REQUIRED_FIELDS) && !in_array($key, self::$OPTIONAL_FIELDS))
- return false;
- $this->moduleData[$key] = $value;
- return true;
- }
-
- // ############## Callbacks #############################
-
- /**
- * Server IP changed - rebuild all AD modules.
- */
- public function event_serverIpChanged()
- {
- $this->generate(false);
- }
-
-}
diff --git a/inc/configmodule/branding.inc.php b/inc/configmodule/branding.inc.php
deleted file mode 100644
index b2f28c2f..00000000
--- a/inc/configmodule/branding.inc.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-ConfigModule::registerModule(
- ConfigModule_Branding::MODID, // ID
- Dictionary::translate('config-module', 'branding_title'), // Title
- Dictionary::translate('config-module', 'branding_description'), // Description
- Dictionary::translate('config-module', 'group_branding'), // Group
- true // Only one per config?
-);
-
-class ConfigModule_Branding extends ConfigModule
-{
-
- const MODID = 'Branding';
- const VERSION = 1;
-
- private $tmpFile = false;
-
- protected function generateInternal($tgz, $parent)
- {
- if (!$this->validateConfig()) {
- return $this->archive() !== false && file_exists($this->archive()); // No new temp file given, old archive still exists, pretend it worked...
- }
- $task = Taskmanager::submit('MoveFile', array(
- 'source' => $this->tmpFile,
- 'destination' => $tgz,
- 'parentTask' => $parent,
- 'failOnParentFail' => false
- ));
- return $task;
- }
-
- protected function moduleVersion()
- {
- return self::VERSION;
- }
-
- protected function validateConfig()
- {
- return $this->tmpFile !== false && file_exists($this->tmpFile);
- }
-
- public function setData($key, $value)
- {
- if ($key !== 'tmpFile' || !is_string($value) || !file_exists($value))
- return false;
- $this->tmpFile = $value;
- }
-
- public function getData($key)
- {
- return false;
- }
-
-}
diff --git a/inc/configmodule/customodule.inc.php b/inc/configmodule/customodule.inc.php
deleted file mode 100644
index 31796e9c..00000000
--- a/inc/configmodule/customodule.inc.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-ConfigModule::registerModule(
- ConfigModule_CustomModule::MODID, // ID
- Dictionary::translate('config-module', 'custom_title'), // Title
- Dictionary::translate('config-module', 'custom_description'), // Description
- Dictionary::translate('config-module', 'group_generic'), // Group
- false, // Only one per config?
- 100 // Sort order
-);
-
-class ConfigModule_CustomModule extends ConfigModule
-{
- const MODID = 'CustomModule';
- const VERSION = 1;
-
- private $tmpFile = false;
-
- protected function generateInternal($tgz, $parent)
- {
- if (!$this->validateConfig()) {
- return $this->archive() !== false && file_exists($this->archive()); // No new temp file given, old archive still exists, pretend it worked...
- }
- $task = Taskmanager::submit('MoveFile', array(
- 'source' => $this->tmpFile,
- 'destination' => $tgz,
- 'parentTask' => $parent,
- 'failOnParentFail' => false
- ));
- return $task;
- }
-
- protected function moduleVersion()
- {
- return self::VERSION;
- }
-
- protected function validateConfig()
- {
- return $this->tmpFile !== false && file_exists($this->tmpFile);
- }
-
- public function setData($key, $value)
- {
- if ($key !== 'tmpFile' || !file_exists($value))
- return false;
- $this->tmpFile = $value;
- }
-
- public function getData($key)
- {
- return false;
- }
-
-}
diff --git a/inc/configmodule/ldapauth.inc.php b/inc/configmodule/ldapauth.inc.php
deleted file mode 100644
index 67b1997a..00000000
--- a/inc/configmodule/ldapauth.inc.php
+++ /dev/null
@@ -1,76 +0,0 @@
-<?php
-
-ConfigModule::registerModule(
- 'LdapAuth', // ID
- Dictionary::translate('config-module', 'ldapAuth_title'), // Title
- Dictionary::translate('config-module', 'ldapAuth_description'), // Description
- Dictionary::translate('config-module', 'group_authentication'), // Group
- true // Only one per config?
-);
-
-class ConfigModule_LdapAuth extends ConfigModule
-{
-
- const VERSION = 1;
-
- private static $REQUIRED_FIELDS = array('server', 'searchbase');
- private static $OPTIONAL_FIELDS = array('binddn', 'bindpw', 'home', 'ssl', 'fingerprint', 'certificate');
-
- protected function generateInternal($tgz, $parent)
- {
- Trigger::ldadp($this->id(), $parent);
- $config = $this->moduleData;
- if (isset($config['certificate']) && !is_string($config['certificate'])) {
- unset($config['certificate']);
- }
- if (preg_match('/^([^\:]+)\:(\d+)$/', $config['server'], $out)) {
- $config['server'] = $out[1];
- $config['adport'] = $out[2]; // sic!
- } else {
- if (isset($config['certificate'])) {
- $config['adport'] = 636;
- } else {
- $config['adport'] = 389;
- }
- }
- $config['parentTask'] = $parent;
- $config['failOnParentFail'] = false;
- $config['proxyip'] = Property::getServerIp();
- $config['proxyport'] = 3100 + $this->id();
- $config['filename'] = $tgz;
- $config['moduleid'] = $this->id();
- $config['plainldap'] = true;
- return Taskmanager::submit('CreateLdapConfig', $config);
- }
-
- protected function moduleVersion()
- {
- return self::VERSION;
- }
-
- protected function validateConfig()
- {
- // Check if required fields are filled
- return Util::hasAllKeys($this->moduleData, self::$REQUIRED_FIELDS);
- }
-
- public function setData($key, $value)
- {
- if (!in_array($key, self::$REQUIRED_FIELDS) && !in_array($key, self::$OPTIONAL_FIELDS))
- return false;
- $this->moduleData[$key] = $value;
- return true;
- }
-
- // ############## Callbacks #############################
-
- /**
- * Server IP changed - rebuild all LDAP modules.
- */
- public function event_serverIpChanged()
- {
- error_log('Calling generate on ' . $this->title());
- $this->generate(false);
- }
-
-}
diff --git a/inc/configmodule/sshconfig.inc.php b/inc/configmodule/sshconfig.inc.php
deleted file mode 100644
index 853acf6a..00000000
--- a/inc/configmodule/sshconfig.inc.php
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-
-ConfigModule::registerModule(
- ConfigModule_SshConfig::MODID, // ID
- Dictionary::translate('config-module', 'sshconfig_title'), // Title
- Dictionary::translate('config-module', 'sshconfig_description'), // Description
- Dictionary::translate('config-module', 'group_sshconfig'), // Group
- true // Only one per config?
-);
-
-class ConfigModule_SshConfig extends ConfigModule
-{
- const MODID = 'SshConfig';
- const VERSION = 1;
-
- protected function generateInternal($tgz, $parent)
- {
- if (!$this->validateConfig())
- return false;
- $config = $this->moduleData + array(
- 'filename' => $tgz,
- 'failOnParentFail' => false,
- 'parent' => $parent
- );
- // Create config module, which will also check if the pubkey is valid
- return Taskmanager::submit('SshdConfigGenerator', $config);
- }
-
- protected function moduleVersion()
- {
- return self::VERSION;
- }
-
- protected function validateConfig()
- {
- return isset($this->moduleData['publicKey']) && isset($this->moduleData['allowPasswordLogin']) && isset($this->moduleData['listenPort']);
- }
-
- public function setData($key, $value)
- {
- switch ($key) {
- case 'publicKey':
- break;
- case 'allowPasswordLogin':
- if ($value === true || $value === 'yes')
- $value = 'yes';
- elseif ($value === false || $value === 'no')
- $value = 'no';
- else
- return false;
- break;
- case 'listenPort':
- if (!is_numeric($value) || $value < 1 || $value > 65535)
- return false;
- break;
- default:
- return false;
- }
- $this->moduleData[$key] = $value;
- return true;
- }
-
-}
diff --git a/inc/configtgz.inc.php b/inc/configtgz.inc.php
deleted file mode 100644
index b51d2787..00000000
--- a/inc/configtgz.inc.php
+++ /dev/null
@@ -1,317 +0,0 @@
-<?php
-
-class ConfigTgz
-{
-
- private $configId = 0;
- private $configTitle = false;
- private $file = false;
- private $modules = array();
-
- private function __construct()
- {
- ;
- }
-
- public function id()
- {
- return $this->configId;
- }
-
- public function title()
- {
- return $this->configTitle;
- }
-
- public function areAllModulesUpToDate()
- {
- if (!$this->configId > 0)
- Util::traceError('ConfigTgz::areAllModulesUpToDate called on un-inserted config.tgz!');
- foreach ($this->modules as $module) {
- if (!empty($module['filepath']) && file_exists($module['filepath'])) {
- if ($module['status'] !== 'OK')
- return false;
- } else {
- return false;
- }
- }
- return true;
- }
-
- public function isActive()
- {
- return readlink(CONFIG_HTTP_DIR . '/default/config.tgz') === $this->file;
- }
-
- public function getModuleIds()
- {
- $ret = array();
- foreach ($this->modules as $module) {
- $ret[] = $module['moduleid'];
- }
- return $ret;
- }
-
- public function update($title, $moduleIds)
- {
- if (!is_array($moduleIds))
- return false;
- $this->configTitle = $title;
- $this->modules = array();
- // Get all modules to put in config
- $idstr = '0'; // Passed directly in query. Make sure no SQL injection is possible
- foreach ($moduleIds as $module) {
- $idstr .= ',' . (int)$module; // Casting to int should make it safe
- }
- $res = Database::simpleQuery("SELECT moduleid, filepath, status FROM configtgz_module WHERE moduleid IN ($idstr)");
- // Delete old connections
- Database::exec("DELETE FROM configtgz_x_module WHERE configid = :configid", array('configid' => $this->configId));
- // Make connection
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- Database::exec("INSERT INTO configtgz_x_module (configid, moduleid) VALUES (:configid, :moduleid)", array(
- 'configid' => $this->configId,
- 'moduleid' => $row['moduleid']
- ));
- $this->modules[] = $row;
- }
- // Update name
- Database::exec("UPDATE configtgz SET title = :title, status = :status WHERE configid = :configid LIMIT 1", array(
- 'configid' => $this->configId,
- 'title' => $title,
- 'status' => 'OUTDATED'
- ));
- return true;
- }
-
- public static function insert($title, $moduleIds)
- {
- if (!is_array($moduleIds))
- return false;
- $instance = new ConfigTgz;
- $instance->configTitle = $title;
- // Create output file name (config.tgz)
- do {
- $instance->file = CONFIG_TGZ_LIST_DIR . '/config-' . Util::sanitizeFilename($instance->configTitle) . '-' . mt_rand() . '-' . time() . '.tgz';
- } while (file_exists($instance->file));
- Database::exec("INSERT INTO configtgz (title, filepath, status) VALUES (:title, :filepath, :status)", array(
- 'title' => $instance->configTitle,
- 'filepath' => $instance->file,
- 'status' => 'MISSING'
- ));
- $instance->configId = Database::lastInsertId();
- $instance->modules = array();
- // Get all modules to put in config
- $idstr = '0'; // Passed directly in query. Make sure no SQL injection is possible
- foreach ($moduleIds as $module) {
- $idstr .= ',' . (int)$module; // Casting to int should make it safe
- }
- $res = Database::simpleQuery("SELECT moduleid, filepath, status FROM configtgz_module WHERE moduleid IN ($idstr)");
- // Make connection
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- Database::exec("INSERT INTO configtgz_x_module (configid, moduleid) VALUES (:configid, :moduleid)", array(
- 'configid' => $instance->configId,
- 'moduleid' => $row['moduleid']
- ));
- $instance->modules[] = $row;
- }
- return $instance;
- }
-
- public static function get($configId)
- {
- $ret = Database::queryFirst("SELECT configid, title, filepath FROM configtgz WHERE configid = :configid", array(
- 'configid' => $configId
- ));
- if ($ret === false)
- return false;
- $instance = new ConfigTgz;
- $instance->configId = $ret['configid'];
- $instance->configTitle = $ret['title'];
- $instance->file = $ret['filepath'];
- $ret = Database::simpleQuery("SELECT moduleid, filepath, status FROM configtgz_x_module "
- . " INNER JOIN configtgz_module USING (moduleid) "
- . " WHERE configid = :configid", array('configid' => $instance->configId));
- $instance->modules = array();
- while ($row = $ret->fetch(PDO::FETCH_ASSOC)) {
- $instance->modules[] = $row;
- }
- return $instance;
- }
-
- public static function getAllForModule($moduleId)
- {
- $res = Database::simpleQuery("SELECT configid, title, filepath FROM configtgz_x_module "
- . " INNER JOIN configtgz USING (configid) "
- . " WHERE moduleid = :moduleid", array(
- 'moduleid' => $moduleId
- ));
- if ($res === false)
- return false;
- $list = array();
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $instance = new ConfigTgz;
- $instance->configId = $row['configid'];
- $instance->configTitle = $row['title'];
- $instance->file = $row['filepath'];
- $innerRes = Database::simpleQuery("SELECT moduleid, filepath, status FROM configtgz_x_module "
- . " INNER JOIN configtgz_module USING (moduleid) "
- . " WHERE configid = :configid", array('configid' => $instance->configId));
- $instance->modules = array();
- while ($innerRow = $innerRes->fetch(PDO::FETCH_ASSOC)) {
- $instance->modules[] = $innerRow;
- }
- $list[] = $instance;
- }
- return $list;
- }
-
- /**
- * Called when (re)generating a config tgz failed, so we can
- * update the status in the DB and add a server log entry.
- *
- * @param array $task
- * @param array $args contains 'configid' and optionally 'deleteOnError'
- */
- public static function generateFailed($task, $args)
- {
- if (!isset($args['configid']) || !is_numeric($args['configid'])) {
- EventLog::warning('Ignoring generateFailed event as it has no configid assigned.');
- return;
- }
- $config = self::get($args['configid']);
- if ($config === false) {
- EventLog::warning('generateFailed callback for config id ' . $args['configid'] . ', but no instance could be generated.');
- return;
- }
- if (isset($task['data']['error']))
- $error = $task['data']['error'];
- elseif (isset($task['data']['messages']))
- $error = $task['data']['messages'];
- else
- $error = '';
- EventLog::failure("Generating config.tgz '" . $config->configTitle . "' failed.", $error);
- if ($args['deleteOnError'])
- $config->delete();
- else
- $config->markFailed();
- }
-
- /**
- * (Re)generating a config tgz succeeded. Update db entry.
- *
- * @param array $args contains 'configid' and optionally 'deleteOnError'
- */
- public static function generateSucceeded($args)
- {
- if (!isset($args['configid']) || !is_numeric($args['configid'])) {
- EventLog::warning('Ignoring generateSucceeded event as it has no configid assigned.');
- return;
- }
- $config = self::get($args['configid']);
- if ($config === false) {
- EventLog::warning('generateSucceeded callback for config id ' . $args['configid'] . ', but no instance could be generated.');
- return;
- }
- $config->markUpdated();
- }
-
- /**
- *
- * @param type $deleteOnError
- * @param type $timeoutMs
- * @return string - OK (success)
- * - OUTDATED (updating failed, but old version still exists)
- * - MISSING (failed and no old version available)
- */
- public function generate($deleteOnError = false, $timeoutMs = 0)
- {
- if (!($this->configId > 0) || !is_array($this->modules) || $this->file === false)
- Util::traceError ('configId <= 0 or modules not array in ConfigTgz::rebuild()');
- $files = array();
- foreach ($this->modules as $module) {
- if (!empty($module['filepath']) && file_exists($module['filepath']))
- $files[] = $module['filepath'];
- }
- // Hand over to tm
- $task = Taskmanager::submit('RecompressArchive', array(
- 'inputFiles' => $files,
- 'outputFile' => $this->file
- ));
- // Wait for completion
- if ($timeoutMs > 0 && !Taskmanager::isFailed($task) && !Taskmanager::isFinished($task))
- $task = Taskmanager::waitComplete($task, $timeoutMs);
- if ($task === true || (isset($task['statusCode']) && $task['statusCode'] === TASK_FINISHED)) {
- // Success!
- $this->markUpdated();
- return true;
- }
- if (!is_array($task) || !isset($task['id']) || Taskmanager::isFailed($task)) {
- // Failed...
- Taskmanager::addErrorMessage($task);
- if (!$deleteOnError)
- $this->markFailed();
- else
- $this->delete();
- return false;
- }
- // Still running, add callback
- TaskmanagerCallback::addCallback($task, 'cbConfTgzCreated', array(
- 'configid' => $this->configId,
- 'deleteOnError' => $deleteOnError
- ));
- return $task['id'];
- }
-
- public function delete()
- {
- if ($this->configId === 0)
- Util::traceError('ConfigTgz::delete called with invalid config id!');
- $ret = Database::exec("DELETE FROM configtgz WHERE configid = :configid LIMIT 1", array(
- 'configid' => $this->configId
- ), true) !== false;
- if ($ret !== false) {
- if ($this->file !== false)
- Taskmanager::submit('DeleteFile', array('file' => $this->file), true);
- $this->configId = 0;
- $this->modules = false;
- $this->file = false;
- }
- return $ret;
- }
-
- public function markOutdated()
- {
- if ($this->configId === 0)
- Util::traceError('ConfigTgz::markOutdated called with invalid config id!');
- return $this->mark('OUTDATED');
- }
-
- private function markUpdated()
- {
- if ($this->configId === 0)
- Util::traceError('ConfigTgz::markUpdated called with invalid config id!');
- Event::activeConfigChanged();
- if ($this->areAllModulesUpToDate())
- return $this->mark('OK');
- return $this->mark('OUTDATED');
- }
-
- private function markFailed()
- {
- if ($this->configId === 0)
- Util::traceError('ConfigTgz::markFailed called with invalid config id!');
- if ($this->file === false || !file_exists($this->file))
- return $this->mark('MISSING');
- return $this->mark('OUTDATED');
- }
-
- private function mark($status)
- {
- Database::exec("UPDATE configtgz SET status = :status WHERE configid = :configid LIMIT 1", array(
- 'configid' => $this->configId,
- 'status' => $status
- ));
- return $status;
- }
-
-}
diff --git a/inc/database.inc.php b/inc/database.inc.php
index 735b2181..c3901453 100644
--- a/inc/database.inc.php
+++ b/inc/database.inc.php
@@ -113,6 +113,7 @@ class Database
return false;
Util::traceError("Database Error: \n" . $e->getMessage());
}
+ return false;
}
/**
diff --git a/inc/message.inc.php b/inc/message.inc.php
index d6a62f4e..15e89041 100644
--- a/inc/message.inc.php
+++ b/inc/message.inc.php
@@ -55,6 +55,7 @@ class Message
*/
public static function renderList()
{
+ self::$flushed = true;
if (empty(self::$list))
return;
// Ajax
@@ -75,11 +76,10 @@ class Message
foreach ($item['params'] as $index => $text) {
$message = str_replace('{{' . $index . '}}', '<b>' . htmlspecialchars($text) . '</b>', $message);
}
- Render::addTemplate('messagebox-' . $item['type'], array('message' => $message),'main');
+ Render::addTemplate('messagebox-' . $item['type'], array('message' => $message), 'main');
self::$alreadyDisplayed[] = $item;
}
self::$list = array();
- self::$flushed = true;
}
/**
diff --git a/inc/module.inc.php b/inc/module.inc.php
index 261c2990..894bc0f6 100644
--- a/inc/module.inc.php
+++ b/inc/module.inc.php
@@ -178,4 +178,9 @@ class Module
return Dictionary::getCategoryName($this->category);
}
+ public function getDir()
+ {
+ return 'modules/' . $this->name;
+ }
+
}
diff --git a/inc/property.inc.php b/inc/property.inc.php
index 0cb57f81..13e3c66d 100644
--- a/inc/property.inc.php
+++ b/inc/property.inc.php
@@ -66,6 +66,7 @@ class Property
EventLog::info('Server IP changed from ' . self::getServerIp() . ' to ' . $value . ($automatic ? ' (auto detected)' : ''));
self::set('server-ip', $value);
Event::serverIpChanged();
+ return true;
}
public static function getBootMenu()
diff --git a/inc/render.inc.php b/inc/render.inc.php
index e3a23f23..5fc5be92 100644
--- a/inc/render.inc.php
+++ b/inc/render.inc.php
@@ -18,7 +18,7 @@ class Render
private static $mustache = false;
private static $body = '';
private static $header = '';
- private static $dashboard = '';
+ private static $dashboard = false;
private static $footer = '';
private static $title = '';
private static $templateCache = array();
@@ -28,7 +28,16 @@ class Render
{
if (self::$mustache !== false)
Util::traceError('Called Render::init() twice!');
- self::$mustache = new Mustache_Engine;
+ $options = array();
+ $tmp = '/tmp/bwlp-cache';
+ $dir = is_dir($tmp);
+ if (!$dir) {
+ @mkdir($tmp, 0755, false);
+ }
+ if (($dir || is_dir($tmp)) && is_writable($tmp)) {
+ $options['cache'] = $tmp;
+ }
+ self::$mustache = new Mustache_Engine($options);
}
/**
@@ -40,7 +49,6 @@ class Render
$zip = isset($_SERVER['HTTP_ACCEPT_ENCODING']) && (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false);
if ($zip)
ob_start();
- $page = strtolower($_GET['do']);
echo
'<!DOCTYPE html>
<html>
@@ -63,7 +71,7 @@ class Render
' </head>
<body>
',
- self::$dashboard,
+ (self::$dashboard !== false ? self::parse('main-menu', self::$dashboard, 'main') : ''),
'<div class="main" id="mainpage"><div class="container-fluid">
',
self::$body
@@ -168,18 +176,20 @@ class Render
/**
* Parse template with given params and return; do not add to body
* @param string $template name of template, relative to templates/, without .html extension
+ * @param array $params tags to render into template
+ * @param string $module name of module to load template from; defaults to currently active module
* @return string Rendered template
*/
public static function parse($template, $params = false, $module = false)
{
+ if ($module === false) {
+ $module = Page::getModule()->getIdentifier();
+ }
// Load html snippet
- $html = self::getTemplate($template,$module);
+ $html = self::getTemplate($template, $module);
if ($html === false) {
return '<h3>Template ' . htmlspecialchars($template) . '</h3>' . nl2br(htmlspecialchars(print_r($params, true))) . '<hr>';
}
- if($module === false) {
- $module = Page::getModule()->getIdentifier();
- }
if (!is_array($params)) {
$params = array();
}
@@ -201,8 +211,10 @@ class Render
}
// Always add token to parameter list
$params['token'] = Session::get('token');
- // Likewise, add currently selected language (its two letter code) to params
- $params['current_lang'] = LANG;
+ if (defined('LANG')) {
+ // Likewise, add currently selected language (its two letter code) to params
+ $params['current_lang'] = LANG;
+ }
// Add desired password field type
$params['password_type'] = Property::getPasswordFieldType();
// Return rendered html
@@ -242,20 +254,18 @@ class Render
/**
* Private helper: Load the given template and return it
*/
- private static function getTemplate($template, $module = false)
+ private static function getTemplate($template, $module)
{
- if (isset(self::$templateCache[$template])) {
- return self::$templateCache[$template];
- }
- // Select current module
- if(!$module){
- $module = strtolower(empty($_REQUEST['do']) ? 'Main' : $_REQUEST['do']);
+ $id = "$template/$module";
+ if (isset(self::$templateCache[$id])) {
+ return self::$templateCache[$id];
}
// Load from disk
$data = @file_get_contents('modules/' . $module . '/templates/' . $template . '.html');
- if ($data === false)
- $data = '<b>Non-existent template ' . $template . ' requested!</b>';
- self::$templateCache[$template] = & $data;
+ if ($data === false) {
+ $data = '<b>Non-existent/unreadable template ' . $template . ' requested!</b>';
+ }
+ self::$templateCache[$id] =& $data;
return $data;
}
@@ -264,7 +274,7 @@ class Render
*/
public static function setDashboard($params)
{
- self::$dashboard = self::parse('main-menu', $params, 'main');
+ self::$dashboard = $params;
}
}
diff --git a/inc/request.inc.php b/inc/request.inc.php
index 604a2b0e..f46210af 100644
--- a/inc/request.inc.php
+++ b/inc/request.inc.php
@@ -5,11 +5,12 @@
*/
class Request
{
-
+
/**
- *
+ *
* @param string $key Key of field to get from $_GET
* @param string $default Value to return if $_GET does not contain $key
+ * @param string $type if the parameter exists, cast it to given type
* @return mixed Field from $_GET, or $default if not set
*/
public static function get($key, $default = false, $type = false)
diff --git a/inc/session.inc.php b/inc/session.inc.php
index a0f8ab4c..b4299e06 100644
--- a/inc/session.inc.php
+++ b/inc/session.inc.php
@@ -41,6 +41,7 @@ class Session
if (self::readSessionData()) return true;
// Loading session data failed
self::delete();
+ return false;
}
public static function get($key)
diff --git a/inc/taskmanagercallback.inc.php b/inc/taskmanagercallback.inc.php
index cec763fb..7d4e79f3 100644
--- a/inc/taskmanagercallback.inc.php
+++ b/inc/taskmanagercallback.inc.php
@@ -124,6 +124,10 @@ class TaskmanagerCallback
*/
public static function cbConfModCreated($task, $args)
{
+ $mod = Module::get('sysconfig');
+ if ($mod === false)
+ return;
+ $mod->activate();
if (Taskmanager::isFailed($task)) {
ConfigModule::generateFailed($task, $args);
} else {
@@ -139,6 +143,10 @@ class TaskmanagerCallback
*/
public static function cbConfTgzCreated($task, $args)
{
+ $mod = Module::get('sysconfig');
+ if ($mod === false)
+ return;
+ $mod->activate();
if (Taskmanager::isFailed($task)) {
ConfigTgz::generateFailed($task, $args);
} else {
diff --git a/inc/up_json_encode.php b/inc/up_json_encode.php
index c33cb012..0f5776c2 100644
--- a/inc/up_json_encode.php
+++ b/inc/up_json_encode.php
@@ -164,7 +164,7 @@ function up_json_encode($var, $options = 0, $_indent = "")
} elseif (is_float($var)) {
if (is_nan($var) || is_infinite($var)) {
${'.json_last_error'} = JSON_ERROR_INF_OR_NAN;
- return;
+ return false;
} else {
$json = "$var";
}
@@ -174,7 +174,7 @@ function up_json_encode($var, $options = 0, $_indent = "")
else {
trigger_error("up_json_encode: don't know what a '" . gettype($var) . "' is.", E_USER_WARNING);
${'.json_last_error'} = JSON_ERROR_UNSUPPORTED_TYPE;
- return;
+ return false;
}
#-- done
diff --git a/inc/validator.inc.php b/inc/validator.inc.php
index 6eac80f9..23debd2c 100644
--- a/inc/validator.inc.php
+++ b/inc/validator.inc.php
@@ -32,6 +32,7 @@ class Validator
default:
Util::traceError('Unknown validation method: ' . $data[0]);
}
+ return false; // make code inspector happy - doesn't know traceError doesn't return
}
/**