From a8b0095b335780ae0bb950bc44021215d43a6b2d Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 12 Feb 2018 14:17:07 +0100 Subject: [permissionmanager] Introduce "location-aware" flag for permissions This flag tells wether the permission can be restricted to certain locations in a meaningful way. This flag has to be set in the permissions.json of the according module. For example, the permission to reboot the server cannot be limited to certain locations in a meaningful way, while the view of the client log can be filtered to only show log entries for clients in specific locations. --- .../dozmod/permissions/permissions.json | 52 ++++++++++++++++------ 1 file changed, 38 insertions(+), 14 deletions(-) (limited to 'modules-available/dozmod/permissions/permissions.json') diff --git a/modules-available/dozmod/permissions/permissions.json b/modules-available/dozmod/permissions/permissions.json index e8dfb558..b4ff034b 100644 --- a/modules-available/dozmod/permissions/permissions.json +++ b/modules-available/dozmod/permissions/permissions.json @@ -1,14 +1,38 @@ -[ - "images.delete", - "mail.save", - "mail.testmail", - "runtimeconfig.save", - "templates.save", - "templates.reset", - "users.setmail", - "users.setlogin", - "users.setsu", - "users.orglogin", - "log.showuser", - "log.showtarget" -] \ No newline at end of file +{ + "images.delete": { + "location-aware": false + }, + "log.showtarget": { + "location-aware": false + }, + "log.showuser": { + "location-aware": false + }, + "mail.save": { + "location-aware": false + }, + "mail.testmail": { + "location-aware": false + }, + "runtimeconfig.save": { + "location-aware": false + }, + "templates.reset": { + "location-aware": false + }, + "templates.save": { + "location-aware": false + }, + "users.orglogin": { + "location-aware": false + }, + "users.setlogin": { + "location-aware": false + }, + "users.setmail": { + "location-aware": false + }, + "users.setsu": { + "location-aware": false + } +} \ No newline at end of file -- cgit v1.2.3-55-g7522 From 59430e90b1b9334761d815aeb6e519effe7e5243 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 13 Feb 2018 17:52:52 +0100 Subject: [dozmod] Move subpages to pages/, hide pages where user has no permission --- modules-available/dozmod/inc/pagedozmodlog.inc.php | 163 ---------- .../dozmod/inc/pagedozmodusers.inc.php | 121 -------- .../dozmod/inc/pagemailtemplates.inc.php | 136 -------- modules-available/dozmod/lang/de/module.json | 2 +- modules-available/dozmod/lang/de/permissions.json | 24 +- modules-available/dozmod/lang/en/module.json | 2 +- modules-available/dozmod/lang/en/permissions.json | 24 +- modules-available/dozmod/page.inc.php | 341 +++------------------ modules-available/dozmod/pages/actionlog.inc.php | 168 ++++++++++ .../dozmod/pages/expiredimages.inc.php | 97 ++++++ modules-available/dozmod/pages/mailconfig.inc.php | 97 ++++++ .../dozmod/pages/runtimeconfig.inc.php | 112 +++++++ modules-available/dozmod/pages/templates.inc.php | 139 +++++++++ modules-available/dozmod/pages/users.inc.php | 121 ++++++++ .../dozmod/permissions/permissions.json | 12 +- .../dozmod/templates/images-delete.html | 1 + modules-available/dozmod/templates/mailconfig.html | 7 +- .../dozmod/templates/runtimeconfig.html | 1 + 18 files changed, 823 insertions(+), 745 deletions(-) delete mode 100644 modules-available/dozmod/inc/pagedozmodlog.inc.php delete mode 100644 modules-available/dozmod/inc/pagedozmodusers.inc.php delete mode 100644 modules-available/dozmod/inc/pagemailtemplates.inc.php create mode 100644 modules-available/dozmod/pages/actionlog.inc.php create mode 100644 modules-available/dozmod/pages/expiredimages.inc.php create mode 100644 modules-available/dozmod/pages/mailconfig.inc.php create mode 100644 modules-available/dozmod/pages/runtimeconfig.inc.php create mode 100644 modules-available/dozmod/pages/templates.inc.php create mode 100644 modules-available/dozmod/pages/users.inc.php (limited to 'modules-available/dozmod/permissions/permissions.json') diff --git a/modules-available/dozmod/inc/pagedozmodlog.inc.php b/modules-available/dozmod/inc/pagedozmodlog.inc.php deleted file mode 100644 index 80441cd1..00000000 --- a/modules-available/dozmod/inc/pagedozmodlog.inc.php +++ /dev/null @@ -1,163 +0,0 @@ -action = Request::get('action', '', 'string'); - if ($this->action !== '' && $this->action !== 'showtarget' && $this->action !== 'showuser') { - Util::traceError('Invalid action for actionlog: "' . $this->action . '"'); - } - $this->uuid = Request::get('uuid', '', 'string'); - } - - protected function doRender() - { - Render::addTemplate('actionlog-header'); - if ($this->action === '') { - $this->generateLog("SELECT al.dateline, al.targetid, al.description," - . " img.displayname AS imgname, tu.firstname AS tfirstname, tu.lastname AS tlastname, l.displayname AS lecturename," - . " al.userid AS uuserid, usr.firstname AS ufirstname, usr.lastname AS ulastname" - . " FROM sat.actionlog al" - . " LEFT JOIN sat.imagebase img ON (img.imagebaseid = targetid)" - . " LEFT JOIN sat.user usr ON (usr.userid = al.userid)" - . " LEFT JOIN sat.user tu ON (tu.userid = al.targetid)" - . " LEFT JOIN sat.lecture l ON (l.lectureid = targetid)" - . " ORDER BY al.dateline DESC LIMIT 500", array(), true, true); - } elseif ($this->action === 'showuser') { - if (User::hasPermission("log.showuser")) { - $this->listUser(); - } - } else { - if (User::hasPermission("log.showtarget")) { - $this->listTarget(); - } - } - } - - private function listUser() - { - // Query user - $user = Database::queryFirst('SELECT userid, firstname, lastname, email, lastlogin,' - . ' organization.displayname AS orgname FROM sat.user' - . ' LEFT JOIN sat.organization USING (organizationid)' - . ' WHERE userid = :uuid' - . ' LIMIT 1', array('uuid' => $this->uuid)); - if ($user === false) { - Message::addError('unknown-userid', $this->uuid); - Util::redirect('?do=dozmod§ion=actionlog'); - } - // Mangle date and render - $user['lastlogin_s'] = date('d.m.Y H:i', $user['lastlogin']); - Render::addTemplate('actionlog-user', $user); - // Finally add the actionlog - $this->generateLog("SELECT al.dateline, al.targetid, al.description," - . " img.displayname AS imgname, usr.firstname AS tfirstname, usr.lastname AS tlastname, l.displayname AS lecturename" - . " FROM sat.actionlog al" - . " LEFT JOIN sat.imagebase img ON (img.imagebaseid = targetid)" - . " LEFT JOIN sat.user usr ON (usr.userid = targetid)" - . " LEFT JOIN sat.lecture l ON (l.lectureid = targetid)" - . " WHERE al.userid = :uuid" - . " ORDER BY al.dateline DESC LIMIT 500", array('uuid' => $this->uuid), false, true); - } - - private function listTarget() - { - // We have to guess what kind of target it is - if (!$this->addImageHeader() - && !$this->addLectureHeader()) { - Message::addError('unknown-targetid', $this->uuid); - // Keep going, there might still be log entries for a deleted uuid - } - - // Finally add the actionlog - $this->generateLog("SELECT al.dateline, al.userid AS uuserid, al.description," - . " usr.firstname AS ufirstname, usr.lastname AS ulastname" - . " FROM sat.actionlog al" - . " LEFT JOIN sat.user usr ON (usr.userid = al.userid)" - . " WHERE al.targetid = :uuid" - . " ORDER BY al.dateline DESC LIMIT 500", array('uuid' => $this->uuid), true, false); - } - - private function addImageHeader() - { - $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,' - . ' img.displayname, img.description, img.createtime, img.updatetime,' - . ' os.displayname AS osname' - . ' FROM sat.imagebase img' - . ' LEFT JOIN sat.user o ON (img.ownerid = o.userid)' - . ' LEFT JOIN sat.user u ON (img.updaterid = u.userid)' - . ' LEFT JOIN sat.operatingsystem os ON (img.osid = os.osid)' - . ' WHERE img.imagebaseid = :uuid' - . ' LIMIT 1', array('uuid' => $this->uuid)); - if ($image !== false) { - // Mangle date and render - $image['createtime_s'] = date('d.m.Y H:i', $image['createtime']); - $image['updatetime_s'] = date('d.m.Y H:i', $image['updatetime']); - $image['descriptionHtml'] = nl2br(htmlspecialchars($image['description'])); - Render::addTemplate('actionlog-image', $image); - } - return $image !== false; - } - - private function addLectureHeader() - { - $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,' - . ' l.displayname, l.description, l.createtime, l.updatetime,' - . ' img.displayname AS imgname, img.imagebaseid' - . ' FROM sat.lecture l' - . ' LEFT JOIN sat.user o ON (l.ownerid = o.userid)' - . ' LEFT JOIN sat.user u ON (l.updaterid = u.userid)' - . ' LEFT JOIN sat.imageversion ver ON (ver.imageversionid = l.imageversionid)' - . ' LEFT JOIN sat.imagebase img ON (img.imagebaseid = ver.imagebaseid)' - . ' WHERE l.lectureid = :uuid' - . ' LIMIT 1', array('uuid' => $this->uuid)); - if ($lecture !== false) { - // Mangle date and render - $lecture['createtime_s'] = date('d.m.Y H:i', $lecture['createtime']); - $lecture['updatetime_s'] = date('d.m.Y H:i', $lecture['updatetime']); - $lecture['descriptionHtml'] = nl2br(htmlspecialchars($lecture['description'])); - Render::addTemplate('actionlog-lecture', $lecture); - } - return $lecture !== false; - } - - private function generateLog($query, $params, $showActor, $showTarget) - { - // query action log - $res = Database::simpleQuery($query, $params); - $events = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $row['dateline_s'] = date('d.m.Y H:i', $row['dateline']); - if (isset($row['imgname'])) { - $row['targeturl'] = '?do=dozmod§ion=actionlog&action=showtarget&uuid=' . $row['targetid']; - $row['targetname'] = $row['imgname']; - } elseif (isset($row['tlastname'])) { - $row['targeturl'] = '?do=dozmod§ion=actionlog&action=showuser&uuid=' . $row['targetid']; - $row['targetname'] = $row['tlastname'] . ', ' . $row['tfirstname']; - } elseif (isset($row['lecturename'])) { - $row['targeturl'] = '?do=dozmod§ion=actionlog&action=showtarget&uuid=' . $row['targetid']; - $row['targetname'] = $row['lecturename']; - } - $events[] = $row; - } - $data = array('events' => $events); - if ($showActor) { - $data['showActor'] = true; - } - if ($showTarget) { - $data['showTarget'] = true; - } - - $data['allowedShowUser'] = User::hasPermission("log.showuser"); - $data['allowedShowTarget'] = User::hasPermission("log.showtarget"); - Render::addTemplate('actionlog-log', $data); - } - -} \ No newline at end of file diff --git a/modules-available/dozmod/inc/pagedozmodusers.inc.php b/modules-available/dozmod/inc/pagedozmodusers.inc.php deleted file mode 100644 index f4ac852b..00000000 --- a/modules-available/dozmod/inc/pagedozmodusers.inc.php +++ /dev/null @@ -1,121 +0,0 @@ -listUsers(); - $this->listOrganizations(); - } - - protected function doAjax() - { - User::load(); - - $action = Request::post('action', '', 'string'); - if ($action === 'setmail' || $action === 'setsu' || $action == 'setlogin') { - if (User::hasPermission("users.".$action)) { - $this->setUserOption($action); - } - } elseif ($action === 'setorglogin') { - if (User::hasPermission("users.orglogin")) { - $this->setOrgOption($action); - } - } else { - die('No such action'); - } - } - - // Helpers - - private function listUsers() - { - $res = Database::simpleQuery('SELECT userid, firstname, lastname, email, lastlogin, user.canlogin, issuperuser, emailnotifications,' - . ' organization.displayname AS orgname FROM sat.user' - . ' LEFT JOIN sat.organization USING (organizationid)' - . ' ORDER BY lastname ASC, firstname ASC'); - $rows = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $row['canlogin'] = $this->checked($row['canlogin']); - $row['issuperuser'] = $this->checked($row['issuperuser']); - $row['emailnotifications'] = $this->checked($row['emailnotifications']); - $row['lastlogin'] = date('d.m.Y', $row['lastlogin']); - $rows[] = $row; - } - Render::addTemplate('userlist', array('users' => $rows)); - } - - private function listOrganizations() - { - $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'] = $this->checked($row['canlogin']); - $rows[] = $row; - } - Render::addTemplate('orglist', array('organizations' => $rows)); - } - - private function checked($val) - { - if ($val) - return 'checked="checked"'; - return ''; - } - - private function setUserOption($option) - { - $val = (string) Request::post('value', '-'); - if ($val !== '1' && $val !== '0') - die('Nein'); - if ($option === 'setmail') { - $field = 'emailnotifications'; - } elseif ($option === 'setsu') { - $field = 'issuperuser'; - } elseif ($option === 'setlogin') { - $field = 'canlogin'; - } else { - die('Unknown'); - } - $user = (string) Request::post('userid', '?'); - $ret = Database::exec("UPDATE sat.user SET $field = :onoff WHERE userid = :userid", array( - 'userid' => $user, - 'onoff' => $val - )); - error_log("Setting $field to $val for $user - affected: $ret"); - if ($ret === false) - die('Error'); - if ($ret === 0) - die(1 - $val); - die($val); - } - - private function setOrgOption($option) - { - $val = (string) Request::post('value', '-'); - if ($val !== '1' && $val !== '0') - die('Nein'); - if ($option === 'setorglogin') { - $field = 'canlogin'; - } else { - die('Unknown'); - } - $ret = Database::exec("UPDATE sat.organization SET $field = :onoff WHERE organizationid = :organizationid", array( - 'organizationid' => (string) Request::post('organizationid', ''), - 'onoff' => $val - )); - if ($ret === false) - die('Error'); - if ($ret === 0) - die(1 - $val); - die($val); - } - -} \ No newline at end of file diff --git a/modules-available/dozmod/inc/pagemailtemplates.inc.php b/modules-available/dozmod/inc/pagemailtemplates.inc.php deleted file mode 100644 index ff47977f..00000000 --- a/modules-available/dozmod/inc/pagemailtemplates.inc.php +++ /dev/null @@ -1,136 +0,0 @@ -fetchTemplates(); - } elseif ($action === 'save') { - if (User::hasPermission("templates.save")) { - $this->handleSave(); - } - } elseif ($action === 'reset') { - if(User::hasPermission("templates.reset")) { - $this->handleReset(); - } - } else { - Message::addError('main.invalid-action', $action); - Util::redirect('?do=dozmod§ion=templates'); - } - } - - private function enrichHtml() { - /* for each template */ - foreach ($this->templates as &$t) { - $lis = ""; - $optManVars = ""; - $optVars = ""; - foreach ($t['mandatory_variables'] as $var) { - $optManVars .= ""; - $lis .= "
  • $var
  • "; - } - foreach($t['optional_variables'] as $var) { - $optVars .= ""; - $lis .= "
  • $var
  • "; - } - /* also options for hidden inputs */ - - $t['html_availableVariables'] = $lis; - $t['html_mandatoryVariables'] = $optManVars; - $t['html_optionalVariables'] = $optVars; - - /* also for javascript */ - $t['list_mandatoryVariables'] = - implode(',', $t['mandatory_variables']); - - $t['list_optionalVariables'] = - implode(',', $t['optional_variables']); - - settype($t['original'], 'bool'); - settype($t['edit_version'], 'int'); - settype($t['version'], 'int'); - $t['modified'] = !$t['original']; - $t['conflict'] = !$t['original'] && $t['edit_version'] < $t['version']; - } - } - - protected function doRender() - { - $this->enrichHtml(); - Render::addTemplate('templates', [ - 'templates' => $this->templates, - 'allowedReset' => User::hasPermission("templates.reset"), - 'allowedSave' => User::hasPermission("templates.save"), - ]); - } - - private function forcmp($string) - { - return trim(str_replace("\r\n", "\n", $string)); - } - - private function handleSave() - { - $data = Request::post('templates'); - if (is_array($data)) { - $this->fetchTemplates(); - foreach ($this->templates as &$template) { - if (isset($data[$template['name']])) { - if ($this->forcmp($template['template']) !== $this->forcmp($data[$template['name']]['template'])) { - if (empty($template['original_template'])) { - $template['original_template'] = $template['template']; - } - $template['edit_version'] = $template['version']; - } - $template['original'] = (empty($template['original_template']) && $template['original']) - || $this->forcmp($template['original_template']) === $this->forcmp($data[$template['name']]['template']); - if ($template['original']) { - $template['original_template'] = ''; - } - $template['template'] = $data[$template['name']]['template']; - } - } - unset($template); - $data = json_encode(array('templates' => $this->templates)); - Database::exec("UPDATE sat.configuration SET value = :value WHERE parameter = 'templates'", array('value' => $data)); - Message::addSuccess('templates-saved'); - } else { - Message::addError('nothing-submitted'); - } - Util::redirect('?do=dozmod§ion=templates'); - } - - private function handleReset() - { - $result = Download::asStringPost('http://127.0.0.1:9080/do/reset-mail-templates', array(), 10, $code); - if ($code == 999) { - Message::addError('timeout'); - } elseif ($code != 200) { - Message::addError('dozmod-error', $code); - } else { - Message::addSuccess('all-templates-reset', $result); - } - Util::redirect('?do=dozmod§ion=templates'); - } - - private function fetchTemplates() { - $templates= Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'templates')); - if ($templates != null) { - $templates = @json_decode($templates['value'], true); - if (is_array($templates)) { - $names = array_map(function ($e) { return $e['name']; }, $templates['templates']); - array_multisort($names, SORT_ASC, $templates['templates']); - $this->templates = $templates['templates']; - } - } - - } - -} diff --git a/modules-available/dozmod/lang/de/module.json b/modules-available/dozmod/lang/de/module.json index 02e8c84d..c9acd4ee 100644 --- a/modules-available/dozmod/lang/de/module.json +++ b/modules-available/dozmod/lang/de/module.json @@ -4,7 +4,7 @@ "submenu_actionlog": "Aktions-Log", "submenu_expiredimages": "Abgelaufene VM-Versionen", "submenu_mailconfig": "Email-Konfiguration", - "submenu_runtime": "Limits und Standardwerte", + "submenu_runtimeconfig": "Limits und Standardwerte", "submenu_templates": "Textbausteine f\u00fcr E-Mails", "submenu_users": "Benutzer und Berechtigungen" } \ No newline at end of file diff --git a/modules-available/dozmod/lang/de/permissions.json b/modules-available/dozmod/lang/de/permissions.json index 07158a1d..9c5af91d 100644 --- a/modules-available/dozmod/lang/de/permissions.json +++ b/modules-available/dozmod/lang/de/permissions.json @@ -1,14 +1,14 @@ { - "images.delete": "Zur Löschung vorgemerkete Abbilder löschen.", - "mail.save": "Änderungen an der SMTP-Konfiguration zum Versenden von Mails speichern.", - "mail.testmail": "Eine Test E-Mail verschicken.", - "runtimeconfig.save": "Änderungen an der Laufzeit-Konfiguration speichern.", - "templates.save": "E-Mail Templates speichern.", - "templates.reset": "E-Mail Templates zurücksetzen.", - "users.setmail": "E-Mail Benachrichtigungen für einzelne Benutzer aktivieren/deaktivieren.", - "users.setlogin": "Anmeldungen für einzelne Benutzer aktivieren/deaktivieren.", - "users.setsu": "Benutzer zu SuperUser ernennen.", - "users.orglogin": "Anmeldungen für Benutzer von bestimmten Einrichtungen aktivieren/deaktivieren.", - "log.showuser": "User Data im Aktions-Log anzeigen.", - "log.showtarget": "Target Data im Aktions-Log anzeigen." + "actionlog.showtarget": "Target Data im Aktions-Log anzeigen.", + "actionlog.showuser": "User Data im Aktions-Log anzeigen.", + "expiredimages.delete": "Zur L\u00f6schung vorgemerkete Abbilder l\u00f6schen.", + "mailconfig.save": "\u00c4nderungen an der SMTP-Konfiguration zum Versenden von Mails speichern.", + "mailconfig.testmail": "Eine Test E-Mail verschicken.", + "runtimeconfig.save": "\u00c4nderungen an der Laufzeit-Konfiguration speichern.", + "templates.reset": "E-Mail Templates zur\u00fccksetzen.", + "templates.save": "E-Mail Templates speichern.", + "users.setorglogin": "Anmeldungen f\u00fcr Benutzer von bestimmten Einrichtungen aktivieren\/deaktivieren.", + "users.setlogin": "Anmeldungen f\u00fcr einzelne Benutzer aktivieren\/deaktivieren.", + "users.setmail": "E-Mail Benachrichtigungen f\u00fcr einzelne Benutzer aktivieren\/deaktivieren.", + "users.setsu": "Benutzer zu SuperUser ernennen." } \ No newline at end of file diff --git a/modules-available/dozmod/lang/en/module.json b/modules-available/dozmod/lang/en/module.json index 17a2b838..b7a04762 100644 --- a/modules-available/dozmod/lang/en/module.json +++ b/modules-available/dozmod/lang/en/module.json @@ -4,7 +4,7 @@ "submenu_actionlog": "action log", "submenu_expiredimages": "Expired VM versions", "submenu_mailconfig": "email configuration", - "submenu_runtime": "limits and defaults", + "submenu_runtimeconfig": "limits and defaults", "submenu_templates": "templates", "submenu_users": "users and permissions" } \ No newline at end of file diff --git a/modules-available/dozmod/lang/en/permissions.json b/modules-available/dozmod/lang/en/permissions.json index 923a8461..a86cf155 100644 --- a/modules-available/dozmod/lang/en/permissions.json +++ b/modules-available/dozmod/lang/en/permissions.json @@ -1,14 +1,14 @@ { - "images.delete": "Delete images marked for deletion.", - "mail.save": "Save SMTP configuration for sending mails.", - "mail.testmail": "Send a testmail.", - "runtimeconfig.save": "Save limits and defaults of a runtime configuration.", - "templates.save": "Save email templates.", - "templates.reset": "Reset email templates.", - "users.setmail": "Enable/Disable Email Notification.", - "users.setlogin": "Enable/Disable Login.", - "users.setsu": "Set User to superuser.", - "users.orglogin": "Enalbe/Disable Login for Users from certain organisations.", - "log.showuser": "Show User Data in Log.", - "log.showtarget": "Show Target Data in Log." + "actionlog.showtarget": "Show Target Data in Log.", + "actionlog.showuser": "Show User Data in Log.", + "expiredimages.delete": "Delete images marked for deletion.", + "mailconfig.save": "Save SMTP configuration for sending mails.", + "mailconfig.testmail": "Send a testmail.", + "runtimeconfig.save": "Save limits and defaults of a runtime configuration.", + "templates.reset": "Reset email templates.", + "templates.save": "Save email templates.", + "users.setorglogin": "Enalbe\/Disable Login for Users from certain organisations.", + "users.setlogin": "Enable\/Disable Login.", + "users.setmail": "Enable\/Disable Email Notification.", + "users.setsu": "Set User to superuser." } \ No newline at end of file diff --git a/modules-available/dozmod/page.inc.php b/modules-available/dozmod/page.inc.php index b58d57aa..a8e0da0e 100644 --- a/modules-available/dozmod/page.inc.php +++ b/modules-available/dozmod/page.inc.php @@ -2,25 +2,37 @@ class Page_DozMod extends Page { - /** @var \Page sub page classes */ - private $subPage = false; + /** @var bool true if we have a proper subpage */ + private $haveSubPage = false; + + private $validSections = ['expiredimages', 'mailconfig', 'templates', 'runtimeconfig', 'users', 'actionlog']; + + private $section; private function setupSubPage() { - if ($this->subPage !== false) + if ($this->haveSubPage !== false) return; /* different pages for different sections */ - $section = Request::any('section', 'mailconfig', 'string'); - /* instantiate sub pages */ - if ($section === 'templates') { - $this->subPage = new Page_mail_templates(); - } - if ($section === 'users') { - $this->subPage = new Page_dozmod_users(); - } - if ($section === 'actionlog') { - $this->subPage = new Page_dozmod_log(); - } + $this->section = Request::any('section', false, 'string'); + if ($this->section === 'blockstats') // HACK HACK + return; + if ($this->section === false) { + foreach ($this->validSections as $this->section) { + if (User::hasPermission($this->section . '.*')) + break; + } + } elseif (!in_array($this->section, $this->validSections)) { + Util::traceError('Invalid section: ' . $this->section); + } + // Check permissions + User::assertPermission($this->section . '.*'); + $include = 'modules/' . Page::getModule()->getIdentifier() . '/pages/' . $this->section . '.inc.php'; + if (!file_exists($include)) + return; + + require_once $include; + $this->haveSubPage = true; } protected function doPreprocess() @@ -32,117 +44,41 @@ class Page_DozMod extends Page Util::redirect('?do=Main'); } - /* add sub-menus */ - Dashboard::addSubmenu('?do=dozmod§ion=expiredimages', Dictionary::translate('submenu_expiredimages', true)); - Dashboard::addSubmenu('?do=dozmod§ion=mailconfig', Dictionary::translate('submenu_mailconfig', true)); - Dashboard::addSubmenu('?do=dozmod§ion=templates', Dictionary::translate('submenu_templates', true)); - Dashboard::addSubmenu('?do=dozmod§ion=runtimeconfig', Dictionary::translate('submenu_runtime', true)); - Dashboard::addSubmenu('?do=dozmod§ion=users', Dictionary::translate('submenu_users', true)); - Dashboard::addSubmenu('?do=dozmod§ion=actionlog', Dictionary::translate('submenu_actionlog', true)); - $this->setupSubPage(); - if ($this->subPage !== false) { - $this->subPage->doPreprocess(); - return; + if ($this->haveSubPage !== false) { + SubPage::doPreprocess(); + } + // Catch unhandled POST redirect + if (Request::isPost()) { + Util::redirect('?do=dozmod§ion=' . $this->section); } - /* execute actions */ - $action = Request::post('action', false, 'string'); + /* Leave this here for translation module + Dictionary::translate('submenu_expiredimages', true); + Dictionary::translate('submenu_mailconfig', true); + Dictionary::translate('submenu_templates', true); + Dictionary::translate('submenu_runtimeconfig', true); + Dictionary::translate('submenu_users', true); + Dictionary::translate('submenu_actionlog', true); + */ - if ($action === 'mail') { - if (User::hasPermission("mail.save")) { - $this->mailHandler(); - } - } elseif ($action === 'runtime') { - if (User::hasPermission("runtimeconfig.save")) { - $this->runtimeHandler(); - } - } elseif ($action === 'delimages') { - if (User::hasPermission("images.delete")) { - $result = $this->handleDeleteImages(); - if (!empty($result)) { - Message::addInfo('delete-images', $result); - } - Util::redirect('?do=DozMod'); + /* add sub-menus */ + foreach ($this->validSections as $section) { + if (User::hasPermission($section . '.*')) { + Dashboard::addSubmenu('?do=dozmod§ion=' . $section, Dictionary::translate('submenu_' . $section, true)); } - } elseif ($action !== false) { - Util::traceError('Invalid action: ' . $action); } } protected function doRender() { /* different pages for different sections */ - if ($this->subPage !== false) { - $this->subPage->doRender(); + if ($this->haveSubPage !== false) { + SubPage::doRender(); return; } - $section = Request::get('section', false, 'string'); - - if ($section === false || $section === 'expiredimages') { - $expiredImages = $this->loadExpiredImages(); - if ($section === false && empty($expiredImages)) { - $section = 'mailconfig'; - } else { - $section = 'expiredimages'; - } - } - - if ($section === 'expiredimages') { - if (empty($expiredImages)) { - Message::addSuccess('no-expired-images'); - } else { - Render::addTemplate('images-delete', array('images' => $expiredImages, 'allowedDelete' => User::hasPermission("images.delete"))); - } - } - if ($section === 'mailconfig') { - // Mail config - $mailConf = Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'mailconfig')); - if ($mailConf != null) { - $mailConf = @json_decode($mailConf['value'], true); - if (is_array($mailConf)) { - $mailConf['set_' . $mailConf['ssl']] = 'selected="selected"'; - } - } - $mailConf['allowedSave'] = User::hasPermission('mail.save'); - $mailConf['allowedTest'] = User::hasPermission('mail.testmail'); - Render::addTemplate('mailconfig', $mailConf); - } - if ($section === 'runtimeconfig') { - // Runtime config - $runtimeConf = Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'runtimelimits')); - if ($runtimeConf !== false) { - $runtimeConf = json_decode($runtimeConf['value'], true); - - /* convert some value to corresponding "selected" texts */ - if ($runtimeConf['defaultLecturePermissions']['edit']) { - $runtimeConf['defaultLecturePermissions']['edit'] = 'checked'; - } - if ($runtimeConf['defaultLecturePermissions']['admin']) { - $runtimeConf['defaultLecturePermissions']['admin'] = 'checked'; - } - if ($runtimeConf['defaultImagePermissions']['edit']) { - $runtimeConf['defaultImagePermissions']['edit'] = 'checked'; - } - if ($runtimeConf['defaultImagePermissions']['admin']) { - $runtimeConf['defaultImagePermissions']['admin'] = 'checked'; - } - if ($runtimeConf['defaultImagePermissions']['link']) { - $runtimeConf['defaultImagePermissions']['link'] = 'checked'; - } - if ($runtimeConf['defaultImagePermissions']['download']) { - $runtimeConf['defaultImagePermissions']['download'] = 'checked'; - } - - if ($runtimeConf['allowLoginByDefault']) { - $runtimeConf['allowLoginByDefault'] = 'checked'; - } - } - $runtimeConf['allowedSave'] = User::hasPermission("runtimeconfig.save"); - Render::addTemplate('runtimeconfig', $runtimeConf); - } - if ($section === 'blockstats') { + if ($this->section === 'blockstats') { $this->showBlockStats(); } @@ -164,73 +100,19 @@ class Page_DozMod extends Page Render::addTemplate('blockstats', $data); } - private function loadExpiredImages() - { - $res = Database::simpleQuery("SELECT b.displayname," - . " own.firstname, own.lastname, own.email," - . " v.imageversionid, v.createtime, v.filesize, v.deletestate," - . " lat.expiretime AS latexptime, lat.deletestate AS latdelstate" - . " FROM sat.imageversion v" - . " INNER JOIN sat.imagebase b ON (b.imagebaseid = v.imagebaseid)" - . " INNER JOIN sat.user own ON (b.ownerid = own.userid)" - . " LEFT JOIN sat.imageversion lat ON (b.latestversionid = lat.imageversionid)" - . " WHERE v.deletestate <> 'KEEP'" - . " ORDER BY b.displayname ASC, v.createtime ASC"); - $NOW = time(); - $rows = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - if ($row['latexptime'] > $NOW && $row['latdelstate'] === 'KEEP') { - $row['hasNewerClass'] = 'glyphicon-ok green'; - $row['checked'] = 'checked'; - } else { - $row['hasNewerClass'] = 'glyphicon-remove red'; - } - if ($row['deletestate'] === 'WANT_DELETE') { - $row['name_extra_class'] = 'slx-strike'; - } - $row['version'] = date('d.m.Y H:i:s', $row['createtime']); - $row['rawfilesize'] = $row['filesize']; - $row['filesize'] = Util::readableFileSize($row['filesize']); - $rows[] = $row; - } - return $rows; - } - - private function cleanMailArray() - { - $keys = array('host', 'port', 'ssl', 'senderAddress', 'replyTo', 'username', 'password', 'serverName'); - $data = array(); - foreach ($keys as $key) { - $data[$key] = Request::post($key, ''); - settype($data[$key], 'string'); - if (is_numeric($data[$key])) { - settype($data[$key], 'int'); - } - } - return $data; - } - protected function doAjax() { User::load(); - $this->setupSubPage(); - if ($this->subPage !== false) { - $this->subPage->doAjax(); + + if ($this->haveSubPage !== false) { + SubPage::doAjax(); return; } $action = Request::post('action'); - if ($action === 'mail') { - if (User::hasPermission("mail.testmail")) { - $this->handleTestMail(); - } - } elseif ($action === 'delimages') { - if (User::hasPermission("images.delete")) { - die($this->handleDeleteImages()); - } - } elseif ($action === 'getblockinfo') { + if ($action === 'getblockinfo') { $this->ajaxGetBlockInfo(); } } @@ -264,125 +146,4 @@ class Page_DozMod extends Page die(Render::parse('blockstats-details', $data)); } - private function handleDeleteImages() - { - $images = Request::post('images', false); - if (is_array($images)) { - foreach ($images as $image => $val) { - if (strtolower($val) !== 'on') - continue; - Database::exec("UPDATE sat.imageversion SET deletestate = 'WANT_DELETE'" - . " WHERE deletestate = 'SHOULD_DELETE' AND imageversionid = :imageversionid", array( - 'imageversionid' => $image - )); - } - if (!empty($images)) { - $ret = Download::asStringPost('http://127.0.0.1:9080/do/delete-images', false, 10, $code); - if ($code == 999) { - $ret .= "\nConnection to DMSD failed."; - } - return $ret; - } - } - return false; - } - - private function handleTestMail() - { - $do = Request::post('button'); - if ($do === 'test') { - // Prepare array - $data = $this->cleanMailArray(); - Header('Content-Type: text/plain; charset=utf-8'); - $data['recipient'] = Request::post('recipient', ''); - if (!preg_match('/.+@.+\..+/', $data['recipient'])) { - $result = 'No recipient given!'; - } else { - $result = Download::asStringPost('http://127.0.0.1:9080/do/mailtest', $data, 10, $code); - if ($code == 999) { - $result .= "\nTimeout."; - } elseif ($code != 200) { - $result .= "\nReturn code $code"; - } - } - die($result); - } - } - - private function mailHandler() - { - // Check action - $do = Request::post('button'); - if ($do === 'save') { - // Prepare array - $data = $this->cleanMailArray(); - $data = json_encode($data); - Database::exec('INSERT INTO sat.configuration (parameter, value)' - . ' VALUES (:param, :value)' - . ' ON DUPLICATE KEY UPDATE value = VALUES(value)', array( - 'param' => 'mailconfig', - 'value' => $data - )); - Message::addSuccess('mail-config-saved'); - } else { - Message::addError('main.invalid-action', $do); - } - Util::redirect('?do=DozMod§ion=mailconfig'); - } - - private function runtimeHandler() - { - // Check action - $do = Request::post('button'); - if ($do === 'save') { - $data = []; - $data['defaultLecturePermissions'] = Request::post('defaultLecturePermissions', NULL, "array"); - $data['defaultImagePermissions'] = Request::post('defaultImagePermissions', NULL, "array"); - - $params = [ - 'int' => [ - 'maxImageValidityDays' => array('min' => 7, 'max' => 9999), - 'maxLectureValidityDays' => array('min' => 7, 'max' => 9999), - 'maxLocationsPerLecture' => array('min' => 0, 'max' => 999), - 'maxTransfers' => array('min' => 1, 'max' => 10), - ], - 'bool' => [ - 'allowLoginByDefault' => array('default' => true) - ], - ]; - foreach ($params as $type => $list) { - foreach ($list as $field => $limits) { - $default = isset($limits['default']) ? $limits['default'] : false; - $value = Request::post($field, $default); - settype($value, $type); - if (isset($limits['min']) && $value < $limits['min']) { - $value = $limits['min']; - } - if (isset($limits['max']) && $value > $limits['max']) { - $value = $limits['max']; - } - $data[$field] = $value; - } - } - - /* ensure types */ - settype($data['defaultLecturePermissions']['edit'], 'boolean'); - settype($data['defaultLecturePermissions']['admin'], 'boolean'); - settype($data['defaultImagePermissions']['edit'], 'boolean'); - settype($data['defaultImagePermissions']['admin'], 'boolean'); - settype($data['defaultImagePermissions']['link'], 'boolean'); - settype($data['defaultImagePermissions']['download'], 'boolean'); - - $data = json_encode($data); - Database::exec('INSERT INTO sat.configuration (parameter, value)' - . ' VALUES (:param, :value)' - . ' ON DUPLICATE KEY UPDATE value = VALUES(value)', array( - 'param' => 'runtimelimits', - 'value' => $data - )); - Message::addSuccess('runtimelimits-config-saved'); - } - Util::redirect('?do=DozMod§ion=runtimeconfig'); - } - } diff --git a/modules-available/dozmod/pages/actionlog.inc.php b/modules-available/dozmod/pages/actionlog.inc.php new file mode 100644 index 00000000..6cbd2868 --- /dev/null +++ b/modules-available/dozmod/pages/actionlog.inc.php @@ -0,0 +1,168 @@ + self::$uuid)); + if ($user === false) { + Message::addError('unknown-userid', self::$uuid); + Util::redirect('?do=dozmod§ion=actionlog'); + } + // Mangle date and render + $user['lastlogin_s'] = date('d.m.Y H:i', $user['lastlogin']); + Render::addTemplate('actionlog-user', $user); + // Finally add the actionlog + self::generateLog("SELECT al.dateline, al.targetid, al.description," + . " img.displayname AS imgname, usr.firstname AS tfirstname, usr.lastname AS tlastname, l.displayname AS lecturename" + . " FROM sat.actionlog al" + . " LEFT JOIN sat.imagebase img ON (img.imagebaseid = targetid)" + . " LEFT JOIN sat.user usr ON (usr.userid = targetid)" + . " LEFT JOIN sat.lecture l ON (l.lectureid = targetid)" + . " WHERE al.userid = :uuid" + . " ORDER BY al.dateline DESC LIMIT 500", array('uuid' => self::$uuid), false, true); + } + + private static function listTarget() + { + // We have to guess what kind of target it is + if (!self::addImageHeader() + && !self::addLectureHeader()) { + Message::addError('unknown-targetid', self::$uuid); + // Keep going, there might still be log entries for a deleted uuid + } + + // Finally add the actionlog + self::generateLog("SELECT al.dateline, al.userid AS uuserid, al.description," + . " usr.firstname AS ufirstname, usr.lastname AS ulastname" + . " FROM sat.actionlog al" + . " LEFT JOIN sat.user usr ON (usr.userid = al.userid)" + . " WHERE al.targetid = :uuid" + . " ORDER BY al.dateline DESC LIMIT 500", array('uuid' => self::$uuid), true, false); + } + + private static function addImageHeader() + { + $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,' + . ' img.displayname, img.description, img.createtime, img.updatetime,' + . ' os.displayname AS osname' + . ' FROM sat.imagebase img' + . ' LEFT JOIN sat.user o ON (img.ownerid = o.userid)' + . ' LEFT JOIN sat.user u ON (img.updaterid = u.userid)' + . ' LEFT JOIN sat.operatingsystem os ON (img.osid = os.osid)' + . ' WHERE img.imagebaseid = :uuid' + . ' LIMIT 1', array('uuid' => self::$uuid)); + if ($image !== false) { + // Mangle date and render + $image['createtime_s'] = date('d.m.Y H:i', $image['createtime']); + $image['updatetime_s'] = date('d.m.Y H:i', $image['updatetime']); + $image['descriptionHtml'] = nl2br(htmlspecialchars($image['description'])); + Render::addTemplate('actionlog-image', $image); + } + return $image !== false; + } + + private static function addLectureHeader() + { + $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,' + . ' l.displayname, l.description, l.createtime, l.updatetime,' + . ' img.displayname AS imgname, img.imagebaseid' + . ' FROM sat.lecture l' + . ' LEFT JOIN sat.user o ON (l.ownerid = o.userid)' + . ' LEFT JOIN sat.user u ON (l.updaterid = u.userid)' + . ' LEFT JOIN sat.imageversion ver ON (ver.imageversionid = l.imageversionid)' + . ' LEFT JOIN sat.imagebase img ON (img.imagebaseid = ver.imagebaseid)' + . ' WHERE l.lectureid = :uuid' + . ' LIMIT 1', array('uuid' => self::$uuid)); + if ($lecture !== false) { + // Mangle date and render + $lecture['createtime_s'] = date('d.m.Y H:i', $lecture['createtime']); + $lecture['updatetime_s'] = date('d.m.Y H:i', $lecture['updatetime']); + $lecture['descriptionHtml'] = nl2br(htmlspecialchars($lecture['description'])); + Render::addTemplate('actionlog-lecture', $lecture); + } + return $lecture !== false; + } + + private static function generateLog($query, $params, $showActor, $showTarget) + { + // query action log + $res = Database::simpleQuery($query, $params); + $events = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $row['dateline_s'] = date('d.m.Y H:i', $row['dateline']); + if (isset($row['imgname'])) { + $row['targeturl'] = '?do=dozmod§ion=actionlog&action=showtarget&uuid=' . $row['targetid']; + $row['targetname'] = $row['imgname']; + } elseif (isset($row['tlastname'])) { + $row['targeturl'] = '?do=dozmod§ion=actionlog&action=showuser&uuid=' . $row['targetid']; + $row['targetname'] = $row['tlastname'] . ', ' . $row['tfirstname']; + } elseif (isset($row['lecturename'])) { + $row['targeturl'] = '?do=dozmod§ion=actionlog&action=showtarget&uuid=' . $row['targetid']; + $row['targetname'] = $row['lecturename']; + } + $events[] = $row; + } + $data = array('events' => $events); + if ($showActor) { + $data['showActor'] = true; + } + if ($showTarget) { + $data['showTarget'] = true; + } + + $data['allowedShowUser'] = User::hasPermission("actionlog.showuser"); + $data['allowedShowTarget'] = User::hasPermission("actionlog.showtarget"); + Render::addTemplate('actionlog-log', $data); + } + + public static function doAjax() + { + + } + +} \ No newline at end of file diff --git a/modules-available/dozmod/pages/expiredimages.inc.php b/modules-available/dozmod/pages/expiredimages.inc.php new file mode 100644 index 00000000..2b5a2274 --- /dev/null +++ b/modules-available/dozmod/pages/expiredimages.inc.php @@ -0,0 +1,97 @@ + $val) { + if (strtolower($val) !== 'on') + continue; + Database::exec("UPDATE sat.imageversion SET deletestate = 'WANT_DELETE'" + . " WHERE deletestate = 'SHOULD_DELETE' AND imageversionid = :imageversionid", array( + 'imageversionid' => $image + )); + } + if (!empty($images)) { + $ret = Download::asStringPost('http://127.0.0.1:9080/do/delete-images', false, 10, $code); + if ($code == 999) { + $ret .= "\nConnection to DMSD failed."; + } + return $ret; + } + } + return false; + } + + private static function loadExpiredImages() + { + $res = Database::simpleQuery("SELECT b.displayname," + . " own.firstname, own.lastname, own.email," + . " v.imageversionid, v.createtime, v.filesize, v.deletestate," + . " lat.expiretime AS latexptime, lat.deletestate AS latdelstate" + . " FROM sat.imageversion v" + . " INNER JOIN sat.imagebase b ON (b.imagebaseid = v.imagebaseid)" + . " INNER JOIN sat.user own ON (b.ownerid = own.userid)" + . " LEFT JOIN sat.imageversion lat ON (b.latestversionid = lat.imageversionid)" + . " WHERE v.deletestate <> 'KEEP'" + . " ORDER BY b.displayname ASC, v.createtime ASC"); + $NOW = time(); + $rows = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if ($row['latexptime'] > $NOW && $row['latdelstate'] === 'KEEP') { + $row['hasNewerClass'] = 'glyphicon-ok green'; + $row['checked'] = 'checked'; + } else { + $row['hasNewerClass'] = 'glyphicon-remove red'; + } + if ($row['deletestate'] === 'WANT_DELETE') { + $row['name_extra_class'] = 'slx-strike'; + } + $row['version'] = date('d.m.Y H:i:s', $row['createtime']); + $row['rawfilesize'] = $row['filesize']; + $row['filesize'] = Util::readableFileSize($row['filesize']); + $rows[] = $row; + } + return $rows; + } + + public static function doRender() + { + $expiredImages = self::loadExpiredImages(); + + if (empty($expiredImages)) { + Message::addSuccess('no-expired-images'); + } else { + Render::addTemplate('images-delete', array('images' => $expiredImages, 'allowedDelete' => User::hasPermission("expiredimages.delete"))); + } + } + + public static function doAjax() + { + $action = Request::post('action'); + if ($action === 'delimages') { + User::assertPermission("expiredimages.delete"); + die(self::handleDeleteImages()); + } + die('Huh?'); + } + +} diff --git a/modules-available/dozmod/pages/mailconfig.inc.php b/modules-available/dozmod/pages/mailconfig.inc.php new file mode 100644 index 00000000..1f0a750c --- /dev/null +++ b/modules-available/dozmod/pages/mailconfig.inc.php @@ -0,0 +1,97 @@ + 'mailconfig', + 'value' => $data + )); + Message::addSuccess('mail-config-saved'); + } else { + Message::addError('main.invalid-action', $do); + } + Util::redirect('?do=DozMod§ion=mailconfig'); + } + + private static function cleanMailArray() + { + $keys = array('host', 'port', 'ssl', 'senderAddress', 'replyTo', 'username', 'password', 'serverName'); + $data = array(); + foreach ($keys as $key) { + $data[$key] = Request::post($key, ''); + settype($data[$key], 'string'); + if (is_numeric($data[$key])) { + settype($data[$key], 'int'); + } + } + return $data; + } + + public static function doRender() + { + // Mail config + $mailConf = Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'mailconfig')); + if ($mailConf != null) { + $mailConf = @json_decode($mailConf['value'], true); + if (is_array($mailConf)) { + $mailConf['set_' . $mailConf['ssl']] = 'selected="selected"'; + } + } + Permission::addGlobalTags($mailConf['perms'], NULL, ['mailconfig.save', 'mailconfig.testmail']); + Render::addTemplate('mailconfig', $mailConf); + } + + public static function doAjax() + { + $action = Request::post('action'); + if ($action === 'mail') { + if (User::hasPermission("mailconfig.testmail")) { + self::handleTestMail(); + } + } + } + + private static function handleTestMail() + { + $do = Request::post('button'); + if ($do === 'test') { + // Prepare array + $data = self::cleanMailArray(); + Header('Content-Type: text/plain; charset=utf-8'); + $data['recipient'] = Request::post('recipient', ''); + if (!preg_match('/.+@.+\..+/', $data['recipient'])) { + $result = 'No recipient given!'; + } else { + $result = Download::asStringPost('http://127.0.0.1:9080/do/mailtest', $data, 10, $code); + if ($code == 999) { + $result .= "\nTimeout."; + } elseif ($code != 200) { + $result .= "\nReturn code $code"; + } + } + die($result); + } + } + +} diff --git a/modules-available/dozmod/pages/runtimeconfig.inc.php b/modules-available/dozmod/pages/runtimeconfig.inc.php new file mode 100644 index 00000000..63ba4650 --- /dev/null +++ b/modules-available/dozmod/pages/runtimeconfig.inc.php @@ -0,0 +1,112 @@ + [ + 'maxImageValidityDays' => array('min' => 7, 'max' => 9999), + 'maxLectureValidityDays' => array('min' => 7, 'max' => 9999), + 'maxLocationsPerLecture' => array('min' => 0, 'max' => 999), + 'maxTransfers' => array('min' => 1, 'max' => 10), + ], + 'bool' => [ + 'allowLoginByDefault' => array('default' => true) + ], + ]; + foreach ($params as $type => $list) { + foreach ($list as $field => $limits) { + $default = isset($limits['default']) ? $limits['default'] : false; + $value = Request::post($field, $default); + settype($value, $type); + if (isset($limits['min']) && $value < $limits['min']) { + $value = $limits['min']; + } + if (isset($limits['max']) && $value > $limits['max']) { + $value = $limits['max']; + } + $data[$field] = $value; + } + } + + /* ensure types */ + settype($data['defaultLecturePermissions']['edit'], 'boolean'); + settype($data['defaultLecturePermissions']['admin'], 'boolean'); + settype($data['defaultImagePermissions']['edit'], 'boolean'); + settype($data['defaultImagePermissions']['admin'], 'boolean'); + settype($data['defaultImagePermissions']['link'], 'boolean'); + settype($data['defaultImagePermissions']['download'], 'boolean'); + + $data = json_encode($data); + Database::exec('INSERT INTO sat.configuration (parameter, value)' + . ' VALUES (:param, :value)' + . ' ON DUPLICATE KEY UPDATE value = VALUES(value)', array( + 'param' => 'runtimelimits', + 'value' => $data + )); + Message::addSuccess('runtimelimits-config-saved'); + } + Util::redirect('?do=DozMod§ion=runtimeconfig'); + } + + public static function doRender() + { + // Runtime config + $runtimeConf = Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'runtimelimits')); + if ($runtimeConf !== false) { + $runtimeConf = json_decode($runtimeConf['value'], true); + + /* convert some value to corresponding "selected" texts */ + if ($runtimeConf['defaultLecturePermissions']['edit']) { + $runtimeConf['defaultLecturePermissions']['edit'] = 'checked'; + } + if ($runtimeConf['defaultLecturePermissions']['admin']) { + $runtimeConf['defaultLecturePermissions']['admin'] = 'checked'; + } + if ($runtimeConf['defaultImagePermissions']['edit']) { + $runtimeConf['defaultImagePermissions']['edit'] = 'checked'; + } + if ($runtimeConf['defaultImagePermissions']['admin']) { + $runtimeConf['defaultImagePermissions']['admin'] = 'checked'; + } + if ($runtimeConf['defaultImagePermissions']['link']) { + $runtimeConf['defaultImagePermissions']['link'] = 'checked'; + } + if ($runtimeConf['defaultImagePermissions']['download']) { + $runtimeConf['defaultImagePermissions']['download'] = 'checked'; + } + + if ($runtimeConf['allowLoginByDefault']) { + $runtimeConf['allowLoginByDefault'] = 'checked'; + } + } + $runtimeConf['allowedSave'] = User::hasPermission("runtimeconfig.save"); + Render::addTemplate('runtimeconfig', $runtimeConf); + } + + public static function doAjax() + { + + } + +} diff --git a/modules-available/dozmod/pages/templates.inc.php b/modules-available/dozmod/pages/templates.inc.php new file mode 100644 index 00000000..b857115f --- /dev/null +++ b/modules-available/dozmod/pages/templates.inc.php @@ -0,0 +1,139 @@ +$var"; + $lis .= "
  • $var
  • "; + } + foreach($t['optional_variables'] as $var) { + $optVars .= ""; + $lis .= "
  • $var
  • "; + } + /* also options for hidden inputs */ + + $t['html_availableVariables'] = $lis; + $t['html_mandatoryVariables'] = $optManVars; + $t['html_optionalVariables'] = $optVars; + + /* also for javascript */ + $t['list_mandatoryVariables'] = + implode(',', $t['mandatory_variables']); + + $t['list_optionalVariables'] = + implode(',', $t['optional_variables']); + + settype($t['original'], 'bool'); + settype($t['edit_version'], 'int'); + settype($t['version'], 'int'); + $t['modified'] = !$t['original']; + $t['conflict'] = !$t['original'] && $t['edit_version'] < $t['version']; + } + } + + public static function doRender() + { + self::enrichHtml(); + Render::addTemplate('templates', [ + 'templates' => self::$templates, + 'allowedReset' => User::hasPermission("templates.reset"), + 'allowedSave' => User::hasPermission("templates.save"), + ]); + } + + private static function forcmp($string) + { + return trim(str_replace("\r\n", "\n", $string)); + } + + private static function handleSave() + { + $data = Request::post('templates'); + if (is_array($data)) { + self::fetchTemplates(); + foreach (self::$templates as &$template) { + if (isset($data[$template['name']])) { + if (self::forcmp($template['template']) !== self::forcmp($data[$template['name']]['template'])) { + if (empty($template['original_template'])) { + $template['original_template'] = $template['template']; + } + $template['edit_version'] = $template['version']; + } + $template['original'] = (empty($template['original_template']) && $template['original']) + || self::forcmp($template['original_template']) === self::forcmp($data[$template['name']]['template']); + if ($template['original']) { + $template['original_template'] = ''; + } + $template['template'] = $data[$template['name']]['template']; + } + } + unset($template); + $data = json_encode(array('templates' => self::$templates)); + Database::exec("UPDATE sat.configuration SET value = :value WHERE parameter = 'templates'", array('value' => $data)); + Message::addSuccess('templates-saved'); + } else { + Message::addError('nothing-submitted'); + } + Util::redirect('?do=dozmod§ion=templates'); + } + + private static function handleReset() + { + $result = Download::asStringPost('http://127.0.0.1:9080/do/reset-mail-templates', array(), 10, $code); + if ($code == 999) { + Message::addError('timeout'); + } elseif ($code != 200) { + Message::addError('dozmod-error', $code); + } else { + Message::addSuccess('all-templates-reset', $result); + } + Util::redirect('?do=dozmod§ion=templates'); + } + + private static function fetchTemplates() { + $templates= Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'templates')); + if ($templates != null) { + $templates = @json_decode($templates['value'], true); + if (is_array($templates)) { + $names = array_map(static function ($e) { return $e['name']; }, $templates['templates']); + array_multisort($names, SORT_ASC, $templates['templates']); + self::$templates = $templates['templates']; + } + } + + } + + public static function doAjax() + { + + } + +} diff --git a/modules-available/dozmod/pages/users.inc.php b/modules-available/dozmod/pages/users.inc.php new file mode 100644 index 00000000..79d13827 --- /dev/null +++ b/modules-available/dozmod/pages/users.inc.php @@ -0,0 +1,121 @@ +fetch(PDO::FETCH_ASSOC)) { + $row['canlogin'] = self::checked($row['canlogin']); + $row['issuperuser'] = self::checked($row['issuperuser']); + $row['emailnotifications'] = self::checked($row['emailnotifications']); + $row['lastlogin'] = date('d.m.Y', $row['lastlogin']); + $rows[] = $row; + } + Render::addTemplate('userlist', array('users' => $rows)); + } + + private static function listOrganizations() + { + $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']); + $rows[] = $row; + } + Render::addTemplate('orglist', array('organizations' => $rows)); + } + + private static function checked($val) + { + if ($val) + return 'checked="checked"'; + return ''; + } + + private static function setUserOption($option) + { + $val = (string) Request::post('value', '-'); + if ($val !== '1' && $val !== '0') + die('Nein'); + if ($option === 'setmail') { + $field = 'emailnotifications'; + } elseif ($option === 'setsu') { + $field = 'issuperuser'; + } elseif ($option === 'setlogin') { + $field = 'canlogin'; + } else { + die('Unknown'); + } + $user = (string) Request::post('userid', '?'); + $ret = Database::exec("UPDATE sat.user SET $field = :onoff WHERE userid = :userid", array( + 'userid' => $user, + 'onoff' => $val + )); + error_log("Setting $field to $val for $user - affected: $ret"); + if ($ret === false) + die('Error'); + if ($ret === 0) + die(1 - $val); + die($val); + } + + private static function setOrgOption($option) + { + $val = (string) Request::post('value', '-'); + if ($val !== '1' && $val !== '0') + die('Nein'); + if ($option === 'setorglogin') { + $field = 'canlogin'; + } else { + die('Unknown'); + } + $ret = Database::exec("UPDATE sat.organization SET $field = :onoff WHERE organizationid = :organizationid", array( + 'organizationid' => (string) Request::post('organizationid', ''), + 'onoff' => $val + )); + if ($ret === false) + die('Error'); + if ($ret === 0) + die(1 - $val); + die($val); + } + +} \ No newline at end of file diff --git a/modules-available/dozmod/permissions/permissions.json b/modules-available/dozmod/permissions/permissions.json index b4ff034b..c149cb69 100644 --- a/modules-available/dozmod/permissions/permissions.json +++ b/modules-available/dozmod/permissions/permissions.json @@ -1,17 +1,17 @@ { - "images.delete": { + "expiredimages.delete": { "location-aware": false }, - "log.showtarget": { + "actionlog.showtarget": { "location-aware": false }, - "log.showuser": { + "actionlog.showuser": { "location-aware": false }, - "mail.save": { + "mailconfig.save": { "location-aware": false }, - "mail.testmail": { + "mailconfig.testmail": { "location-aware": false }, "runtimeconfig.save": { @@ -23,7 +23,7 @@ "templates.save": { "location-aware": false }, - "users.orglogin": { + "users.setorglogin": { "location-aware": false }, "users.setlogin": { diff --git a/modules-available/dozmod/templates/images-delete.html b/modules-available/dozmod/templates/images-delete.html index ed75a0d2..78690426 100644 --- a/modules-available/dozmod/templates/images-delete.html +++ b/modules-available/dozmod/templates/images-delete.html @@ -9,6 +9,7 @@
    + diff --git a/modules-available/dozmod/templates/mailconfig.html b/modules-available/dozmod/templates/mailconfig.html index d5d4db29..3aa1eda5 100644 --- a/modules-available/dozmod/templates/mailconfig.html +++ b/modules-available/dozmod/templates/mailconfig.html @@ -55,13 +55,14 @@
    - + - - + +
    +
    diff --git a/modules-available/dozmod/templates/runtimeconfig.html b/modules-available/dozmod/templates/runtimeconfig.html index 1d4cc6cb..e7295d48 100644 --- a/modules-available/dozmod/templates/runtimeconfig.html +++ b/modules-available/dozmod/templates/runtimeconfig.html @@ -116,6 +116,7 @@
    +
    -- cgit v1.2.3-55-g7522 From cbd3277d1845baa350274bd6d8b65c915d886f3a Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 16 Feb 2018 17:19:18 +0100 Subject: [dozmod] Remove testmail permission, would leak pw and makes little sense --- modules-available/dozmod/pages/mailconfig.inc.php | 7 +++---- modules-available/dozmod/permissions/permissions.json | 3 --- modules-available/dozmod/templates/mailconfig.html | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) (limited to 'modules-available/dozmod/permissions/permissions.json') diff --git a/modules-available/dozmod/pages/mailconfig.inc.php b/modules-available/dozmod/pages/mailconfig.inc.php index 1f0a750c..08205f2e 100644 --- a/modules-available/dozmod/pages/mailconfig.inc.php +++ b/modules-available/dozmod/pages/mailconfig.inc.php @@ -58,17 +58,16 @@ class SubPage $mailConf['set_' . $mailConf['ssl']] = 'selected="selected"'; } } - Permission::addGlobalTags($mailConf['perms'], NULL, ['mailconfig.save', 'mailconfig.testmail']); + Permission::addGlobalTags($mailConf['perms'], null, ['mailconfig.save']); Render::addTemplate('mailconfig', $mailConf); } public static function doAjax() { + User::assertPermission("mailconfig.save"); $action = Request::post('action'); if ($action === 'mail') { - if (User::hasPermission("mailconfig.testmail")) { - self::handleTestMail(); - } + self::handleTestMail(); } } diff --git a/modules-available/dozmod/permissions/permissions.json b/modules-available/dozmod/permissions/permissions.json index c149cb69..c46768d7 100644 --- a/modules-available/dozmod/permissions/permissions.json +++ b/modules-available/dozmod/permissions/permissions.json @@ -11,9 +11,6 @@ "mailconfig.save": { "location-aware": false }, - "mailconfig.testmail": { - "location-aware": false - }, "runtimeconfig.save": { "location-aware": false }, diff --git a/modules-available/dozmod/templates/mailconfig.html b/modules-available/dozmod/templates/mailconfig.html index 3aa1eda5..dbcdddcb 100644 --- a/modules-available/dozmod/templates/mailconfig.html +++ b/modules-available/dozmod/templates/mailconfig.html @@ -55,7 +55,7 @@
    - + -- cgit v1.2.3-55-g7522 From bf6d65f55eacde61e996b3b08994ddc6e66e0424 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 28 Mar 2018 14:30:22 +0200 Subject: [dozmod] Simplify permissions, don't link user in userlist if actionlog is inaccessible Closes #3332 --- modules-available/dozmod/lang/de/permissions.json | 9 ++++----- modules-available/dozmod/lang/de/template-tags.json | 7 +------ modules-available/dozmod/lang/en/permissions.json | 9 ++++----- modules-available/dozmod/lang/en/template-tags.json | 7 +------ modules-available/dozmod/pages/actionlog.inc.php | 11 +++-------- modules-available/dozmod/pages/users.inc.php | 5 ++++- modules-available/dozmod/permissions/permissions.json | 8 ++++---- modules-available/dozmod/templates/actionlog-log.html | 6 ++++-- modules-available/dozmod/templates/userlist.html | 6 +++++- 9 files changed, 30 insertions(+), 38 deletions(-) (limited to 'modules-available/dozmod/permissions/permissions.json') diff --git a/modules-available/dozmod/lang/de/permissions.json b/modules-available/dozmod/lang/de/permissions.json index 9c5af91d..df913265 100644 --- a/modules-available/dozmod/lang/de/permissions.json +++ b/modules-available/dozmod/lang/de/permissions.json @@ -1,14 +1,13 @@ { - "actionlog.showtarget": "Target Data im Aktions-Log anzeigen.", - "actionlog.showuser": "User Data im Aktions-Log anzeigen.", + "actionlog.view": "Aktions-Log einsehen.", "expiredimages.delete": "Zur L\u00f6schung vorgemerkete Abbilder l\u00f6schen.", "mailconfig.save": "\u00c4nderungen an der SMTP-Konfiguration zum Versenden von Mails speichern.", - "mailconfig.testmail": "Eine Test E-Mail verschicken.", "runtimeconfig.save": "\u00c4nderungen an der Laufzeit-Konfiguration speichern.", "templates.reset": "E-Mail Templates zur\u00fccksetzen.", "templates.save": "E-Mail Templates speichern.", - "users.setorglogin": "Anmeldungen f\u00fcr Benutzer von bestimmten Einrichtungen aktivieren\/deaktivieren.", "users.setlogin": "Anmeldungen f\u00fcr einzelne Benutzer aktivieren\/deaktivieren.", "users.setmail": "E-Mail Benachrichtigungen f\u00fcr einzelne Benutzer aktivieren\/deaktivieren.", - "users.setsu": "Benutzer zu SuperUser ernennen." + "users.setorglogin": "Anmeldungen f\u00fcr Benutzer von bestimmten Einrichtungen aktivieren\/deaktivieren.", + "users.setsu": "Benutzer zu SuperUser ernennen.", + "users.view": "Benutzerliste sehen." } \ No newline at end of file diff --git a/modules-available/dozmod/lang/de/template-tags.json b/modules-available/dozmod/lang/de/template-tags.json index a1c23d2e..84f6e0de 100644 --- a/modules-available/dozmod/lang/de/template-tags.json +++ b/modules-available/dozmod/lang/de/template-tags.json @@ -40,7 +40,6 @@ "lang_lecturePermissionEdit": "Bearbeiten", "lang_loadDefaults": "Alle Texte auf Auslieferungszustand zur\u00fccksetzen", "lang_mailConfig": "SMTP-Konfiguration zum Versenden von Mails", - "lang_mailConfigHeadline": "EMail-Konfiguration", "lang_mailDescription": "F\u00fcllen Sie die folgenden Felder aus, wenn sie m\u00f6chten, dass Dozierende per Mail benachrichtigt werden, falls eine von ihnen genutzte oder erstellte VM oder Veranstaltung abl\u00e4uft. Um diese Funktion zu deaktivieren, lassen Sie eines der mit (*) gekennzeichneten Felder leer. Wenn das hier angegebene E-Mail-Konto nur zum Versenden von Mails genutzt wird, sollten Sie einen Auto-Responder einrichten f\u00fcr den Fall, dass ein Dozierender auf eine der automatisch generierten Mails antwortet (bzw. eine explizit angegebene Reply-To Adresse ignoriert).", "lang_mailTemplates": "E-Mail Templates", "lang_maxImageValidity": "G\u00fcltigkeitsdauer neuer VM-Versionen (Tage)", @@ -50,7 +49,6 @@ "lang_miscOptions": "Verschiedene Einstellungen", "lang_modified": "Modifiziert", "lang_organization": "Einrichtung", - "lang_organizationList": "Liste der Einrichtungen", "lang_organizationListHeader": "Nutzungsrechte f\u00fcr den Satelliten festlegen", "lang_os": "Betriebssystem", "lang_owner": "Besitzer", @@ -61,7 +59,6 @@ "lang_replaceWithOriginal": "Originaltext in Textbox laden", "lang_replyTo": "Reply-To Adresse", "lang_runtimeConfig": "Laufzeit-Konfiguration", - "lang_runtimeConfigHeadline": "Laufzeit-Konfiguration", "lang_runtimeConfigLimits": "Beschr\u00e4nkungen", "lang_senderAddress": "Absenderadresse", "lang_senderName": "Absender Anzeigename", @@ -71,7 +68,6 @@ "lang_sslExplicit": "Explizites SSL (\"STARTTLS\")", "lang_sslImplicit": "Implizites SSL", "lang_sslNone": "Kein SSL", - "lang_subHeading": "Images, die abgelaufen oder besch\u00e4digt sind", "lang_superUser": "Ist SuperUser (darf alle Veranstaltungen und VMs bearbeiten\/l\u00f6schen)", "lang_system": "System", "lang_template": "Template", @@ -83,10 +79,9 @@ "lang_updateTime": "Letzte Bearbeitung", "lang_user": "Benutzername", "lang_userId": "Benutzer-ID", - "lang_userList": "Benutzerliste", "lang_userListDescription": "Hier k\u00f6nnen Sie individuelle Nutzer zu \"Super-Usern\" machen. Diese haben in der bwLehrpool-Suite auf alle Veranstaltungen und VMs Vollzugriff, unabh\u00e4ngig von den gesetzten Berechtigungen. Au\u00dferdem k\u00f6nnen Sie hier Benutzer vom Zugriff mittels der bwLehrpool-Suite ausschlie\u00dfen.", "lang_userListHeader": "Dem Satelliten bekannte Benutzer", "lang_usernameplaceholder": "SMTP Benutzername", "lang_version": "Version vom", "lang_when": "Wann" -} +} \ No newline at end of file diff --git a/modules-available/dozmod/lang/en/permissions.json b/modules-available/dozmod/lang/en/permissions.json index a86cf155..0827c8d2 100644 --- a/modules-available/dozmod/lang/en/permissions.json +++ b/modules-available/dozmod/lang/en/permissions.json @@ -1,14 +1,13 @@ { - "actionlog.showtarget": "Show Target Data in Log.", - "actionlog.showuser": "Show User Data in Log.", + "actionlog.view": "View action log.", "expiredimages.delete": "Delete images marked for deletion.", "mailconfig.save": "Save SMTP configuration for sending mails.", - "mailconfig.testmail": "Send a testmail.", "runtimeconfig.save": "Save limits and defaults of a runtime configuration.", "templates.reset": "Reset email templates.", "templates.save": "Save email templates.", - "users.setorglogin": "Enalbe\/Disable Login for Users from certain organisations.", "users.setlogin": "Enable\/Disable Login.", "users.setmail": "Enable\/Disable Email Notification.", - "users.setsu": "Set User to superuser." + "users.setorglogin": "Enalbe\/Disable Login for Users from certain organisations.", + "users.setsu": "Set User to superuser.", + "users.view": "View user list." } \ No newline at end of file diff --git a/modules-available/dozmod/lang/en/template-tags.json b/modules-available/dozmod/lang/en/template-tags.json index f12e4ab8..329f7260 100644 --- a/modules-available/dozmod/lang/en/template-tags.json +++ b/modules-available/dozmod/lang/en/template-tags.json @@ -40,7 +40,6 @@ "lang_lecturePermissionEdit": "Edit", "lang_loadDefaults": "Reset all templates to their defaults", "lang_mailConfig": "SMTP configuration for sending mails", - "lang_mailConfigHeadline": "Email Configuration", "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)", @@ -50,7 +49,6 @@ "lang_miscOptions": "Misc options", "lang_modified": "modified", "lang_organization": "Organization", - "lang_organizationList": "List of Organizations", "lang_organizationListHeader": "Set access permissions for organizations", "lang_os": "Operating System", "lang_owner": "Owner", @@ -61,7 +59,6 @@ "lang_replaceWithOriginal": "load original text into text box", "lang_replyTo": "Reply-To address", "lang_runtimeConfig": "Limits and Defaults", - "lang_runtimeConfigHeadline": "Configure Limits and Defaults for bwLehrpool-Suite", "lang_runtimeConfigLimits": "Limitations", "lang_senderAddress": "Sender address", "lang_senderName": "Sender's display name", @@ -71,7 +68,6 @@ "lang_sslExplicit": "Explicit SSL (\"STARTTLS\")", "lang_sslImplicit": "Implicit SSL", "lang_sslNone": "No SSL", - "lang_subHeading": "Expired or damaged images", "lang_superUser": "Is super user (can edit\/delete all lectures and VMs)", "lang_system": "System", "lang_template": "Template", @@ -83,10 +79,9 @@ "lang_updateTime": "Last update", "lang_user": "User name", "lang_userId": "User id", - "lang_userList": "User List", "lang_userListDescription": "Here you can promote \"super users\", which will have all permissions in the bwLehrpool-Suite. You can also ban users from accessing this server via the bwLehrpool-Suite.", "lang_userListHeader": "Users known to this satellite", "lang_usernameplaceholder": "SMTP Username", "lang_version": "Version timestamp", "lang_when": "When" -} +} \ No newline at end of file diff --git a/modules-available/dozmod/pages/actionlog.inc.php b/modules-available/dozmod/pages/actionlog.inc.php index 6cbd2868..a014ddf7 100644 --- a/modules-available/dozmod/pages/actionlog.inc.php +++ b/modules-available/dozmod/pages/actionlog.inc.php @@ -8,6 +8,7 @@ class SubPage public static function doPreprocess() { + 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 . '"'); @@ -29,13 +30,9 @@ class SubPage . " LEFT JOIN sat.lecture l ON (l.lectureid = targetid)" . " ORDER BY al.dateline DESC LIMIT 500", array(), true, true); } elseif (self::$action === 'showuser') { - if (User::hasPermission("actionlog.showuser")) { - self::listUser(); - } + self::listUser(); } else { - if (User::hasPermission("actionlog.showtarget")) { - self::listTarget(); - } + self::listTarget(); } } @@ -155,8 +152,6 @@ class SubPage $data['showTarget'] = true; } - $data['allowedShowUser'] = User::hasPermission("actionlog.showuser"); - $data['allowedShowTarget'] = User::hasPermission("actionlog.showtarget"); Render::addTemplate('actionlog-log', $data); } diff --git a/modules-available/dozmod/pages/users.inc.php b/modules-available/dozmod/pages/users.inc.php index 0791da2e..0c958feb 100644 --- a/modules-available/dozmod/pages/users.inc.php +++ b/modules-available/dozmod/pages/users.inc.php @@ -48,7 +48,10 @@ class SubPage $row['lastlogin'] = date('d.m.Y', $row['lastlogin']); $rows[] = $row; } - Render::addTemplate('userlist', array('users' => $rows)); + Render::addTemplate('userlist', array( + 'users' => $rows, + 'nameTag' => User::hasPermission('actionlog.view') ? 'a' : 'span', + )); } private static function listOrganizations() diff --git a/modules-available/dozmod/permissions/permissions.json b/modules-available/dozmod/permissions/permissions.json index c46768d7..b9c82107 100644 --- a/modules-available/dozmod/permissions/permissions.json +++ b/modules-available/dozmod/permissions/permissions.json @@ -2,10 +2,7 @@ "expiredimages.delete": { "location-aware": false }, - "actionlog.showtarget": { - "location-aware": false - }, - "actionlog.showuser": { + "actionlog.view": { "location-aware": false }, "mailconfig.save": { @@ -31,5 +28,8 @@ }, "users.setsu": { "location-aware": false + }, + "users.view": { + "location-aware": false } } \ No newline at end of file diff --git a/modules-available/dozmod/templates/actionlog-log.html b/modules-available/dozmod/templates/actionlog-log.html index 8aa57207..7caa3d34 100644 --- a/modules-available/dozmod/templates/actionlog-log.html +++ b/modules-available/dozmod/templates/actionlog-log.html @@ -18,7 +18,9 @@ {{#showActor}}
    {{#users}} - + -- cgit v1.2.3-55-g7522 From 05b361f1288fa93e272e11eb2e3cc3e6ec5e830a Mon Sep 17 00:00:00 2001 From: Jannik Schönartz Date: Fri, 23 Nov 2018 00:08:07 +0100 Subject: [dozmod] Add LDAP filter submodule --- modules-available/dozmod/lang/de/messages.json | 7 ++ modules-available/dozmod/lang/de/module.json | 1 + modules-available/dozmod/lang/de/permissions.json | 2 + .../dozmod/lang/de/template-tags.json | 8 ++ modules-available/dozmod/lang/en/messages.json | 6 ++ modules-available/dozmod/lang/en/module.json | 1 + modules-available/dozmod/lang/en/permissions.json | 2 + .../dozmod/lang/en/template-tags.json | 8 ++ modules-available/dozmod/page.inc.php | 3 +- modules-available/dozmod/pages/ldapfilters.inc.php | 119 +++++++++++++++++++++ .../dozmod/permissions/permissions.json | 6 ++ .../dozmod/templates/ldapfilter-add.html | 39 +++++++ .../dozmod/templates/ldapfilters.html | 72 +++++++++++++ 13 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 modules-available/dozmod/pages/ldapfilters.inc.php create mode 100644 modules-available/dozmod/templates/ldapfilter-add.html create mode 100644 modules-available/dozmod/templates/ldapfilters.html (limited to 'modules-available/dozmod/permissions/permissions.json') diff --git a/modules-available/dozmod/lang/de/messages.json b/modules-available/dozmod/lang/de/messages.json index 60c37927..47912ae1 100644 --- a/modules-available/dozmod/lang/de/messages.json +++ b/modules-available/dozmod/lang/de/messages.json @@ -3,6 +3,13 @@ "delete-images": "L\u00f6schung: {{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-invalid-filter-id": "Ung\u00fcltige LDAP Filter ID", + "ldap-filter-id-missing": "Fehlende LDAP Filter ID", + "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", "mail-config-saved": "Mail-Konfiguration gespeichert", "no-expired-images": "Keine Abgelaufenen VM-Versionen", "nothing-submitted": "Es wurde nichts \u00fcbermittelt", diff --git a/modules-available/dozmod/lang/de/module.json b/modules-available/dozmod/lang/de/module.json index c9acd4ee..4a5e0249 100644 --- a/modules-available/dozmod/lang/de/module.json +++ b/modules-available/dozmod/lang/de/module.json @@ -3,6 +3,7 @@ "page_title": "Verwalten der bwLehrpool-Suite", "submenu_actionlog": "Aktions-Log", "submenu_expiredimages": "Abgelaufene VM-Versionen", + "submenu_ldapfilters": "LDAP Filter", "submenu_mailconfig": "Email-Konfiguration", "submenu_runtimeconfig": "Limits und Standardwerte", "submenu_templates": "Textbausteine f\u00fcr E-Mails", diff --git a/modules-available/dozmod/lang/de/permissions.json b/modules-available/dozmod/lang/de/permissions.json index df913265..ad099d37 100644 --- a/modules-available/dozmod/lang/de/permissions.json +++ b/modules-available/dozmod/lang/de/permissions.json @@ -1,6 +1,8 @@ { "actionlog.view": "Aktions-Log einsehen.", "expiredimages.delete": "Zur L\u00f6schung vorgemerkete Abbilder l\u00f6schen.", + "ldapfilters.save": "LDAP Filter speichern.", + "ldapfilters.view": "LDAP Filter einsehen.", "mailconfig.save": "\u00c4nderungen an der SMTP-Konfiguration zum Versenden von Mails speichern.", "runtimeconfig.save": "\u00c4nderungen an der Laufzeit-Konfiguration speichern.", "templates.reset": "E-Mail Templates zur\u00fccksetzen.", diff --git a/modules-available/dozmod/lang/de/template-tags.json b/modules-available/dozmod/lang/de/template-tags.json index 84f6e0de..7fbeda37 100644 --- a/modules-available/dozmod/lang/de/template-tags.json +++ b/modules-available/dozmod/lang/de/template-tags.json @@ -35,6 +35,14 @@ "lang_lastEditor": "Zuletzt bearbeitet von", "lang_lastLogin": "Letzte Anmeldung", "lang_latestVersion": "Neuste Version", + "lang_ldapFilterAdd": "LDAP Filter Hinzuf\u00fcgen", + "lang_ldapFilterAttribute": "Attribut", + "lang_ldapFilterDeleteConfirmation": "Willst du diesen LDAP Filter wirklich L\u00f6schen.", + "lang_ldapFilterDescription": "Dies sind die Filter, die ein Benutzer in der bwLehrpool-Suite Veranstaltungen hinzuf\u00fcgen kann.", + "lang_ldapFilterEdit": "LDAP Filter bearbeiten", + "lang_ldapFilterName": "Filtername", + "lang_ldapfilters": "LDAP Filter", + "lang_ldapFilterValue": "Wert", "lang_lecture": "Veranstaltung", "lang_lecturePermissionAdmin": "Administration", "lang_lecturePermissionEdit": "Bearbeiten", diff --git a/modules-available/dozmod/lang/en/messages.json b/modules-available/dozmod/lang/en/messages.json index 6d7ea0ac..4d914406 100644 --- a/modules-available/dozmod/lang/en/messages.json +++ b/modules-available/dozmod/lang/en/messages.json @@ -3,6 +3,12 @@ "delete-images": "Delete: {{0}}", "dozmod-error": "Error communicating with the bwLehrpool-Suite server: {{0}}", "images-pending-delete-exist": "VMs marked for deletion: {{0}}", + "ldap-filter-created": "LDAP filter was successfully created", + "ldap-filter-deleted": "LDAP filter successfully deleted", + "ldap-invalid-filter-id": "Invalid LDAP filter id", + "ldap-filter-id-missing": "LDAP filter id was missing", + "ldap-filter-insert-failed": "LDAP filter could not be inserted into the database", + "ldap-filter-save-missing-information": "LDAP filter informations were missing", "mail-config-saved": "Mail config saved", "no-expired-images": "No expired VMs", "nothing-submitted": "There was nothing submitted", diff --git a/modules-available/dozmod/lang/en/module.json b/modules-available/dozmod/lang/en/module.json index b7a04762..c2b4439d 100644 --- a/modules-available/dozmod/lang/en/module.json +++ b/modules-available/dozmod/lang/en/module.json @@ -3,6 +3,7 @@ "page_title": "Manage the bwLehrpool-Suite", "submenu_actionlog": "action log", "submenu_expiredimages": "Expired VM versions", + "submenu_ldapfilters": "LDAP filters", "submenu_mailconfig": "email configuration", "submenu_runtimeconfig": "limits and defaults", "submenu_templates": "templates", diff --git a/modules-available/dozmod/lang/en/permissions.json b/modules-available/dozmod/lang/en/permissions.json index 0827c8d2..797f7c2f 100644 --- a/modules-available/dozmod/lang/en/permissions.json +++ b/modules-available/dozmod/lang/en/permissions.json @@ -1,6 +1,8 @@ { "actionlog.view": "View action log.", "expiredimages.delete": "Delete images marked for deletion.", + "ldapfilters.save": "Save LDAP filter.", + "ldapfilters.view": "View LDAP filters. ", "mailconfig.save": "Save SMTP configuration for sending mails.", "runtimeconfig.save": "Save limits and defaults of a runtime configuration.", "templates.reset": "Reset email templates.", diff --git a/modules-available/dozmod/lang/en/template-tags.json b/modules-available/dozmod/lang/en/template-tags.json index 3ee95e8c..4f9ab877 100644 --- a/modules-available/dozmod/lang/en/template-tags.json +++ b/modules-available/dozmod/lang/en/template-tags.json @@ -35,6 +35,14 @@ "lang_lastEditor": "Edited by", "lang_lastLogin": "Last login", "lang_latestVersion": "latest version", + "lang_ldapFilterAdd": "Add LDAP filter", + "lang_ldapFilterAttribute": "Attribute", + "lang_ldapFilterDeleteConfirmation": "Do you really want to delete this LDAP filter.", + "lang_ldapFilterDescription": "These are the LDAP filters that can be applied to lectures in the bwLehrpool-Suite.", + "lang_ldapFilterEdit": "Edit LDAP filter", + "lang_ldapFilterName": "Filter name", + "lang_ldapfilters": "LDAP filters", + "lang_ldapFilterValue": "Value", "lang_lecture": "Lecture", "lang_lecturePermissionAdmin": "Administrate", "lang_lecturePermissionEdit": "Edit", diff --git a/modules-available/dozmod/page.inc.php b/modules-available/dozmod/page.inc.php index a8e0da0e..47110dd0 100644 --- a/modules-available/dozmod/page.inc.php +++ b/modules-available/dozmod/page.inc.php @@ -5,7 +5,7 @@ class Page_DozMod extends Page /** @var bool true if we have a proper subpage */ private $haveSubPage = false; - private $validSections = ['expiredimages', 'mailconfig', 'templates', 'runtimeconfig', 'users', 'actionlog']; + private $validSections = ['expiredimages', 'mailconfig', 'templates', 'runtimeconfig', 'users', 'actionlog', 'ldapfilters']; private $section; @@ -60,6 +60,7 @@ class Page_DozMod extends Page Dictionary::translate('submenu_runtimeconfig', true); Dictionary::translate('submenu_users', true); Dictionary::translate('submenu_actionlog', true); + Dictionary::translate('submenu_ldapfilters', true); */ /* add sub-menus */ diff --git a/modules-available/dozmod/pages/ldapfilters.inc.php b/modules-available/dozmod/pages/ldapfilters.inc.php new file mode 100644 index 00000000..6b5ce2dc --- /dev/null +++ b/modules-available/dozmod/pages/ldapfilters.inc.php @@ -0,0 +1,119 @@ + $ldapfilters, + 'hasEditPermission' => User::hasPermission('ldapfilters.save') + ); + + Render::addTemplate('ldapfilters', $data); + } else if (self::$show === 'edit') { + $filterid = Request::get('filterid', false, 'int'); + + if ($filterid === false) { + Render::addTemplate('ldapfilter-add', array( + 'filterid' => 0 + )); + } else { + $ldapfilter = Database::queryFirst("SELECT * FROM sat.ldapfilter WHERE filterid=:id", array( 'id' => $filterid)); + + $data = array( + 'filterid' => $filterid, + 'filtername' => $ldapfilter['filtername'], + 'attribute' => $ldapfilter['attribute'], + 'value' => $ldapfilter['value'] + ); + Render::addTemplate('ldapfilter-add', $data); + } + } + } + + private function deleteLdapFilter() { + User::assertPermission('ldapfilters.save'); + $filterid = Request::post('filterid', false, 'int'); + if ($filterid === false) { + Message::addError('ldap-filter-id-missing'); + return; + } + $res = Database::exec("DELETE FROM sat.ldapfilter WHERE filterid=:id", array('id' => $filterid)); + if ($res !== 1) { + Message::addWarning('ldap-invalid-filter-id', $filterid); + } else { + Message::addSuccess('ldap-filter-deleted'); + } + } + + private function saveLdapFilter() { + $filterid = Request::post('filterid', '', 'int'); + $filtername = Request::post('filtername', false, 'string'); + $filterattribute = Request::post('attribute', false, 'string'); + $filtervalue = Request::post('value', false, 'string'); + + if ($filtername === false || $filterattribute === false || $filtervalue === false) { + Message::addError('ldap-filter-save-missing-information'); + return; + } + + if ($filterid === 0) { + // Insert filter in the db. + $res = Database::exec("INSERT INTO sat.ldapfilter (filtername, attribute, value) VALUES (:filtername, :attribute, :value)", array( + 'filtername' => $filtername, + 'attribute' => $filterattribute, + 'value' => $filtervalue + )); + + if ($res !== 1) { + Message::addError('ldap-filter-insert-failed'); + } else { + Message::addSuccess('ldap-filter-created'); + } + + } else { + // Update filter in the db. + $res = Database::exec("UPDATE sat.ldapfilter SET filtername=:filtername, attribute=:attribute, value=:value WHERE filterid=:filterid", array( + 'filterid' => $filterid, + 'filtername' => $filtername, + 'attribute' => $filterattribute, + 'value' => $filtervalue + )); + + if ($res !== 1) { + Message::addError('ldap-filter-insert-failed'); + } else { + Message::addSuccess('ldap-filter-created'); + } + + } + Util::redirect("?do=dozmod§ion=ldapfilters"); + } + + public static function doAjax() + { + + } + +} \ No newline at end of file diff --git a/modules-available/dozmod/permissions/permissions.json b/modules-available/dozmod/permissions/permissions.json index b9c82107..dc5a46ed 100644 --- a/modules-available/dozmod/permissions/permissions.json +++ b/modules-available/dozmod/permissions/permissions.json @@ -5,6 +5,12 @@ "actionlog.view": { "location-aware": false }, + "ldapfilters.view": { + "location-aware": false + }, + "ldapfilters.save": { + "location-aware": false + }, "mailconfig.save": { "location-aware": false }, diff --git a/modules-available/dozmod/templates/ldapfilter-add.html b/modules-available/dozmod/templates/ldapfilter-add.html new file mode 100644 index 00000000..c74fbcda --- /dev/null +++ b/modules-available/dozmod/templates/ldapfilter-add.html @@ -0,0 +1,39 @@ +

    {{lang_ldapfilters}}

    + +
    +
    + {{lang_ldapFilterEdit}} +
    +
    + +

    {{lang_ldapFilterDescription}}

    +
    + + + +
    + + +
    +
    + + +
    +
    + + +
    + +
    + {{lang_cancel}} + +
    + +
    +
    + + diff --git a/modules-available/dozmod/templates/ldapfilters.html b/modules-available/dozmod/templates/ldapfilters.html new file mode 100644 index 00000000..49ecc222 --- /dev/null +++ b/modules-available/dozmod/templates/ldapfilters.html @@ -0,0 +1,72 @@ +

    {{lang_ldapfilters}}

    +
    {{#uuserid}} - {{#allowedShowUser}}{{/allowedShowUser}} {{ulastname}}, {{ufirstname}}{{#allowedShowUser}}{{/allowedShowUser}} + + {{ulastname}}, {{ufirstname}} + {{/uuserid}} {{^uuserid}} {{lang_system}} @@ -28,7 +30,7 @@ {{#showTarget}} {{#targeturl}} - {{#allowedShowTarget}}{{/allowedShowTarget}}{{targetname}}{{#allowedShowTarget}}{{/allowedShowTarget}} + {{targetname}} {{/targeturl}} {{^targeturl}} {{targetname}} diff --git a/modules-available/dozmod/templates/userlist.html b/modules-available/dozmod/templates/userlist.html index b8080b44..3b919099 100644 --- a/modules-available/dozmod/templates/userlist.html +++ b/modules-available/dozmod/templates/userlist.html @@ -22,7 +22,11 @@
    {{lastname}}, {{firstname}} + <{{nameTag}} href="?do=dozmod&section=actionlog&action=showuser&uuid={{userid}}"> + {{lastname}}, {{firstname}} + + {{orgname}} {{lastlogin}} {{email}}
    + + + + + + {{#hasEditPermission}} + + + {{/hasEditPermission}} + + + + {{#ldapfilters}} + + + + + {{#hasEditPermission}} + + + {{/hasEditPermission}} + + {{/ldapfilters}} + +
    {{lang_ldapFilterName}}{{lang_ldapFilterAttribute}}{{lang_ldapFilterValue}}{{lang_edit}}{{lang_delete}}
    {{filtername}}{{attribute}}{{value}} + + + + + +
    + +{{#hasEditPermission}} + +{{/hasEditPermission}} + +
    + + + +
    + + -- cgit v1.2.3-55-g7522 From 541b9aae3a8f96b0a800dbccf348e360c92a292c Mon Sep 17 00:00:00 2001 From: Udo Walter Date: Fri, 23 Nov 2018 00:10:20 +0100 Subject: [dozmod] add network share submodule --- modules-available/dozmod/lang/de/messages.json | 2 + modules-available/dozmod/lang/de/module.json | 1 + modules-available/dozmod/lang/de/permissions.json | 2 + .../dozmod/lang/de/template-tags.json | 11 +++ modules-available/dozmod/lang/en/messages.json | 2 + modules-available/dozmod/lang/en/module.json | 1 + modules-available/dozmod/lang/en/permissions.json | 2 + .../dozmod/lang/en/template-tags.json | 11 +++ modules-available/dozmod/page.inc.php | 3 +- .../dozmod/pages/networkshares.inc.php | 63 ++++++++++++++ .../dozmod/permissions/permissions.json | 6 ++ .../dozmod/templates/networkshares-edit.html | 85 +++++++++++++++++++ .../dozmod/templates/networkshares.html | 95 ++++++++++++++++++++++ 13 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 modules-available/dozmod/pages/networkshares.inc.php create mode 100644 modules-available/dozmod/templates/networkshares-edit.html create mode 100644 modules-available/dozmod/templates/networkshares.html (limited to 'modules-available/dozmod/permissions/permissions.json') diff --git a/modules-available/dozmod/lang/de/messages.json b/modules-available/dozmod/lang/de/messages.json index 60c37927..85b8ca70 100644 --- a/modules-available/dozmod/lang/de/messages.json +++ b/modules-available/dozmod/lang/de/messages.json @@ -4,6 +4,8 @@ "dozmod-error": "Fehler bei der Kommunikation mit dem bwLehrpool-Suite server: {{0}}", "images-pending-delete-exist": "Zur L\u00f6schung markierte VM-Versionen: {{0}}", "mail-config-saved": "Mail-Konfiguration gespeichert", + "networkshare-deleted": "Netzlaufwerk gel\u00f6scht", + "networkshare-saved": "Netzlaufwerk gespeichert", "no-expired-images": "Keine Abgelaufenen VM-Versionen", "nothing-submitted": "Es wurde nichts \u00fcbermittelt", "runtimelimits-config-saved": "Einstellungen gespeichert", diff --git a/modules-available/dozmod/lang/de/module.json b/modules-available/dozmod/lang/de/module.json index c9acd4ee..7bd3e0c0 100644 --- a/modules-available/dozmod/lang/de/module.json +++ b/modules-available/dozmod/lang/de/module.json @@ -4,6 +4,7 @@ "submenu_actionlog": "Aktions-Log", "submenu_expiredimages": "Abgelaufene VM-Versionen", "submenu_mailconfig": "Email-Konfiguration", + "submenu_networkshares": "Netzlaufwerke", "submenu_runtimeconfig": "Limits und Standardwerte", "submenu_templates": "Textbausteine f\u00fcr E-Mails", "submenu_users": "Benutzer und Berechtigungen" diff --git a/modules-available/dozmod/lang/de/permissions.json b/modules-available/dozmod/lang/de/permissions.json index df913265..53cbf1d8 100644 --- a/modules-available/dozmod/lang/de/permissions.json +++ b/modules-available/dozmod/lang/de/permissions.json @@ -2,6 +2,8 @@ "actionlog.view": "Aktions-Log einsehen.", "expiredimages.delete": "Zur L\u00f6schung vorgemerkete Abbilder l\u00f6schen.", "mailconfig.save": "\u00c4nderungen an der SMTP-Konfiguration zum Versenden von Mails speichern.", + "networkshares.save": "Netzlaufwerke einsehen.", + "networkshares.view": "\u00c4nderungen an den Netzlaufwerken speichern.", "runtimeconfig.save": "\u00c4nderungen an der Laufzeit-Konfiguration speichern.", "templates.reset": "E-Mail Templates zur\u00fccksetzen.", "templates.save": "E-Mail Templates speichern.", diff --git a/modules-available/dozmod/lang/de/template-tags.json b/modules-available/dozmod/lang/de/template-tags.json index 84f6e0de..fa4b49f5 100644 --- a/modules-available/dozmod/lang/de/template-tags.json +++ b/modules-available/dozmod/lang/de/template-tags.json @@ -1,8 +1,11 @@ { "lang_actionTarget": "Aktionsziel", + "lang_active": "Aktiv", + "lang_addShare": "Netzlaufwerk hinzufügen", "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_asteriskRequired": "Felder mit (*) sind erforderlich", + "lang_authMethod": "Authentifizierung", "lang_blockCount": "Anzahl Bl\u00f6cke", "lang_bwlehrpoolsuite": "bwLehrpool-Suite", "lang_canLoginOrganization": "Nutzer dieser Einrichtung k\u00f6nnen sich am Satelliten anmelden", @@ -21,6 +24,7 @@ "lang_descriptionRuntimeLimits": "Hier k\u00f6nnen Sie verschiedene Limits festlegen, z.B. wie lange eine VM nach dem Hochladen g\u00fcltig ist. Nach Ablauf dieses Zeitraums ist der Verantwortliche gezwungen, eine neue Version der VM hochzuladen. Damit k\u00f6nnen Sie das Ansammeln nicht mehr ben\u00f6tigter VMs eind\u00e4mmen. Weiterhin k\u00f6nnen Sie die maximale Anzahl gleichzeitiger Transfers pro Benutzer einschr\u00e4nken.\r\n\r\nVer\u00e4nderte Einstellungen wirken sich nicht auf bereits bestehende VMs aus.", "lang_description_delete_images": "Diese Liste zeigt VMs, die entweder abgelaufen sind, oder deren Datei besch\u00e4digt, verschoben oder gel\u00f6scht wurde. Diese Images sind zur Zeit im Lehrpool nicht verf\u00fcgbar, ihre endg\u00fcltige L\u00f6schung muss aber manuell best\u00e4tigt werden, um gr\u00f6\u00dfere Katastrophen durch Softwarefehler, verstellte Systemuhren etc. zu vermeiden.", "lang_dozmodLogHeading": "bwLehrpool-Suite Aktionslog", + "lang_editNetworkshare": "Netzlaufwerk bearbeiten", "lang_email": "EMail", "lang_emailNotifications": "EMail-Benachrichtigungen aktiviert", "lang_error": "Fehler", @@ -39,6 +43,7 @@ "lang_lecturePermissionAdmin": "Administration", "lang_lecturePermissionEdit": "Bearbeiten", "lang_loadDefaults": "Alle Texte auf Auslieferungszustand zur\u00fccksetzen", + "lang_loggedInUser": "Angemeldeter Nutzer", "lang_mailConfig": "SMTP-Konfiguration zum Versenden von Mails", "lang_mailDescription": "F\u00fcllen Sie die folgenden Felder aus, wenn sie m\u00f6chten, dass Dozierende per Mail benachrichtigt werden, falls eine von ihnen genutzte oder erstellte VM oder Veranstaltung abl\u00e4uft. Um diese Funktion zu deaktivieren, lassen Sie eines der mit (*) gekennzeichneten Felder leer. Wenn das hier angegebene E-Mail-Konto nur zum Versenden von Mails genutzt wird, sollten Sie einen Auto-Responder einrichten f\u00fcr den Fall, dass ein Dozierender auf eine der automatisch generierten Mails antwortet (bzw. eine explizit angegebene Reply-To Adresse ignoriert).", "lang_mailTemplates": "E-Mail Templates", @@ -48,11 +53,14 @@ "lang_maxTransfers": "Maximale Zahl gleichzeitiger Up-\/Downloads pro Benutzer", "lang_miscOptions": "Verschiedene Einstellungen", "lang_modified": "Modifiziert", + "lang_name": "Name", + "lang_networkshares": "Netzlaufwerke", "lang_organization": "Einrichtung", "lang_organizationListHeader": "Nutzungsrechte f\u00fcr den Satelliten festlegen", "lang_os": "Betriebssystem", "lang_owner": "Besitzer", "lang_passwordplaceholder": "SMTP Passwort", + "lang_path": "Pfad", "lang_placeholders": "Platzhalter", "lang_port": "Port", "lang_reallyResetTemplates": "Sind Sie sicher, dass Sie alle Texte l\u00f6schen und auf die Standardwerte zur\u00fccksetzen wollen?", @@ -61,15 +69,18 @@ "lang_runtimeConfig": "Laufzeit-Konfiguration", "lang_runtimeConfigLimits": "Beschr\u00e4nkungen", "lang_senderAddress": "Absenderadresse", + "lang_shareDeleteConfirm": "Willst du dieses Netzlaufwerk wirklich l\u00f6schen?", "lang_senderName": "Absender Anzeigename", "lang_size": "Gr\u00f6\u00dfe", "lang_spaceWastedDuplication": "Potentiell durch mehrfach vorkommende Bl\u00f6cke belegter Speicherplatz", + "lang_specificUser": "Spezifischer Nutzer", "lang_ssl": "SSL-Modus", "lang_sslExplicit": "Explizites SSL (\"STARTTLS\")", "lang_sslImplicit": "Implizites SSL", "lang_sslNone": "Kein SSL", "lang_superUser": "Ist SuperUser (darf alle Veranstaltungen und VMs bearbeiten\/l\u00f6schen)", "lang_system": "System", + "lang_target": "Ziel", "lang_template": "Template", "lang_templatePageDescription": "Hier k\u00f6nnen Sie die Textbausteine bearbeiten, aus denen die Mails generiert werden, die der bwLehrpool-Server bez\u00fcglich Virtueller Maschinen und Veranstaltungen versendet. Diese Funktionalit\u00e4t unterst\u00fctzt zur Zeit keine Internationalisierung.", "lang_test": "Test-Mail senden", diff --git a/modules-available/dozmod/lang/en/messages.json b/modules-available/dozmod/lang/en/messages.json index 6d7ea0ac..8d309d1d 100644 --- a/modules-available/dozmod/lang/en/messages.json +++ b/modules-available/dozmod/lang/en/messages.json @@ -4,6 +4,8 @@ "dozmod-error": "Error communicating with the bwLehrpool-Suite server: {{0}}", "images-pending-delete-exist": "VMs marked for deletion: {{0}}", "mail-config-saved": "Mail config saved", + "networkshare-deleted": "Network share deleted", + "networkshare-saved": "Network share saved", "no-expired-images": "No expired VMs", "nothing-submitted": "There was nothing submitted", "runtimelimits-config-saved": "Configuration saved successfully", diff --git a/modules-available/dozmod/lang/en/module.json b/modules-available/dozmod/lang/en/module.json index b7a04762..91ebf304 100644 --- a/modules-available/dozmod/lang/en/module.json +++ b/modules-available/dozmod/lang/en/module.json @@ -4,6 +4,7 @@ "submenu_actionlog": "action log", "submenu_expiredimages": "Expired VM versions", "submenu_mailconfig": "email configuration", + "submenu_networkshares": "Network Shares", "submenu_runtimeconfig": "limits and defaults", "submenu_templates": "templates", "submenu_users": "users and permissions" diff --git a/modules-available/dozmod/lang/en/permissions.json b/modules-available/dozmod/lang/en/permissions.json index 0827c8d2..c1e44504 100644 --- a/modules-available/dozmod/lang/en/permissions.json +++ b/modules-available/dozmod/lang/en/permissions.json @@ -2,6 +2,8 @@ "actionlog.view": "View action log.", "expiredimages.delete": "Delete images marked for deletion.", "mailconfig.save": "Save SMTP configuration for sending mails.", + "networkshares.save": "View network drives.", + "networkshares.view": "Save network drives.", "runtimeconfig.save": "Save limits and defaults of a runtime configuration.", "templates.reset": "Reset email templates.", "templates.save": "Save email templates.", diff --git a/modules-available/dozmod/lang/en/template-tags.json b/modules-available/dozmod/lang/en/template-tags.json index 3ee95e8c..9cbc7378 100644 --- a/modules-available/dozmod/lang/en/template-tags.json +++ b/modules-available/dozmod/lang/en/template-tags.json @@ -1,8 +1,11 @@ { "lang_actionTarget": "Action target", + "lang_active": "Active", + "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_asteriskRequired": "Fields marked with (*) are required", + "lang_authMethod": "Authentication", "lang_blockCount": "Block count", "lang_bwlehrpoolsuite": "bwLehrpool-Suite", "lang_canLoginOrganization": "Users from this organization can login", @@ -21,6 +24,7 @@ "lang_descriptionRuntimeLimits": "Here you can define some limits, e.g. how long a newly uploaded VM will be valid. This should make sure that you don't end up with a lot of old, unused VMs over time.\r\n\r\nModified settings won't apply for already existing VMs.", "lang_description_delete_images": "This is a list of VMs that either expired, or where the disk image is damaged or missing. These VMs are not available in bwLehrpool currently, but you have to manually confirm the deletion of the disk images for safety reasons (clock skew etc.)", "lang_dozmodLogHeading": "bwLehrpool-Suite action log", + "lang_editNetworkshare": "Edit Network Share", "lang_email": "E-Mail", "lang_emailNotifications": "E-Mail notifications enabled", "lang_error": "Error", @@ -39,6 +43,7 @@ "lang_lecturePermissionAdmin": "Administrate", "lang_lecturePermissionEdit": "Edit", "lang_loadDefaults": "Reset all templates to their defaults", + "lang_loggedInUser": "Logged in User", "lang_mailConfig": "SMTP configuration for sending mails", "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", @@ -48,11 +53,14 @@ "lang_maxTransfers": "Max concurrent transfers per user", "lang_miscOptions": "Misc options", "lang_modified": "modified", + "lang_name": "Name", + "lang_networkshares": "Network Shares", "lang_organization": "Organization", "lang_organizationListHeader": "Set access permissions for organizations", "lang_os": "Operating System", "lang_owner": "Owner", "lang_passwordplaceholder": "SMTP Password", + "lang_path": "Path", "lang_placeholders": "Placeholders", "lang_port": "Port", "lang_reallyResetTemplates": "Are you sure you want to reset all texts to their default values?", @@ -62,14 +70,17 @@ "lang_runtimeConfigLimits": "Limitations", "lang_senderAddress": "Sender address", "lang_senderName": "Sender's display name", + "lang_shareDeleteConfirm": "Do you really want to delete this network share?", "lang_size": "Size", "lang_spaceWastedDuplication": "Potentially wasted space by duplicate blocks", + "lang_specificUser": "Specific User", "lang_ssl": "SSL mode", "lang_sslExplicit": "Explicit SSL (\"STARTTLS\")", "lang_sslImplicit": "Implicit SSL", "lang_sslNone": "No SSL", "lang_superUser": "Is super user (can edit\/delete all lectures and VMs)", "lang_system": "System", + "lang_target": "Target", "lang_template": "Template", "lang_templatePageDescription": "Here you can edit text fragments that are used to compose the information and reminder mails sent by the bwLehrpool server, e.g. when a lecture or VM is about to expire.", "lang_test": "Send test mail", diff --git a/modules-available/dozmod/page.inc.php b/modules-available/dozmod/page.inc.php index a8e0da0e..9fc65f5f 100644 --- a/modules-available/dozmod/page.inc.php +++ b/modules-available/dozmod/page.inc.php @@ -5,7 +5,7 @@ class Page_DozMod extends Page /** @var bool true if we have a proper subpage */ private $haveSubPage = false; - private $validSections = ['expiredimages', 'mailconfig', 'templates', 'runtimeconfig', 'users', 'actionlog']; + private $validSections = ['expiredimages', 'mailconfig', 'templates', 'runtimeconfig', 'users', 'actionlog', 'networkshares']; private $section; @@ -60,6 +60,7 @@ class Page_DozMod extends Page Dictionary::translate('submenu_runtimeconfig', true); Dictionary::translate('submenu_users', true); Dictionary::translate('submenu_actionlog', true); + Dictionary::translate('submenu_networkshares', true); */ /* add sub-menus */ diff --git a/modules-available/dozmod/pages/networkshares.inc.php b/modules-available/dozmod/pages/networkshares.inc.php new file mode 100644 index 00000000..d0bbe03a --- /dev/null +++ b/modules-available/dozmod/pages/networkshares.inc.php @@ -0,0 +1,63 @@ + $shareid]); + if ($res) Message::addSuccess('networkshare-deleted'); + } + } else if ($action === 'save') { + User::assertPermission('networkshares.save'); + $shareid = Request::post('shareid', false, 'int'); + $sharename = Request::post('sharename', false, 'string'); + $path = Request::post('path', false, 'string'); + $target = Request::post('target', null, 'string'); + $username = Request::post('username', null, 'string'); + $password = Request::post('password', null, 'string'); + if ($sharename && $path) { + if ($shareid) { + Database::exec('UPDATE sat.presetnetworkshare SET sharename = :sharename, path = :path, target = :target, username = :username, password = :password' + .' WHERE shareid = :shareid', compact('shareid', 'sharename', 'path', 'target', 'username', 'password')); + } else { + Database::exec('INSERT INTO sat.presetnetworkshare (sharename, path, target, username, password, active)' + .' VALUES (:sharename, :path, :target, :username, :password, 0)', compact('sharename', 'path', 'target', 'username', 'password')); + } + Message::addSuccess('networkshare-saved'); + } + } else if ($action === 'toggleActive') { + User::assertPermission('networkshares.save'); + $shareid = Request::post('shareid', false, 'int'); + Database::exec('UPDATE sat.presetnetworkshare SET active = !active WHERE shareid = :shareid', compact('shareid')); + } + User::assertPermission('networkshares.view'); + } + + public static function doRender() + { + $show = Request::get('show', 'list', 'string'); + if ($show === 'list') { + $res = Database::simpleQuery('SELECT * FROM sat.presetnetworkshare;'); + $rows = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $row['specificUser'] = $row['username'] && $row['password']; + $rows[] = $row; + } + Render::addTemplate('networkshares', ['networkshares' => $rows, 'hasEditPermissions' => User::hasPermission('networkshares.save')]); + } else if ($show === 'edit') { + $shareid = Request::get('shareid', 0, 'int'); + $data = Database::queryFirst('SELECT * FROM sat.presetnetworkshare WHERE shareid = :shareid', ['shareid' => $shareid]); + if ($data['username'] && $data['password']) $data['specificUser'] = 'selected'; + else $data['loggedInUser'] = 'selected'; + Render::addTemplate('networkshares-edit', $data); + } + } + +} diff --git a/modules-available/dozmod/permissions/permissions.json b/modules-available/dozmod/permissions/permissions.json index b9c82107..db20a3c0 100644 --- a/modules-available/dozmod/permissions/permissions.json +++ b/modules-available/dozmod/permissions/permissions.json @@ -8,6 +8,12 @@ "mailconfig.save": { "location-aware": false }, + "networkshares.view": { + "location-aware": false + }, + "networkshares.save": { + "location-aware": false + }, "runtimeconfig.save": { "location-aware": false }, diff --git a/modules-available/dozmod/templates/networkshares-edit.html b/modules-available/dozmod/templates/networkshares-edit.html new file mode 100644 index 00000000..32aa902f --- /dev/null +++ b/modules-available/dozmod/templates/networkshares-edit.html @@ -0,0 +1,85 @@ +

    {{lang_networkshares}}

    + +
    +
    + {{lang_editNetworkshare}} +
    +
    +
    + + + + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + {{lang_cancel}} + + +
    +
    +
    +
    + + \ No newline at end of file diff --git a/modules-available/dozmod/templates/networkshares.html b/modules-available/dozmod/templates/networkshares.html new file mode 100644 index 00000000..48506b4e --- /dev/null +++ b/modules-available/dozmod/templates/networkshares.html @@ -0,0 +1,95 @@ +

    {{lang_networkshares}}

    + + + + + + + + + + {{#hasEditPermissions}} + + + + {{/hasEditPermissions}} + + + + {{#networkshares}} + + + + + + + {{#hasEditPermissions}} + + + + {{/hasEditPermissions}} + + {{/networkshares}} + +
    {{lang_name}}{{lang_path}}{{lang_target}}{{lang_authMethod}}{{lang_username}}{{lang_active}}{{lang_edit}}{{lang_delete}}
    {{sharename}}{{path}}{{#target}}{{.}}:{{/target}}{{#specificUser}}{{lang_specificUser}}{{/specificUser}}{{^specificUser}}{{lang_loggedInUser}}{{/specificUser}}{{#specificUser}}{{username}}{{/specificUser}} +
    + + + + +
    +
    + + + + + +
    +{{#hasEditPermissions}} + +{{/hasEditPermissions}} + + +
    + + + +
    + + \ No newline at end of file -- cgit v1.2.3-55-g7522 From b98119be9411ad73b989fdf29284ad59b8340e4e Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 10 Dec 2018 15:43:07 +0100 Subject: [dozmod] Add editor for predefined run scripts Assigning scripts to certain locations only is currently not possible. Whether this is required is to be discussed, since predefined scripts selectable by bwLehrpool-Suite users would almost cover this use case. Refs #3145 --- modules-available/dozmod/lang/de/messages.json | 2 + modules-available/dozmod/lang/de/module.json | 1 + modules-available/dozmod/lang/de/permissions.json | 2 + .../dozmod/lang/de/template-tags.json | 18 +++ modules-available/dozmod/page.inc.php | 3 +- modules-available/dozmod/pages/runscripts.inc.php | 133 +++++++++++++++++++++ .../dozmod/permissions/permissions.json | 6 + modules-available/dozmod/style.css | 20 ++++ .../dozmod/templates/runscripts-edit.html | 89 ++++++++++++++ .../dozmod/templates/runscripts-list.html | 89 ++++++++++++++ 10 files changed, 362 insertions(+), 1 deletion(-) create mode 100644 modules-available/dozmod/pages/runscripts.inc.php create mode 100644 modules-available/dozmod/templates/runscripts-edit.html create mode 100644 modules-available/dozmod/templates/runscripts-list.html (limited to 'modules-available/dozmod/permissions/permissions.json') diff --git a/modules-available/dozmod/lang/de/messages.json b/modules-available/dozmod/lang/de/messages.json index f74c3eab..4a4be923 100644 --- a/modules-available/dozmod/lang/de/messages.json +++ b/modules-available/dozmod/lang/de/messages.json @@ -18,6 +18,8 @@ "networkshare-saved": "Netzlaufwerk gespeichert", "no-expired-images": "Keine Abgelaufenen VM-Versionen", "nothing-submitted": "Es wurde nichts \u00fcbermittelt", + "runscript-invalid-id": "Ung\u00fcltige Script-ID: {{0}}", + "runscript-saved": "Script gespeichert", "runtimelimits-config-saved": "Einstellungen gespeichert", "templates-saved": "Templates wurden gespeichert", "timeout": "Zeit\u00fcberschreitung", diff --git a/modules-available/dozmod/lang/de/module.json b/modules-available/dozmod/lang/de/module.json index b2746b81..de8b10f7 100644 --- a/modules-available/dozmod/lang/de/module.json +++ b/modules-available/dozmod/lang/de/module.json @@ -6,6 +6,7 @@ "submenu_ldapfilters": "LDAP Filter", "submenu_mailconfig": "Email-Konfiguration", "submenu_networkshares": "Netzlaufwerke", + "submenu_runscripts": "Startscripte", "submenu_runtimeconfig": "Limits und Standardwerte", "submenu_templates": "Textbausteine f\u00fcr E-Mails", "submenu_users": "Benutzer und Berechtigungen" diff --git a/modules-available/dozmod/lang/de/permissions.json b/modules-available/dozmod/lang/de/permissions.json index 845be3b9..a1675148 100644 --- a/modules-available/dozmod/lang/de/permissions.json +++ b/modules-available/dozmod/lang/de/permissions.json @@ -6,6 +6,8 @@ "mailconfig.save": "\u00c4nderungen an der SMTP-Konfiguration zum Versenden von Mails speichern.", "networkshares.save": "Netzlaufwerke einsehen.", "networkshares.view": "\u00c4nderungen an den Netzlaufwerken speichern.", + "runscripts.save": "Startkripte erstellen\/bearbeiten", + "runscripts.view": "Startscripte auflisten", "runtimeconfig.save": "\u00c4nderungen an der Laufzeit-Konfiguration speichern.", "templates.reset": "E-Mail Templates zur\u00fccksetzen.", "templates.save": "E-Mail Templates speichern.", diff --git a/modules-available/dozmod/lang/de/template-tags.json b/modules-available/dozmod/lang/de/template-tags.json index 99756995..ef775a16 100644 --- a/modules-available/dozmod/lang/de/template-tags.json +++ b/modules-available/dozmod/lang/de/template-tags.json @@ -25,6 +25,7 @@ "lang_description_delete_images": "Diese Liste zeigt VMs, die entweder abgelaufen sind, oder deren Datei besch\u00e4digt, verschoben oder gel\u00f6scht wurde. Diese Images sind zur Zeit im Lehrpool nicht verf\u00fcgbar, ihre endg\u00fcltige L\u00f6schung muss aber manuell best\u00e4tigt werden, um gr\u00f6\u00dfere Katastrophen durch Softwarefehler, verstellte Systemuhren etc. zu vermeiden.", "lang_dozmodLogHeading": "bwLehrpool-Suite Aktionslog", "lang_editNetworkshare": "Netzlaufwerk bearbeiten", + "lang_editScript": "Startscript bearbeiten", "lang_email": "EMail", "lang_emailNotifications": "EMail-Benachrichtigungen aktiviert", "lang_error": "Fehler", @@ -34,6 +35,7 @@ "lang_hasNewer": "Neuere Version existiert", "lang_hash": "Hash", "lang_heading": "Zu l\u00f6schende VM-Versionen", + "lang_hidden": "Versteckt", "lang_host": "Host", "lang_image": "VM", "lang_lastEditor": "Zuletzt bearbeitet von", @@ -60,12 +62,14 @@ "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_minimized": "Minimiert", "lang_miscOptions": "Verschiedene Einstellungen", "lang_modified": "Modifiziert", "lang_name": "Name", "lang_networkshares": "Netzlaufwerke", "lang_networksharesIntro": "Hier k\u00f6nnen Sie vordefinierte Netzlaufwerke anlegen, die den Nutzern der bwLehrpool-Suite zur Auswahl gestellt werden. Es ist den Nutzern der bwLehrpool-Suite weiterhin m\u00f6glich, komplett eigene Netzwerkfreigaben zu definieren. Die Angaben hier sollen lediglich das Hinzuf\u00fcgen h\u00e4ufig genutzter Laufwerke vereinfachen, bzw. das \u00c4ndern eines Netzwerkpfades vereinfachen, da in diesem Fall nur der Zentrale Eintrag hier angepasst werden muss, und nicht mehr wie zuvor jede Veranstaltung einzeln.", "lang_none": "(Keiner)", + "lang_normal": "Normal", "lang_organization": "Einrichtung", "lang_organizationListHeader": "Nutzungsrechte f\u00fcr den Satelliten festlegen", "lang_os": "Betriebssystem", @@ -78,8 +82,22 @@ "lang_reallyResetTemplates": "Sind Sie sicher, dass Sie alle Texte l\u00f6schen und auf die Standardwerte zur\u00fccksetzen wollen?", "lang_replaceWithOriginal": "Originaltext in Textbox laden", "lang_replyTo": "Reply-To Adresse", + "lang_runScriptAdd": "Script hinzuf\u00fcgen", + "lang_runScriptDeleteConfirmation": "Script wirklich l\u00f6schen?", "lang_runtimeConfig": "Laufzeit-Konfiguration", "lang_runtimeConfigLimits": "Beschr\u00e4nkungen", + "lang_scriptContent": "Scriptinhalt", + "lang_scriptExtension": "Dateinamenerweiterung", + "lang_scriptExtensionHead": "Erweiterung", + "lang_scriptIsGlobal": "Script ist global, wird in jeder Veranstaltung ausgef\u00fchrt", + "lang_scriptIsGlobalHead": "Global", + "lang_scriptIsPredefined": "Script ist ein vordefiniertes Script, das in der bwLehrpool-Suite zur Auswahl steht", + "lang_scriptPassCredentials": "Benutzername\/Passwort an dieses Script \u00fcbergeben", + "lang_scriptPassCredentialsHead": "User\/Pass", + "lang_scriptVisibility": "Anzeigemodus", + "lang_scriptVisibilityHead": "Anzeige", + "lang_scriptsHead": "Startscripte f\u00fcr Virtuelle Umgebungen", + "lang_scriptsIntro": "Hier k\u00f6nnen Sie Startskripte definieren, die entweder global bei jedem Start einer Veranstaltung ausgef\u00fchrt werden, oder den Nutzerinnen der bwLehrpool-Suite zur Vorauswahl zur Verf\u00fcgung gestellt werden.", "lang_senderAddress": "Absenderadresse", "lang_senderName": "Absender Anzeigename", "lang_shareDeleteConfirm": "Willst du dieses Netzlaufwerk wirklich l\u00f6schen?", diff --git a/modules-available/dozmod/page.inc.php b/modules-available/dozmod/page.inc.php index cdb347ab..776109cf 100644 --- a/modules-available/dozmod/page.inc.php +++ b/modules-available/dozmod/page.inc.php @@ -5,7 +5,7 @@ class Page_DozMod extends Page /** @var bool true if we have a proper subpage */ private $haveSubPage = false; - private $validSections = ['expiredimages', 'mailconfig', 'templates', 'runtimeconfig', 'users', 'actionlog', 'networkshares', 'ldapfilters']; + private $validSections = ['expiredimages', 'mailconfig', 'templates', 'runtimeconfig', 'users', 'actionlog', 'networkshares', 'ldapfilters', 'runscripts']; private $section; @@ -62,6 +62,7 @@ class Page_DozMod extends Page Dictionary::translate('submenu_actionlog', true); Dictionary::translate('submenu_networkshares', true); Dictionary::translate('submenu_ldapfilters', true); + Dictionary::translate('submenu_runscripts', true); */ /* add sub-menus */ diff --git a/modules-available/dozmod/pages/runscripts.inc.php b/modules-available/dozmod/pages/runscripts.inc.php new file mode 100644 index 00000000..c6566c13 --- /dev/null +++ b/modules-available/dozmod/pages/runscripts.inc.php @@ -0,0 +1,133 @@ + $scriptname, + 'content' => Request::post('content', '', 'string'), + 'visibility' => Request::post('visibility', 1, 'int'), + 'extension' => preg_replace('/[^a-z0-9_\-~\!\$\=]/i', '', Request::post('extension', '', 'string')), + 'passcreds' => Request::post('passcreds', 0, 'int') !== 0, + 'isglobal' => Request::post('isglobal', 0, 'int') !== 0, + ]; + if ($id === 0) { + // New entry + $ret = Database::exec('INSERT INTO sat.presetrunscript + (scriptname, content, extension, visibility, passcreds, isglobal) VALUES + (:scriptname, :content, :extension, :visibility, :passcreds, :isglobal)', $data); + $id = Database::lastInsertId(); + } else { + // Edit entry + $data['id'] = $id; + Database::exec('UPDATE sat.presetrunscript SET + scriptname = :scriptname, content = :content, extension = :extension, visibility = :visibility, + passcreds = :passcreds, isglobal = :isglobal + WHERE runscriptid = :id', $data); + } + $oslist = Request::post('osid', false, 'array'); + if (is_array($oslist)) { + $oslist = array_filter($oslist, 'is_numeric'); + $query = Database::prepare('INSERT INTO sat.presetrunscript_x_operatingsystem + (runscriptid, osid) VALUES (:id, :osid)'); + foreach ($oslist as $osid) { + $query->execute(['id' => $id, 'osid' => $osid]); + } + $query->closeCursor(); + Database::exec('DELETE FROM sat.presetrunscript_x_operatingsystem + WHERE runscriptid = :id AND osid NOT IN (:oslist)', ['id' => $id, 'oslist' => $oslist]); + } + Message::addSuccess('runscript-saved'); + } + + public static function doRender() + { + $show = Request::get('show', 'list', 'string'); + if ($show === 'list') { + $res = Database::simpleQuery('SELECT runscriptid, scriptname, extension, visibility, passcreds, isglobal + FROM sat.presetrunscript + ORDER BY scriptname ASC'); + $rows = []; + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if ($row['visibility'] == 0) { + $row['visibility'] = 'eye-close'; + } elseif ($row['visibility'] == 1) { + $row['visibility'] = 'eye-open'; + } else { + $row['visibility'] = 'arrow-down'; + } + $rows[] = $row; + } + Render::addTemplate('runscripts-list', ['list' => $rows, 'hasEditPermission' => User::hasPermission('runscripts.save')]); + } elseif ($show === 'edit') { + // Edit + $id = Request::get('runscriptid', false, 'int'); + if ($id === false) { + Message::addError('main.parameter-missing', 'runscriptid'); + Util::redirect('?do=dozmod§ion=runscripts'); + } + if ($id === 0) { + $row = [ + 'runscriptid' => 0, + 'visibility_1_checked' => 'checked', + 'isglobal_1_checked' => 'checked', + ]; + } else { + $row = Database::queryFirst('SELECT runscriptid, scriptname, content, extension, visibility, passcreds, isglobal + FROM sat.presetrunscript + WHERE runscriptid = :runscriptid', ['runscriptid' => $id]); + $row['visibility_' . $row['visibility'] . '_selected'] = 'selected'; + $row['passcreds_checked'] = $row['passcreds'] ? 'checked' : ''; + $row['isglobal_' . $row['isglobal'] . '_checked'] = 'checked'; + if ($row === false) { + Message::addError('runscript-invalid-id', $id); + Util::redirect('?do=dozmod§ion=runscripts'); + } + } + // Get OS + $row['oslist'] = []; + $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)) { + $row['oslist'][] = [ + 'osid' => $osrow['osid'], + 'displayname' => $osrow['displayname'], + 'checked' => $osrow['isvalid'] ? 'checked' : '', + ]; + } + // Output + Render::addTemplate('runscripts-edit', $row); + } + } + + public static function doAjax() + { + + } + +} diff --git a/modules-available/dozmod/permissions/permissions.json b/modules-available/dozmod/permissions/permissions.json index 4496b771..3f9cd604 100644 --- a/modules-available/dozmod/permissions/permissions.json +++ b/modules-available/dozmod/permissions/permissions.json @@ -23,6 +23,12 @@ "runtimeconfig.save": { "location-aware": false }, + "runscripts.view": { + "location-aware": false + }, + "runscripts.save": { + "location-aware": false + }, "templates.reset": { "location-aware": false }, diff --git a/modules-available/dozmod/style.css b/modules-available/dozmod/style.css index 23dd121e..4cec715a 100644 --- a/modules-available/dozmod/style.css +++ b/modules-available/dozmod/style.css @@ -48,4 +48,24 @@ .table > tbody > tr > td > div { display: inline-block; +} + +/* number of columns in tree view depending on screen size */ +.column-list { + column-gap: 20px; + column-count: 2; + padding-left: 20px; + padding-right: 20px; +} + +@media (min-width: 768px) { + .column-list { + column-count: 3; + } +} + +@media (min-width: 992px) { + .column-list { + column-count: 4; + } } \ No newline at end of file diff --git a/modules-available/dozmod/templates/runscripts-edit.html b/modules-available/dozmod/templates/runscripts-edit.html new file mode 100644 index 00000000..8d81b33c --- /dev/null +++ b/modules-available/dozmod/templates/runscripts-edit.html @@ -0,0 +1,89 @@ +

    {{lang_scriptsHead}}

    + +
    + + + +
    +
    + {{lang_editScript}} +
    +
    +
    + + +
    +
    + + + + +
    +
    + + +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    + +
    + {{#oslist}} +
    + + +
    + {{/oslist}} +
    + +
    + {{lang_cancel}} + +
    + +
    +
    + +
    + + diff --git a/modules-available/dozmod/templates/runscripts-list.html b/modules-available/dozmod/templates/runscripts-list.html new file mode 100644 index 00000000..4d519afb --- /dev/null +++ b/modules-available/dozmod/templates/runscripts-list.html @@ -0,0 +1,89 @@ +

    {{lang_scriptsHead}}

    + +

    + {{lang_scriptsIntro}} +

    + + + + + + + + + + {{#hasEditPermission}} + + + {{/hasEditPermission}} + + + + {{#list}} + + + + + + + {{#hasEditPermission}} + + + {{/hasEditPermission}} + + {{/list}} + +
    {{lang_name}}{{lang_scriptExtensionHead}}{{lang_scriptVisibilityHead}}{{lang_scriptPassCredentialsHead}}{{lang_scriptIsGlobalHead}}{{lang_edit}}{{lang_delete}}
    {{scriptname}}.{{extension}} + {{#passcreds}} + + {{/passcreds}} + + {{#isglobal}} + + {{/isglobal}} + + + + + + +
    + +{{#hasEditPermission}} + +{{/hasEditPermission}} + +
    + + + +
    + + -- cgit v1.2.3-55-g7522 From 1ee6bdcda1b285b24829eefc9b9e0ca14b828f77 Mon Sep 17 00:00:00 2001 From: Udo Walter Date: Tue, 12 Feb 2019 11:44:51 +0100 Subject: [dozmod] Add UI to create preset network rules --- modules-available/dozmod/lang/de/messages.json | 6 ++ modules-available/dozmod/lang/de/module.json | 1 + modules-available/dozmod/lang/de/permissions.json | 2 + .../dozmod/lang/de/template-tags.json | 4 + modules-available/dozmod/lang/en/messages.json | 6 ++ modules-available/dozmod/lang/en/module.json | 1 + modules-available/dozmod/lang/en/permissions.json | 2 + .../dozmod/lang/en/template-tags.json | 4 + modules-available/dozmod/page.inc.php | 2 +- .../dozmod/pages/networkrules.inc.php | 98 ++++++++++++++++++++++ .../dozmod/permissions/permissions.json | 6 ++ .../dozmod/templates/networkrules-edit.html | 43 ++++++++++ .../dozmod/templates/networkrules.html | 82 ++++++++++++++++++ 13 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 modules-available/dozmod/pages/networkrules.inc.php create mode 100644 modules-available/dozmod/templates/networkrules-edit.html create mode 100644 modules-available/dozmod/templates/networkrules.html (limited to 'modules-available/dozmod/permissions/permissions.json') diff --git a/modules-available/dozmod/lang/de/messages.json b/modules-available/dozmod/lang/de/messages.json index 4a4be923..805472d0 100644 --- a/modules-available/dozmod/lang/de/messages.json +++ b/modules-available/dozmod/lang/de/messages.json @@ -11,6 +11,12 @@ "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-invalid-direction": "Ung\u00fcltige Richtung: {{0}}", + "networkrule-invalid-ruleid": "Nicht-existierende Regel: {{0}}", + "networkrule-missing-host": "Fehlende Hostangabe", + "networkrule-missing-port": "Fehlende Portangabe", + "networkrule-saved": "Netzwerk-Regel gespeichert", "networkshare-deleted": "Netzlaufwerk gel\u00f6scht", "networkshare-invalid-auth-type": "Ung\u00fcltiger Authentifizierungs-Typ: {{0}}", "networkshare-invalid-shareid": "Nicht-existierender Share: {{0}}", diff --git a/modules-available/dozmod/lang/de/module.json b/modules-available/dozmod/lang/de/module.json index 8902852a..ff4519a7 100644 --- a/modules-available/dozmod/lang/de/module.json +++ b/modules-available/dozmod/lang/de/module.json @@ -5,6 +5,7 @@ "submenu_expiredimages": "Abgelaufene VM-Versionen", "submenu_ldapfilters": "LDAP-Filter", "submenu_mailconfig": "Email-Konfiguration", + "submenu_networkrules": "Netzwerk-Regeln", "submenu_networkshares": "Netzlaufwerke", "submenu_runscripts": "Startskripte", "submenu_runtimeconfig": "Limits und Standardwerte", diff --git a/modules-available/dozmod/lang/de/permissions.json b/modules-available/dozmod/lang/de/permissions.json index a1675148..6475f7ab 100644 --- a/modules-available/dozmod/lang/de/permissions.json +++ b/modules-available/dozmod/lang/de/permissions.json @@ -4,6 +4,8 @@ "ldapfilters.save": "LDAP Filter speichern.", "ldapfilters.view": "LDAP Filter einsehen.", "mailconfig.save": "\u00c4nderungen an der SMTP-Konfiguration zum Versenden von Mails speichern.", + "networkrules.save": "Netzwerk-Regeln einsehen.", + "networkrules.view": "\u00c4nderungen an den Netzwerk-Regeln speichern.", "networkshares.save": "Netzlaufwerke einsehen.", "networkshares.view": "\u00c4nderungen an den Netzlaufwerken speichern.", "runscripts.save": "Startkripte erstellen\/bearbeiten", diff --git a/modules-available/dozmod/lang/de/template-tags.json b/modules-available/dozmod/lang/de/template-tags.json index 0a719057..320c7592 100644 --- a/modules-available/dozmod/lang/de/template-tags.json +++ b/modules-available/dozmod/lang/de/template-tags.json @@ -1,6 +1,7 @@ { "lang_actionTarget": "Aktionsziel", "lang_active": "Aktiv", + "lang_addRule": "Netzwerk-Regel hinzuf\u00fcgen", "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.", @@ -23,7 +24,9 @@ "lang_descriptionPermissionConfig": "Dies sind die Berechtigungen, die ein Benutzer standardm\u00e4\u00dfig f\u00fcr fremde VMs\/Veranstaltungen hat. Sie werden angewandt, wenn der Besitzer keine anderweitigen Berechtigungen w\u00e4hlt.", "lang_descriptionRuntimeLimits": "Hier k\u00f6nnen Sie verschiedene Limits festlegen, z.B. wie lange eine VM nach dem Hochladen g\u00fcltig ist. Nach Ablauf dieses Zeitraums ist der Verantwortliche gezwungen, eine neue Version der VM hochzuladen. Damit k\u00f6nnen Sie das Ansammeln nicht mehr ben\u00f6tigter VMs eind\u00e4mmen. Weiterhin k\u00f6nnen Sie die maximale Anzahl gleichzeitiger Transfers pro Benutzer einschr\u00e4nken.\r\n\r\nVer\u00e4nderte Einstellungen wirken sich nicht auf bereits bestehende VMs aus.", "lang_description_delete_images": "Diese Liste zeigt VMs, die entweder abgelaufen sind, oder deren Datei besch\u00e4digt, verschoben oder gel\u00f6scht wurde. Diese Images sind zur Zeit im Lehrpool nicht verf\u00fcgbar, ihre endg\u00fcltige L\u00f6schung muss aber manuell best\u00e4tigt werden, um gr\u00f6\u00dfere Katastrophen durch Softwarefehler, verstellte Systemuhren etc. zu vermeiden.", + "lang_direction": "Richtung", "lang_dozmodLogHeading": "bwLehrpool-Suite Aktionslog", + "lang_editNetworkrule": "Netzwerk-Regel bearbeiten", "lang_editNetworkshare": "Netzlaufwerk bearbeiten", "lang_editScript": "Startscript bearbeiten", "lang_email": "EMail", @@ -66,6 +69,7 @@ "lang_miscOptions": "Verschiedene Einstellungen", "lang_modified": "Modifiziert", "lang_name": "Name", + "lang_networkrules": "Netzwerk-Regeln", "lang_networkshares": "Netzlaufwerke", "lang_networksharesIntro": "Hier k\u00f6nnen Sie vordefinierte Netzlaufwerke anlegen, die den Nutzern der bwLehrpool-Suite zur Auswahl gestellt werden. Es ist den Nutzern der bwLehrpool-Suite weiterhin m\u00f6glich, komplett eigene Netzwerkfreigaben zu definieren. Die Angaben hier sollen lediglich das Hinzuf\u00fcgen h\u00e4ufig genutzter Laufwerke vereinfachen, bzw. das \u00c4ndern eines Netzwerkpfades vereinfachen, da in diesem Fall nur der Zentrale Eintrag hier angepasst werden muss, und nicht mehr wie zuvor jede Veranstaltung einzeln.", "lang_none": "(Keiner)", diff --git a/modules-available/dozmod/lang/en/messages.json b/modules-available/dozmod/lang/en/messages.json index d09ff279..6d8296ec 100644 --- a/modules-available/dozmod/lang/en/messages.json +++ b/modules-available/dozmod/lang/en/messages.json @@ -11,6 +11,12 @@ "ldap-filter-saved": "Successfully modified LDAP filter", "ldap-invalid-filter-id": "Invalid LDAP filter id", "mail-config-saved": "Mail config saved", + "networkrule-deleted": "Network rule deleted", + "networkrule-invalid-direction": "Invalid direction: {{0}}", + "networkrule-invalid-ruleid": "Invalid rule id: {{0}}", + "networkrule-missing-host": "Missing host", + "networkrule-missing-port": "Missing port", + "networkrule-saved": "Network rule saved", "networkshare-deleted": "Network share deleted", "networkshare-invalid-auth-type": "Invalid auth type: {{0}}", "networkshare-invalid-shareid": "Invalid share id: {{0}}", diff --git a/modules-available/dozmod/lang/en/module.json b/modules-available/dozmod/lang/en/module.json index 4e3969ff..8967493d 100644 --- a/modules-available/dozmod/lang/en/module.json +++ b/modules-available/dozmod/lang/en/module.json @@ -5,6 +5,7 @@ "submenu_expiredimages": "Expired VM versions", "submenu_ldapfilters": "LDAP filters", "submenu_mailconfig": "email configuration", + "submenu_networkrules": "Network Rules", "submenu_networkshares": "Network Shares", "submenu_runtimeconfig": "limits and defaults", "submenu_templates": "templates", diff --git a/modules-available/dozmod/lang/en/permissions.json b/modules-available/dozmod/lang/en/permissions.json index d45e5207..dec3171a 100644 --- a/modules-available/dozmod/lang/en/permissions.json +++ b/modules-available/dozmod/lang/en/permissions.json @@ -4,6 +4,8 @@ "ldapfilters.save": "Save LDAP filter.", "ldapfilters.view": "View LDAP filters. ", "mailconfig.save": "Save SMTP configuration for sending mails.", + "networkrules.save": "View network rules.", + "networkrules.view": "Save network rules.", "networkshares.save": "View network drives.", "networkshares.view": "Save network drives.", "runtimeconfig.save": "Save limits and defaults of a runtime configuration.", diff --git a/modules-available/dozmod/lang/en/template-tags.json b/modules-available/dozmod/lang/en/template-tags.json index ddc89284..3f2ae1fc 100644 --- a/modules-available/dozmod/lang/en/template-tags.json +++ b/modules-available/dozmod/lang/en/template-tags.json @@ -1,6 +1,7 @@ { "lang_actionTarget": "Action target", "lang_active": "Active", + "lang_addRule": "Add Network Rule", "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.", @@ -23,7 +24,9 @@ "lang_descriptionPermissionConfig": "These are the default permissions being used for VMs and lectures if the owner does not specify any.", "lang_descriptionRuntimeLimits": "Here you can define some limits, e.g. how long a newly uploaded VM will be valid. This should make sure that you don't end up with a lot of old, unused VMs over time.\r\n\r\nModified settings won't apply for already existing VMs.", "lang_description_delete_images": "This is a list of VMs that either expired, or where the disk image is damaged or missing. These VMs are not available in bwLehrpool currently, but you have to manually confirm the deletion of the disk images for safety reasons (clock skew etc.)", + "lang_direction": "Direction", "lang_dozmodLogHeading": "bwLehrpool-Suite action log", + "lang_editNetworkrule": "Edit Network Rule", "lang_editNetworkshare": "Edit Network Share", "lang_email": "E-Mail", "lang_emailNotifications": "E-Mail notifications enabled", @@ -63,6 +66,7 @@ "lang_miscOptions": "Misc options", "lang_modified": "modified", "lang_name": "Name", + "lang_networkrules": "Network Rules", "lang_networkshares": "Network Shares", "lang_networksharesIntro": "This is the list of predefined network shares. bwLehrpool-Suite users can still add custom network shares to their lectures, however having commonly used network shares as predefined entries should be much more convenient. Another advantage is that changing the path of a network share centrally avoids having to edit a dozen lectures' configuration manually.", "lang_none": "(none)", diff --git a/modules-available/dozmod/page.inc.php b/modules-available/dozmod/page.inc.php index 776109cf..b772890f 100644 --- a/modules-available/dozmod/page.inc.php +++ b/modules-available/dozmod/page.inc.php @@ -5,7 +5,7 @@ class Page_DozMod extends Page /** @var bool true if we have a proper subpage */ private $haveSubPage = false; - private $validSections = ['expiredimages', 'mailconfig', 'templates', 'runtimeconfig', 'users', 'actionlog', 'networkshares', 'ldapfilters', 'runscripts']; + private $validSections = ['expiredimages', 'mailconfig', 'templates', 'runtimeconfig', 'users', 'actionlog', 'networkshares', 'ldapfilters', 'runscripts', 'networkrules']; private $section; diff --git a/modules-available/dozmod/pages/networkrules.inc.php b/modules-available/dozmod/pages/networkrules.inc.php new file mode 100644 index 00000000..6011e3ff --- /dev/null +++ b/modules-available/dozmod/pages/networkrules.inc.php @@ -0,0 +1,98 @@ + $ruleid]); + if ($res !== false) { + Message::addSuccess('networkrule-deleted'); + } + } + } else if ($action === 'save') { + User::assertPermission('networkrules.save'); + $ruleid = Request::post('ruleid', 0, 'int'); + $rulename = Request::post('rulename', '', 'string'); + $host = Request::post('host', '', 'string'); + $port = Request::post('port', '', 'string'); + $direction = Request::post('direction', '', 'string'); + + if (!in_array($direction, ['IN', 'OUT'], true)) { + Message::addError('networkrule-invalid-direction', $direction); + } elseif (empty($host)) { + Message::addError('networkrule-missing-host'); + } elseif (empty($port)) { + Message::addError('networkrule-missing-port'); + } else { + $data = json_encode([ + 'host' => $host, + 'port' => $port, + 'direction' => $direction + ]); + if ($ruleid !== 0) { + Database::exec('UPDATE sat.presetnetworkrules SET rulename = :rulename, ruledata = :data' + .' WHERE ruleid = :ruleid', compact('ruleid', 'rulename', 'data')); + } else { + Database::exec('INSERT INTO sat.presetnetworkrules (rulename, ruledata)' + .' VALUES (:rulename, :data)', compact('rulename', 'data')); + } + Message::addSuccess('networkrule-saved'); + } + } + if (Request::isPost()) { + Util::redirect('?do=dozmod§ion=networkrules'); + } + User::assertPermission('networkrules.view'); + } + + public static function doRender() + { + $show = Request::get('show', 'list', 'string'); + if ($show === 'list') { + $res = Database::simpleQuery('SELECT ruleid, rulename, ruledata + FROM sat.presetnetworkrules ORDER BY rulename ASC'); + $rows = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $dec = json_decode($row['ruledata'], true); + if (!is_array($dec)) { + $dec = []; + } + $rows[] = $row + $dec; + } + Render::addTemplate('networkrules', [ + 'networkrules' => $rows, + 'hasEditPermissions' => User::hasPermission('networkrules.save') + ]); + } else if ($show === 'edit') { + $ruleid = Request::get('ruleid', 0, 'int'); + if ($ruleid === 0) { + $data = []; + } else { + $data = Database::queryFirst('SELECT ruleid, rulename, ruledata + FROM sat.presetnetworkrules WHERE ruleid = :ruleid', ['ruleid' => $ruleid]); + if ($data === false) { + Message::addError('networkrule-invalid-ruleid', $ruleid); + Util::redirect('?do=dozmod§ion=networkrules'); + } + $dec = json_decode($data['ruledata'], true); + if (is_array($dec)) { + $data += $dec; + } + if ($data['direction'] === 'IN') { + $data['inSelected'] = 'selected'; + } else { + $data['outSelected'] = 'selected'; + } + } + Render::addTemplate('networkrules-edit', $data); + } + } + +} diff --git a/modules-available/dozmod/permissions/permissions.json b/modules-available/dozmod/permissions/permissions.json index 3f9cd604..c8958089 100644 --- a/modules-available/dozmod/permissions/permissions.json +++ b/modules-available/dozmod/permissions/permissions.json @@ -14,6 +14,12 @@ "mailconfig.save": { "location-aware": false }, + "networkrules.view": { + "location-aware": false + }, + "networkrules.save": { + "location-aware": false + }, "networkshares.view": { "location-aware": false }, diff --git a/modules-available/dozmod/templates/networkrules-edit.html b/modules-available/dozmod/templates/networkrules-edit.html new file mode 100644 index 00000000..c04e2825 --- /dev/null +++ b/modules-available/dozmod/templates/networkrules-edit.html @@ -0,0 +1,43 @@ +

    {{lang_networkrules}}

    + +
    +
    + {{lang_editNetworkrule}} +
    +
    +
    + + + + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + {{lang_cancel}} + + +
    +
    +
    +
    \ No newline at end of file diff --git a/modules-available/dozmod/templates/networkrules.html b/modules-available/dozmod/templates/networkrules.html new file mode 100644 index 00000000..4344ff4f --- /dev/null +++ b/modules-available/dozmod/templates/networkrules.html @@ -0,0 +1,82 @@ +

    {{lang_networkrules}}

    + +

    + {{lang_networkrulesIntro}} +

    + + + + + + + + + {{#hasEditPermissions}} + + + {{/hasEditPermissions}} + + + + {{#networkrules}} + + + + + + {{#hasEditPermissions}} + + + {{/hasEditPermissions}} + + {{/networkrules}} + +
    {{lang_name}}{{lang_host}}{{lang_port}}{{lang_direction}}{{lang_edit}}{{lang_delete}}
    {{rulename}}{{host}}{{port}}{{direction}} + + + + + +
    +{{#hasEditPermissions}} + +{{/hasEditPermissions}} + + +
    + + + +
    + + \ No newline at end of file -- cgit v1.2.3-55-g7522