summaryrefslogtreecommitdiffstats
path: root/modules-available/dozmod
diff options
context:
space:
mode:
Diffstat (limited to 'modules-available/dozmod')
-rw-r--r--modules-available/dozmod/api.inc.php107
-rw-r--r--modules-available/dozmod/lang/de/messages.json10
-rw-r--r--modules-available/dozmod/lang/de/template-tags.json7
-rw-r--r--modules-available/dozmod/lang/en/template-tags.json7
-rw-r--r--modules-available/dozmod/page.inc.php6
-rw-r--r--modules-available/dozmod/pages/actionlog.inc.php8
-rw-r--r--modules-available/dozmod/pages/expiredimages.inc.php15
-rw-r--r--modules-available/dozmod/pages/mailconfig.inc.php2
-rw-r--r--modules-available/dozmod/pages/networkrules.inc.php2
-rw-r--r--modules-available/dozmod/pages/networkshares.inc.php2
-rw-r--r--modules-available/dozmod/pages/runscripts.inc.php4
-rw-r--r--modules-available/dozmod/pages/runtimeconfig.inc.php26
-rw-r--r--modules-available/dozmod/pages/special.inc.php4
-rw-r--r--modules-available/dozmod/pages/templates.inc.php2
-rw-r--r--modules-available/dozmod/pages/users.inc.php8
-rw-r--r--modules-available/dozmod/templates/runtimeconfig.html16
16 files changed, 140 insertions, 86 deletions
diff --git a/modules-available/dozmod/api.inc.php b/modules-available/dozmod/api.inc.php
index d9f7354c..b5030cc5 100644
--- a/modules-available/dozmod/api.inc.php
+++ b/modules-available/dozmod/api.inc.php
@@ -10,6 +10,8 @@
**/
+use JetBrains\PhpStorm\NoReturn;
+
if (!Module::isAvailable('locations')) {
die('require locations module');
}
@@ -17,27 +19,30 @@ if (!Module::isAvailable('locations')) {
define('LIST_URL', CONFIG_DOZMOD_URL . '/vmchooser/list');
define('VMX_URL', CONFIG_DOZMOD_URL . '/vmchooser/lecture');
-$availableRessources = ['list', 'vmx', 'netrules', 'runscript', 'metadata', 'netshares'];
+$availableRessources = ['list', 'netrules', 'metadata', 'imagemeta'];
/* BEGIN: A simple caching mechanism ---------------------------- */
-function cache_hash($obj)
+function cache_hash($obj): string
{
return md5(serialize($obj));
}
-function cache_key_to_filename($key)
+function cache_key_to_filename(string $key): string
{
return "/tmp/bwlp-slxadmin-cache-$key";
}
-function cache_put($key, $value)
+function cache_put(string $key, string $value): void
{
$filename = cache_key_to_filename($key);
- file_put_contents($filename, $value);
+ // Try to avoid another client concurrently accessing the cache seeing an empty file
+ $tmp = $filename . '-' . mt_rand();
+ file_put_contents($tmp, $value);
+ rename($tmp, $filename);
}
-function cache_has($key)
+function cache_has(string $key): bool
{
$filename = cache_key_to_filename($key);
$mtime = @filemtime($filename);
@@ -46,21 +51,18 @@ function cache_has($key)
return false; // cache miss
}
$now = time();
- if ($now < $mtime || $now - $mtime > CONFIG_DOZMOD_EXPIRE) {
- return false;
- } else {
- return true;
- }
+ return $now >= $mtime && $now - $mtime <= CONFIG_DOZMOD_EXPIRE;
}
-function cache_get($key)
+function cache_get(string $key): string
{
$filename = cache_key_to_filename($key);
return file_get_contents($filename);
}
/* good for large binary files */
-function cache_get_passthru($key)
+#[NoReturn]
+function cache_get_passthru(string $key): void
{
$filename = cache_key_to_filename($key);
$fp = fopen($filename, "r");
@@ -68,7 +70,7 @@ function cache_get_passthru($key)
fpassthru($fp);
exit;
}
- error_log('Cannot passthrough cache file ' . $filename);
+ error_log('DMSD-cache: Cannot passthrough cache file ' . $filename);
}
/* END: Cache ---------------------------------------------------- */
@@ -76,7 +78,7 @@ function cache_get_passthru($key)
/* this script requires 2 (3 with implicit client ip) parameters
*
-* resource = vmx,...
+* resource = list,metadata,...
* lecture_uuid = client can choose
**/
@@ -85,11 +87,16 @@ function cache_get_passthru($key)
* Takes raw lecture list xml, returns array of uuids.
*
* @param string $responseXML XML from dozmod server
- * @return array list of UUIDs, false on error
+ * @return array list of UUIDs
*/
-function xmlToLectureIds($responseXML)
+function xmlToLectureIds(string $responseXML): array
{
- $xml = new SimpleXMLElement($responseXML);
+ try {
+ $xml = new SimpleXMLElement($responseXML);
+ } catch (Exception $e) {
+ EventLog::warning('Error parsing XML response data from DMSD: ' . $e->getMessage(), $responseXML);
+ return [];
+ }
if (!isset($xml->eintrag))
return [];
@@ -102,7 +109,8 @@ function xmlToLectureIds($responseXML)
return $uuids;
}
-function sendExamModeMismatch()
+#[NoReturn]
+function sendExamModeMismatch(): void
{
Header('Content-Type: text/xml; charset=utf-8');
echo
@@ -112,8 +120,8 @@ function sendExamModeMismatch()
<image_name param="null"/>
<priority param="100"/>
<creator param="Ernie Esslingen"/>
- <short_description param="Klausurmodus geändert, bitte PC neustarten"/>
- <long_description param="Der Klausurmodus wurde ein- oder ausgeschaltet, bitte starten Sie den PC neu"/>
+ <short_description param="Prüfungsmodus geändert, bitte PC neustarten"/>
+ <long_description param="Der Prüfungsmodus wurde ein- oder ausgeschaltet, bitte starten Sie den PC neu"/>
<uuid param="exam-mode-warning"/>
<virtualmachine param="exam-mode-warning"/>
<os param="debian8"/>
@@ -142,7 +150,7 @@ BLA;
}
/** Caching wrapper around _getLecturesForLocations() */
-function getListForLocations($locationIds, $raw)
+function getListForLocations(array $locationIds, bool $raw)
{
/* if in any of the locations there is an exam active, consider the client
to be in "exam-mode" and only offer him exams (no lectures) */
@@ -179,7 +187,12 @@ function getListForLocations($locationIds, $raw)
if ($examMode) {
$url .= '&exams';
}
+ $t = microtime(true);
$value = Download::asString($url, 60, $code);
+ $t = microtime(true) - $t;
+ if ($t > 5) {
+ error_log("DMSD-cache: Download of lecture list took $t ($code)");
+ }
if ($value === false || $code < 200 || $code > 299)
return false;
cache_put($rawKey, $value);
@@ -191,30 +204,37 @@ function getListForLocations($locationIds, $raw)
return $list;
}
-function getLectureUuidsForLocations($locationIds)
+function getLectureUuidsForLocations(array $locationIds)
{
return getListForLocations($locationIds, false);
}
-function outputLectureXmlForLocation($locationIds)
+function outputLectureXmlForLocation(array $locationIds)
{
return getListForLocations($locationIds, true);
}
-function _getVmData($lecture_uuid, $subResource = false)
+function _getVmData(string $lecture_uuid, string $subResource = null)
{
$url = VMX_URL . '/' . $lecture_uuid;
- if ($subResource !== false) {
+ if ($subResource !== null) {
$url .= '/' . $subResource;
}
+ $t = microtime(true);
$response = Download::asString($url, 60, $code);
- if ($code < 200 || $code > 299)
+ $t = microtime(true) - $t;
+ if ($t > 5) {
+ error_log("DMSD-cache: Download of $subResource took $t ($code)");
+ }
+ if ($code < 200 || $code > 299) {
+ error_log("DMSD-cache: Return code $code, payload len " . strlen($response));
return (int)$code;
+ }
return $response;
}
/** Caching wrapper around _getVmData() **/
-function outputResource($lecture_uuid, $resource)
+function outputResource(string $lecture_uuid, string $resource): void
{
if ($resource === 'metadata') {
// HACK: config.tgz is compressed, don't use gzip output handler
@@ -235,7 +255,7 @@ function outputResource($lecture_uuid, $resource)
} else {
$value = _getVmData($lecture_uuid, $resource);
if ($value === false)
- return false;
+ return;
if (is_int($value)) {
http_response_code($value);
exit;
@@ -243,16 +263,16 @@ function outputResource($lecture_uuid, $resource)
cache_put($key, $value);
die($value);
}
- return false;
}
+#[NoReturn]
function fatalDozmodUnreachable()
{
Header('HTTP/1.1 504 Gateway Timeout');
die('DMSD currently not available');
}
-function readLectureParam($locationIds)
+function readLectureParam(array $locationIds): string
{
$lecture = Request::get('lecture', false, 'string');
if ($lecture === false) {
@@ -272,12 +292,26 @@ function readLectureParam($locationIds)
}
+// in this context the lecture param is an image id (container),
+// just read and check if valid.
+// TODO do we need to check if this is allowed?
+function readImageParam(): string
+{
+ $image = Request::get('lecture', false, 'string');
+
+ if ($image === false) {
+ Header('HTTP/1.1 400 Bad Request');
+ die('Missing IMAGE UUID');
+ }
+ return $image;
+}
+
// -----------------------------------------------------------------------------//
/* request data, don't trust */
$resource = Request::get('resource', false, 'string');
if ($resource === false) {
- Util::traceError("you have to specify the 'resource' parameter");
+ ErrorHandler::traceError("you have to specify the 'resource' parameter");
}
if (!in_array($resource, $availableRessources)) {
@@ -298,12 +332,11 @@ $location_ids = Location::getLocationRootChain($location_ids);
if ($resource === 'list') {
outputLectureXmlForLocation($location_ids);
// Won't return on success...
- fatalDozmodUnreachable();
+} elseif ($resource === 'imagemeta') {
+ $image = readImageParam();
+ outputResource($image, $resource);
} else {
$lecture = readLectureParam($location_ids);
outputResource($lecture, $resource);
- fatalDozmodUnreachable();
}
-
-Header('HTTP/1.1 400 Bad Request');
-die("I don't know how to give you that resource");
+fatalDozmodUnreachable();
diff --git a/modules-available/dozmod/lang/de/messages.json b/modules-available/dozmod/lang/de/messages.json
index 7eba0b2d..c904b0c8 100644
--- a/modules-available/dozmod/lang/de/messages.json
+++ b/modules-available/dozmod/lang/de/messages.json
@@ -1,28 +1,28 @@
{
"all-templates-reset": "Alle Templates wurden zur\u00fcckgesetzt",
- "dozmod-error": "Fehler bei der Kommunikation mit dem bwLehrpool-Suite server: {{0}}",
+ "dozmod-error": "Fehler bei der Kommunikation mit dem bwLehrpool-Suite Server: {{0}}",
"images-pending-delete-exist": "Zur L\u00f6schung markierte VM-Versionen: {{0}}",
"ldap-filter-created": "LDAP Filter wurde erfolgreich erstellt",
"ldap-filter-deleted": "LDAP Filter wurde erfolgreich gel\u00f6scht",
"ldap-filter-id-missing": "Fehlende LDAP Filter ID",
- "ldap-filter-insert-failed": "LDAP filter konnte der Datenbank nicht hinzugef\u00fcgt werden",
+ "ldap-filter-insert-failed": "LDAP Filter konnte der Datenbank nicht hinzugef\u00fcgt werden",
"ldap-filter-save-missing-information": "Es fehlen LDAP Filter Informationen",
"ldap-filter-saved": "LDAP Filter wurde erfolgreich gespeichert",
"ldap-invalid-filter-id": "Ung\u00fcltige LDAP Filter ID",
"mail-config-saved": "Mail-Konfiguration gespeichert",
- "networkrule-deleted": "Netzwerk-Regel gel\u00f6scht",
+ "networkrule-deleted": "Netzwerkregel gel\u00f6scht",
"networkrule-empty-set": "Leeres Regelset; nicht gespeichert",
"networkrule-invalid-direction": "Ung\u00fcltige Richtung: {{0}}",
"networkrule-invalid-host": "Ung\u00fcltiger Host: {{0}}; Zeile ignoriert",
"networkrule-invalid-port": "Ung\u00fcltiger Port: {{0}}; Zeile ignoriert",
"networkrule-invalid-ruleid": "Nicht-existierende Regel: {{0}}",
- "networkrule-saved": "Netzwerk-Regel gespeichert",
+ "networkrule-saved": "Netzwerkregel gespeichert",
"networkshare-deleted": "Netzlaufwerk gel\u00f6scht",
"networkshare-invalid-auth-type": "Ung\u00fcltiger Authentifizierungs-Typ: {{0}}",
"networkshare-invalid-shareid": "Nicht-existierender Share: {{0}}",
"networkshare-missing-path": "Fehlende Pfadangabe",
"networkshare-saved": "Netzlaufwerk gespeichert",
- "no-expired-images": "Keine Abgelaufenen VM-Versionen",
+ "no-expired-images": "Keine abgelaufenen VM-Versionen",
"nothing-submitted": "Es wurde nichts \u00fcbermittelt",
"runscript-deleted": "Skript gel\u00f6scht",
"runscript-invalid-id": "Ung\u00fcltige Skript-ID: {{0}}",
diff --git a/modules-available/dozmod/lang/de/template-tags.json b/modules-available/dozmod/lang/de/template-tags.json
index 39c37c08..338e8e42 100644
--- a/modules-available/dozmod/lang/de/template-tags.json
+++ b/modules-available/dozmod/lang/de/template-tags.json
@@ -5,6 +5,8 @@
"lang_addShare": "Netzlaufwerk hinzuf\u00fcgen",
"lang_allowLoginByDefault": "Login standardm\u00e4\u00dfig erlauben",
"lang_allowLoginDescription": "Wenn diese Option aktiviert ist, k\u00f6nnen sich alle Mitarbeiter der Einrichtung \u00fcber die bwLehrpool-Suite anmelden und VMs\/Veranstaltungen verwalten. Wenn Sie diese Option deaktivieren, m\u00fcssen Sie in der Untersektion \"Benutzer und Berechtigungen\" jeden Benutzer nach dem ersten Loginversuch manuell freischalten.",
+ "lang_allowStudentDownload": "Studenten den Download lizenzfreier VMs erlauben",
+ "lang_allowStudentDownloadDescription": "Wenn diese Option aktiviert ist, k\u00f6nnen Studenten alle VMs herunterladen, bei denen beim Upload der Haken \"enth\u00e4lt lizenzpflichtige Software\" nicht gesetzt wurde. Es liegt hier in der Verantwortung der VM-Ersteller, diesen Haken nur unter entsprechenden Umst\u00e4nden zu entfernen.",
"lang_asteriskRequired": "Felder mit (*) sind erforderlich",
"lang_authMethod": "Authentifizierung",
"lang_blockCount": "Anzahl Bl\u00f6cke",
@@ -14,7 +16,7 @@
"lang_confirmDeleteOrphanedFiles": "Sind Sie sicher, dass Sie alle aufgelisteten Dateien unwiderruflich vom VM-Store l\u00f6schen wollen?",
"lang_createTime": "Erstellt",
"lang_currentFilter": "Aktueller Filter",
- "lang_defaultImagePermissionAdmin": "Administrieren",
+ "lang_defaultImagePermissionAdmin": "Administration",
"lang_defaultImagePermissionDownload": "Download",
"lang_defaultImagePermissionEdit": "Bearbeiten",
"lang_defaultImagePermissionLink": "Veranstaltung verkn\u00fcpfen",
@@ -68,6 +70,7 @@
"lang_maxLectureVisibility": "Sp\u00e4testes Enddatum einer Veranstaltung (Tage in der Zukunft)",
"lang_maxLocationsPerLecture": "Max. explizite Orte pro Veranstaltung",
"lang_maxTransfers": "Maximale Zahl gleichzeitiger Up-\/Downloads pro Benutzer",
+ "lang_maxVmHddSizeGb": "Maximale VM-Gr\u00f6\u00dfe (GiB, 0 = kein Limit)",
"lang_minimized": "Minimiert",
"lang_miscOptions": "Verschiedene Einstellungen",
"lang_modified": "Modifiziert",
@@ -116,7 +119,7 @@
"lang_senderAddress": "Absenderadresse",
"lang_senderName": "Absender Anzeigename",
"lang_serverSideCopy": "Serverseitiges Kopieren",
- "lang_serverSideCopyDescription": "Wenn aktiviert, werden bei VM-Uploads solche Bl\u00f6cke, die bereits in anderen VM-Abbildern vorhanden sind, nicht erneut vom Client hochgeladen, sondern durch den Satelliten-Server vom verwendeten Fileserver gelesen und kopiert. Abh\u00e4ngig von der Netzwerkinfrastruktur und Hardwareausstattung des Fileservers kann dies den Uploadvorgang merklich beschleunigen. Da diese Funktion allerdings zus\u00e4tzliche I\/O-Last auf dem Fileserver erzeugt, ist ihre Verwendung u.U. nicht erw\u00fcnscht.",
+ "lang_serverSideCopyDescription": "Wenn aktiviert, werden bei VM-Uploads solche Bl\u00f6cke, die bereits in anderen VM-Abbildern vorhanden sind, nicht erneut vom Client hochgeladen, sondern durch den Satellitenserver vom verwendeten Fileserver gelesen und kopiert. Abh\u00e4ngig von der Netzwerkinfrastruktur und Hardwareausstattung des Fileservers kann dies den Uploadvorgang merklich beschleunigen. Da diese Funktion allerdings zus\u00e4tzliche I\/O-Last auf dem Fileserver erzeugt, ist ihre Verwendung u.U. nicht erw\u00fcnscht.",
"lang_shareDeleteConfirm": "Wollen Sie dieses Netzlaufwerk wirklich l\u00f6schen?",
"lang_size": "Gr\u00f6\u00dfe",
"lang_spaceWastedDuplication": "Potentiell durch mehrfach vorkommende Bl\u00f6cke belegter Speicherplatz",
diff --git a/modules-available/dozmod/lang/en/template-tags.json b/modules-available/dozmod/lang/en/template-tags.json
index b4a1d9e8..b741e03d 100644
--- a/modules-available/dozmod/lang/en/template-tags.json
+++ b/modules-available/dozmod/lang/en/template-tags.json
@@ -5,6 +5,8 @@
"lang_addShare": "Add Network Share",
"lang_allowLoginByDefault": "Allow all staff members to login and use the bwLehrpool-Suite",
"lang_allowLoginDescription": "If this option is enabled, all members of the organization marked as staff or employee are allowed to login to this server and manage VMs\/courses. Otherwise, new users need to be individually allowed access after their first login attempt by visiting the sub page \"users and permissions\" in this web interface.",
+ "lang_allowStudentDownload": "Allow students to download license-free VMs",
+ "lang_allowStudentDownloadDescription": "If enabled, students can download all VMs that don't have the \"contains software subject to licensing\" checkbox enabled (to be set when uploading a new VM). The author of a VM is responsible for only removing that checkbox for applicable VMs.",
"lang_asteriskRequired": "Fields marked with (*) are required",
"lang_authMethod": "Authentication",
"lang_blockCount": "Block count",
@@ -65,9 +67,10 @@
"lang_mailDescription": "Fill in the following fields if you want to notify tutors\/professors\/lecturers about expiring VMs and lectures. If you leave one of the required fields blank, the feature will be disabled.",
"lang_mailTemplates": "E-Mail Templates",
"lang_maxImageValidity": "New VM validity (days)",
- "lang_maxLectureVisibility": "Max time lecture end date may lie in the future (days)",
+ "lang_maxLectureVisibility": "Max. time lecture end date may lie in the future (days)",
"lang_maxLocationsPerLecture": "Max. explicit locations per lecture",
- "lang_maxTransfers": "Max concurrent transfers per user",
+ "lang_maxTransfers": "Max. concurrent transfers per user",
+ "lang_maxVmHddSizeGb": "Max. VM size (GiB, 0 = unlimited)",
"lang_minimized": "Minimized",
"lang_miscOptions": "Misc options",
"lang_modified": "modified",
diff --git a/modules-available/dozmod/page.inc.php b/modules-available/dozmod/page.inc.php
index cf6e4857..4a43d881 100644
--- a/modules-available/dozmod/page.inc.php
+++ b/modules-available/dozmod/page.inc.php
@@ -22,7 +22,7 @@ class Page_DozMod extends Page
break;
}
} elseif (!in_array($this->section, $this->validSections)) {
- Util::traceError('Invalid section: ' . $this->section);
+ ErrorHandler::traceError('Invalid section: ' . $this->section);
}
// Check permissions
User::assertPermission($this->section . '.*');
@@ -68,7 +68,7 @@ class Page_DozMod extends Page
/* add sub-menus */
foreach ($this->validSections as $section) {
if ($section !== 'special' && User::hasPermission($section . '.*')) {
- Dashboard::addSubmenu('?do=dozmod&section=' . $section, Dictionary::translate('submenu_' . $section, true));
+ Dashboard::addSubmenu('?do=dozmod&section=' . $section, Dictionary::translate('submenu_' . $section));
}
}
}
@@ -78,7 +78,6 @@ class Page_DozMod extends Page
/* different pages for different sections */
if ($this->haveSubPage !== false) {
SubPage::doRender();
- return;
}
}
@@ -90,7 +89,6 @@ class Page_DozMod extends Page
if ($this->haveSubPage !== false) {
SubPage::doAjax();
- return;
}
}
diff --git a/modules-available/dozmod/pages/actionlog.inc.php b/modules-available/dozmod/pages/actionlog.inc.php
index eaa5218c..182198c2 100644
--- a/modules-available/dozmod/pages/actionlog.inc.php
+++ b/modules-available/dozmod/pages/actionlog.inc.php
@@ -11,7 +11,7 @@ class SubPage
User::assertPermission("actionlog.view");
self::$action = Request::get('action', '', 'string');
if (self::$action !== '' && self::$action !== 'showtarget' && self::$action !== 'showuser') {
- Util::traceError('Invalid action for actionlog: "' . self::$action . '"');
+ ErrorHandler::traceError('Invalid action for actionlog: "' . self::$action . '"');
}
self::$uuid = Request::get('uuid', '', 'string');
}
@@ -92,7 +92,7 @@ class SubPage
return $desc;
}
- private static function addImageHeader()
+ private static function addImageHeader(): bool
{
$image = Database::queryFirst('SELECT o.userid AS ouserid, o.firstname AS ofirstname, o.lastname AS olastname,
u.userid AS uuserid, u.firstname AS ufirstname, u.lastname AS ulastname,
@@ -114,7 +114,7 @@ class SubPage
return $image !== false;
}
- private static function addLectureHeader()
+ private static function addLectureHeader(): bool
{
$lecture = Database::queryFirst('SELECT o.userid AS ouserid, o.firstname AS ofirstname, o.lastname AS olastname,
u.userid AS uuserid, u.firstname AS ufirstname, u.lastname AS ulastname,
@@ -144,7 +144,7 @@ class SubPage
// query action log
$res = Database::simpleQuery($query, $params);
$events = array();
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ foreach ($res as $row) {
$row['dateline_s'] = date('d.m.Y H:i', $row['dateline']);
if (isset($row['imgname'])) {
$row['targeturl'] = '?do=dozmod&section=actionlog&action=showtarget&uuid=' . $row['targetid'];
diff --git a/modules-available/dozmod/pages/expiredimages.inc.php b/modules-available/dozmod/pages/expiredimages.inc.php
index 3217ae1e..ab563273 100644
--- a/modules-available/dozmod/pages/expiredimages.inc.php
+++ b/modules-available/dozmod/pages/expiredimages.inc.php
@@ -8,7 +8,7 @@ class SubPage
}
- private static function loadExpiredImages()
+ private static function loadExpiredImages(): array
{
$res = Database::simpleQuery("SELECT b.displayname,
own.firstname, own.lastname, own.userid,
@@ -22,7 +22,7 @@ class SubPage
ORDER BY b.displayname ASC, v.createtime ASC");
$NOW = time();
$rows = array();
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ foreach ($res as $row) {
if ($row['latexptime'] > $NOW && $row['latdelstate'] === 'KEEP') {
$row['hasNewerClass'] = 'glyphicon-ok green';
$row['checked'] = 'checked';
@@ -43,14 +43,9 @@ class SubPage
public static function doRender()
{
$expiredImages = self::loadExpiredImages();
-
- if (empty($expiredImages)) {
- Message::addSuccess('no-expired-images');
- } else {
- $data = ['images' => $expiredImages];
- Permission::addGlobalTags($data['perm'], null, ['expiredimages.delete', 'orphaned.scan']);
- Render::addTemplate('images-delete', $data);
- }
+ $data = ['images' => $expiredImages];
+ Permission::addGlobalTags($data['perm'], null, ['expiredimages.delete', 'orphaned.scan']);
+ Render::addTemplate('images-delete', $data);
}
public static function doAjax()
diff --git a/modules-available/dozmod/pages/mailconfig.inc.php b/modules-available/dozmod/pages/mailconfig.inc.php
index 08205f2e..aa03a4d3 100644
--- a/modules-available/dozmod/pages/mailconfig.inc.php
+++ b/modules-available/dozmod/pages/mailconfig.inc.php
@@ -34,7 +34,7 @@ class SubPage
Util::redirect('?do=DozMod&section=mailconfig');
}
- private static function cleanMailArray()
+ private static function cleanMailArray(): array
{
$keys = array('host', 'port', 'ssl', 'senderAddress', 'replyTo', 'username', 'password', 'serverName');
$data = array();
diff --git a/modules-available/dozmod/pages/networkrules.inc.php b/modules-available/dozmod/pages/networkrules.inc.php
index 710e90a9..218b7b06 100644
--- a/modules-available/dozmod/pages/networkrules.inc.php
+++ b/modules-available/dozmod/pages/networkrules.inc.php
@@ -74,7 +74,7 @@ class SubPage
$res = Database::simpleQuery('SELECT ruleid, rulename, ruledata
FROM sat.presetnetworkrule ORDER BY rulename ASC');
$rows = array();
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ foreach ($res as $row) {
$rows[] = $row;
}
Render::addTemplate('networkrules', [
diff --git a/modules-available/dozmod/pages/networkshares.inc.php b/modules-available/dozmod/pages/networkshares.inc.php
index 659321b4..852a8c67 100644
--- a/modules-available/dozmod/pages/networkshares.inc.php
+++ b/modules-available/dozmod/pages/networkshares.inc.php
@@ -66,7 +66,7 @@ class SubPage
$res = Database::simpleQuery('SELECT shareid, sharename, sharedata, active
FROM sat.presetnetworkshare ORDER BY sharename ASC');
$rows = array();
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ foreach ($res as $row) {
$dec = json_decode($row['sharedata'], true);
if (!is_array($dec)) {
$dec = [];
diff --git a/modules-available/dozmod/pages/runscripts.inc.php b/modules-available/dozmod/pages/runscripts.inc.php
index 9e6062d4..5665ba83 100644
--- a/modules-available/dozmod/pages/runscripts.inc.php
+++ b/modules-available/dozmod/pages/runscripts.inc.php
@@ -98,7 +98,7 @@ class SubPage
FROM sat.presetrunscript
ORDER BY scriptname ASC');
$rows = [];
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ foreach ($res as $row) {
if ($row['visibility'] == 0) {
$row['visibility'] = 'eye-close';
} elseif ($row['visibility'] == 1) {
@@ -139,7 +139,7 @@ class SubPage
$res = Database::simpleQuery('SELECT o.osid, o.displayname, pxo.osid AS isvalid FROM sat.operatingsystem o
LEFT JOIN sat.presetrunscript_x_operatingsystem pxo ON (o.osid = pxo.osid AND pxo.runscriptid = :runscriptid)
ORDER BY o.displayname ASC', ['runscriptid' => $id]);
- while ($osrow = $res->fetch(PDO::FETCH_ASSOC)) {
+ foreach ($res as $osrow) {
$row['oslist'][] = [
'osid' => $osrow['osid'],
'displayname' => $osrow['displayname'],
diff --git a/modules-available/dozmod/pages/runtimeconfig.inc.php b/modules-available/dozmod/pages/runtimeconfig.inc.php
index ab8500f2..f5790e82 100644
--- a/modules-available/dozmod/pages/runtimeconfig.inc.php
+++ b/modules-available/dozmod/pages/runtimeconfig.inc.php
@@ -31,12 +31,13 @@ class SubPage
'maxTransfers' => array('min' => 1, 'max' => 10),
],
'bool' => [
- 'allowLoginByDefault' => array('default' => false)
+ 'allowLoginByDefault' => array('default' => false),
+ 'allowStudentDownload' => array('default' => false),
],
];
foreach ($params as $type => $list) {
foreach ($list as $field => $limits) {
- $default = isset($limits['default']) ? $limits['default'] : false;
+ $default = $limits['default'] ?? false;
$value = Request::post($field, $default, $type);
if (isset($limits['min']) && $value < $limits['min']) {
$value = $limits['min'];
@@ -52,6 +53,8 @@ class SubPage
if (!in_array($data['serverSideCopy'], ['OFF', 'ON', 'AUTO', 'USER'])) {
$data['serverSideCopy'] = 'OFF';
}
+ // VM size limit
+ $data['vmSizeLimit'] = ceil(max(0, Request::post('vmSizeLimit', '0', 'float') * 1024 * 1024 * 1024));
/* ensure types */
settype($data['defaultLecturePermissions']['edit'], 'boolean');
@@ -61,6 +64,7 @@ class SubPage
settype($data['defaultImagePermissions']['link'], 'boolean');
settype($data['defaultImagePermissions']['download'], 'boolean');
+ // Write to DB - java server app wil reload this periodically
$data = json_encode($data);
Database::exec('INSERT INTO sat.configuration (parameter, value)'
. ' VALUES (:param, :value)'
@@ -81,31 +85,35 @@ class SubPage
$runtimeConf = json_decode($runtimeConf['value'], true);
/* convert some value to corresponding "selected" texts */
- if ($runtimeConf['defaultLecturePermissions']['edit']) {
+ if ($runtimeConf['defaultLecturePermissions']['edit'] ?? false) {
$runtimeConf['defaultLecturePermissions']['edit'] = 'checked';
}
- if ($runtimeConf['defaultLecturePermissions']['admin']) {
+ if ($runtimeConf['defaultLecturePermissions']['admin'] ?? false) {
$runtimeConf['defaultLecturePermissions']['admin'] = 'checked';
}
- if ($runtimeConf['defaultImagePermissions']['edit']) {
+ if ($runtimeConf['defaultImagePermissions']['edit'] ?? false) {
$runtimeConf['defaultImagePermissions']['edit'] = 'checked';
}
- if ($runtimeConf['defaultImagePermissions']['admin']) {
+ if ($runtimeConf['defaultImagePermissions']['admin'] ?? false) {
$runtimeConf['defaultImagePermissions']['admin'] = 'checked';
}
- if ($runtimeConf['defaultImagePermissions']['link']) {
+ if ($runtimeConf['defaultImagePermissions']['link'] ?? false) {
$runtimeConf['defaultImagePermissions']['link'] = 'checked';
}
- if ($runtimeConf['defaultImagePermissions']['download']) {
+ if ($runtimeConf['defaultImagePermissions']['download'] ?? false) {
$runtimeConf['defaultImagePermissions']['download'] = 'checked';
}
- if ($runtimeConf['allowLoginByDefault']) {
+ if ($runtimeConf['allowLoginByDefault'] ?? false) {
$runtimeConf['allowLoginByDefault'] = 'checked';
}
+ if ($runtimeConf['allowStudentDownload'] ?? false) {
+ $runtimeConf['allowStudentDownload'] = 'checked';
+ }
if (isset($runtimeConf['serverSideCopy'])) {
$runtimeConf[$runtimeConf['serverSideCopy'] . '_selected'] = 'selected';
}
+ $runtimeConf['vmSizeLimit'] = ceil(($runtimeConf['vmSizeLimit'] ?? 0) / (1024 * 1024 * 1024));
}
$runtimeConf['allowedSave'] = User::hasPermission("runtimeconfig.save");
Render::addTemplate('runtimeconfig', $runtimeConf);
diff --git a/modules-available/dozmod/pages/special.inc.php b/modules-available/dozmod/pages/special.inc.php
index 5a532b51..d6ac53d6 100644
--- a/modules-available/dozmod/pages/special.inc.php
+++ b/modules-available/dozmod/pages/special.inc.php
@@ -15,7 +15,7 @@ class SubPage
. " GROUP BY blocksha1, blocksize HAVING blockcount > 1 ORDER BY blockcount DESC, blocksha1 ASC");
$data = array('hashes' => array());
$spaceWasted = 0;
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ foreach ($res as $row) {
$row['hash_hex'] = bin2hex($row['blocksha1']);
$row['blocksize_s'] = Util::readableFileSize($row['blocksize']);
$data['hashes'][] = $row;
@@ -57,7 +57,7 @@ class SubPage
die('Database error: ' . Database::lastError());
}
$data = array('rows' => array());
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ foreach ($res as $row) {
$row['createtime_s'] = date('d.m.Y H:i', $row['createtime']);
$row['filesize_s'] = Util::readableFileSize($row['filesize']);
$data['rows'][] = $row;
diff --git a/modules-available/dozmod/pages/templates.inc.php b/modules-available/dozmod/pages/templates.inc.php
index b857115f..b916e14c 100644
--- a/modules-available/dozmod/pages/templates.inc.php
+++ b/modules-available/dozmod/pages/templates.inc.php
@@ -69,7 +69,7 @@ class SubPage
]);
}
- private static function forcmp($string)
+ private static function forcmp(string $string): string
{
return trim(str_replace("\r\n", "\n", $string));
}
diff --git a/modules-available/dozmod/pages/users.inc.php b/modules-available/dozmod/pages/users.inc.php
index 50f0f763..fe00a71b 100644
--- a/modules-available/dozmod/pages/users.inc.php
+++ b/modules-available/dozmod/pages/users.inc.php
@@ -42,7 +42,7 @@ class SubPage
. ' LEFT JOIN sat.organization USING (organizationid)'
. ' ORDER BY lastname ASC, firstname ASC');
$rows = array();
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ foreach ($res as $row) {
settype($row['lastlogin'], 'int');
$row['canlogin'] = self::checked($row['canlogin']);
$row['issuperuser'] = self::checked($row['issuperuser']);
@@ -63,14 +63,14 @@ class SubPage
$res = Database::simpleQuery('SELECT organizationid, displayname, canlogin FROM sat.organization'
. ' ORDER BY displayname ASC');
$rows = array();
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $row['canlogin'] = self::checked($row['canlogin']);
+ foreach ($res as $row) {
+ $row['canlogin'] = self::checked((bool)$row['canlogin']);
$rows[] = $row;
}
Render::addTemplate('orglist', array('organizations' => $rows));
}
- private static function checked($val)
+ private static function checked(bool $val): string
{
if ($val)
return 'checked="checked"';
diff --git a/modules-available/dozmod/templates/runtimeconfig.html b/modules-available/dozmod/templates/runtimeconfig.html
index 44fb4106..1540042d 100644
--- a/modules-available/dozmod/templates/runtimeconfig.html
+++ b/modules-available/dozmod/templates/runtimeconfig.html
@@ -19,7 +19,7 @@
<div class="checkbox">
<input type="checkbox" name="defaultLecturePermissions[admin]" value="1" {{defaultLecturePermissions.admin}} id ="lecture_admin" class="form-control">
- <label for"lecture_admin">
+ <label for="lecture_admin">
{{lang_lecturePermissionAdmin}}
</label>
</div>
@@ -94,6 +94,12 @@
<input name="maxTransfers" class="form-control" type="number" value="{{maxTransfers}}" min="1" max="10" pattern="^\d+$">
</td>
</tr>
+ <tr class="input-group">
+ <td class="input-group-addon">{{lang_maxVmHddSizeGb}}</td>
+ <td>
+ <input name="vmSizeLimit" class="form-control" type="number" value="{{vmSizeLimit}}" min="0" max="65535" pattern="\d+">
+ </td>
+ </tr>
</table>
</fieldset>
<br>
@@ -107,6 +113,14 @@
<p><i>{{lang_allowLoginDescription}}</i></p>
</div>
<br>
+ <div class="checkbox">
+ <input type="checkbox" name="allowStudentDownload" value="1" {{allowStudentDownload}} id="allowStudentDownload" class="form-control">
+ <label for="allowStudentDownload">
+ {{lang_allowStudentDownload}}
+ </label>
+ <p><i>{{lang_allowStudentDownloadDescription}}</i></p>
+ </div>
+ <br>
<div>
<label for="serverSideCopy">
{{lang_serverSideCopy}}