summaryrefslogtreecommitdiffstats
path: root/modules/dozmod
diff options
context:
space:
mode:
authorJonathan Bauer2016-04-01 16:50:13 +0200
committerJonathan Bauer2016-04-01 16:50:13 +0200
commitdbc0d9614421e064cc62aacf116ebb783c83f2f3 (patch)
tree091844b8578ff1d9ac18edfd3cee3e63210133d7 /modules/dozmod
parent[ldapauth] Add homedir conf to ldap wizard (diff)
downloadslx-admin-dbc0d9614421e064cc62aacf116ebb783c83f2f3.tar.gz
slx-admin-dbc0d9614421e064cc62aacf116ebb783c83f2f3.tar.xz
slx-admin-dbc0d9614421e064cc62aacf116ebb783c83f2f3.zip
[merge] merging c3sl / fr - initial commit
Diffstat (limited to 'modules/dozmod')
-rw-r--r--modules/dozmod/config.json4
-rw-r--r--modules/dozmod/module.inc.php252
-rw-r--r--modules/dozmod/templates/images-delete.html57
-rw-r--r--modules/dozmod/templates/mailconfig.html91
-rw-r--r--modules/dozmod/templates/orglist.html51
-rw-r--r--modules/dozmod/templates/userlist.html62
6 files changed, 517 insertions, 0 deletions
diff --git a/modules/dozmod/config.json b/modules/dozmod/config.json
new file mode 100644
index 00000000..4e7fa5fb
--- /dev/null
+++ b/modules/dozmod/config.json
@@ -0,0 +1,4 @@
+{
+ "category":"content",
+ "enabled":"true"
+}
diff --git a/modules/dozmod/module.inc.php b/modules/dozmod/module.inc.php
new file mode 100644
index 00000000..f98d8952
--- /dev/null
+++ b/modules/dozmod/module.inc.php
@@ -0,0 +1,252 @@
+<?php
+
+class Page_DozMod extends Page
+{
+
+ protected function doPreprocess()
+ {
+ User::load();
+
+ if (!User::hasPermission('superadmin')) {
+ Message::addError('no-permission');
+ Util::redirect('?do=Main');
+ }
+
+ $action = Request::post('action');
+
+ if ($action === 'mail') {
+ $this->mailHandler();
+ }
+ if ($action === 'delimages') {
+ $result = $this->handleDeleteImages();
+ if (!empty($result)) {
+ Message::addInfo('delete-images', $result);
+ }
+ Util::redirect('?do=DozMod');
+ }
+ }
+
+ protected function doRender()
+ {
+ $this->listDeletePendingImages();
+ // Mail config
+ $conf = Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'mailconfig'));
+ if ($conf != null) {
+ $conf = @json_decode($conf['value'], true);
+ if (is_array($conf)) {
+ $conf['set_' . $conf['ssl']] = 'selected="selected"';
+ }
+ }
+ Render::addTemplate('mailconfig', $conf);
+ // User list for making people admin
+ $this->listUsers();
+ $this->listOrganizations();
+ }
+
+ private function listDeletePendingImages()
+ {
+ $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';
+ } 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['filesize'] = Util::readableFileSize($row['filesize']);
+ $rows[] = $row;
+ }
+ if (empty($rows))
+ return;
+ Render::addTemplate('images-delete', array('images' => $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()
+ {
+ if (!User::hasPermission('superadmin'))
+ return;
+
+ $action = Request::post('action');
+ if ($action === 'mail') {
+ $this->handleTestMail();
+ } elseif ($action === 'setmail' || $action === 'setsu' || $action == 'setlogin') {
+ $this->setUserOption($action);
+ } elseif ($action === 'setorglogin') {
+ $this->setOrgOption($action);
+ } elseif ($action === 'delimages') {
+ die($this->handleDeleteImages());
+ }
+ }
+
+ 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, 2, $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, 2, $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');
+ }
+ Util::redirect('?do=DozMod');
+ }
+
+ 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);
+ }
+
+}
diff --git a/modules/dozmod/templates/images-delete.html b/modules/dozmod/templates/images-delete.html
new file mode 100644
index 00000000..c4cbfd34
--- /dev/null
+++ b/modules/dozmod/templates/images-delete.html
@@ -0,0 +1,57 @@
+<h2>{{lang_heading}}</h2>
+
+<div class="panel panel-default">
+ <div class="panel-heading">
+ {{lang_subHeading}}
+ </div>
+ <div class="panel-body">
+ <p>{{lang_description}}</p>
+ <div class="table-responsive">
+ <form id="delform" method="post" action="?do=DozMod" onsubmit="return slxPostdel()">
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="action" value="delimages">
+ <table class="table table-stripped table-condensed">
+ <thead>
+ <tr>
+ <th>{{lang_image}}</th>
+ <th>{{lang_version}}</th>
+ <th>{{lang_owner}}</th>
+ <th><span class="glyphicon glyphicon-upload" title="{{lang_hasNewer}}"></th>
+ <th>{{lang_size}}</th>
+ <th><span class="glyphicon glyphicon-trash" title="{{lang_delete}}"></span></th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#images}}
+ <tr>
+ <td class="text-left slx-nowrap {{name_extra_class}}">{{displayname}}<br><span class="small">{{imageversionid}}</span></td>
+ <td class="text-left slx-nowrap">{{version}}</td>
+ <td class="text-left slx-nowrap"><a href="mailto:{{email}}">{{lastname}}, {{firstname}}</a></td>
+ <td class="text-left slx-nowrap"><span class="glyphicon {{hasNewerClass}}"></span></td>
+ <td class="text-right slx-nowrap">{{filesize}}</td>
+ <td><input name="images[{{imageversionid}}]" type="checkbox" checked="checked"></td>
+ </tr>
+ {{/images}}
+ </tbody>
+ </table>
+ <button id="delbtn" class="btn btn-danger" type="submit" name="button" value="save">{{lang_delButton}}</button>
+ </form>
+ <pre style="display:none" id="deloutput"></pre>
+ </div>
+ </div>
+</div>
+
+<script type="text/javascript"><!--
+
+function slxPostdel() {
+ var f = $('#delform');
+ $('#delbtn').prop('disabled', true);
+ $.post('?do=DozMod', f.serialize()).done(function (data) {
+ $('#deloutput').text(data).css('display', '');
+ }).fail(function () {
+ $('#deloutput').text('ERROR').css('display', '');
+ });
+ return false;
+}
+
+--> </script> \ No newline at end of file
diff --git a/modules/dozmod/templates/mailconfig.html b/modules/dozmod/templates/mailconfig.html
new file mode 100644
index 00000000..b19776c0
--- /dev/null
+++ b/modules/dozmod/templates/mailconfig.html
@@ -0,0 +1,91 @@
+<h2>{{lang_mailConfigHeadline}}</h2>
+
+<div class="panel panel-default">
+ <div class="panel-heading">
+ {{lang_mailConfig}}
+ </div>
+ <div class="panel-body">
+ <p>{{lang_mailDescription}}</p>
+ <p>[BETA] Diese Funktionalität ist neu. Wir bitten um Nachsicht, falls es Situationen gibt, in denen zu viele
+ oder zu wenige Nachrichten verschickt werden.</p>
+ <form action="?do=DozMod" method="post" id="mailconf">
+ <input type="text" name="prevent_autofill" id="prevent_autofill" value="" style="display:none;">
+ <input type="password" name="password_fake" id="password_fake" value="" style="display:none;">
+ <div class="input-group">
+ <label class="input-group-addon slx-ga2" for="host-id">{{lang_host}} *</label>
+ <input type="text" name="host" id ="host-id" class="form-control" placeholder="smtp.example.com" value="{{host}}">
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon slx-ga2" for="port-id">{{lang_port}} *</label>
+ <input type="text" name="port" id ="port-id" class="form-control" placeholder="465" value="{{port}}">
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon slx-ga2" for="ssl-id">{{lang_ssl}} *</label>
+ <select class="form-control" name="ssl" id="ssl-id">
+ <option value="NONE" {{set_NONE}}>{{lang_sslNone}}</option>
+ <option value="IMPLICIT" {{set_IMPLICIT}}>{{lang_sslImplicit}}</option>
+ <option value="EXPLICIT" {{set_EXPLICIT}}>{{lang_sslExplicit}}</option>
+ </select>
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon slx-ga2" for="senderAddress-id">{{lang_senderAddress}} *</label>
+ <input type="text" name="senderAddress" id ="senderAddress-id" class="form-control" placeholder="smtp-username@hs-example.com" value="{{senderAddress}}">
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon slx-ga2" for="serverName-id">{{lang_senderName}}</label>
+ <input type="text" name="serverName" id ="serverName-id" class="form-control" placeholder="bwLehrpool HS Example" value="{{serverName}}">
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon slx-ga2" for="replyTo-id">{{lang_replyTo}}</label>
+ <input type="text" name="replyTo" id ="replyTo-id" class="form-control" placeholder="helpdesk@hs-example.com" value="{{replyTo}}">
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon slx-ga2" for="username-id">{{lang_username}}</label>
+ <input type="text" name="username" id ="username-id" class="form-control" placeholder="smtp-username" value="{{username}}">
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon slx-ga2" for="password-id">{{lang_password}}</label>
+ <input type="{{password_type}}" name="password" id ="password-id" class="form-control" placeholder="geheim" value="{{password}}">
+ </div>
+ <p>{{lang_asteriskRequired}}</p>
+ <br>
+ <p>{{lang_testConfiguration}}</p>
+ <div class="input-group">
+ <label class="input-group-addon slx-ga2" for="test-id">{{lang_testRecipient}}</label>
+ <input type="text" name="recipient" id ="test-id" class="form-control" placeholder="test@example.com" value="">
+ </div>
+ <br>
+ <button class="btn btn-primary btn-sm" type="button" id="test-button" name="button" value="test" onclick="slxTestConfig()">{{lang_test}}</button>
+ <span id="test-spin" style="display:none"><span class="glyphicon glyphicon-refresh slx-rotation"></span></span>
+ <pre id="test-output" style="display:none"></pre>
+ <button class="btn btn-primary btn-sm" type="submit" name="button" value="save">{{lang_save}}</button>
+ <br>
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="action" value="mail">
+ </form>
+ </div>
+</div>
+
+<script type="text/javascript"><!--
+function slxTestConfig() {
+ $('#test-button').prop('disabled', true);
+ $('#test-spin').css('display', '');
+ var str = $('#mailconf').serialize();
+ str += '&button=test';
+ console.log(str);
+ $.post('?do=DozMod', str).done(function(data) {
+ console.log('Success');
+ console.log(data);
+ checkRes(data);
+ }).fail(function() {
+ checkRes('DozMod refused the connection');
+ }).always(function() {
+ $('#test-button').prop('disabled', false);
+ $('#test-spin').css('display', 'none');
+ });
+ }
+
+ function checkRes(text) {
+ $('#test-output').css('display', '').text(text);
+ }
+// --> </script> \ No newline at end of file
diff --git a/modules/dozmod/templates/orglist.html b/modules/dozmod/templates/orglist.html
new file mode 100644
index 00000000..d325cc4d
--- /dev/null
+++ b/modules/dozmod/templates/orglist.html
@@ -0,0 +1,51 @@
+<h2>{{lang_organizationList}}</h2>
+
+<div class="panel panel-default">
+ <div class="panel-heading">
+ {{lang_organizationListHeader}}
+ </div>
+ <div class="panel-body">
+ <div class="table-responsive">
+ <table class="table table-stripped table-condensed">
+ <thead>
+ <tr>
+ <th>{{lang_organization}}</th>
+ <th><span class="glyphicon glyphicon-ok" title="{{lang_canLogin}}"></span></th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#organizations}}
+ <tr>
+ <td class="text-left slx-nowrap">{{displayname}}</td>
+ <td><input onclick="seto('setorglogin', this, '{{organizationid}}')" type="checkbox" {{{canlogin}}}></td>
+ </tr>
+ {{/organizations}}
+ </tbody>
+ </table>
+ </div>
+ </div>
+</div>
+
+<script type="text/javascript"><!--
+
+function seto(action, el, orgid) {
+ var box = $(el);
+ var v = el.checked ? '1' : '0';
+ var old = el.checked == true;
+ box.css('display', 'none');
+ $.post('?do=DozMod', { token: TOKEN, action: action, organizationid: orgid, value: v }).done(function (data) {
+ if (data != 1 && data != 0) {
+ el.checked = !old;
+ box.parent().css('background-color', 'red !important');
+ } else {
+ el.checked = (data == 1);
+ }
+ box.css('display', '');
+ }).fail(function() {
+ el.checked = !old;
+ box.parent().css('background-color', 'red !important');
+ box.css('display', '');
+ });
+}
+
+--> </script> \ No newline at end of file
diff --git a/modules/dozmod/templates/userlist.html b/modules/dozmod/templates/userlist.html
new file mode 100644
index 00000000..a76eae5e
--- /dev/null
+++ b/modules/dozmod/templates/userlist.html
@@ -0,0 +1,62 @@
+<h2>{{lang_userList}}</h2>
+
+<div class="panel panel-default">
+ <div class="panel-heading">
+ {{lang_userListHeader}}
+ </div>
+ <div class="panel-body">
+ <p>{{lang_userListDescription}}</p>
+ <div class="table-responsive">
+ <table class="table table-stripped table-condensed">
+ <thead>
+ <tr>
+ <th>{{lang_user}}</th>
+ <th>{{lang_organization}}</th>
+ <th>{{lang_lastLogin}}</th>
+ <th>{{lang_email}}</th>
+ <th><span class="glyphicon glyphicon-envelope" title="{{lang_emailNotifications}}"></span></th>
+ <th><span class="glyphicon glyphicon-king" title="{{lang_superUser}}"></span></th>
+ <th><span class="glyphicon glyphicon-ok" title="{{lang_canLogin}}"></span></th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#users}}
+ <tr>
+ <td class="text-left slx-nowrap">{{lastname}}, {{firstname}}</td>
+ <td class="text-left slx-nowrap">{{orgname}}</td>
+ <td class="text-left slx-nowrap">{{lastlogin}}</td>
+ <td class="text-left slx-nowrap"><a href="mailto:{{email}}">{{email}}</a></td>
+ <td><input onclick="setu('setmail', this, '{{userid}}')" type="checkbox" {{{emailnotifications}}}></td>
+ <td><input onclick="setu('setsu', this, '{{userid}}')" type="checkbox" {{{issuperuser}}}></td>
+ <td><input onclick="setu('setlogin', this, '{{userid}}')" type="checkbox" {{{canlogin}}}></td>
+ </tr>
+ {{/users}}
+ </tbody>
+ </table>
+ </div>
+ </div>
+</div>
+
+<script type="text/javascript"><!--
+
+function setu(action, el, uid) {
+ var box = $(el);
+ var v = el.checked ? '1' : '0';
+ var old = el.checked == true;
+ box.css('display', 'none');
+ $.post('?do=DozMod', { token: TOKEN, action: action, userid: uid, value: v }).done(function (data) {
+ if (data != 1 && data != 0) {
+ el.checked = !old;
+ box.parent().css('background-color', 'red !important');
+ } else {
+ el.checked = (data == 1);
+ }
+ box.css('display', '');
+ }).fail(function() {
+ el.checked = !old;
+ box.parent().css('background-color', 'red !important');
+ box.css('display', '');
+ });
+}
+
+--> </script> \ No newline at end of file