diff options
author | root | 2019-02-19 18:53:50 +0100 |
---|---|---|
committer | root | 2019-02-19 18:53:50 +0100 |
commit | 0ad4c0f8196b61699754762aacbaab0223478ab9 (patch) | |
tree | de434c4aea8d07ecd01cd3badd48d057d62c2d1b /modules-available/dozmod/pages | |
parent | [usb-lock-off] Edit rule cleanup and fix of the dropdown boxes. (diff) | |
parent | [statistics] Fix RAM change warning to handle increase too (diff) | |
download | slx-admin-usb-lock-off.tar.gz slx-admin-usb-lock-off.tar.xz slx-admin-usb-lock-off.zip |
Merge branch 'master' into usb-lock-offusb-lock-off
Diffstat (limited to 'modules-available/dozmod/pages')
-rw-r--r-- | modules-available/dozmod/pages/actionlog.inc.php | 163 | ||||
-rw-r--r-- | modules-available/dozmod/pages/expiredimages.inc.php | 97 | ||||
-rw-r--r-- | modules-available/dozmod/pages/ldapfilters.inc.php | 119 | ||||
-rw-r--r-- | modules-available/dozmod/pages/mailconfig.inc.php | 96 | ||||
-rw-r--r-- | modules-available/dozmod/pages/networkrules.inc.php | 98 | ||||
-rw-r--r-- | modules-available/dozmod/pages/networkshares.inc.php | 108 | ||||
-rw-r--r-- | modules-available/dozmod/pages/runscripts.inc.php | 133 | ||||
-rw-r--r-- | modules-available/dozmod/pages/runtimeconfig.inc.php | 112 | ||||
-rw-r--r-- | modules-available/dozmod/pages/templates.inc.php | 139 | ||||
-rw-r--r-- | modules-available/dozmod/pages/users.inc.php | 128 |
10 files changed, 1193 insertions, 0 deletions
diff --git a/modules-available/dozmod/pages/actionlog.inc.php b/modules-available/dozmod/pages/actionlog.inc.php new file mode 100644 index 00000000..a014ddf7 --- /dev/null +++ b/modules-available/dozmod/pages/actionlog.inc.php @@ -0,0 +1,163 @@ +<?php + +class SubPage +{ + + private static $action; + private static $uuid; + + 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 . '"'); + } + self::$uuid = Request::get('uuid', '', 'string'); + } + + public static function doRender() + { + Render::addTemplate('actionlog-header'); + if (self::$action === '') { + self::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 (self::$action === 'showuser') { + self::listUser(); + } else { + self::listTarget(); + } + } + + private static 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' => 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; + } + + 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 @@ +<?php + +class SubPage +{ + + public static function doPreprocess() + { + $action = Request::post('action', false, 'string'); + + if ($action === 'delimages') { + if (User::hasPermission("expiredimages.delete")) { + $result = self::handleDeleteImages(); + if (!empty($result)) { + Message::addInfo('delete-images', $result); + } + Util::redirect('?do=DozMod'); + } + } + } + + private static 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 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/ldapfilters.inc.php b/modules-available/dozmod/pages/ldapfilters.inc.php new file mode 100644 index 00000000..d0ae41b8 --- /dev/null +++ b/modules-available/dozmod/pages/ldapfilters.inc.php @@ -0,0 +1,119 @@ +<?php + +class SubPage +{ + private static $show; + + public static function doPreprocess() + { + self::$show = Request::any('show', false, 'string'); + $action = Request::post('action'); + + if ($action === 'deleteFilter') { + User::assertPermission("ldapfilters.save"); + self::deleteLdapFilter(); + } else if ($action === 'saveFilter') { + User::assertPermission("ldapfilters.save"); + self::saveLdapFilter(); + } + User::assertPermission("ldapfilters.view"); + } + + public static function doRender() + { + if (self::$show === false) { + // Get all ldapfilters from the sat db. + $ldapfilters = Database::queryAll("SELECT filterid, filtername, filterkey, filtervalue FROM sat.presetlecturefilter + WHERE filtertype ='LDAP' ORDER BY filtername ASC"); + + $data = array( + 'ldapfilters' => $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 filterid, filtername, filterkey, filtervalue FROM sat.presetlecturefilter + WHERE filterid = :id AND filtertype = 'LDAP'", array( 'id' => $filterid)); + // TODO: Show error if not exists + + Render::addTemplate('ldapfilter-add', $ldapfilter); + } + } + } + + private static 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.presetlecturefilter WHERE filterid = :id AND filtertype = 'LDAP'", array('id' => $filterid)); + if ($res !== 1) { + Message::addWarning('ldap-invalid-filter-id', $filterid); + } else { + Message::addSuccess('ldap-filter-deleted'); + } + } + + private static 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.presetlecturefilter (filtertype, filtername, filterkey, filtervalue) + VALUES ('LDAP', :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.presetlecturefilter SET + filtername = :filtername, filterkey = :attribute, filtervalue = :value + WHERE filterid = :filterid AND filtertype = 'LDAP'", array( + 'filterid' => $filterid, + 'filtername' => $filtername, + 'attribute' => $filterattribute, + 'value' => $filtervalue + )); + + if ($res !== 1) { + Message::addError('ldap-filter-insert-failed'); + } else { + Message::addSuccess('ldap-filter-saved'); + } + + } + Util::redirect("?do=dozmod§ion=ldapfilters"); + } + + public static function doAjax() + { + + } + +}
\ No newline at end of file diff --git a/modules-available/dozmod/pages/mailconfig.inc.php b/modules-available/dozmod/pages/mailconfig.inc.php new file mode 100644 index 00000000..08205f2e --- /dev/null +++ b/modules-available/dozmod/pages/mailconfig.inc.php @@ -0,0 +1,96 @@ +<?php + +class SubPage +{ + + public static function doPreprocess() + { + $action = Request::post('action', false, 'string'); + + if ($action === 'mail') { + User::assertPermission("mailconfig.save"); + self::mailHandler(); + } + } + + private static function mailHandler() + { + // Check action + $do = Request::post('button'); + if ($do === 'save') { + // Prepare array + $data = self::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 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']); + Render::addTemplate('mailconfig', $mailConf); + } + + public static function doAjax() + { + User::assertPermission("mailconfig.save"); + $action = Request::post('action'); + if ($action === 'mail') { + 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/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 @@ +<?php + +class SubPage +{ + + public static function doPreprocess() + { + $action = Request::post('action', '', 'string'); + + if ($action === 'delete') { + User::assertPermission('networkrules.save'); + $ruleid = Request::post('ruleid', false, 'int'); + if ($ruleid !== false) { + $res = Database::exec('DELETE FROM sat.presetnetworkrules WHERE ruleid = :ruleid', ['ruleid' => $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/pages/networkshares.inc.php b/modules-available/dozmod/pages/networkshares.inc.php new file mode 100644 index 00000000..659321b4 --- /dev/null +++ b/modules-available/dozmod/pages/networkshares.inc.php @@ -0,0 +1,108 @@ +<?php + +class SubPage +{ + + public static function doPreprocess() + { + $action = Request::post('action', '', 'string'); + + if ($action === 'delete') { + User::assertPermission('networkshares.save'); + $shareid = Request::post('shareid', false, 'int'); + if ($shareid !== false) { + $res = Database::exec('DELETE FROM sat.presetnetworkshare WHERE shareid = :shareid', ['shareid' => $shareid]); + if ($res !== false) { + Message::addSuccess('networkshare-deleted'); + } + } + } else if ($action === 'save') { + User::assertPermission('networkshares.save'); + $shareid = Request::post('shareid', 0, 'int'); + $sharename = Request::post('sharename', '', 'string'); + $path = Request::post('path', false, 'string'); + $target = Request::post('target', '', 'string'); + $authType = Request::post('auth', '', 'string'); + $username = Request::post('username', '', 'string'); + $password = Request::post('password', '', 'string'); + if (!in_array($authType, ['LOGIN_USER', 'OTHER_USER'], true)) { + Message::addError('networkshare-invalid-auth-type', $authType); + } elseif (empty($path)) { + Message::addError('networkshare-missing-path'); + } else { + $data = json_encode([ + 'auth' => $authType, + 'path' => $path, + 'displayname' => $sharename, + 'mountpoint' => $target, + 'username' => $username, + 'password' => $password, + ]); + if ($shareid !== 0) { + Database::exec('UPDATE sat.presetnetworkshare SET sharename = :sharename, sharedata = :data' + .' WHERE shareid = :shareid', compact('shareid', 'sharename', 'data')); + } else { + Database::exec('INSERT INTO sat.presetnetworkshare (sharename, sharedata, active)' + .' VALUES (:sharename, :data, 1)', compact('sharename', 'data')); + } + Message::addSuccess('networkshare-saved'); + } + } else if ($action === 'activate' || $action === 'deactivate') { + User::assertPermission('networkshares.save'); + $shareid = Request::post('shareid', false, 'int'); + $active = ($action === 'activate' ? 1 : 0); + Database::exec('UPDATE sat.presetnetworkshare SET active = :active WHERE shareid = :shareid', compact('active', 'shareid')); + } + if (Request::isPost()) { + Util::redirect('?do=dozmod§ion=networkshares'); + } + User::assertPermission('networkshares.view'); + } + + public static function doRender() + { + $show = Request::get('show', 'list', 'string'); + if ($show === 'list') { + $res = Database::simpleQuery('SELECT shareid, sharename, sharedata, active + FROM sat.presetnetworkshare ORDER BY sharename ASC'); + $rows = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $dec = json_decode($row['sharedata'], true); + if (!is_array($dec)) { + $dec = []; + } + if ($dec['auth'] === 'LOGIN_USER') { + $row['loginAsUser'] = true; + } + $rows[] = $row + $dec; + } + Render::addTemplate('networkshares', [ + 'networkshares' => $rows, + 'hasEditPermissions' => User::hasPermission('networkshares.save') + ]); + } else if ($show === 'edit') { + $shareid = Request::get('shareid', 0, 'int'); + if ($shareid === 0) { + $data = []; + } else { + $data = Database::queryFirst('SELECT shareid, sharename, sharedata + FROM sat.presetnetworkshare WHERE shareid = :shareid', ['shareid' => $shareid]); + if ($data === false) { + Message::addError('networkshare-invalid-shareid', $shareid); + Util::redirect('?do=dozmod§ion=networkshares'); + } + $dec = json_decode($data['sharedata'], true); + if (is_array($dec)) { + $data += $dec; + } + if ($data['auth'] === 'LOGIN_USER') { + $data['loggedInUser_selected'] = 'selected'; + } else { + $data['specificUser_selected'] = 'selected'; + } + } + Render::addTemplate('networkshares-edit', $data); + } + } + +} 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 @@ +<?php + +class SubPage +{ + + public static function doPreprocess() + { + /* execute actions */ + $action = Request::post('action', false, 'string'); + + if ($action === 'save') { + User::assertPermission("runscripts.save"); + self::saveScript(); + } + + if (Request::isPost()) { + Util::redirect('?do=dozmod§ion=runscripts'); + } + User::assertPermission('runscripts.view'); + } + + private static function saveScript() + { + $id = Request::post('runscriptid', false, 'int'); + $scriptname = Request::post('scriptname', '', 'string'); + if ($id === false) { + Message::addError('main.parameter-missing', 'runscriptid'); + return; + } + $data = [ + 'scriptname' => $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/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 @@ +<?php + +class SubPage +{ + + public static function doPreprocess() + { + /* execute actions */ + $action = Request::post('action', false, 'string'); + + if ($action === 'runtime') { + User::assertPermission("runtimeconfig.save"); + self::runtimeHandler(); + } + } + + private static 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'); + } + + 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 @@ +<?php + +class SubPage +{ + + private static $templates = []; + + public static function doPreprocess() + { + $action = Request::post('action', 'show', 'string'); + if ($action === 'show') { + self::fetchTemplates(); + } elseif ($action === 'save') { + if (User::hasPermission("templates.save")) { + self::handleSave(); + } + } elseif ($action === 'reset') { + if(User::hasPermission("templates.reset")) { + self::handleReset(); + } + } else { + Message::addError('main.invalid-action', $action); + Util::redirect('?do=dozmod§ion=templates'); + } + } + + private static function enrichHtml() { + /* for each template */ + foreach (self::$templates as &$t) { + $lis = ""; + $optManVars = ""; + $optVars = ""; + foreach ($t['mandatory_variables'] as $var) { + $optManVars .= "<option selected=\"selected\" value=\"$var\">$var</option>"; + $lis .= "<li><strong>$var</strong></li>"; + } + foreach($t['optional_variables'] as $var) { + $optVars .= "<option selected=\"selected\" value=\"$var\">$var</option>"; + $lis .= "<li>$var</li>"; + } + /* 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..50f0f763 --- /dev/null +++ b/modules-available/dozmod/pages/users.inc.php @@ -0,0 +1,128 @@ +<?php + +class SubPage +{ + + public static function doPreprocess() + { + // Currently there's only one view, actions are ajax + User::assertPermission('users.view'); + } + + public static function doRender() + { + self::listUsers(); + self::listOrganizations(); + } + + public static function doAjax() + { + User::load(); + + $action = Request::post('action', '', 'string'); + if ($action === 'setmail' || $action === 'setsu' || $action == 'setlogin') { + if (User::hasPermission("users.".$action)) { + self::setUserOption($action); + } + } elseif ($action === 'setorglogin') { + if (User::hasPermission("users.setorglogin")) { + self::setOrgOption($action); + } + } else { + die('No such action'); + } + } + + // Helpers + + private static 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)) { + settype($row['lastlogin'], 'int'); + $row['canlogin'] = self::checked($row['canlogin']); + $row['issuperuser'] = self::checked($row['issuperuser']); + $row['emailnotifications'] = self::checked($row['emailnotifications']); + if ($row['lastlogin'] !== 0) { + $row['lastlogin_s'] = date('d.m.Y', $row['lastlogin']); + } + $rows[] = $row; + } + Render::addTemplate('userlist', array( + 'users' => $rows, + 'nameTag' => User::hasPermission('actionlog.view') ? 'a' : 'span', + )); + } + + 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); + } + +} |