diff options
author | Jonathan Bauer | 2016-04-01 16:50:13 +0200 |
---|---|---|
committer | Jonathan Bauer | 2016-04-01 16:50:13 +0200 |
commit | dbc0d9614421e064cc62aacf116ebb783c83f2f3 (patch) | |
tree | 091844b8578ff1d9ac18edfd3cee3e63210133d7 /modules/dozmod | |
parent | [ldapauth] Add homedir conf to ldap wizard (diff) | |
download | slx-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.json | 4 | ||||
-rw-r--r-- | modules/dozmod/module.inc.php | 252 | ||||
-rw-r--r-- | modules/dozmod/templates/images-delete.html | 57 | ||||
-rw-r--r-- | modules/dozmod/templates/mailconfig.html | 91 | ||||
-rw-r--r-- | modules/dozmod/templates/orglist.html | 51 | ||||
-rw-r--r-- | modules/dozmod/templates/userlist.html | 62 |
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 |