summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2014-10-09 16:01:11 +0200
committerSimon Rettberg2014-10-09 16:01:11 +0200
commite1dc0d3c99217504de2ac8467156274786efc0bd (patch)
tree130d7fed1fff8aaaffe5942cf2a3d6bb1dad03c8
parentMinor fixes and improvements (diff)
downloadslx-admin-e1dc0d3c99217504de2ac8467156274786efc0bd.tar.gz
slx-admin-e1dc0d3c99217504de2ac8467156274786efc0bd.tar.xz
slx-admin-e1dc0d3c99217504de2ac8467156274786efc0bd.zip
Big load of changes
- Added callback functionality for taskmanager tasks. You can launch a task and define a callback function to be run when the task finished. This requires activating the cronjob - Added cron functionality: Add cronjob that calls the cron api every 5 minutes to use it. (See cron.inc.php) - Added eventlog - Added missing translations - Merged main-menu-login and main-menu-logout
-rw-r--r--apis/cron.inc.php28
-rw-r--r--apis/init.inc.php61
-rw-r--r--apis/update.inc.php137
-rw-r--r--inc/configmodule.inc.php24
-rw-r--r--inc/database.inc.php2
-rw-r--r--inc/defaultdata.inc.php21
-rw-r--r--inc/event.inc.php96
-rw-r--r--inc/eventlog.inc.php23
-rw-r--r--inc/permission.inc.php7
-rw-r--r--inc/property.inc.php27
-rw-r--r--inc/taskmanager.inc.php23
-rw-r--r--inc/taskmanagercallback.inc.php43
-rw-r--r--inc/trigger.inc.php93
-rw-r--r--inc/user.inc.php41
-rw-r--r--inc/validator.inc.php50
-rw-r--r--index.php22
-rw-r--r--install/content.sql2
-rw-r--r--install/schema.sql (renamed from DB_SCRIBBLE)74
-rw-r--r--lang/de/messages.json3
-rw-r--r--lang/de/settings/cat_setting.json3
-rw-r--r--lang/de/settings/setting.json20
-rw-r--r--lang/de/templates/main-menu-login.json14
-rw-r--r--lang/de/templates/main-menu.json (renamed from lang/de/templates/main-menu-logout.json)4
-rw-r--r--lang/de/templates/translation/edit.json2
-rw-r--r--lang/de/templates/translation/template-list.json5
-rw-r--r--lang/en/messages.json5
-rw-r--r--lang/en/settings/cat_setting.json3
-rw-r--r--lang/en/settings/setting.json20
-rw-r--r--lang/en/templates/main-menu-login.json14
-rw-r--r--lang/en/templates/main-menu.json (renamed from lang/en/templates/main-menu-logout.json)4
-rw-r--r--lang/en/templates/sysconfig/_page.json2
-rw-r--r--lang/en/templates/translation/edit.json2
-rw-r--r--lang/en/templates/translation/template-list.json5
-rw-r--r--lang/lang.sql95
-rw-r--r--lang/pt/settings/setting.json18
-rw-r--r--lang/pt/templates/main-menu-logout.json14
-rw-r--r--lang/pt/templates/main-menu.json (renamed from lang/pt/templates/main-menu-login.json)1
-rw-r--r--lang/pt/templates/sysconfig/_page.json1
-rw-r--r--lang/pt/templates/translation/edit.json1
-rw-r--r--lang/pt/templates/translation/template-list.json3
-rw-r--r--modules/eventlog.inc.php55
-rw-r--r--modules/sysconfig.inc.php2
-rw-r--r--modules/syslog.inc.php5
-rw-r--r--modules/translation.inc.php34
-rw-r--r--style/bg.pngbin0 -> 31176 bytes
-rw-r--r--style/default.css10
-rw-r--r--templates/eventlog/_page.html43
-rw-r--r--templates/main-menu-login.html50
-rw-r--r--templates/main-menu.html (renamed from templates/main-menu-logout.html)10
-rw-r--r--templates/page-syslog.html30
50 files changed, 711 insertions, 541 deletions
diff --git a/apis/cron.inc.php b/apis/cron.inc.php
new file mode 100644
index 00000000..2d0fc66c
--- /dev/null
+++ b/apis/cron.inc.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * cronjob callback. This script does periodic checks, logging,
+ * housekeeping etc. Should be called every 5 mins by cron.
+ * Make a crontab entry that runs this as the same user the
+ * www-php is normally run as, eg. */
+// */5 * * * * www-data php /path/to/api.php cron
+
+if (!isLocalExecution())
+ exit(0);
+
+switch (mt_rand(1, 10)) {
+case 1:
+ Database::exec("DELETE FROM clientlog WHERE (UNIX_TIMESTAMP() - dateline) > 86400 * 90");
+ break;
+case 2:
+ Database::exec("DELETE FROM eventlog WHERE (UNIX_TIMESTAMP() - dateline) > 86400 * 90");
+ break;
+case 3:
+ Database::exec("DELETE FROM property WHERE dateline <> 0 AND dateline < UNIX_TIMESTAMP()");
+ break;
+case 4:
+ Database::exec("DELETE FROM callback WHERE (UNIX_TIMESTAMP() - dateline) > 86400");
+ break;
+}
+
+Trigger::checkCallbacks();
diff --git a/apis/init.inc.php b/apis/init.inc.php
index a1344fc4..617114d7 100644
--- a/apis/init.inc.php
+++ b/apis/init.inc.php
@@ -1,62 +1,9 @@
<?php
+// via cron:
+// @reboot www-data php /path/to/api.php init
+
if (!isLocalExecution())
exit(0);
-EventLog::info('System boot...');
-$everythingFine = true;
-
-DefaultData::populate();
-
-// Tasks: fire away
-$mountId = Trigger::mount();
-$ldadpId = Trigger::ldadp();
-$autoIp = Trigger::autoUpdateServerIp();
-$ipxeId = Trigger::ipxe();
-
-// Check status of all tasks
-// Mount vm store
-if ($mountId === false) {
- EventLog::info('No VM store type defined.');
- $everythingFine = false;
-} else {
- $res = Taskmanager::waitComplete($mountId, 5000);
- if (Taskmanager::isFailed($res)) {
- EventLog::failure('Mounting VM store failed: ' . $res['data']['messages']);
- $everythingFine = false;
- }
-}
-// LDAP AD Proxy
-if ($ldadpId === false) {
- EventLog::failure('Cannot start LDAP-AD-Proxy: Taskmanager unreachable!');
- $everythingFine = false;
-} else {
- $res = Taskmanager::waitComplete($ldadpId, 5000);
- if (Taskmanager::isFailed($res)) {
- EventLog::failure('Starting LDAP-AD-Proxy failed: ' . $res['data']['messages']);
- $everythingFine = false;
- }
-}
-// Primary IP address
-if (!$autoIp) {
- EventLog::failure("The server's IP address could not be determined automatically, and there is no active address configured.");
- $everythingFine = false;
-}
-// iPXE generation
-if ($ipxeId === false) {
- EventLog::failure('Cannot generate PXE menu: Taskmanager unreachable!');
- $everythingFine = false;
-} else {
- $res = Taskmanager::waitComplete($ipxeId, 5000);
- if (Taskmanager::isFailed($res)) {
- EventLog::failure('Update PXE Menu failed: ' . $res['data']['error']);
- $everythingFine = false;
- }
-}
-
-// Just so we know booting is done (and we don't expect any more errors from booting up)
-if ($everythingFine) {
- EventLog::info('Bootup finished without errors.');
-} else {
- EventLog::info('There were errors during bootup. Maybe the server is not fully configured yet.');
-}
+Event::systemBooted();
diff --git a/apis/update.inc.php b/apis/update.inc.php
index 4fb4b3fb..384fe0be 100644
--- a/apis/update.inc.php
+++ b/apis/update.inc.php
@@ -39,8 +39,48 @@ while ($currentVersion < $targetVersion) {
}
Message::addSuccess('db-update-done');
+Eventlog::info("Database updated to version $currentVersion");
Util::redirect('index.php?do=Main');
+////////////////
+
+function tableHasColumn($table, $column)
+{
+ $table = preg_replace('/\W/', '', $table);
+ $column = preg_replace('/\W/', '', $column);
+ $res = Database::simpleQuery("DESCRIBE `$table`", array(), false);
+ if ($res !== false) {
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ if ((is_array($column) && in_array($row['Field'], $column)) || (is_string($column) && $row['Field'] === $column))
+ return true;
+ }
+ }
+ return false;
+}
+
+function tableDropColumn($table, $column)
+{
+ $table = preg_replace('/\W/', '', $table);
+ $column = preg_replace('/\W/', '', $column);
+ $res = Database::simpleQuery("DESCRIBE `$table`", array(), false);
+ if ($res !== false) {
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ if ((is_array($column) && in_array($row['Field'], $column)) || (is_string($column) && $row['Field'] === $column))
+ Database::exec("ALTER TABLE `$table` DROP `{$row['Field']}`");
+ }
+ }
+}
+
+function tableExists($table)
+{
+ $res = Database::simpleQuery("SHOW TABLES", array(), false);
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ if ($row['Tables_in_openslx'] === $table)
+ return true;
+ }
+ return false;
+}
+
// The update functions. Number at the end refers to current version, the function will update to the next version
// #######################
// ##### 2014-05-28
@@ -48,17 +88,7 @@ Util::redirect('index.php?do=Main');
function update_1()
{
- $res = Database::simpleQuery("DESCRIBE property", array(), false);
- $type = false;
- if ($res === false)
- return;
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- if ($row['Field'] !== 'dateline')
- continue;
- $type = $row['Type'];
- break;
- }
- if ($type === false) {
+ if (!tableHasColumn('property', 'dateline')) {
Database::exec("ALTER TABLE `property` ADD `dateline` INT( 10 ) UNSIGNED NOT NULL DEFAULT '0' AFTER `name` , ADD INDEX ( `dateline` )");
} else {
Database::exec("ALTER TABLE `property` CHANGE `dateline` `dateline` INT( 10 ) UNSIGNED NOT NULL DEFAULT '0'");
@@ -71,17 +101,9 @@ function update_1()
// Add 'news' table to database schema
function update_2()
{
- $res = Database::simpleQuery("show tables", array(), false);
- $found = false;
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- if ($row['Tables_in_openslx'] !== 'news')
- continue;
- $found = true;
- break;
- }
- if ($found === false) {
+ if (!tableExists('news')) {
// create table
- Database::exec("CREATE TABLE `news` (
+ Database::exec("CREATE TABLE IF NOT EXISTS `news` (
`newsid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`dateline` int(10) unsigned NOT NULL,
`title` varchar(200) DEFAULT NULL,
@@ -99,32 +121,8 @@ function update_2()
// Remove setting descriptions from DB, put into json files now
function update_3()
{
- $res = Database::simpleQuery("DESCRIBE setting", array(), false);
- if ($res !== false) {
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- switch ($row['Field']) {
- case 'de':
- case 'en':
- case 'pt':
- case 'description':
- Database::exec("ALTER TABLE setting DROP {$row['Field']}");
- break;
- }
- }
- }
- $res = Database::simpleQuery("DESCRIBE cat_setting", array(), false);
- if ($res !== false) {
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- switch ($row['Field']) {
- case 'de':
- case 'en':
- case 'pt':
- case 'name':
- Database::exec("ALTER TABLE cat_setting DROP {$row['Field']}");
- break;
- }
- }
- }
+ tableDropColumn('setting', array('de', 'en', 'pt', 'description'));
+ tableDropColumn('cat_setting', array('de', 'en', 'pt', 'name'));
return true;
}
@@ -133,27 +131,10 @@ function update_3()
// Remove description column from permission table, add eventlog table
function update_4()
{
- $res = Database::simpleQuery("DESCRIBE permission", array(), false);
- if ($res !== false) {
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- switch ($row['Field']) {
- case 'description':
- Database::exec("ALTER TABLE permission DROP {$row['Field']}");
- break;
- }
- }
- }
- $res = Database::simpleQuery("show tables", array(), false);
- $found = false;
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- if ($row['Tables_in_openslx'] !== 'eventlog')
- continue;
- $found = true;
- break;
- }
- if ($found === false) {
+ tableDropColumn('permission', 'description');
+ if (!tableExists('eventlog')) {
// create table
- Database::exec("CREATE TABLE `eventlog` (
+ Database::exec("CREATE TABLE IF NOT EXISTS `eventlog` (
`logid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`dateline` int(10) unsigned NOT NULL,
`logtypeid` varchar(30) NOT NULL,
@@ -166,3 +147,25 @@ function update_4()
}
return true;
}
+
+// #######################
+// ##### 2014-08-18
+// Add details column to eventlog table, add callback table
+function update_5()
+{
+ if (!tableHasColumn('eventlog', 'extra'))
+ Database::exec("ALTER TABLE `eventlog` ADD `extra` TEXT NOT NULL");
+ if (!tableHasColumn('user', 'lasteventid'))
+ Database::exec("ALTER TABLE `user` ADD `lasteventid` INT( 10 ) UNSIGNED NOT NULL DEFAULT '0'");
+ if (!tableExists('callback')) {
+ Database::exec("CREATE TABLE IF NOT EXISTS `callback` (
+ `taskid` varchar(40) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
+ `dateline` int(10) unsigned NOT NULL,
+ `cbfunction` varchar(16) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
+ PRIMARY KEY (`taskid`,`cbfunction`),
+ KEY `dateline` (`dateline`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8
+ ");
+ }
+ return true;
+}
diff --git a/inc/configmodule.inc.php b/inc/configmodule.inc.php
index c0838b5c..1788a53a 100644
--- a/inc/configmodule.inc.php
+++ b/inc/configmodule.inc.php
@@ -5,13 +5,13 @@ class ConfigModule
public static function insertAdConfig($title, $server, $searchbase, $binddn, $bindpw, $home)
{
- // TODO: Lock table, race condition if about 500 admins insert a config at the same time
+ Database::exec("LOCK TABLE configtgz_module WRITE");
Database::exec("INSERT INTO configtgz_module (title, moduletype, filepath, contents) "
. " VALUES (:title, 'AD_AUTH', '', '')", array('title' => $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");
+ $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) {
@@ -42,12 +42,32 @@ class ConfigModule
'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) "
diff --git a/inc/database.inc.php b/inc/database.inc.php
index 0d48c23c..72b7d0d7 100644
--- a/inc/database.inc.php
+++ b/inc/database.inc.php
@@ -16,7 +16,7 @@ class Database
*/
public static function getExpectedSchemaVersion()
{
- return 5;
+ return 6;
}
public static function needSchemaUpdate()
diff --git a/inc/defaultdata.inc.php b/inc/defaultdata.inc.php
index 12a304f6..abc857bb 100644
--- a/inc/defaultdata.inc.php
+++ b/inc/defaultdata.inc.php
@@ -25,6 +25,7 @@ class DefaultData
2 => 20, // Internet access
3 => 100, // Timesync
4 => 10, // System config
+ 5 => 15, // Public Shared folder
);
foreach ($cats as $cat => $sort) {
Database::exec("INSERT IGNORE INTO cat_setting (catid, sortval) VALUES (:catid, :sortval)", array(
@@ -94,7 +95,7 @@ class DefaultData
'catid' => '2',
'defaultvalue' => 'off',
'permissions' => '2',
- 'validator' => 'list:off|on|auto|wpad'
+ 'validator' => 'list:off|on|auto'
),
array(
'setting' => 'SLX_PROXY_PORT',
@@ -137,11 +138,25 @@ class DefaultData
'defaultvalue' => '1200',
'permissions' => '2',
'validator' => 'regex:/^\d*$/'
- )
+ ),
+ array(
+ 'setting' => 'SLX_COMMON_SHARE_PATH',
+ 'catid' => '5',
+ 'defaultvalue' => '',
+ 'permissions' => '2',
+ 'validator' => 'function:networkShare'
+ ),
+ array(
+ 'setting' => 'SLX_COMMON_SHARE_AUTH',
+ 'catid' => '5',
+ 'defaultvalue' => 'guest',
+ 'permissions' => '2',
+ 'validator' => 'list:guest|user'
+ ),
);
foreach ($data as $entry) {
Database::exec("INSERT IGNORE INTO setting (setting, catid, defaultvalue, permissions, validator)"
- . "VALUES (:setting, :catid, :defaultvalue, :permissions, :validator)");
+ . "VALUES (:setting, :catid, :defaultvalue, :permissions, :validator)", $entry);
}
}
diff --git a/inc/event.inc.php b/inc/event.inc.php
new file mode 100644
index 00000000..6689e12f
--- /dev/null
+++ b/inc/event.inc.php
@@ -0,0 +1,96 @@
+<?php
+
+/**
+ * Class with static functions that are called when a specific event
+ * took place, like the server has been booted, or the interface address
+ * has been changed.
+ * In contrast to the trigger class, this class should contain functions
+ * for things that happen semi-automatically in reaction to something else
+ * (which in turn might have been triggered explicitly).
+ */
+class Event
+{
+
+ /**
+ * Called when the system (re)booted. Could be implemented
+ * by a @reboot entry in crontab (running as the same user php does)
+ */
+ public static function systemBooted()
+ {
+ EventLog::info('System boot...');
+ $everythingFine = true;
+
+ DefaultData::populate();
+
+ // Tasks: fire away
+ $mountId = Trigger::mount();
+ $autoIp = Trigger::autoUpdateServerIp();
+ $ldadpId = Trigger::ldadp();
+ $ipxeId = Trigger::ipxe();
+
+ // Check status of all tasks
+ // Mount vm store
+ if ($mountId === false) {
+ EventLog::info('No VM store type defined.');
+ $everythingFine = false;
+ } else {
+ $res = Taskmanager::waitComplete($mountId, 5000);
+ if (Taskmanager::isFailed($res)) {
+ EventLog::failure('Mounting VM store failed', $res['data']['messages']);
+ $everythingFine = false;
+ }
+ }
+ // LDAP AD Proxy
+ if ($ldadpId === false) {
+ EventLog::failure('Cannot start LDAP-AD-Proxy: Taskmanager unreachable!');
+ $everythingFine = false;
+ } else {
+ $res = Taskmanager::waitComplete($ldadpId, 5000);
+ if (Taskmanager::isFailed($res)) {
+ EventLog::failure('Starting LDAP-AD-Proxy failed', $res['data']['messages']);
+ $everythingFine = false;
+ }
+ }
+ // Primary IP address
+ if (!$autoIp) {
+ EventLog::failure("The server's IP address could not be determined automatically, and there is no valid address configured.");
+ $everythingFine = false;
+ }
+ // iPXE generation
+ if ($ipxeId === false) {
+ EventLog::failure('Cannot generate PXE menu: Taskmanager unreachable!');
+ $everythingFine = false;
+ } else {
+ $res = Taskmanager::waitComplete($ipxeId, 5000);
+ if (Taskmanager::isFailed($res)) {
+ EventLog::failure('Update PXE Menu failed', $res['data']['error']);
+ $everythingFine = false;
+ }
+ }
+
+ // Just so we know booting is done (and we don't expect any more errors from booting up)
+ if ($everythingFine) {
+ EventLog::info('Bootup finished without errors.');
+ } else {
+ EventLog::info('There were errors during bootup. Maybe the server is not fully configured yet.');
+ }
+ }
+
+ /**
+ * Server's primary IP address changed.
+ */
+ public static function serverIpChanged()
+ {
+ Trigger::rebuildAdModules();
+ }
+
+ /**
+ * The activated configuration changed.
+ */
+ public static function activeConfigChanged()
+ {
+ $task = Trigger::ldadp();
+ TaskmanagerCallback::addCallback($task, 'ldadpStartup');
+ }
+
+}
diff --git a/inc/eventlog.inc.php b/inc/eventlog.inc.php
index dadccdd7..181f8d38 100644
--- a/inc/eventlog.inc.php
+++ b/inc/eventlog.inc.php
@@ -3,28 +3,31 @@
class EventLog
{
- private static function log($type, $message)
+ private static function log($type, $message, $details)
{
- Database::exec("INSERT INTO eventlog (dateline, logtypeid, description)"
- . " VALUES (UNIX_TIMESTAMP(), :type, :message)", array(
+ Database::exec("INSERT INTO eventlog (dateline, logtypeid, description, extra)"
+ . " VALUES (UNIX_TIMESTAMP(), :type, :message, :details)", array(
'type' => $type,
- 'message' => $message
+ 'message' => $message,
+ 'details' => $details
));
}
- public static function failure($message)
+ public static function failure($message, $details = '')
{
- self::log('failure', $message);
+ self::log('failure', $message, $details);
}
- public static function warning($message)
+ public static function warning($message, $details = '')
{
- self::log('warning', $message);
+ self::log('warning', $message, $details);
+ Property::setLastWarningId(Database::lastInsertId());
}
- public static function info($message)
+ public static function info($message, $details = '')
{
- self::log('info', $message);
+ self::log('info', $message, $details);
+ Property::setLastWarningId(Database::lastInsertId());
}
}
diff --git a/inc/permission.inc.php b/inc/permission.inc.php
index f90319a4..d04e3c3b 100644
--- a/inc/permission.inc.php
+++ b/inc/permission.inc.php
@@ -3,9 +3,10 @@
class Permission
{
private static $permissions = array(
- 'superadmin' => 1,
- 'baseconfig_global' => 2,
- 'baseconfig_local' => 4,
+ 'superadmin' => 1, // Can do everything
+ 'baseconfig_global' => 2, // Change configuration globally
+ 'baseconfig_local' => 4, // Change configuration for specifig groups/rooms
+ 'translation' => 8, // Can edit translations
);
public static function get($permission)
diff --git a/inc/property.inc.php b/inc/property.inc.php
index 605d901d..e4b4340b 100644
--- a/inc/property.inc.php
+++ b/inc/property.inc.php
@@ -19,11 +19,11 @@ class Property
private static function get($key, $default = false)
{
if (self::$cache === false) {
- if (mt_rand(1, 20) === 10) {
- Database::exec("DELETE FROM property WHERE dateline <> 0 AND dateline < UNIX_TIMESTAMP()");
- }
- $res = Database::simpleQuery("SELECT name, value FROM property");
+ $NOW = time();
+ $res = Database::simpleQuery("SELECT name, dateline, value FROM property");
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ if ($row['dateline'] != 0 && $row['dateline'] < $NOW)
+ continue;
self::$cache[$row['name']] = $row['value'];
}
}
@@ -37,7 +37,7 @@ class Property
*
* @param string $key key of value to set
* @param type $value the value to store for $key
- * @param int minage how long to keep this entry around at least, in minutes. 0 for infinite
+ * @param int $minage how long to keep this entry around at least, in minutes. 0 for infinite
*/
private static function set($key, $value, $minage = 0)
{
@@ -59,6 +59,8 @@ class Property
public static function setServerIp($value)
{
+ if ($value !== self::getServerIp())
+ Event::serverIpChanged();
self::set('server-ip', $value);
}
@@ -113,6 +115,7 @@ class Property
{
return json_decode(self::get('vmstore-config'), true);
}
+
public static function getVmStoreUrl()
{
$store = self::getVmStoreConfig();
@@ -136,15 +139,25 @@ class Property
{
return self::get('dl-' . $name);
}
-
+
public static function setDownloadTask($name, $taskId)
{
self::set('dl-' . $name, $taskId, 5);
}
-
+
public static function getCurrentSchemaVersion()
{
return self::get('webif-version');
}
+ public static function setLastWarningId($id)
+ {
+ self::set('last-warn-event-id', $id);
+ }
+
+ public static function getLastWarningId()
+ {
+ return self::get('last-warn-event-id', 0);
+ }
+
}
diff --git a/inc/taskmanager.inc.php b/inc/taskmanager.inc.php
index 5813164a..528b3f78 100644
--- a/inc/taskmanager.inc.php
+++ b/inc/taskmanager.inc.php
@@ -28,7 +28,7 @@ class Taskmanager
* @param string $task name of task to start
* @param array $data data to pass to the task. the structure depends on the task.
* @param boolean $async if true, the function will not wait for the reply of the taskmanager, which means
- * the return value is just true (and you won't know if the task could acutally be started)
+ * the return value is just true (and you won't know if the task could acutally be started)
* @return array struct representing the task status, or result of submit, false on communication error
*/
public static function submit($task, $data = false, $async = false)
@@ -49,8 +49,7 @@ class Taskmanager
if ($async)
return true;
$reply = self::readReply($seq);
- if ($reply === false || !is_array($reply) || !isset($reply['id'])
- || (isset($reply['statusCode']) && $reply['statusCode'] === NO_SUCH_TASK)) {
+ if ($reply === false || !is_array($reply) || !isset($reply['id']) || (isset($reply['statusCode']) && $reply['statusCode'] === NO_SUCH_TASK)) {
self::addErrorMessage($reply);
return false;
}
@@ -117,7 +116,7 @@ class Taskmanager
/**
* Check whether the given task can be considered failed.
*
- * @param mixed $task task id or struct representing task
+ * @param array $task struct representing task, obtained by ::status
* @return boolean true if task failed, false if finished successfully or still waiting/running
*/
public static function isFailed($task)
@@ -129,6 +128,22 @@ class Taskmanager
return false;
}
+ /**
+ * Check whether the given task is finished, i.e. either failed or succeeded,
+ * but is not running, still waiting for execution or simply unknown.
+ *
+ * @param array $task struct representing task, obtained by ::status
+ * @return boolean true if task failed or finished, false if waiting for execution or currently executing, no valid task, etc.
+ */
+ public static function isFinished($task)
+ {
+ if (!is_array($task) || !isset($task['statusCode']) || !isset($task['id']))
+ return false;
+ if ($task['statusCode'] === TASK_ERROR || $task['statusCode'] === TASK_FINISHED)
+ return true;
+ return false;
+ }
+
public static function addErrorMessage($task)
{
static $failure = false;
diff --git a/inc/taskmanagercallback.inc.php b/inc/taskmanagercallback.inc.php
new file mode 100644
index 00000000..3ef4745c
--- /dev/null
+++ b/inc/taskmanagercallback.inc.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * Contains all callbacks for detached taskmanager tasks.
+ */
+class TaskmanagerCallback
+{
+
+ /**
+ * Add a callback for given task id. This is the only exception in this class,
+ * as this is not a callback, but a function to define one :)
+ *
+ * @param string|array $task Task or Task ID to define callback for
+ * @param string $callback name of callback function, must be a static method in this class
+ */
+ public static function addCallback($task, $callback)
+ {
+ if (!call_user_func_array('method_exists', array('TaskmanagerCallback', $callback))) {
+ EventLog::warning("addCallback: Invalid callback function: $callback");
+ return;
+ }
+ if (is_array($task) && isset($task['id']))
+ $task = $task['id'];
+ if (!is_string($task)) {
+ EventLog::warning("addCallback: Not a valid task id: $task");
+ return;
+ }
+ Database::exec("INSERT INTO callback (taskid, dateline, cbfunction) VALUES (:task, UNIX_TIMESTAMP(), :callback)", array(
+ 'task' => $task,
+ 'callback' => $callback
+ ));
+ }
+
+ /**
+ * Result of trying to (re)launch ldadp.
+ */
+ public static function ldadpStartup($task)
+ {
+ if (Taskmanager::isFailed($task))
+ EventLog::warning("Could not start/stop LDAP-AD-Proxy instances", $task['data']['messages']);
+ }
+
+}
diff --git a/inc/trigger.inc.php b/inc/trigger.inc.php
index 0b31c7b3..73ad6ce8 100644
--- a/inc/trigger.inc.php
+++ b/inc/trigger.inc.php
@@ -10,7 +10,7 @@
*/
class Trigger
{
-
+
/**
* Compile iPXE pxelinux menu. Needs to be done whenever the server's IP
* address changes.
@@ -26,7 +26,7 @@ class Trigger
return false;
return $task['id'];
}
-
+
/**
* Try to automatically determine the primary IP address of the server.
* This only works if the server has either one public IPv4 address (and potentially
@@ -84,53 +84,53 @@ class Trigger
public static function ldadp($parent = NULL)
{
$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'");
+ . " INNER JOIN configtgz_x_module USING (moduleid)"
+ . " INNER JOIN configtgz USING (configid)"
+ . " WHERE moduletype = 'AD_AUTH'");
// TODO: Multiconfig support
$id = array();
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
if (readlink('/srv/openslx/www/boot/default/config.tgz') === $row['filepath']) {
- $id[] = (int)$row['moduleid'];
+ $id[] = (int) $row['moduleid'];
break;
}
}
$task = Taskmanager::submit('LdadpLauncher', array(
- 'ids' => $id,
- 'parentTask' => $parent,
- 'failOnParentFail' => false
+ 'ids' => $id,
+ 'parentTask' => $parent,
+ 'failOnParentFail' => false
));
if (!isset($task['id']))
return false;
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()
{
- $res = Database::simpleQuery("SELECT moduleid, filepath, content FROM configtgz_module"
- . " WHERE moduletype = 'AD_AUTH'");
- if ($res->rowCount() === 0)
- return;
-
$task = Taskmanager::submit('LdadpLauncher', array('ids' => array())); // Stop all running instances
+ $ads = ConfigModule::getAdConfigs();
+ if (empty($ads))
+ return;
+
$parent = isset($task['id']) ? $task['id'] : NULL;
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $config = json_decode($row['contents']);
- $config['proxyip'] = Property::getServerIp();
- $config['moduleid'] = $row['moduleid'];
- $config['filename'] = $row['filepath'];
- $config['parentTask'] = $parent;
- $config['failOnParentFail'] = false;
- $task = Taskmanager::submit('CreateAdConfig', $config);
- $parent = isset($task['id']) ? $task['id'] : NULL;
+ foreach ($ads as $ad) {
+ $ad['parentTask'] = $parent;
+ $ad['failOnParentFail'] = false;
+ $task = Taskmanager::submit('CreateAdConfig', $ad);
+ if (isset($task['id']))
+ $parent = $task['id'];
+ }
+ if (Taskmanager::waitComplete($parent, 2000) === false) {
+ EventLog::warning('Rebuilding LDAP-AD-Proxy config failed. AD Auth might not work properly.');
+ sleep(1);
}
-
+ Trigger::ldadp();
}
-
+
/**
* Mount the VM store into the server.
*
@@ -139,17 +139,42 @@ class Trigger
public static function mount()
{
$vmstore = Property::getVmStoreConfig();
- if (!is_array($vmstore)) return false;
+ if (!is_array($vmstore))
+ return false;
$storetype = $vmstore['storetype'];
- if ($storetype === 'nfs') $addr = $vmstore['nfsaddr'];
- if ($storetype === 'cifs') $addr = $vmstore['cifsaddr'];
- if ($storetype === 'internal') $addr = 'null';
+ if ($storetype === 'nfs')
+ $addr = $vmstore['nfsaddr'];
+ if ($storetype === 'cifs')
+ $addr = $vmstore['cifsaddr'];
+ if ($storetype === 'internal')
+ $addr = 'null';
return Taskmanager::submit('MountVmStore', array(
- 'address' => $addr,
- 'type' => 'images',
- 'username' => $vmstore['cifsuser'],
- 'password' => $vmstore['cifspasswd']
+ 'address' => $addr,
+ 'type' => 'images',
+ 'username' => $vmstore['cifsuser'],
+ 'password' => $vmstore['cifspasswd']
));
}
+
+ /**
+ * Check and process all callbacks
+ */
+ public static function checkCallbacks()
+ {
+ $res = Database::simpleQuery("SELECT taskid, cbfunction FROM callback");
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ $status = Taskmanager::status($row['taskid']);
+ if (Taskmanager::isFailed($status) || Taskmanager::isFinished($status))
+ Database::exec("DELETE FROM callback WHERE taskid = :task AND cbfunction = :cb LIMIT 1", array('task' => $row['taskid'], 'cb' => $row['cbfunction']));
+ if (Taskmanager::isFinished($status)) {
+ $func = array('TaskmanagerCallback', preg_replace('/\W/', '', $row['cbfunction']));
+ if (!call_user_func_array('method_exists', $func)) {
+ Eventlog::warning("Callback {$row['cbfunction']} doesn't exist.");
+ } else {
+ call_user_func($func, $status);
+ }
+ }
+ }
+ }
}
diff --git a/inc/user.inc.php b/inc/user.inc.php
index 19d17753..111849fe 100644
--- a/inc/user.inc.php
+++ b/inc/user.inc.php
@@ -4,6 +4,7 @@ require_once('inc/session.inc.php');
class User
{
+
private static $user = false;
public static function isLoggedIn()
@@ -13,26 +14,29 @@ class User
public static function getName()
{
- if (self::$user === false) return false;
+ if (!self::isLoggedIn())
+ return false;
return self::$user['fullname'];
}
public static function hasPermission($permission)
{
- if (self::$user === false) return false;
+ if (!self::isLoggedIn())
+ return false;
return (self::$user['permissions'] & Permission::get($permission)) != 0;
}
public static function load()
{
- if (self::isLoggedIn()) {
+ if (self::isLoggedIn())
return true;
- }
if (Session::load()) {
$uid = Session::get('uid');
- if ($uid === false || $uid < 1) self::logout();
+ if ($uid === false || $uid < 1)
+ self::logout();
self::$user = Database::queryFirst('SELECT * FROM user WHERE userid = :uid LIMIT 1', array(':uid' => $uid));
- if (self::$user === false) self::logout();
+ if (self::$user === false)
+ self::logout();
return true;
}
return false;
@@ -41,8 +45,10 @@ class User
public static function login($user, $pass)
{
$ret = Database::queryFirst('SELECT userid, passwd FROM user WHERE login = :user LIMIT 1', array(':user' => $user));
- if ($ret === false) return false;
- if (!Crypto::verify($pass, $ret['passwd'])) return false;
+ if ($ret === false)
+ return false;
+ if (!Crypto::verify($pass, $ret['passwd']))
+ return false;
Session::create();
Session::set('uid', $ret['userid']);
Session::set('token', md5(rand() . time() . rand() . $_SERVER['REMOTE_ADDR'] . rand() . $_SERVER['REMOTE_PORT'] . rand() . $_SERVER['HTTP_USER_AGENT']));
@@ -57,5 +63,22 @@ class User
exit(0);
}
-}
+ public static function setLastSeenEvent($eventid)
+ {
+ if (!self::isLoggedIn())
+ return;
+ Database::exec("UPDATE user SET lasteventid = :eventid WHERE userid = :userid LIMIT 1", array(
+ 'eventid' => $eventid,
+ 'userid' => self::$user['userid']
+ ));
+ self::$user['lasteventid'] = $eventid;
+ }
+ public static function getLastSeenEvent()
+ {
+ if (!self::isLoggedIn())
+ return false;
+ return self::$user['lasteventid'];
+ }
+
+}
diff --git a/inc/validator.inc.php b/inc/validator.inc.php
index 88be14f2..944ac2ef 100644
--- a/inc/validator.inc.php
+++ b/inc/validator.inc.php
@@ -12,18 +12,20 @@ class Validator
public static function validate($condition, $value)
{
- if (empty($condition)) return $value;
+ if (empty($condition))
+ return $value;
$data = explode(':', $condition, 2);
switch ($data[0]) {
- case 'regex':
- if (preg_match($data[1], $value)) return $value;
- return false;
- case 'list':
- return self::validateList($data[1], $value);
- case 'function':
- return self::$data[1]($value);
- default:
- Util::traceError('Unknown validation method: ' . $data[0]);
+ case 'regex':
+ if (preg_match($data[1], $value))
+ return $value;
+ return false;
+ case 'list':
+ return self::validateList($data[1], $value);
+ case 'function':
+ return self::$data[1]($value);
+ default:
+ Util::traceError('Unknown validation method: ' . $data[0]);
}
}
@@ -36,11 +38,29 @@ class Validator
*/
private static function linuxPassword($value)
{
- if (empty($value)) return '';
- if (preg_match('/^\$6\$.+\$./', $value)) return $value;
+ if (empty($value))
+ return '';
+ if (preg_match('/^\$6\$.+\$./', $value))
+ return $value;
return Crypto::hash6($value);
}
-
+
+ /**
+ * "Fix" network share path for SMB shares where a backslash
+ * is used instead of a slash.
+ * @param string $value network path
+ * @return string cleaned up path
+ */
+ private static function networkShare($value)
+ {
+ $value = trim($value);
+ if (substr($value, 0, 2) === '\\\\')
+ $value = str_replace('\\', '/', $value);
+ if (substr($value, 0, 2) === '//')
+ $value = str_replace(' ', '\\040', $value);
+ return $value;
+ }
+
/**
* Validate value against list.
* @param string $list The list as a string of items, separated by "|"
@@ -50,9 +70,9 @@ class Validator
private static function validateList($list, $value)
{
$list = explode('|', $list);
- if (in_array($value, $list)) return $value;
+ if (in_array($value, $list))
+ return $value;
return false;
}
}
-
diff --git a/index.php b/index.php
index 919c4620..2f507e2c 100644
--- a/index.php
+++ b/index.php
@@ -114,21 +114,13 @@ if (AJAX) {
Page::preprocess();
// Generate Main menu
-//$menu = new Menu;// TODO: Merge both templates again - having 99% copy&paste sucks...
-if (User::getName() === false) {
- Render::addTemplate('main-menu-login', array(
- 'url' => urlencode($_SERVER['REQUEST_URI']),
- 'langs' => Dictionary::getLanguages(true),
- 'dbupdate' => Database::needSchemaUpdate()
- ));
-} else {
- Render::addTemplate('main-menu-logout', array(
- 'url' => urlencode($_SERVER['REQUEST_URI']),
- 'langs' => Dictionary::getLanguages(true),
- 'dbupdate' => Database::needSchemaUpdate(),
- 'user' => User::getName()
- ));
-}
+Render::addTemplate('main-menu', array(
+ 'url' => urlencode($_SERVER['REQUEST_URI']),
+ 'langs' => Dictionary::getLanguages(true),
+ 'dbupdate' => Database::needSchemaUpdate(),
+ 'user' => User::getName(),
+ 'warning' => User::getName() && User::getLastSeenEvent() < Property::getLastWarningId()
+));
Message::renderList();
diff --git a/install/content.sql b/install/content.sql
new file mode 100644
index 00000000..3b8a49f3
--- /dev/null
+++ b/install/content.sql
@@ -0,0 +1,2 @@
+INSERT INTO property (name, dateline, value) VALUES ('webif-version', 0, 5);
+
diff --git a/DB_SCRIBBLE b/install/schema.sql
index 1dd81685..b7edc2e7 100644
--- a/DB_SCRIBBLE
+++ b/install/schema.sql
@@ -1,17 +1,3 @@
--- Entries commented out: satellite_install script won't like them
--- CREATE DATABASE openslx;
--- CREATE USER openslx@localhost;
--- SET PASSWORD FOR openslx@localhost = Password('geheim');
--- GRANT ALL ON openslx.* TO openslx@localhost;
-
-
-
-
-
-USE openslx;
-
-
-
-- phpMyAdmin SQL Dump
-- version 4.0.8
-- http://www.phpmyadmin.net
@@ -231,63 +217,3 @@ ALTER TABLE `setting`
ALTER TABLE `setting_distro`
ADD CONSTRAINT `setting_distro_ibfk_1` FOREIGN KEY (`setting`) REFERENCES `setting` (`setting`) ON DELETE CASCADE ON UPDATE CASCADE;
-
-
-
--- phpMyAdmin SQL Dump
--- version 4.0.8
--- http://www.phpmyadmin.net
---
--- Host: localhost
--- Generation Time: Jun 13, 2014 at 05:11 PM
--- Server version: 5.5.35-0ubuntu0.12.04.2
--- PHP Version: 5.3.10-1ubuntu3.11
-
-SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
-SET time_zone = "+00:00";
-
---
--- Database: `openslx`
---
-
---
--- Dumping data for table `cat_setting`
---
-
-INSERT IGNORE INTO `cat_setting` (`catid`, `name`, `sortval`) VALUES
-(0, 'Unkategorisiert', 20000),
-(1, 'Inaktivität und Abschaltung', 30),
-(2, 'Internetzugriff', 20),
-(3, 'Zeitsynchronisation', 100),
-(4, 'Grundsystem', 10);
-
---
--- Dumping data for table `permission`
---
-
-INSERT IGNORE INTO `permission` (`mask`, `identifier`, `description`) VALUES
-(1, 'superadmin', 'SuperAdmin - Dieser Benutzer darf alle Einstellungen sehen und ändern, unabhängig davon, ob ihr die Rechte dafür explizit gewährt wurden.'),
-(2, 'baseconfig_global', 'Basiskonfiguration global und für jeden Poolraum ändern.'),
-(4, 'baseconfig_local', 'Basiskonfiguration für dem Benutzer zugewiesene Poolräume ändern.');
-
---
--- Dumping data for table `setting`
---
-
-INSERT IGNORE INTO `setting` (`setting`, `catid`, `defaultvalue`, `permissions`, `validator`, `description`) VALUES
-('SLX_ADDONS', 0, 'vmware', 2, '', 'Zu ladende Addons. Zur Zeit steht nur vmware zur Verfügung.'),
-('SLX_BIOS_CLOCK', 3, 'off', 2, 'regex:/^(off|local|utc)$/', 'Legt fest, ob und wie die interne Uhr des Rechners im Bezug auf die Systemzeit des /MiniLinux/ gesetzt werden soll.\r\n*off* = Die interne Uhr des Rechners wird nicht verändert.\r\n*local* = Die interne Uhr wird auf die Lokalzeit gesetzt. Bevorzugt wenn z.B. noch eine native Windows-Installation auf dem PC vorhanden ist.\r\n*utc* = Die interne Uhr wird auf die /Koordinierte Weltzeit/ gesetzt. Dies ist die gängige Einstellung in einem reinen Linux-Umfeld.'),
-('SLX_LOGOUT_TIMEOUT', 1, '1800', 2, 'regex:/^\\d*$/', 'Zeit /in Sekunden/, die eine Benutzersitzung ohne Aktion sein darf, bevor sie beendet wird.\r\nFeld leer lassen, um die Funktion zu deaktivieren.'),
-('SLX_NET_DOMAIN', 2, '', 2, '', 'DNS-Domäne, in die sich die Clients eingliedern, sofern der DHCP Server keine solche vorgibt.'),
-('SLX_NTP_SERVER', 3, '0.de.pool.ntp.org 1.de.pool.ntp.org', 2, '', 'Adresse des NTP-Zeitservers. Es können mehrere Server mit Leerzeichen getrennt angegeben werden.\r\nDie Server werden der Reihe nach angefragt, bis ein antwortender Server gefunden wird.'),
-('SLX_PROXY_BLACKLIST', 2, '', 2, '', 'Adressen bzw. Adressbereiche, für die der Proxyserver nicht verwendet werden soll (z.B. der Adressbereich der Einrichtung). Gültige Angaben sind einzelne IP-Adressen, sowie IP-Bereiche in CIDR-Notation (z.B. 1.2.0.0/16). Mehrere Angaben können durch Leerzeichen getrennt werden.'),
-('SLX_PROXY_IP', 2, '', 2, '', 'Die Adresse des zu verwendenden Proxy Servers.'),
-('SLX_PROXY_MODE', 2, 'off', 2, 'regex:/^(off|on|auto|wpad)$/', 'Legt fest, ob zum Zugriff aufs Internet ein Proxy-Server benötigt wird.\r\n*off* = keinen Proxy benutzen.\r\n*on* = Proxy immer benutzen.\r\n*auto* = Proxy nur benutzen, wenn sich der Client-PC in einem privaten Adressbereich befindet.'),
-('SLX_PROXY_PORT', 2, '', 2, 'regex:/^\\d*$/', 'Der Port des zu verwendenden Proxy Servers.'),
-('SLX_PROXY_TYPE', 2, 'socks5', 2, '', 'Art des Proxys.\r\n*socks4*, *socks5*,\r\n*http-connect* (HTTP Proxy mit Unterstützung der CONNECT-Methode),\r\n*http-relay* (Klassischer HTTP Proxy)'),
-('SLX_REMOTE_LOG_SESSIONS', 0, 'anonymous', 2, 'regex:/^(yes|anonymous|no)$/', 'Legt fest, ob Logins und Logouts der Benutzer an den Satelliten gemeldet werden sollen.\r\n*yes* = Mit Benutzerkennung loggen\r\n*anonymous* = Anonym loggen\r\n*no* = Nicht loggen'),
-('SLX_ROOT_PASS', 4, '', 2, 'function:linuxPassword', 'Das root-Passwort des Grundsystems. Wird nur für Diagnosezwecke am Client benötigt.\r\nFeld leer lassen, um root-Logins zu verbieten.\r\n/Hinweis/: Das Passwort wird crypt $6$ gehasht, daher wir das Passwort nach dem Speichern nicht mehr lesbar sein!'),
-('SLX_SHUTDOWN_SCHEDULE', 1, '22:10 00:00', 2, 'regex:/^(\\s*\\d{1,2}:\\d{1,2})*$/', 'Feste Uhrzeit, zu der sich die Rechner ausschalten, auch wenn noch ein Benutzer aktiv ist.\r\nMehrere Zeitpunkte können durch Leerzeichen getrennt angegeben werden.'),
-('SLX_SHUTDOWN_TIMEOUT', 1, '1200', 2, 'regex:/^\\d*$/', 'Zeit in Sekunden, nach dem ein Rechner abgeschaltet wird, sofern kein Benutzer angemeldet ist.\r\nFeld leer lassen, um die Funktion zu deaktivieren.');
-
-INSERT INTO property (name, dateline, value) VALUES ('webif-version', 0, 3);
diff --git a/lang/de/messages.json b/lang/de/messages.json
index 0c9bd3d6..70dce460 100644
--- a/lang/de/messages.json
+++ b/lang/de/messages.json
@@ -14,11 +14,12 @@
"error-read": "Fehler beim Lesen von {{0}}",
"error-rename": "Konnte {{0}} nicht in {{1}} umbenennen",
"error-write": "Fehler beim Schreiben von {{0}}",
- "i18n-empty-tag": "Ein String wurde ohne Tag \u00fcbermittelt.",
+ "i18n-empty-tag": "Ein String wurde ohne Tag \u00fcbermittelt",
"i18n-invalid-lang": "Ung\u00fcltige Sprache: {{0}}",
"invalid-action": "Ung\u00fcltige Aktion: {{0}}",
"invalid-file": "Die Datei {{0}} existiert nicht!",
"invalid-ip": "Kein Interface ist auf die Adresse {{0}} konfiguriert",
+ "invalid-path": "Ung\u00fcltiger Pfad.",
"invalid-template": "Ausgew\u00e4hlte Template ist nicht g\u00fcltig",
"loginfail": "Benutzername oder Kennwort falsch",
"missing-file": "Es wurde keine Datei ausgew\u00e4hlt!",
diff --git a/lang/de/settings/cat_setting.json b/lang/de/settings/cat_setting.json
index ab3d80a9..a545f513 100644
--- a/lang/de/settings/cat_setting.json
+++ b/lang/de/settings/cat_setting.json
@@ -3,5 +3,6 @@
"cat_1": "Inaktivit\u00e4t und Abschaltung",
"cat_2": "Internetzugriff",
"cat_3": "Zeitsynchronisation",
- "cat_4": "Grundsystem"
+ "cat_4": "Grundsystem",
+ "cat_5": "Gemeinsames Netzlaufwerk"
} \ No newline at end of file
diff --git a/lang/de/settings/setting.json b/lang/de/settings/setting.json
index 04249776..1c8cc537 100644
--- a/lang/de/settings/setting.json
+++ b/lang/de/settings/setting.json
@@ -1,16 +1,18 @@
{
"SLX_ADDONS": "Zu ladende Addons. Zur Zeit steht nur vmware zur Verf\u00fcgung.",
- "SLX_BIOS_CLOCK": "Legt fest, ob und wie die interne Uhr des Rechners im Bezug auf die Systemzeit des \/MiniLinux\/ gesetzt werden soll.\n*off* = Die interne Uhr des Rechners wird nicht ver\u00e4ndert.\n*local* = Die interne Uhr wird auf die Lokalzeit gesetzt. Bevorzugt wenn z.B. noch eine native Windows-Installation auf dem PC vorhanden ist.\n*utc* = Die interne Uhr wird auf die \/Koordinierte Weltzeit\/ gesetzt. Dies ist die g\u00e4ngige Einstellung in einem reinen Linux-Umfeld.",
- "SLX_LOGOUT_TIMEOUT": "Zeit \/in Sekunden\/, die eine Benutzersitzung ohne Aktion sein darf, bevor sie beendet wird.\nFeld leer lassen, um die Funktion zu deaktivieren.",
+ "SLX_BIOS_CLOCK": "Legt fest, ob und wie die interne Uhr des Rechners im Bezug auf die Systemzeit des \/MiniLinux\/ gesetzt werden soll.*off* = Die interne Uhr des Rechners wird nicht ver\u00e4ndert.*local* = Die interne Uhr wird auf die Lokalzeit gesetzt. Bevorzugt wenn z.B. noch eine native Windows-Installation auf dem PC vorhanden ist.*utc* = Die interne Uhr wird auf die \/Koordinierte Weltzeit\/ gesetzt. Dies ist die g\u00e4ngige Einstellung in einem reinen Linux-Umfeld.",
+ "SLX_COMMON_SHARE_AUTH": "Authentifizierungsmethode f\u00fcr das gemeinsame Netzlaufwerk. *guest* bedeutet, dass keine Authentifizierung notwendig ist, *user* bedeutet, dass die Credentials des angemeldeten Benutzers verwendet werden.",
+ "SLX_COMMON_SHARE_PATH": "Netzwerkpfad des gemeinsamen Netzlaufwerks. Es werden NFS (keine Authentifizierung) und CIFS\/SMB (mit und ohne Authentifizierung) unterst\u00fctzt.",
+ "SLX_LOGOUT_TIMEOUT": "Zeit \/in Sekunden\/, die eine Benutzersitzung ohne Aktion sein darf, bevor sie beendet wird.Feld leer lassen, um die Funktion zu deaktivieren.",
"SLX_NET_DOMAIN": "DNS-Dom\u00e4ne, in die sich die Clients eingliedern, sofern der DHCP Server keine solche vorgibt.",
- "SLX_NTP_SERVER": "Adresse des NTP-Zeitservers. Es k\u00f6nnen mehrere Server mit Leerzeichen getrennt angegeben werden.\nDie Server werden der Reihe nach angefragt, bis ein antwortender Server gefunden wird.",
+ "SLX_NTP_SERVER": "Adresse des NTP-Zeitservers. Es k\u00f6nnen mehrere Server mit Leerzeichen getrennt angegeben werden.Die Server werden der Reihe nach angefragt, bis ein antwortender Server gefunden wird.",
"SLX_PROXY_BLACKLIST": "Adressen bzw. Adressbereiche, f\u00fcr die der Proxyserver nicht verwendet werden soll (z.B. der Adressbereich der Einrichtung). G\u00fcltige Angaben sind einzelne IP-Adressen, sowie IP-Bereiche in CIDR-Notation (z.B. 1.2.0.0\/16). Mehrere Angaben k\u00f6nnen durch Leerzeichen getrennt werden.",
"SLX_PROXY_IP": "Die Adresse des zu verwendenden Proxy Servers.",
- "SLX_PROXY_MODE": "Legt fest, ob zum Zugriff aufs Internet ein Proxy-Server ben\u00f6tigt wird.\n*off* = keinen Proxy benutzen.\n*on* = Proxy immer benutzen.\n*auto* = Proxy nur benutzen, wenn sich der Client-PC in einem privaten Adressbereich befindet.",
+ "SLX_PROXY_MODE": "Legt fest, ob zum Zugriff aufs Internet ein Proxy-Server ben\u00f6tigt wird.*off* = keinen Proxy benutzen.*on* = Proxy immer benutzen.*auto* = Proxy nur benutzen, wenn sich der Client-PC in einem privaten Adressbereich befindet.",
"SLX_PROXY_PORT": "Der Port des zu verwendenden Proxy Servers.",
- "SLX_PROXY_TYPE": "Art des Proxys.\n*socks4*, *socks5*,\n*http-connect* (HTTP Proxy mit Unterst\u00fctzung der CONNECT-Methode),\n*http-relay* (Klassischer HTTP Proxy)",
- "SLX_REMOTE_LOG_SESSIONS": "Legt fest, ob Logins und Logouts der Benutzer an den Satelliten gemeldet werden sollen.\n*yes* = Mit Benutzerkennung loggen\n*anonymous* = Anonym loggen\n*no* = Nicht loggen",
- "SLX_ROOT_PASS": "Das root-Passwort des Grundsystems. Wird nur f\u00fcr Diagnosezwecke am Client ben\u00f6tigt.\nFeld leer lassen, um root-Logins zu verbieten.\n\/Hinweis\/: Das Passwort wird crypt $6$ gehasht, daher wir das Passwort nach dem Speichern nicht mehr lesbar sein!",
- "SLX_SHUTDOWN_SCHEDULE": "Feste Uhrzeit, zu der sich die Rechner ausschalten, auch wenn noch ein Benutzer aktiv ist.\nMehrere Zeitpunkte k\u00f6nnen durch Leerzeichen getrennt angegeben werden.",
- "SLX_SHUTDOWN_TIMEOUT": "Zeit in Sekunden, nach dem ein Rechner abgeschaltet wird, sofern kein Benutzer angemeldet ist.\nFeld leer lassen, um die Funktion zu deaktivieren."
+ "SLX_PROXY_TYPE": "Art des Proxys.*socks4*, *socks5*,*http-connect* (HTTP Proxy mit Unterst\u00fctzung der CONNECT-Methode),*http-relay* (Klassischer HTTP Proxy)",
+ "SLX_REMOTE_LOG_SESSIONS": "Legt fest, ob Logins und Logouts der Benutzer an den Satelliten gemeldet werden sollen.*yes* = Mit Benutzerkennung loggen*anonymous* = Anonym loggen*no* = Nicht loggen",
+ "SLX_ROOT_PASS": "Das root-Passwort des Grundsystems. Wird nur f\u00fcr Diagnosezwecke am Client ben\u00f6tigt.Feld leer lassen, um root-Logins zu verbieten.\/Hinweis\/: Das Passwort wird crypt $6$ gehasht, daher wir das Passwort nach dem Speichern nicht mehr lesbar sein!",
+ "SLX_SHUTDOWN_SCHEDULE": "Feste Uhrzeit, zu der sich die Rechner ausschalten, auch wenn noch ein Benutzer aktiv ist.Mehrere Zeitpunkte k\u00f6nnen durch Leerzeichen getrennt angegeben werden.",
+ "SLX_SHUTDOWN_TIMEOUT": "Zeit in Sekunden, nach dem ein Rechner abgeschaltet wird, sofern kein Benutzer angemeldet ist.Feld leer lassen, um die Funktion zu deaktivieren."
} \ No newline at end of file
diff --git a/lang/de/templates/main-menu-login.json b/lang/de/templates/main-menu-login.json
deleted file mode 100644
index 083d68a7..00000000
--- a/lang/de/templates/main-menu-login.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "lang_administration": "\u00dcbersetzungen",
- "lang_client": "Client",
- "lang_clientLog": "Client Log",
- "lang_configurationBasic": "Grundkonfiguration",
- "lang_configurationVariables": "KonfigurationsVariablen",
- "lang_language": "Sprachen",
- "lang_localization": "Lokalisierung",
- "lang_login": "Anmelden",
- "lang_news": "News",
- "lang_server": "Server",
- "lang_settings": "Einstellungen",
- "lang_vmLocation": "VM Speicherort"
-} \ No newline at end of file
diff --git a/lang/de/templates/main-menu-logout.json b/lang/de/templates/main-menu.json
index 6b7ba9ff..b61cc1bb 100644
--- a/lang/de/templates/main-menu-logout.json
+++ b/lang/de/templates/main-menu.json
@@ -6,9 +6,11 @@
"lang_configurationVariables": "KonfigurationsVariablen",
"lang_language": "Sprachen",
"lang_localization": "Lokalisierung",
+ "lang_login": "Anmelden",
"lang_logout": "Abmelden",
"lang_news": "News",
"lang_server": "Server",
"lang_settings": "Einstellungen",
- "lang_vmLocation": "VM Speicherort"
+ "lang_vmLocation": "VM Speicherort",
+ "lang_warning": "Warnung"
} \ No newline at end of file
diff --git a/lang/de/templates/translation/edit.json b/lang/de/templates/translation/edit.json
index c2c6b755..671e51d8 100644
--- a/lang/de/templates/translation/edit.json
+++ b/lang/de/templates/translation/edit.json
@@ -7,6 +7,6 @@
"lang_newTAG": "Neue Tag",
"lang_portugueseTAG": "Portugiesisch TAG",
"lang_save": "Speichern",
- "lang_templateAdminHelp": "",
+ "lang_templateAdminHelp": "Hier k\u00f6nnen Sie die verwendeten Texte und S\u00e4tze \u00fcbersetzen.",
"lang_templateHint": "Hinweis: Gelbe Linie zeigt eine \u00dcbersetzung fehlt und roten Linien zeigen ein Tag wird nicht von das Template verwendet."
} \ No newline at end of file
diff --git a/lang/de/templates/translation/template-list.json b/lang/de/templates/translation/template-list.json
new file mode 100644
index 00000000..5d6945bc
--- /dev/null
+++ b/lang/de/templates/translation/template-list.json
@@ -0,0 +1,5 @@
+{
+ "lang_adminInfo": "Dies ist eine Liste aller Templates. Die \u0022Status\u0022-Spalte zeigt an, wenn f\u00fcr ein Template \u00fcbersetzungen fehlen, oder veraltete Tags definiert sind.",
+ "lang_langAdministration": "Templates",
+ "lang_status": "Status"
+} \ No newline at end of file
diff --git a/lang/en/messages.json b/lang/en/messages.json
index fbec163e..37ca550a 100644
--- a/lang/en/messages.json
+++ b/lang/en/messages.json
@@ -14,9 +14,12 @@
"error-read": "Error reading {{0}}",
"error-rename": "Could not rename {{0}} into {{1}}",
"error-write": "Failed to write {{0}}",
+ "i18n-empty-tag": "A string without tag was submitted",
+ "i18n-invalid-lang": "Invalid language: {{0}}",
"invalid-action": "Invalid action: {{0}}",
"invalid-file": "The file {{0}} does not exist!",
"invalid-ip": "No interface is configured with the address {{0}}",
+ "invalid-path": "Invalid path.",
"invalid-template": "Selected template is not valid",
"loginfail": "Username or Password incorrect",
"missing-file": "There was no file selected!",
@@ -36,6 +39,8 @@
"taskmanager-error": "Failed to connect to the Task Manager",
"taskmanager-format": "Task Manager has returned invalid data",
"token": "Invalid token. CSRF attack?",
+ "unsuccessful-action": "Not successful",
+ "updated-tags": "Tags have been updated",
"upload-complete": "Upload of {{0}} was successful",
"upload-failed": "Upload failed: {{0}}",
"value-invalid": "The value {{1}} is invalid for option {{0}} and has been ignored"
diff --git a/lang/en/settings/cat_setting.json b/lang/en/settings/cat_setting.json
index 4f408f32..8d15df18 100644
--- a/lang/en/settings/cat_setting.json
+++ b/lang/en/settings/cat_setting.json
@@ -3,5 +3,6 @@
"cat_1": "Inactivity and Shutdown",
"cat_2": "Internet Access",
"cat_3": "Time Synchronization",
- "cat_4": "Basic System"
+ "cat_4": "Basic System",
+ "cat_5": "Common network share"
} \ No newline at end of file
diff --git a/lang/en/settings/setting.json b/lang/en/settings/setting.json
index fc857465..68378b9a 100644
--- a/lang/en/settings/setting.json
+++ b/lang/en/settings/setting.json
@@ -1,16 +1,18 @@
{
"SLX_ADDONS": "To load addons. There currently only vmware is available.",
- "SLX_BIOS_CLOCK": "Specifies whether and how the internal clock of the computer should be set in relation to the system time of the \/MiniLinux\/.\n*off* = The internal clock of the computer is not changed.\n*local* = The internal clock is set to local time. Preferably if, for example, there is still a native Windows installation available on the PC.\n*utc* = The internal clock is set to the \/Coordinated Universal Time\/. This is the most common setup in a pure Linux environment.",
- "SLX_LOGOUT_TIMEOUT": "Time \/in seconds\/, in which a user session may remain without action before it is terminated.\nLeave field blank to disable the function.",
+ "SLX_BIOS_CLOCK": "Specifies whether and how the internal clock of the computer should be set in relation to the system time of the \/MiniLinux\/.*off* = The internal clock of the computer is not changed.*local* = The internal clock is set to local time. Preferably if, for example, there is still a native Windows installation available on the PC.*utc* = The internal clock is set to the \/Coordinated Universal Time\/. This is the most common setup in a pure Linux environment.",
+ "SLX_COMMON_SHARE_AUTH": "Athentication method for the common network share. *guest* means no authentication (public share), *user* means the user's credentials will be used.",
+ "SLX_COMMON_SHARE_PATH": "Path of network share. Supported are NFS (no authentication only) and CIFS\/SMB (with and without authentication).",
+ "SLX_LOGOUT_TIMEOUT": "Time \/in seconds\/, in which a user session may remain without action before it is terminated.Leave field blank to disable the function.",
"SLX_NET_DOMAIN": "DNS domain in which the client integrate, provided the DHCP server does not specifies such.",
- "SLX_NTP_SERVER": "Address of the NTP time server. Multiple servers can be specified separated by spaces.\nThe servers are queried in sequence until a responding server is found.",
+ "SLX_NTP_SERVER": "Address of the NTP time server. Multiple servers can be specified separated by spaces.The servers are queried in sequence until a responding server is found.",
"SLX_PROXY_BLACKLIST": "Address or addresses ranges in which the proxy server is not used (for example the address range of the device). Valid entries are individual IP addresses and IP ranges in CIDR notation (for example 1.2.0.0\/16). Multiple selections can be separated by spaces.",
"SLX_PROXY_IP": "The address to use for the proxy server.",
- "SLX_PROXY_MODE": "Determines whether a proxy server is required to access the Internet.\n*off* = do not use a Proxy.\n*on* = Always use proxy.\n*auto* = Only use proxy when the client PC is in a private address space.",
+ "SLX_PROXY_MODE": "Determines whether a proxy server is required to access the Internet.*off* = do not use a Proxy.*on* = Always use proxy.*auto* = Only use proxy when the client PC is in a private address space.",
"SLX_PROXY_PORT": "The port to use for the proxy server.",
- "SLX_PROXY_TYPE": "Type of the proxy.\n*socks4*, *socks5*,\n*http-connect* (HTTP proxy with support from the CONNECT method),\n*http-relay* (Classic HTTP proxy)",
- "SLX_REMOTE_LOG_SESSIONS": "Determines whether logins and logouts of the users should be reported to the satellite.\n*yes* = login with user ID\n*anonymous* = anonymous login\n*no* = no login",
- "SLX_ROOT_PASS": "The root password of the basic system. Only required for diagnostic purposes on the client.\nLeave field blank to disallow root logins.\n\/Hint\/: The password is encrypted with $6$ hash, so it is no longer readable after saving!",
- "SLX_SHUTDOWN_SCHEDULE": "Fixed time to turn off the computer, even if there is a user active.\nSeveral times can be specified, separated by spaces.",
- "SLX_SHUTDOWN_TIMEOUT": "Time in seconds after which a computer is switched off, if no user is logged on.\nLeave blank to disable the function."
+ "SLX_PROXY_TYPE": "Type of the proxy.*socks4*, *socks5*,*http-connect* (HTTP proxy with support from the CONNECT method),*http-relay* (Classic HTTP proxy)",
+ "SLX_REMOTE_LOG_SESSIONS": "Determines whether logins and logouts of the users should be reported to the satellite.*yes* = login with user ID*anonymous* = anonymous login*no* = no login",
+ "SLX_ROOT_PASS": "The root password of the basic system. Only required for diagnostic purposes on the client.Leave field blank to disallow root logins.\/Hint\/: The password is encrypted with $6$ hash, so it is no longer readable after saving!",
+ "SLX_SHUTDOWN_SCHEDULE": "Fixed time to turn off the computer, even if there is a user active.Several times can be specified, separated by spaces.",
+ "SLX_SHUTDOWN_TIMEOUT": "Time in seconds after which a computer is switched off, if no user is logged on.Leave blank to disable the function."
} \ No newline at end of file
diff --git a/lang/en/templates/main-menu-login.json b/lang/en/templates/main-menu-login.json
deleted file mode 100644
index 26391c9f..00000000
--- a/lang/en/templates/main-menu-login.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "lang_administration": "Translations",
- "lang_client": "Client",
- "lang_clientLog": "Client Log",
- "lang_configurationBasic": "Basic Configuration",
- "lang_configurationVariables": "Configuration Variables",
- "lang_language": "Language",
- "lang_localization": "Localization",
- "lang_login": "Login",
- "lang_news": "News",
- "lang_server": "Server",
- "lang_settings": "Settings",
- "lang_vmLocation": "VM Location"
-} \ No newline at end of file
diff --git a/lang/en/templates/main-menu-logout.json b/lang/en/templates/main-menu.json
index 54d7831e..16e83084 100644
--- a/lang/en/templates/main-menu-logout.json
+++ b/lang/en/templates/main-menu.json
@@ -6,9 +6,11 @@
"lang_configurationVariables": "Configuration Variables",
"lang_language": "Language",
"lang_localization": "Localization",
+ "lang_login": "Login",
"lang_logout": "Logout",
"lang_news": "News",
"lang_server": "Server",
"lang_settings": "Settings",
- "lang_vmLocation": "VM Location"
+ "lang_vmLocation": "VM Location",
+ "lang_warning": "Warning"
} \ No newline at end of file
diff --git a/lang/en/templates/sysconfig/_page.json b/lang/en/templates/sysconfig/_page.json
index 679514c2..e6c643a0 100644
--- a/lang/en/templates/sysconfig/_page.json
+++ b/lang/en/templates/sysconfig/_page.json
@@ -1,6 +1,6 @@
{
"lang_activate": "Activate",
- "lang_active": "",
+ "lang_active": "Active",
"lang_availableModules": "Available Configuration Modules",
"lang_availableSystem": "Available System Configuration",
"lang_close": "Close",
diff --git a/lang/en/templates/translation/edit.json b/lang/en/templates/translation/edit.json
index ff3f44ca..05c6697a 100644
--- a/lang/en/templates/translation/edit.json
+++ b/lang/en/templates/translation/edit.json
@@ -7,6 +7,6 @@
"lang_newTAG": "New TAG",
"lang_portugueseTAG": "Portuguese TAG",
"lang_save": "Save",
- "lang_templateAdminHelp": "",
+ "lang_templateAdminHelp": "Here you can translate and edit phrases and texts.",
"lang_templateHint": "Hint: Yellow lines indicate a translation is missing and red lines indicate a tag is not being used by the template."
} \ No newline at end of file
diff --git a/lang/en/templates/translation/template-list.json b/lang/en/templates/translation/template-list.json
new file mode 100644
index 00000000..e3feb70b
--- /dev/null
+++ b/lang/en/templates/translation/template-list.json
@@ -0,0 +1,5 @@
+{
+ "lang_adminInfo": "This is a list of all templates. The \u0022status\u0022-column tells if there are translations missing, or unused tags are defined.",
+ "lang_langAdministration": "Templates",
+ "lang_status": "Status"
+} \ No newline at end of file
diff --git a/lang/lang.sql b/lang/lang.sql
deleted file mode 100644
index d6ad37c5..00000000
--- a/lang/lang.sql
+++ /dev/null
@@ -1,95 +0,0 @@
-ALTER TABLE cat_setting ADD COLUMN en varchar(250);
-ALTER TABLE cat_setting ADD COLUMN de varchar(250);
-ALTER TABLE cat_setting ADD COLUMN pt varchar(250);
-
-UPDATE cat_setting SET en='Uncategorized', de='Unkategorisiert', pt='Sem Categoria' WHERE catid=0;
-UPDATE cat_setting SET en='Inactivity and Shutdown', de='Inaktivität und Abschaltung', pt='Inatividade e Desligamento' WHERE catid=1;
-UPDATE cat_setting SET en='Internet Access', de='Internetzugriff', pt='Acesso à Internet' WHERE catid=2;
-UPDATE cat_setting SET en='Time Synchronization', de='Zeitsynchronisation', pt='Sincronização de Tempo' WHERE catid=3;
-UPDATE cat_setting SET en='Basic System', de='Grundsystem', pt='Sistema Básico' WHERE catid=4;
-
-ALTER TABLE setting ADD COLUMN en text;
-ALTER TABLE setting ADD COLUMN de text;
-ALTER TABLE setting ADD COLUMN pt text;
-
-UPDATE setting SET en='To load addons. There currently only vmware is available.', de='Zu ladende Addons. Zur Zeit steht nur vmware zur Verfügung.', pt='Para carregar addons. Atualmente apenas o vmware está disponível.' WHERE setting='SLX_ADDONS';
-
-UPDATE setting SET en='Determines whether logins and logouts of the users should be reported to the satellite.
-*yes* = login with user ID
-*anonymous* = anonymous login
-*no* = no login', de='Legt fest, ob Logins und Logouts der Benutzer an den Satelliten gemeldet werden sollen.
-*yes* = Mit Benutzerkennung loggen
-*anonymous* = Anonym loggen
-*no* = Nicht loggen', pt='Determina se logins e logouts dos usuários devem ser reportados ao satélite.
-*yes* = Login com ID de usuário
-*anonymous* = login anônimo
-*no* = sem login' WHERE setting='SLX_REMOTE_LOG_SESSIONS';
-
-UPDATE setting SET en='Time /in seconds/, in which a user session may remain without action before it is terminated.
-Leave field blank to disable the function.', de='Zeit /in Sekunden/, die eine Benutzersitzung ohne Aktion sein darf, bevor sie beendet wird.
-Feld leer lassen, um die Funktion zu deaktivieren.', pt='Hora /em segundos/, em que uma sessão de usuário pode permanecer sem ação antes de ser encerrada.
-Deixe o campo em branco para desativar a função.' WHERE setting='SLX_LOGOUT_TIMEOUT';
-
-UPDATE setting SET en='Fixed time to turn off the computer, even if there is a user active.
-Several times can be specified, separated by spaces.', de='Feste Uhrzeit, zu der sich die Rechner ausschalten, auch wenn noch ein Benutzer aktiv ist.
-Mehrere Zeitpunkte können durch Leerzeichen getrennt angegeben werden.', pt='Horário fixo para desligar o computador, até mesmo caso tenha um usuário ativo.
-Múltiplos horários podem ser especificados, separados por espaços.' WHERE setting='SLX_SHUTDOWN_SCHEDULE';
-
-UPDATE setting SET en='Time in seconds after which a computer is switched off, if no user is logged on.
-Leave blank to disable the function.', de='Zeit in Sekunden, nach dem ein Rechner abgeschaltet wird, sofern kein Benutzer angemeldet ist.
-Feld leer lassen, um die Funktion zu deaktivieren.', pt='Tempo em segundos no qual um computador é desligado, caso não tenha um usuário logado.
-Deixar em branco para desabilitar a função.' WHERE setting='SLX_SHUTDOWN_TIMEOUT';
-
-UPDATE setting SET en='DNS domain in which the client integrate, provided the DHCP server does not specifies such.', de='DNS-Domäne, in die sich die Clients eingliedern, sofern der DHCP Server keine solche vorgibt.', pt='Domínio DNS no qual o cliente se integra, desde que o servidor DHCP não especifique tal.' WHERE setting='SLX_NET_DOMAIN';
-
-UPDATE setting SET en='Address or addresses ranges in which the proxy server is not used (for example the address range of the device). Valid entries are individual IP addresses and IP ranges in CIDR notation (for example 1.2.0.0/16). Multiple selections can be separated by spaces.', de='Adressen bzw. Adressbereiche, für die der Proxyserver nicht verwendet werden soll (z.B. der Adressbereich der Einrichtung). Gültige Angaben sind einzelne IP-Adressen, sowie IP-Bereiche in CIDR-Notation (z.B. 1.2.0.0/16). Mehrere Angaben können durch Leerzeichen getrennt werden.', pt='Intervalos de endereços em que o servidor proxy não é usado (por exemplo, o intervalo de endereço do dispositivo). As entradas válidas são endereços IP individuais e intervalos de IP em notação CIDR (por exemplo 1.2.0.0/16). Seleções múltiplas podem ser separadas por espaços.' WHERE setting='SLX_PROXY_BLACKLIST';
-
-UPDATE setting SET en='The address to use for the proxy server.', de='Die Adresse des zu verwendenden Proxy Servers.', pt='O endereço de servidor proxy a ser usado.' WHERE setting='SLX_PROXY_IP';
-
-UPDATE setting SET en='Determines whether a proxy server is required to access the Internet.
-*off* = do not use a Proxy.
-*on* = Always use proxy.
-*auto* = Only use proxy when the client PC is in a private address space.', de='Legt fest, ob zum Zugriff aufs Internet ein Proxy-Server benötigt wird.
-*off* = keinen Proxy benutzen.
-*on* = Proxy immer benutzen.
-*auto* = Proxy nur benutzen, wenn sich der Client-PC in einem privaten Adressbereich befindet.', pt='Determina se um servidor proxy é necessário para acessar a Internet.
-*off* = não utilizar proxy.
-*on* = sempre utilizar proxy.
-*auto* = apenas utilizar proxy quando o PC cliente estiver em um espaço de endereço privado.' WHERE setting='SLX_PROXY_MODE';
-
-UPDATE setting SET en='The port to use for the proxy server.', de='Der Port des zu verwendenden Proxy Servers.', pt='A porta a ser utilizada pelo servidor proxy.' WHERE setting='SLX_PROXY_PORT';
-
-UPDATE setting SET en='Type of the proxy.
-*socks4*, *socks5*,
-*http-connect* (HTTP proxy with support from the CONNECT method),
-*http-relay* (Classic HTTP proxy)', de='Art des Proxys.
-*socks4*, *socks5*,
-*http-connect* (HTTP Proxy mit Unterstützung der CONNECT-Methode),
-*http-relay* (Klassischer HTTP Proxy)', pt='Tipo do proxy.
-*socks4*, *socks5*,
-*http-connect* (Proxy HTTP com suporte ao método CONNECT),
-*http-relay* (Clássico proxy HTTP)' WHERE setting='SLX_PROXY_TYPE';
-
-UPDATE setting SET en='Specifies whether and how the internal clock of the computer should be set in relation to the system time of the /MiniLinux/.
-*off* = The internal clock of the computer is not changed.
-*local* = The internal clock is set to local time. Preferably if, for example, there is still a native Windows installation available on the PC.
-*utc* = The internal clock is set to the /Coordinated Universal Time/. This is the most common setup in a pure Linux environment.', de='Legt fest, ob und wie die interne Uhr des Rechners im Bezug auf die Systemzeit des /MiniLinux/ gesetzt werden soll.
-*off* = Die interne Uhr des Rechners wird nicht verändert.
-*local* = Die interne Uhr wird auf die Lokalzeit gesetzt. Bevorzugt wenn z.B. noch eine native Windows-Installation auf dem PC vorhanden ist.
-*utc* = Die interne Uhr wird auf die /Koordinierte Weltzeit/ gesetzt. Dies ist die gängige Einstellung in einem reinen Linux-Umfeld.', pt='Especifica se e como o relógio interno do computador deve ser definido em relação ao horário do sistema do /MiniLinux/.
-*off* = O relógio interno do computador não é alterado.
-*local* = O relógio interno está definido para a hora local. De preferência se, por exemplo, ainda existe uma instalação Windows nativo disponível no PC.
-*utc* = O relógio interno é definido para o /Tempo Universal Coordenado/. Esta é a configuração mais comum em um ambiente puramente Linux' WHERE setting='SLX_BIOS_CLOCK';
-
-UPDATE setting SET en='Address of the NTP time server. Multiple servers can be specified separated by spaces.
-The servers are queried in sequence until a responding server is found.', de='Adresse des NTP-Zeitservers. Es können mehrere Server mit Leerzeichen getrennt angegeben werden.
-Die Server werden der Reihe nach angefragt, bis ein antwortender Server gefunden wird.', pt='Endereço do servidor de horário NTP. Vários servidores podem ser especificados separados por espaços.
-Os servidores são consultados em seqüência até que um servidor respondendo for encontrado.' WHERE setting='SLX_NTP_SERVER';
-
-UPDATE setting SET en='The root password of the basic system. Only required for diagnostic purposes on the client.
-Leave field blank to disallow root logins.
-/Hint/: The password is encrypted with $6$ hash, so it is no longer readable after saving!', de='Das root-Passwort des Grundsystems. Wird nur für Diagnosezwecke am Client benötigt.
-Feld leer lassen, um root-Logins zu verbieten.
-/Hinweis/: Das Passwort wird crypt $6$ gehasht, daher wir das Passwort nach dem Speichern nicht mehr lesbar sein!', pt='A senha root do sistema base. Exigido somente para fins de diagnóstico no cliente.
-Deixar campo em branco para não permitir login com root.
-/Dica/: A senha é criptografada com hash $6$, então se torna ilegível após ser salva!' WHERE setting='SLX_ROOT_PASS';
diff --git a/lang/pt/settings/setting.json b/lang/pt/settings/setting.json
index f8c0d672..66ec3b1c 100644
--- a/lang/pt/settings/setting.json
+++ b/lang/pt/settings/setting.json
@@ -1,16 +1,16 @@
{
"SLX_ADDONS": "Para carregar addons. Atualmente apenas o vmware est\u00e1 dispon\u00edvel.",
- "SLX_BIOS_CLOCK": "Especifica se e como o rel\u00f3gio interno do computador deve ser definido em rela\u00e7\u00e3o ao hor\u00e1rio do sistema do \/MiniLinux\/.\n*off* = O rel\u00f3gio interno do computador n\u00e3o \u00e9 alterado.\n*local* = O rel\u00f3gio interno est\u00e1 definido para a hora local. De prefer\u00eancia se, por exemplo, ainda existe uma instala\u00e7\u00e3o Windows nativo dispon\u00edvel no PC.\n*utc* = O rel\u00f3gio interno \u00e9 definido para o \/Tempo Universal Coordenado\/. Esta \u00e9 a configura\u00e7\u00e3o mais comum em um ambiente puramente Linux",
- "SLX_LOGOUT_TIMEOUT": "Hora \/em segundos\/, em que uma sess\u00e3o de usu\u00e1rio pode permanecer sem a\u00e7\u00e3o antes de ser encerrada.\nDeixe o campo em branco para desativar a fun\u00e7\u00e3o.",
+ "SLX_BIOS_CLOCK": "Especifica se e como o rel\u00f3gio interno do computador deve ser definido em rela\u00e7\u00e3o ao hor\u00e1rio do sistema do \/MiniLinux\/.*off* = O rel\u00f3gio interno do computador n\u00e3o \u00e9 alterado.*local* = O rel\u00f3gio interno est\u00e1 definido para a hora local. De prefer\u00eancia se, por exemplo, ainda existe uma instala\u00e7\u00e3o Windows nativo dispon\u00edvel no PC.*utc* = O rel\u00f3gio interno \u00e9 definido para o \/Tempo Universal Coordenado\/. Esta \u00e9 a configura\u00e7\u00e3o mais comum em um ambiente puramente Linux",
+ "SLX_LOGOUT_TIMEOUT": "Hora \/em segundos\/, em que uma sess\u00e3o de usu\u00e1rio pode permanecer sem a\u00e7\u00e3o antes de ser encerrada.Deixe o campo em branco para desativar a fun\u00e7\u00e3o.",
"SLX_NET_DOMAIN": "Dom\u00ednio DNS no qual o cliente se integra, desde que o servidor DHCP n\u00e3o especifique tal.",
- "SLX_NTP_SERVER": "Endere\u00e7o do servidor de hor\u00e1rio NTP. V\u00e1rios servidores podem ser especificados separados por espa\u00e7os.\nOs servidores s\u00e3o consultados em seq\u00fc\u00eancia at\u00e9 que um servidor respondendo for encontrado.",
+ "SLX_NTP_SERVER": "Endere\u00e7o do servidor de hor\u00e1rio NTP. V\u00e1rios servidores podem ser especificados separados por espa\u00e7os.Os servidores s\u00e3o consultados em seq\u00fc\u00eancia at\u00e9 que um servidor respondendo for encontrado.",
"SLX_PROXY_BLACKLIST": "Intervalos de endere\u00e7os em que o servidor proxy n\u00e3o \u00e9 usado (por exemplo, o intervalo de endere\u00e7o do dispositivo). As entradas v\u00e1lidas s\u00e3o endere\u00e7os IP individuais e intervalos de IP em nota\u00e7\u00e3o CIDR (por exemplo 1.2.0.0\/16). Sele\u00e7\u00f5es m\u00faltiplas podem ser separadas por espa\u00e7os.",
"SLX_PROXY_IP": "O endere\u00e7o de servidor proxy a ser usado.",
- "SLX_PROXY_MODE": "Determina se um servidor proxy \u00e9 necess\u00e1rio para acessar a Internet.\n*off* = n\u00e3o utilizar proxy.\n*on* = sempre utilizar proxy.\n*auto* = apenas utilizar proxy quando o PC cliente estiver em um espa\u00e7o de endere\u00e7o privado.",
+ "SLX_PROXY_MODE": "Determina se um servidor proxy \u00e9 necess\u00e1rio para acessar a Internet.*off* = n\u00e3o utilizar proxy.*on* = sempre utilizar proxy.*auto* = apenas utilizar proxy quando o PC cliente estiver em um espa\u00e7o de endere\u00e7o privado.",
"SLX_PROXY_PORT": "A porta a ser utilizada pelo servidor proxy.",
- "SLX_PROXY_TYPE": "Tipo do proxy.\n*socks4*, *socks5*,\n*http-connect* (Proxy HTTP com suporte ao m\u00e9todo CONNECT),\n*http-relay* (Cl\u00e1ssico proxy HTTP)",
- "SLX_REMOTE_LOG_SESSIONS": "Determina se logins e logouts dos usu\u00e1rios devem ser reportados ao sat\u00e9lite.\n*yes* = Login com ID de usu\u00e1rio\n*anonymous* = login an\u00f4nimo\n*no* = sem login",
- "SLX_ROOT_PASS": "A senha root do sistema base. Exigido somente para fins de diagn\u00f3stico no cliente.\nDeixar campo em branco para n\u00e3o permitir login com root.\n\/Dica\/: A senha \u00e9 criptografada com hash $6$, ent\u00e3o se torna ileg\u00edvel ap\u00f3s ser salva!",
- "SLX_SHUTDOWN_SCHEDULE": "Hor\u00e1rio fixo para desligar o computador, at\u00e9 mesmo caso tenha um usu\u00e1rio ativo.\nM\u00faltiplos hor\u00e1rios podem ser especificados, separados por espa\u00e7os.",
- "SLX_SHUTDOWN_TIMEOUT": "Tempo em segundos no qual um computador \u00e9 desligado, caso n\u00e3o tenha um usu\u00e1rio logado.\nDeixar em branco para desabilitar a fun\u00e7\u00e3o."
+ "SLX_PROXY_TYPE": "Tipo do proxy.*socks4*, *socks5*,*http-connect* (Proxy HTTP com suporte ao m\u00e9todo CONNECT),*http-relay* (Cl\u00e1ssico proxy HTTP)",
+ "SLX_REMOTE_LOG_SESSIONS": "Determina se logins e logouts dos usu\u00e1rios devem ser reportados ao sat\u00e9lite.*yes* = Login com ID de usu\u00e1rio*anonymous* = login an\u00f4nimo*no* = sem login",
+ "SLX_ROOT_PASS": "A senha root do sistema base. Exigido somente para fins de diagn\u00f3stico no cliente.Deixar campo em branco para n\u00e3o permitir login com root.\/Dica\/: A senha \u00e9 criptografada com hash $6$, ent\u00e3o se torna ileg\u00edvel ap\u00f3s ser salva!",
+ "SLX_SHUTDOWN_SCHEDULE": "Hor\u00e1rio fixo para desligar o computador, at\u00e9 mesmo caso tenha um usu\u00e1rio ativo.M\u00faltiplos hor\u00e1rios podem ser especificados, separados por espa\u00e7os.",
+ "SLX_SHUTDOWN_TIMEOUT": "Tempo em segundos no qual um computador \u00e9 desligado, caso n\u00e3o tenha um usu\u00e1rio logado.Deixar em branco para desabilitar a fun\u00e7\u00e3o."
} \ No newline at end of file
diff --git a/lang/pt/templates/main-menu-logout.json b/lang/pt/templates/main-menu-logout.json
deleted file mode 100644
index d329ac47..00000000
--- a/lang/pt/templates/main-menu-logout.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "lang_administration": "Tradu\u00e7\u00f5es",
- "lang_client": "Cliente",
- "lang_clientLog": "Log dos Clientes",
- "lang_configurationBasic": "Comfigura\u00e7\u00e3o B\u00e1sica",
- "lang_configurationVariables": "Vari\u00e1veis de Configura\u00e7\u00e3o",
- "lang_language": "L\u00edngua",
- "lang_localization": "Localiza\u00e7\u00e3o",
- "lang_logout": "Sair",
- "lang_news": "Novidades",
- "lang_server": "Servidor",
- "lang_settings": "Op\u00e7\u00f5es",
- "lang_vmLocation": "Localiza\u00e7\u00e3o da VM"
-} \ No newline at end of file
diff --git a/lang/pt/templates/main-menu-login.json b/lang/pt/templates/main-menu.json
index 460a9180..7c0b13d6 100644
--- a/lang/pt/templates/main-menu-login.json
+++ b/lang/pt/templates/main-menu.json
@@ -7,6 +7,7 @@
"lang_language": "L\u00edngua",
"lang_localization": "Localiza\u00e7\u00e3o",
"lang_login": "Entrar",
+ "lang_logout": "Sair",
"lang_news": "Novidades",
"lang_server": "Servidor",
"lang_settings": "Op\u00e7\u00f5es",
diff --git a/lang/pt/templates/sysconfig/_page.json b/lang/pt/templates/sysconfig/_page.json
index b0c1f8e9..059e0169 100644
--- a/lang/pt/templates/sysconfig/_page.json
+++ b/lang/pt/templates/sysconfig/_page.json
@@ -1,6 +1,5 @@
{
"lang_activate": "Ativar",
- "lang_active": "",
"lang_availableModules": "M\u00f3dulos de Configura\u00e7\u00e3o Dispon\u00edveis",
"lang_availableSystem": "Configura\u00e7\u00f5es de Sistema Dispon\u00edveis",
"lang_close": "Fechar",
diff --git a/lang/pt/templates/translation/edit.json b/lang/pt/templates/translation/edit.json
index 42eb5b28..326fa334 100644
--- a/lang/pt/templates/translation/edit.json
+++ b/lang/pt/templates/translation/edit.json
@@ -7,6 +7,5 @@
"lang_newTAG": "Nova TAG",
"lang_portugueseTAG": "TAG em Portugu\u00eas",
"lang_save": "Salvar",
- "lang_templateAdminHelp": "",
"lang_templateHint": "Dica: linhas amarelas indicam que uma tradu\u00e7\u00e3o est\u00e1 faltando e linhas vermelhas indicam que uma tag n\u00e3o \u00e9 utilizada pelo template."
} \ No newline at end of file
diff --git a/lang/pt/templates/translation/template-list.json b/lang/pt/templates/translation/template-list.json
new file mode 100644
index 00000000..c44dc44f
--- /dev/null
+++ b/lang/pt/templates/translation/template-list.json
@@ -0,0 +1,3 @@
+[
+
+] \ No newline at end of file
diff --git a/modules/eventlog.inc.php b/modules/eventlog.inc.php
new file mode 100644
index 00000000..1a63a0a6
--- /dev/null
+++ b/modules/eventlog.inc.php
@@ -0,0 +1,55 @@
+<?php
+
+class Page_EventLog extends Page
+{
+
+ protected function doPreprocess()
+ {
+ User::load();
+ if (!User::hasPermission('superadmin')) {
+ Message::addError('no-permission');
+ Util::redirect('?do=Main');
+ }
+ User::setLastSeenEvent(Property::getLastWarningId());
+ }
+
+ protected function doRender()
+ {
+ Render::setTitle(Dictionary::translate('lang_titleEventLog'));
+ $today = date('d.m.Y');
+ $yesterday = date('d.m.Y', time() - 86400);
+ $lines = array();
+ $paginate = new Paginate("SELECT logid, dateline, logtypeid, description, extra FROM eventlog ORDER BY logid DESC", 50);
+ $res = $paginate->exec();
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ $day = date('d.m.Y', $row['dateline']);
+ if ($day === $today) {
+ $day = Dictionary::translate('today');
+ } elseif ($day === $yesterday) {
+ $day = Dictionary::translate('yesterday');
+ }
+ $row['date'] = $day . date(' H:i', $row['dateline']);
+ $row['icon'] = $this->typeToIcon($row['logtypeid']);
+ $lines[] = $row;
+ }
+
+ $paginate->render('eventlog/_page', array(
+ 'list' => $lines
+ ));
+ }
+
+ private function typeToIcon($type)
+ {
+ switch ($type) {
+ case 'info':
+ return 'ok';
+ case 'warning':
+ return 'exclamation-sign';
+ case 'error':
+ return 'remove';
+ default:
+ return 'question-sign';
+ }
+ }
+
+}
diff --git a/modules/sysconfig.inc.php b/modules/sysconfig.inc.php
index f873fe9e..b27b6a97 100644
--- a/modules/sysconfig.inc.php
+++ b/modules/sysconfig.inc.php
@@ -222,7 +222,7 @@ class Page_SysConfig extends Page
Message::addError('task-error', $task['data']['error']);
} elseif ($task['statusCode'] === TASK_FINISHED) {
Message::addSuccess('config-activated', $row['title']);
- Trigger::ldadp(); // TODO: Feedback
+ Event::activeConfigChanged();
}
Util::redirect('?do=SysConfig');
}
diff --git a/modules/syslog.inc.php b/modules/syslog.inc.php
index 8d591876..facc1557 100644
--- a/modules/syslog.inc.php
+++ b/modules/syslog.inc.php
@@ -50,11 +50,10 @@ class Page_SysLog extends Page
$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';
+ $day = Dictionary::translate('today');
} elseif ($day === $yesterday) {
- $day = 'Gestern';
+ $day = Dictionary::translate('yesterday');
}
$row['date'] = $day . date(' H:i', $row['dateline']);
$lines[] = $row;
diff --git a/modules/translation.inc.php b/modules/translation.inc.php
index 15733b73..594c65dc 100644
--- a/modules/translation.inc.php
+++ b/modules/translation.inc.php
@@ -66,12 +66,12 @@ class Page_Translation extends Page
Render::addTemplate('translation/edit', array(
'path' => 'settings/cat_setting',
'langs' => $langs,
- 'tags' => $this->buildTranslationTable('settings/cat_setting')
+ 'tags' => $this->loadCategoriesArray()
));
Render::addTemplate('translation/edit', array(
'path' => 'settings/setting',
'langs' => $langs,
- 'tags' => $this->buildTranslationTable('settings/setting')
+ 'tags' => $this->loadSettingsArray()
));
break;
case 'template':
@@ -443,5 +443,35 @@ class Page_Translation extends Page
}
Message::addSuccess('deleted-tag');
}
+
+ /**
+ * Load all settings categories for editing.
+ *
+ * @return array
+ */
+ private function loadCategoriesArray()
+ {
+ $want = array();
+ $res = Database::simpleQuery("SELECT catid FROM cat_setting ORDER BY catid ASC");
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ $want[] = 'cat_' . $row['catid'];
+ }
+ return $this->buildTranslationTable('settings/cat_setting', $want);
+ }
+
+ /**
+ * Load all settings categories for editing.
+ *
+ * @return array
+ */
+ private function loadSettingsArray()
+ {
+ $want = array();
+ $res = Database::simpleQuery("SELECT setting FROM setting ORDER BY setting ASC");
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ $want[] = $row['setting'];
+ }
+ return $this->buildTranslationTable('settings/setting', $want);
+ }
}
diff --git a/style/bg.png b/style/bg.png
new file mode 100644
index 00000000..2289cd01
--- /dev/null
+++ b/style/bg.png
Binary files differ
diff --git a/style/default.css b/style/default.css
index 0f1c8e3e..acbddcd6 100644
--- a/style/default.css
+++ b/style/default.css
@@ -1,6 +1,10 @@
body {
- padding-top: 70px;
- padding-bottom: 10px;
+ padding-top: 70px;
+ padding-bottom: 10px;
+}
+
+.panel-heading, .panel-footer, .jumbotron, pre, .input-group-addon {
+ background-image: url('bg.png');
}
.form-signin {
@@ -136,5 +140,5 @@ body {
}
.slx-text-red {
- color: red;
+ color: #ff0;
}
diff --git a/templates/eventlog/_page.html b/templates/eventlog/_page.html
new file mode 100644
index 00000000..910b2dd5
--- /dev/null
+++ b/templates/eventlog/_page.html
@@ -0,0 +1,43 @@
+<div class="container">
+ <h1>{{lang_eventLog}}</h1>
+ {{{pagenav}}}
+ <table class="table table-striped table-condensed">
+ <thead>
+ <th width="1"></th>
+ <th>{{lang_when}}</th>
+ <th>{{lang_event}}</th>
+ <th width="1">{{lang_details}}</th>
+ </thead>
+ <tbody>
+ {{#list}}
+ <tr>
+ <td><span class="glyphicon glyphicon-{{icon}}" title="{{logtypeid}}"></span></td>
+ <td class="text-right" nowrap="nowrap">{{date}}</td>
+ <td>{{description}}</td>
+ <td>{{#extra}}
+ <a class="btn btn-default btn-xs pull-left" onclick="$('#details-body').html($('#extra-{{logid}}').html())" data-toggle="modal" data-target="#myModal">&raquo;</a>
+ <div class="hidden" id="extra-{{logid}}">{{extra}}</div>
+ {{/extra}}</td>
+ </tr>
+ {{/list}}
+ </tbody>
+ </table>
+ {{{pagenav}}}
+</div>
+
+<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+ <div class="modal-dialog modal-lg">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
+ <h4 class="modal-title" id="myModalLabel">{{lang_details}}</h4>
+ </div>
+ <div class="modal-body">
+ <pre id="details-body"></pre>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/templates/main-menu-login.html b/templates/main-menu-login.html
deleted file mode 100644
index 06e729fe..00000000
--- a/templates/main-menu-login.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!-- Fixed navbar -->
-<div class="navbar navbar-default navbar-fixed-top">
- <div class="container">
- <div class="navbar-header">
- <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </button>
- <a class="navbar-brand" href="?do=Main">OpenSLX Admin</a>
- </div>
- <div class="navbar-collapse collapse">
- <ul class="nav navbar-nav">
- <li><a href="?do=SysLog">{{lang_clientLog}}</a></li>
- <li class="dropdown">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown">{{lang_settings}}<b class="caret"></b></a>
- <ul class="dropdown-menu">
- <li class="dropdown-header">{{lang_client}}</li>
- <li><a href="?do=SysConfig">{{lang_localization}}</a></li>
- <li><a href="?do=MiniLinux">bwLehrpool Mini-Linux</a></li>
- <li><a href="?do=BaseConfig">{{lang_configurationVariables}}</a></li>
- <li><a href="?do=Translation">{{lang_administration}}</a></li>
- <li class="divider"></li>
- <li class="dropdown-header">{{lang_server}}</li>
- <li><a href="?do=ServerSetup">{{lang_configurationBasic}}</a></li>
- <li><a href="?do=VmStore">{{lang_vmLocation}}</a></li>
- </ul>
- </li>
- <li><a href="?do=News">{{lang_news}}</a></li>
- <li><a href="?do=SystemStatus">Status</a></li>
- <li class="dropdown">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown"><img src="lang/{{current_lang}}/flag.png"><b class="caret"></b></a>
- <ul class="dropdown-menu">
- <li class="dropdown-header">{{lang_language}}</li>
- {{#langs}}
- <li><a href="?lang={{cc}}&amp;url={{url}}"><img src="lang/{{cc}}/flag.png" alt="{{name}}"> {{name}}</a></li>
- {{/langs}}
- </ul>
- </li>
- {{#dbupdate}}
- <li><a href="api.php?do=update"><span class="slx-text-red"><span class="glyphicon glyphicon-exclamation-sign"></span> Update</span></a></li>
- {{/dbupdate}}
- </ul>
- <ul class="nav navbar-nav navbar-right">
- <li><a href="?do=Session&amp;action=login">{{lang_login}}</a></li>
- </ul>
- </div>
- </div>
-</div>
-
diff --git a/templates/main-menu-logout.html b/templates/main-menu.html
index e70e1def..9cc053b9 100644
--- a/templates/main-menu-logout.html
+++ b/templates/main-menu.html
@@ -38,11 +38,19 @@
</ul>
</li>
{{#dbupdate}}
- <li><a href="api.php?do=update"><span class="slx-text-red"><span class="glyphicon glyphicon-exclamation-sign"></span> Update</span></a></li>
+ <li><a href="api.php?do=update"><span class="slx-text-red badge"><span class="glyphicon glyphicon-exclamation-sign"></span> DB-Update</span></a></li>
{{/dbupdate}}
+ {{#warning}}
+ <li><a href="?do=EventLog"><span class="slx-text-red badge"><span class="glyphicon glyphicon-exclamation-sign"></span> {{lang_warning}}</span></a></li>
+ {{/warning}}
</ul>
<ul class="nav navbar-nav navbar-right">
+ {{#user}}
<li><a href="?do=Session&amp;action=logout&amp;token={{{token}}}"><b>{{user}}</b> ({{lang_logout}})</a></li>
+ {{/user}}
+ {{^user}}
+ <li><a href="?do=Session&amp;action=login">{{lang_login}}</a></li>
+ {{/user}}
</ul>
</div>
</div>
diff --git a/templates/page-syslog.html b/templates/page-syslog.html
index b7064619..123ac074 100644
--- a/templates/page-syslog.html
+++ b/templates/page-syslog.html
@@ -16,11 +16,11 @@
{{{pagenav}}}
<table class="table table-striped table-condensed">
<thead>
- <th></th>
+ <th width="1"></th>
<th>{{lang_when}}</th>
<th>{{lang_client}}</th>
<th>{{lang_event}}</th>
- <th>{{lang_details}}</th>
+ <th width="1">{{lang_details}}</th>
</thead>
<tbody>
{{#list}}
@@ -29,10 +29,10 @@
<td class="text-right" nowrap="nowrap">{{date}}</td>
<td>{{clientip}}</td>
<td>{{description}}</td>
- <td>{{#extra}}<a class="btn btn-default btn-xs pull-left" data-toggle="collapse" data-target="#extra{{logid}}">&raquo;</a>{{/extra}}</td>
- </tr>
- <tr class="collapse" id="extra{{logid}}">
- <td colspan="5"><pre>{{extra}}</pre></td>
+ <td>{{#extra}}
+ <a class="btn btn-default btn-xs pull-left" onclick="$('#details-body').html($('#extra-{{logid}}').html())" data-toggle="modal" data-target="#myModal">&raquo;</a>
+ <div class="hidden" id="extra-{{logid}}">{{extra}}</div>
+ {{/extra}}</td>
</tr>
{{/list}}
</tbody>
@@ -40,3 +40,21 @@
{{{pagenav}}}
</div>
+<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+ <div class="modal-dialog modal-lg">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
+ <h4 class="modal-title" id="myModalLabel">{{lang_details}}</h4>
+ </div>
+ <div class="modal-body">
+ <pre id="details-body"></pre>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+ </div>
+ </div>
+ </div>
+</div>
+
+