diff options
author | Udo Walter | 2018-01-10 16:46:36 +0100 |
---|---|---|
committer | Udo Walter | 2018-01-10 16:46:36 +0100 |
commit | cb9e1f591bc67864d36f65b3ba452e7fdab9b602 (patch) | |
tree | ce0594a41b11e463e697c581b465bb7be8771ae2 /modules-available | |
parent | [locations] fixed root location not getting disabled in the dropdown if (diff) | |
parent | [exams] implemented permission system (diff) | |
download | slx-admin-cb9e1f591bc67864d36f65b3ba452e7fdab9b602.tar.gz slx-admin-cb9e1f591bc67864d36f65b3ba452e7fdab9b602.tar.xz slx-admin-cb9e1f591bc67864d36f65b3ba452e7fdab9b602.zip |
Merge remote-tracking branch 'origin/permission-manager' into permission-manager
Diffstat (limited to 'modules-available')
12 files changed, 363 insertions, 137 deletions
diff --git a/modules-available/exams/lang/de/permissions.json b/modules-available/exams/lang/de/permissions.json new file mode 100644 index 00000000..3ead6249 --- /dev/null +++ b/modules-available/exams/lang/de/permissions.json @@ -0,0 +1,5 @@ +{ + "exams.add": "Neues Examen hinzufügen.", + "exams.delete": "Examen löschen.", + "exams.edit": "Examen bearbeiten." +}
\ No newline at end of file diff --git a/modules-available/exams/lang/en/permissions.json b/modules-available/exams/lang/en/permissions.json new file mode 100644 index 00000000..3e14a761 --- /dev/null +++ b/modules-available/exams/lang/en/permissions.json @@ -0,0 +1,5 @@ +{ + "exams.add": "Add new exam.", + "exams.delete": "Delete exam.", + "exams.edit": "Edit exam." +}
\ No newline at end of file diff --git a/modules-available/exams/page.inc.php b/modules-available/exams/page.inc.php index 75fb6a0b..b32f758c 100644 --- a/modules-available/exams/page.inc.php +++ b/modules-available/exams/page.inc.php @@ -9,6 +9,10 @@ class Page_Exams extends Page private $currentExam; private $rangeMin; private $rangeMax; + private $userEditLocations = []; + private $userDeleteLocations = []; + private $userAddLocations = []; + private $allowedLocations = []; /** if examid is set, also add a column 'selected' **/ @@ -37,9 +41,33 @@ class Page_Exams extends Page . "LEFT JOIN sat.lecture l USING (lectureid) " . "GROUP BY examid " . "ORDER BY examid ASC"); + while ($exam = $tmp->fetch(PDO::FETCH_ASSOC)) { - $this->exams[] = $exam; + // check if allowed to edit this exam + if ($this->allowedToEdit($exam['examid'])) { + $exam['allowedEdit'] = True; + } + // check if allowed to delete this exam + if ($this->allowedToDelete($exam['examid'])) { + $exam['allowedDelete'] = True; + } + + + $locationids = explode(',', $exam['locationids']); + // if global permission, add all exams to the list, no filter required + if ($locationids[0] == 0) { + $this->exams[] = $exam; + } else { + foreach($locationids as $locid) { + // only add the exam if permisson for atleast one of the exam locations + if (in_array($locid, $this->allowedLocations)) { + $this->exams[] = $exam; + break; + } + } + } } + } protected function readLectures() @@ -58,6 +86,67 @@ class Page_Exams extends Page } } + // Returns the list of locations of the exam + protected function getExamLocations($examid) { + $res = Database::simpleQuery("SELECT locationid FROM exams_x_location WHERE examid= :examid", array('examid' => $examid)); + return $res; + } + + // Initialise the user-permission-based lists + protected function setUserLocations() { + + // all locations the user has permission to edit + $this->userEditLocations = User::getAllowedLocations("exams.edit"); + // all locations the user has permission to delete + $this->userDeleteLocations = User::getAllowedLocations("exams.delete"); + // all locations the user has permission to add + $this->userAddLocations = User::getAllowedLocations("exams.add"); + // all locations the user has at least one of the 3 permissions + $this->allowedLocations = array_unique(array_merge($this->userAddLocations, $this->userEditLocations, $this->userDeleteLocations)); + } + + // returns true if user is allowed to delete the exam + protected function allowedToDelete($examid) { + + $res = $this->getExamLocations($examid); + $locations = []; + while ($locId = $res->fetch(PDO::FETCH_ASSOC)) { + $locations[] = $locId['locationid']; + } + + return empty(array_diff($locations, $this->userDeleteLocations)); + + } + + // returns true if user is allowed to add an exam + protected function allowedToAdd() { + return User::hasPermission("exams.add"); + } + + // returns true if user is allowed to edit the exam + protected function allowedToEdit($examid) { + + $res = $this->getExamLocations($examid); + $locations = []; + while ($locId = $res->fetch(PDO::FETCH_ASSOC)) { + $locations[] = $locId['locationid']; + } + + return empty(array_diff($locations, $this->userEditLocations)); + + } + + // checks if user is allowed to save an exam with all the locations + // needs information if it's add (second para = true) or edit (second para = false) + protected function allowedToSave($locationids, $isAdd) { + + if ($isAdd) { + return empty(array_diff($locationids, $this->userAddLocations)); + } else { + return empty(array_diff($locationids, $this->userEditLocations)); + } + } + protected function makeItemsForVis() { $out = []; @@ -88,6 +177,7 @@ class Page_Exams extends Page $locationids[] = $location['locationid']; } } + foreach ($locationids as $locationid) { $out[] = [ 'id' => 'shadow_' . $unique_ids++, @@ -131,13 +221,17 @@ class Page_Exams extends Page protected function makeGroupsForVis() { + $out = []; + foreach ($this->locations as $l) { - $out[] = [ - 'id' => $l['locationid'], - 'content' => $l['locationpad'] . ' ' . $l['locationname'], - 'sortIndex' => $l['sortIndex'], - ]; + if (in_array($l["locationid"], $this->allowedLocations)) { + $out[] = [ + 'id' => $l['locationid'], + 'content' => $l['locationpad'] . ' ' . $l['locationname'], + 'sortIndex' => $l['sortIndex'], + ]; + } } return json_encode($out); } @@ -189,7 +283,7 @@ class Page_Exams extends Page } return $out; } - + protected function makeEditFromArray($source) { if (!isset($source['description']) && isset($source['displayname'])) { @@ -242,42 +336,45 @@ class Page_Exams extends Page if ($examid === 0) { // No examid given, is add - $res = Database::exec("INSERT INTO exams(lectureid, starttime, endtime, autologin, description) VALUES(:lectureid, :starttime, :endtime, :autologin, :description);", - compact('lectureid', 'starttime', 'endtime', 'autologin', 'description')) !== false; + if ($this->allowedToSave($locationids, True)) { + $res = Database::exec("INSERT INTO exams(lectureid, starttime, endtime, autologin, description) VALUES(:lectureid, :starttime, :endtime, :autologin, :description);", + compact('lectureid', 'starttime', 'endtime', 'autologin', 'description')) !== false; - $exam_id = Database::lastInsertId(); - foreach ($locationids as $lid) { - $res = $res && Database::exec("INSERT INTO exams_x_location(examid, locationid) VALUES(:exam_id, :lid)", compact('exam_id', 'lid')) !== false; - } - if ($res === false) { - Message::addError('exam-not-added'); - } else { - Message::addInfo('exam-added-success'); + $exam_id = Database::lastInsertId(); + foreach ($locationids as $lid) { + $res = $res && Database::exec("INSERT INTO exams_x_location(examid, locationid) VALUES(:exam_id, :lid)", compact('exam_id', 'lid')) !== false; + } + if ($res === false) { + Message::addError('exam-not-added'); + } else { + Message::addInfo('exam-added-success'); + } } Util::redirect('?do=exams'); } // Edit + if ($this->allowedToSave($locationids, False)) { + $this->currentExam = Database::queryFirst("SELECT * FROM exams WHERE examid = :examid", array('examid' => $examid)); + if ($this->currentExam === false) { + Message::addError('invalid-exam-id', $examid); + Util::redirect('?do=exams'); + } - $this->currentExam = Database::queryFirst("SELECT * FROM exams WHERE examid = :examid", array('examid' => $examid)); - if ($this->currentExam === false) { - Message::addError('invalid-exam-id', $examid); - Util::redirect('?do=exams'); - } - - /* update fields */ - $res = Database::exec("UPDATE exams SET lectureid = :lectureid, starttime = :starttime, endtime = :endtime, autologin = :autologin, description = :description WHERE examid = :examid", - compact('lectureid', 'starttime', 'endtime', 'description', 'examid', 'autologin')) !== false; - /* drop all connections and reconnect to rooms */ - $res = $res && Database::exec("DELETE FROM exams_x_location WHERE examid = :examid", compact('examid')) !== false; - /* reconnect */ - foreach ($locationids as $lid) { - $res = $res && Database::exec("INSERT INTO exams_x_location(examid, locationid) VALUES(:examid, :lid)", compact('examid', 'lid')) !== false; - } - if ($res !== false) { - Message::addInfo("changes-successfully-saved"); - } else { - Message::addError("error-while-saving-changes"); + /* update fields */ + $res = Database::exec("UPDATE exams SET lectureid = :lectureid, starttime = :starttime, endtime = :endtime, autologin = :autologin, description = :description WHERE examid = :examid", + compact('lectureid', 'starttime', 'endtime', 'description', 'examid', 'autologin')) !== false; + /* drop all connections and reconnect to rooms */ + $res = $res && Database::exec("DELETE FROM exams_x_location WHERE examid = :examid", compact('examid')) !== false; + /* reconnect */ + foreach ($locationids as $lid) { + $res = $res && Database::exec("INSERT INTO exams_x_location(examid, locationid) VALUES(:examid, :lid)", compact('examid', 'lid')) !== false; + } + if ($res !== false) { + Message::addInfo("changes-successfully-saved"); + } else { + Message::addError("error-while-saving-changes"); + } } Util::redirect('?do=exams'); } @@ -286,7 +383,7 @@ class Page_Exams extends Page { User::load(); - if (!User::hasPermission('superadmin')) { + if (!User::isLoggedIn()) { Message::addError('main.no-permission'); Util::redirect('?do=Main'); } @@ -299,26 +396,40 @@ class Page_Exams extends Page $this->action = $req_action; } - if ($this->action === 'show') { + if (Request::isPost()) { + $examid = Request::post('examid', 0, 'int'); + } else if (Request::isGet()) { + $examid = Request::get('examid', 0, 'int'); + } else { + die('Neither Post nor Get Request send.'); + } + + // initialise user-permission-lists + $this->setUserLocations(); + if ($this->action === 'show') { $this->readExams(); $this->readLocations(); $this->readLectures(); } elseif ($this->action === 'add') { - $this->readLectures(); + if($this->allowedToAdd()) { + $this->readLectures(); + } } elseif ($this->action === 'edit') { - $examid = Request::get('examid', 0, 'int'); - $this->currentExam = Database::queryFirst("SELECT * FROM exams WHERE examid = :examid", array('examid' => $examid)); - if ($this->currentExam === false) { - Message::addError('invalid-exam-id', $examid); - Util::redirect('?do=exams'); + if($this->allowedToEdit($examid)) { + $this->currentExam = Database::queryFirst("SELECT * FROM exams WHERE examid = :examid", array('examid' => $examid)); + if ($this->currentExam === false) { + Message::addError('invalid-exam-id', $examid); + Util::redirect('?do=exams'); + } + $this->readLocations($examid); + $this->readLectures(); + } - $this->readLocations($examid); - $this->readLectures(); } elseif ($this->action === 'save') { @@ -329,14 +440,17 @@ class Page_Exams extends Page if (!Request::isPost()) { die('delete only works with a post request'); } - $examid = Request::post('examid'); - $res1 = Database::exec("DELETE FROM exams WHERE examid = :examid;", compact('examid')); - $res2 = Database::exec("DELETE FROM exams_x_location WHERE examid = :examid;", compact('examid')); - if ($res1 === false || $res2 === false) { - Message::addError('exam-not-deleted-error'); - } else { - Message::addInfo('exam-deleted-success'); + + if ($this->allowedToDelete($examid)) { + $res1 = Database::exec("DELETE FROM exams WHERE examid = :examid;", compact('examid')); + $res2 = Database::exec("DELETE FROM exams_x_location WHERE examid = :examid;", compact('examid')); + if ($res1 === false || $res2 === false) { + Message::addError('exam-not-deleted-error'); + } else { + Message::addInfo('exam-deleted-success'); + } } + Util::redirect('?do=exams'); } elseif ($this->action === false) { @@ -348,13 +462,22 @@ class Page_Exams extends Page protected function doRender() { + if (Request::isPost()) { + $examid = Request::post('examid', 0, 'int'); + } else if (Request::isGet()) { + $examid = Request::get('examid', 0, 'int'); + } else { + die('Neither Post nor Get Request send.'); + } + if ($this->action === "show") { // General title and description Render::addTemplate('page-main-heading'); // List of defined exam periods Render::addTemplate('page-exams', [ - 'exams' => $this->makeExamsForTemplate() + 'exams' => $this->makeExamsForTemplate(), + 'allowedToAdd' => $this->allowedToAdd() ]); // List of upcoming lectures marked as exam $upcoming = $this->makeLectureExamList(); @@ -363,6 +486,7 @@ class Page_Exams extends Page } else { Render::addTemplate('page-upcoming-lectures', [ 'pending_lectures' => $upcoming, + 'allowedToAdd' => $this->allowedToAdd(), 'decollapse' => array_key_exists('class', end($upcoming)) ]); } @@ -380,37 +504,62 @@ class Page_Exams extends Page } elseif ($this->action === "add") { - Render::setTitle(Dictionary::translate('title_add-exam')); - $data = []; - $baseLecture = Request::any('lectureid', false, 'string'); - $locations = null; - if ($baseLecture !== false) { - foreach ($this->lectures as &$lecture) { - if ($lecture['lectureid'] === $baseLecture) { - $data['exam'] = $this->makeEditFromArray($lecture); - $locations = explode(',', $lecture['lids']); - $lecture['selected'] = 'selected'; - break; + if($this->allowedToAdd()) { + Render::setTitle(Dictionary::translate('title_add-exam')); + $data = []; + $baseLecture = Request::any('lectureid', false, 'string'); + $locations = null; + if ($baseLecture !== false) { + foreach ($this->lectures as &$lecture) { + if ($lecture['lectureid'] === $baseLecture) { + $data['exam'] = $this->makeEditFromArray($lecture); + $locations = explode(',', $lecture['lids']); + $lecture['selected'] = 'selected'; + break; + } + } + unset($lecture); + } + + $this->readLocations($locations); + $data['lectures'] = $this->lectures; + $data['locations'] = $this->locations; + + // if user has no permission to add for this location, disable the location in the select + foreach ($data['locations'] as &$loc) { + if (!in_array($loc["locationid"], $this->userAddLocations)) { + $loc["disabled"] = "disabled"; } } - unset($lecture); + + Render::addTemplate('page-add-edit-exam', $data); } - $data['lectures'] = $this->lectures; - $this->readLocations($locations); - $data['locations'] = $this->locations; - Render::addTemplate('page-add-edit-exam', $data); } elseif ($this->action === 'edit') { - Render::setTitle(Dictionary::translate('title_edit-exam')); - $exam = $this->makeEditFromArray($this->currentExam); - foreach ($this->lectures as &$lecture) { - if ($lecture['lectureid'] === $this->currentExam['lectureid']) { - $lecture['selected'] = 'selected'; + if ($this->allowedToEdit($examid)) { + Render::setTitle(Dictionary::translate('title_edit-exam')); + $exam = $this->makeEditFromArray($this->currentExam); + foreach ($this->lectures as &$lecture) { + if ($lecture['lectureid'] === $this->currentExam['lectureid']) { + $lecture['selected'] = 'selected'; + } + } + + $data = []; + $data['exam'] = $exam; + $data['locations'] = $this->locations; + $data['lectures'] = $this->lectures; + + // if user has no permission to edit for this location, disable the location in the select + foreach ($data['locations'] as &$loc) { + if (!in_array($loc["locationid"], $this->userEditLocations)) { + $loc["disabled"] = "disabled"; + } } - } - Render::addTemplate('page-add-edit-exam', ['exam' => $exam, 'locations' => $this->locations, 'lectures' => $this->lectures]); + Render::addTemplate('page-add-edit-exam', $data); + } } } diff --git a/modules-available/exams/permissions/permissions.json b/modules-available/exams/permissions/permissions.json new file mode 100644 index 00000000..215b3399 --- /dev/null +++ b/modules-available/exams/permissions/permissions.json @@ -0,0 +1,5 @@ +[ + "exams.add", + "exams.delete", + "exams.edit" +]
\ No newline at end of file diff --git a/modules-available/exams/templates/page-add-edit-exam.html b/modules-available/exams/templates/page-add-edit-exam.html index 58c61b11..11bffed8 100644 --- a/modules-available/exams/templates/page-add-edit-exam.html +++ b/modules-available/exams/templates/page-add-edit-exam.html @@ -19,7 +19,7 @@ </div> <select id="locations" multiple name="locations[]"> {{#locations}} - <option value="{{locationid}}" {{#selected}}selected{{/selected}}>{{locationpad}} {{locationname}}</option> + <option value="{{locationid}}" {{disabled}} {{#selected}}selected{{/selected}}>{{locationpad}} {{locationname}}</option> {{/locations}} </select> </div> diff --git a/modules-available/exams/templates/page-exams.html b/modules-available/exams/templates/page-exams.html index 29b8c319..bb6cbd0a 100644 --- a/modules-available/exams/templates/page-exams.html +++ b/modules-available/exams/templates/page-exams.html @@ -43,10 +43,9 @@ {{^liesInPast}} <a onclick="slxShow({{starttime}}, {{endtime}})" class="btn btn-default btn-sm"><span class="glyphicon glyphicon-eye-open"></span></a> {{/liesInPast}} - <a href="?do=exams&action=edit&examid={{examid}}" class="btn btn-default btn-sm" >{{lang_edit}}</a> - <input type="hidden" name="token" value="{{token}}"> + <a href="?do=exams&action=edit&examid={{examid}}" class="btn btn-default btn-sm {{^allowedEdit}}disabled{{/allowedEdit}}"><span class="glyphicon glyphicon-edit"></span></a> <input type="hidden" name="token" value="{{token}}"> <input type="hidden" name="examid" value="{{examid}}"> - <button class="btn {{btnClass}} btn-sm">{{lang_delete}}</button> + <button {{^allowedDelete}}disabled{{/allowedDelete}} class="btn {{btnClass}} btn-sm"><span class="glyphicon glyphicon-trash"></span></button> </form> </td> </tr> @@ -56,7 +55,7 @@ </div> <div class="text-right"> <div class="btn-group" role="group"> - <a href="?do=exams&action=add" class="btn btn-success"><span class="glyphicon glyphicon-plus-sign"></span> {{lang_addExam}}</a> + <a href="?do=exams&action=add" class="btn btn-success {{^allowedToAdd}}disabled{{/allowedToAdd}}"><span class="glyphicon glyphicon-plus-sign"></span> {{lang_addExam}}</a> </div> </div> </div> diff --git a/modules-available/exams/templates/page-upcoming-lectures.html b/modules-available/exams/templates/page-upcoming-lectures.html index 8ff8143e..074aa42d 100644 --- a/modules-available/exams/templates/page-upcoming-lectures.html +++ b/modules-available/exams/templates/page-upcoming-lectures.html @@ -31,7 +31,7 @@ <td width="20%"> <div class="pull-right text-nowrap"> <a class="btn btn-sm btn-default" role="button" onclick="slxShow({{starttime}}, {{endtime}})"><span class="glyphicon glyphicon-eye-open"></span></a> - <a href="?do=exams&action=add&lectureid={{lectureid}}" class="btn btn-sm btn-success" role="button"> + <a href="?do=exams&action=add&lectureid={{lectureid}}" class="btn btn-sm btn-success {{^allowedToAdd}}disabled{{/allowedToAdd}}" role="button"> <span class="glyphicon glyphicon-plus-sign"></span> <span class="hidden-sm">{{lang_addExam}}</span> </a> diff --git a/modules-available/rebootcontrol/lang/de/permissions.json b/modules-available/rebootcontrol/lang/de/permissions.json new file mode 100644 index 00000000..92eeb37e --- /dev/null +++ b/modules-available/rebootcontrol/lang/de/permissions.json @@ -0,0 +1,5 @@ +{ + "shutdown": "Client herunterfahren.", + "reboot": "Client neustarten.", + "newkeypair": "Neues Schlüsselpaar generieren." +}
\ No newline at end of file diff --git a/modules-available/rebootcontrol/lang/en/permissions.json b/modules-available/rebootcontrol/lang/en/permissions.json new file mode 100644 index 00000000..077890fb --- /dev/null +++ b/modules-available/rebootcontrol/lang/en/permissions.json @@ -0,0 +1,5 @@ +{ + "shutdown": "Shutdown Client.", + "reboot": "Reboot Client.", + "newkeypair": "Generate new Keypair." +}
\ No newline at end of file diff --git a/modules-available/rebootcontrol/page.inc.php b/modules-available/rebootcontrol/page.inc.php index fc3ded8f..fa34a05a 100644 --- a/modules-available/rebootcontrol/page.inc.php +++ b/modules-available/rebootcontrol/page.inc.php @@ -4,6 +4,9 @@ class Page_RebootControl extends Page { private $action = false; + private $allowedShutdownLocs = []; + private $allowedRebootLocs = []; + private $allowedLocs = []; /** * Called before any page rendering happens - early hook to check parameters etc. @@ -17,21 +20,40 @@ class Page_RebootControl extends Page Util::redirect('?do=Main'); // does not return } + $this->allowedShutdownLocs = User::getAllowedLocations("shutdown"); + $this->allowedRebootLocs = User::getAllowedLocations("reboot"); + $this->allowedLocs = array_unique(array_merge($this->allowedShutdownLocs, $this->allowedRebootLocs)); + $this->action = Request::any('action', 'show', 'string'); if ($this->action === 'startReboot' || $this->action === 'startShutdown') { - $clients = Request::post('clients'); - if (!is_array($clients) || empty($clients)) { - Message::addError('no-clients-selected'); - Util::redirect(); - } + $locationId = Request::post('locationId', false, 'int'); if ($locationId === false) { Message::addError('locations.invalid-location-id', $locationId); Util::redirect(); } + $shutdown = $this->action === "startShutdown"; + // Check user permission (if user has no permission, the getAllowed-list will be empty and the check will fail) + if ($shutdown) { + if (!in_array($locationId, $this->allowedShutdownLocs)) { + Message::addError('main.no-permission'); + Util::redirect(); + } + } else { + if (!in_array($locationId, $this->allowedRebootLocs)) { + Message::addError('main.no-permission'); + Util::redirect(); + } + } + + $clients = Request::post('clients'); + if (!is_array($clients) || empty($clients)) { + Message::addError('no-clients-selected'); + Util::redirect(); + } $minutes = Request::post('minutes', 0, 'int'); $list = RebootQueries::getMachinesByUuid($clients); @@ -72,12 +94,34 @@ class Page_RebootControl extends Page //location you want to see, default are "not assigned" clients $requestedLocation = Request::get('location', 0, 'int'); - $data['data'] = RebootQueries::getMachineTable($requestedLocation); - $data['locations'] = Location::getLocations($requestedLocation, 0, true); + // only fill table if user has at least one permission for the location + if (in_array($requestedLocation, $this->allowedLocs)) { + $data['data'] = RebootQueries::getMachineTable($requestedLocation); + $data['allowedToSelect'] = True; + } + $data['locations'] = Location::getLocations($requestedLocation, 0, true); + // Always show public key (it's public, isn't it?) $data['pubKey'] = SSHKey::getPublicKey(); + // disable each location user has no permission for + foreach ($data['locations'] as &$loc) { + if (!in_array($loc["locationid"], $this->allowedLocs)) { + $loc["disabled"] = "disabled"; + } + } + + // Only enable shutdown/reboot-button if user has permission for the location + if (in_array($requestedLocation, $this->allowedShutdownLocs)) { + $data['allowedToShutdown'] = True; + } + if (in_array($requestedLocation, $this->allowedRebootLocs)) { + $data['allowedToReboot'] = True; + } + $data['allowedToGenerateKey'] = User::hasPermission("newkeypair"); + Render::addTemplate('_page', $data); + } } } @@ -86,8 +130,12 @@ class Page_RebootControl extends Page { $this->action = Request::post('action', false, 'string'); if ($this->action === 'generateNewKeypair') { - Property::set("rebootcontrol-private-key", false); - echo SSHKey::getPublicKey(); + if (User::hasPermission("newkeypair")) { + Property::set("rebootcontrol-private-key", false); + echo SSHKey::getPublicKey(); + } else { + echo 'No permission.'; + } } else { echo 'Invalid action.'; } diff --git a/modules-available/rebootcontrol/permissions/permissions.json b/modules-available/rebootcontrol/permissions/permissions.json new file mode 100644 index 00000000..5230c9bd --- /dev/null +++ b/modules-available/rebootcontrol/permissions/permissions.json @@ -0,0 +1,5 @@ +[ + "shutdown", + "reboot", + "newkeypair" +]
\ No newline at end of file diff --git a/modules-available/rebootcontrol/templates/_page.html b/modules-available/rebootcontrol/templates/_page.html index 1bef8dd4..9b470943 100644 --- a/modules-available/rebootcontrol/templates/_page.html +++ b/modules-available/rebootcontrol/templates/_page.html @@ -8,15 +8,15 @@ <input type="hidden" name="token" value="{{token}}"> <div class="row"> <div class="col-md-12"> - <label>{{lang_location}}: - <select id="locationDropdown" name="locationId" class="form-control" onchange="selectLocation()"> - {{#locations}} - <option value="{{locationid}}" {{#selected}}selected{{/selected}}>{{locationpad}} {{locationname}}</option> - {{/locations}} - </select> - </label> - <button type="button" id="selectAllButton" class="btn btn-primary pull-right" onclick="selectAllRows()"><span class="glyphicon glyphicon-check"></span> {{lang_selectall}}</button> - <button type="button" id="unselectAllButton" class="btn btn-default pull-right" onclick="unselectAllRows()" style="display: none;"><span class="glyphicon glyphicon-unchecked"></span> {{lang_unselectall}}</button> + <label>{{lang_location}}: + <select id="locationDropdown" name="locationId" class="form-control" onchange="selectLocation()"> + {{#locations}} + <option value="{{locationid}}" {{disabled}} {{#selected}}selected{{/selected}}>{{locationpad}} {{locationname}}</option> + {{/locations}} + </select> + </label> + <button type="button" id="selectAllButton" {{^allowedToSelect}}disabled{{/allowedToSelect}} class="btn btn-primary pull-right" onclick="selectAllRows()"><span class="glyphicon glyphicon-check"></span> {{lang_selectall}}</button> + <button type="button" id="unselectAllButton" {{^allowedToSelect}}disabled{{/allowedToSelect}} class="btn btn-default pull-right" onclick="unselectAllRows()" style="display: none;"><span class="glyphicon glyphicon-unchecked"></span> {{lang_unselectall}}</button> <button type="button" id="rebootButton" class="btn btn-warning pull-right" data-toggle="modal" data-target="#rebootModal" disabled><span class="glyphicon glyphicon-repeat"></span> {{lang_rebootButton}}</button> <button type="button" id="shutdownButton" class="btn btn-danger pull-right" data-toggle="modal" data-target="#shutdownModal" disabled><span class="glyphicon glyphicon-off"></span> {{lang_shutdownButton}}</button> </div> @@ -25,41 +25,41 @@ <div class="col-md-12"> <table class="table table-condensed table-hover stupidtable" id="dataTable"> <thead> - <tr> - <th data-sort="string">{{lang_client}}</th> - <th data-sort="ipv4">{{lang_ip}}</th> - <th data-sort="string">{{lang_status}}</th> - <th data-sort="string">{{lang_session}}</th> - <th data-sort="string">{{lang_user}}</th> - <th data-sort="int" data-sort-default="desc">{{lang_selected}}</th> - </tr> + <tr> + <th data-sort="string">{{lang_client}}</th> + <th data-sort="ipv4">{{lang_ip}}</th> + <th data-sort="string">{{lang_status}}</th> + <th data-sort="string">{{lang_session}}</th> + <th data-sort="string">{{lang_user}}</th> + <th data-sort="int" data-sort-default="desc">{{lang_selected}}</th> + </tr> </thead> <tbody> {{#data}} - <tr> - <td> - {{hostname}} - {{^hostname}}{{clientip}}{{/hostname}} - </td> - <td>{{clientip}}</td> - <td class="statusColumn"> - {{#status}} - <span class="text-success">{{lang_on}}</span> - {{/status}} - {{^status}} - <span class="text-danger">{{lang_off}}</span> - {{/status}} - </td> - <td>{{#status}}{{currentsession}}{{/status}}</td> - <td>{{#status}}{{currentuser}}{{/status}}</td> - <td data-sort-value="0" class="checkboxColumn"> - <div class="checkbox"> - <input id="m-{{machineuuid}}" type="checkbox" name="clients[]" value='{{machineuuid}}'> - <label for="m-{{machineuuid}}"></label> - </div> - </td> - </tr> + <tr> + <td> + {{hostname}} + {{^hostname}}{{clientip}}{{/hostname}} + </td> + <td>{{clientip}}</td> + <td class="statusColumn"> + {{#status}} + <span class="text-success">{{lang_on}}</span> + {{/status}} + {{^status}} + <span class="text-danger">{{lang_off}}</span> + {{/status}} + </td> + <td>{{#status}}{{currentsession}}{{/status}}</td> + <td>{{#status}}{{currentuser}}{{/status}}</td> + <td data-sort-value="0" class="checkboxColumn"> + <div class="checkbox"> + <input id="m-{{machineuuid}}" type="checkbox" name="clients[]" value='{{machineuuid}}'> + <label for="m-{{machineuuid}}"></label> + </div> + </td> + </tr> {{/data}} </tbody> </table> @@ -79,7 +79,7 @@ </div> <div class="modal-body"> <span id="pubKeyTitle">{{lang_pubKey}}</span> - <button class="btn btn-s btn-warning pull-right" onclick="generateNewKeypair()" type="button"><span class="glyphicon glyphicon-refresh"></span> {{lang_genNew}}</button> + <button {{^allowedToGenerateKey}}disabled{{/allowedToGenerateKey}} class="btn btn-s btn-warning pull-right" onclick="generateNewKeypair()" type="button"><span class="glyphicon glyphicon-refresh"></span> {{lang_genNew}}</button> <pre id="pubKey">{{pubKey}}</pre> </div> <div class="modal-footer"> @@ -100,7 +100,7 @@ </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button> - <button type="submit" name="action" value="startReboot" class="btn btn-warning"><span class="glyphicon glyphicon-repeat"></span> {{lang_reboot}}</button> + <button type="submit" {{^allowedToReboot}}disabled{{/allowedToReboot}} name="action" value="startReboot" class="btn btn-warning"><span class="glyphicon glyphicon-repeat"></span> {{lang_reboot}}</button> </div> </div> </div> @@ -115,11 +115,11 @@ </div> <div class="modal-body"> {{lang_shutdownCheck}} - {{lang_shutdownIn}} <input id="shutdownTimer" name="minutes" title="{{lang_shutdownIn}}" type="number" value="0" min="0" onkeypress="return isNumberKey(event)"> {{lang_minutes}} + {{lang_shutdownIn}} <input id="shutdownTimer" name="minutes" title="{{lang_shutdownIn}}" type="number" value="0" min="0" onkeypress="return isNumberKey(event)"> {{lang_minutes}} </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button> - <button type="submit" name="action" value="startShutdown" class="btn btn-danger"><span class="glyphicon glyphicon-off"></span> {{lang_shutdownButton}}</button> + <button type="submit" {{^allowedToShutdown}}disabled{{/allowedToShutdown}} name="action" value="startShutdown" class="btn btn-danger"><span class="glyphicon glyphicon-off"></span> {{lang_shutdownButton}}</button> </div> </div> </div> @@ -162,7 +162,7 @@ $('#rebootButton').prop('disabled', false); $('#shutdownButton').prop('disabled', false); } - }); + }); $('.checkboxColumn').click(function(e) { if (e.target === this) { $(this).find('input[type="checkbox"]').click(); |