diff options
Diffstat (limited to 'modules-available')
11 files changed, 541 insertions, 319 deletions
diff --git a/modules-available/usblockoff/api.inc.php b/modules-available/usblockoff/api.inc.php index 6a5e4a7d..67f805f5 100644 --- a/modules-available/usblockoff/api.inc.php +++ b/modules-available/usblockoff/api.inc.php @@ -35,6 +35,9 @@ function HandleParameters() $id = Request::get('id', '', 'string'); $serial = Request::get('serial', '', 'string'); deleteDevice($id, $serial); + } elseif ($getAction == "getrule") { + $configid = Request::get('configid', '0', 'int'); + getRule($configid); } } @@ -83,6 +86,42 @@ function newDevice($id, $serial, $hwProps, $deviceProps) } } +function getRule($configid) { + // Get the config from the db. + $config = Database::queryFirst("SELECT * FROM `usb_configs` WHERE configid=:configid", array( + "configid" => $configid + )); + $idList = array(); + $rules = array(); + // For each $id get the rule information and build the rule. + foreach (json_decode($config['rulesconfig']) as $id) { + $idList[] = $id; + + // TODO: Make more efficient with one query instead of one per id. + + $dbquery = Database::simpleQuery("SELECT * FROM `usb_rule_prop` WHERE ruleid=:id", array( + "id" => $id + )); + $rule = ""; + while ($attribute = $dbquery->fetch(PDO::FETCH_ASSOC)) { + if ($attribute['prop'] == "target") { + $rule = $attribute['value'] . $rule; + } else { + if ($attribute['prop'] == "serial" || $attribute['prop'] == "name" || $attribute['prop'] == "hash" || + $attribute['prop'] == "parent-hash" || $attribute['prop'] == "via-port") { + $rule = $rule . " " . $attribute['prop'] . " \"" . $attribute['value'] . "\""; + } else { + $rule = $rule . " " . $attribute['prop'] . " " . $attribute['value']; + } + } + } + $rules[] = $rule; + } + + // Return the completed rules.conf. + echo implode("\n", $rules); +} + function addHwProps($table, $hwid, $propArray) { foreach ($propArray as $prop => $value) { if (empty($value)) { diff --git a/modules-available/usblockoff/config.json b/modules-available/usblockoff/config.json index 12049689..7655f131 100644 --- a/modules-available/usblockoff/config.json +++ b/modules-available/usblockoff/config.json @@ -1,4 +1,4 @@ { "category":"main.beta", - "dependencies": ["bootstrap_switch", "bootstrap_dialog", "statistics", "permissionmanager"] + "dependencies": ["bootstrap_switch", "js_jqueryui", "bootstrap_dialog", "statistics", "permissionmanager"] } diff --git a/modules-available/usblockoff/install.inc.php b/modules-available/usblockoff/install.inc.php index 967771d1..cf260c61 100644 --- a/modules-available/usblockoff/install.inc.php +++ b/modules-available/usblockoff/install.inc.php @@ -1,47 +1,49 @@ <?php $res = array(); -/* -$t1 = $res[] = tableCreate('usb_devices', ' - `uid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - `id` varchar(50), - `serial` varchar(512) NOT NULL DEFAULT 0, - `name` varchar(1024) CHARACTER SET ascii DEFAULT NULL, - `machineuuid` char(36) CHARACTER SET ascii DEFAULT NULL, - `time` INT(11) NOT NULL DEFAULT 0, - `user` varchar(8), - `ruleInformation` varchar(1024), - PRIMARY KEY (`uid`) -'); -*/ $t1 = $res[] = tableCreate('usblockoff_hw', ' - `hwid` INT(10) UNSIGNED NOT NULL , + `hwid` INT(10) UNSIGNED NOT NULL, `serial` VARCHAR(128), PRIMARY KEY (`hwid`, `serial`) '); $t2 = $res[] = tableCreate('usblockoff_hw_prop', ' - `hwid` INT(10) UNSIGNED NOT NULL , + `hwid` INT(10) UNSIGNED NOT NULL, `serial` VARCHAR(128), `prop` CHAR(16), `value` VARCHAR(500), PRIMARY KEY (`hwid`, `serial`, `prop`) '); -// TODO: ADD CONSTRAINT - $res[] = tableCreate('usb_configs', ' `configid` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `configname` VARCHAR(200) NOT NULL, + `rulesconfig` VARCHAR(512), + `daemonconfig` BLOB, + PRIMARY KEY (`configid`) +'); + +$t3 = $res[] = tableCreate('usb_rule_prop', ' + `ruleid` INT(10) UNSIGNED NOT NULL, + `prop` CHAR(16), + `value` VARCHAR(500) +'); + +/* +$res[] = tableCreate('usb_configs', ' + `configid` int(10) UNSIGNED NOT NULL AUTO_INCREMENTloadAddDeviceModal, + `configname` VARCHAR(200) NOT NULL, `rulesconfig` BLOB, `daemonconfig` BLOB, PRIMARY KEY (`configid`) '); +*/ //$ret = Database::exec("DROP TABLE `usb_devices`"); //$ret = Database::exec("DROP TABLE `usblockoff_hw`"); //$ret = Database::exec("DROP TABLE `usblockoff_hw_prop`"); +//$ret = Database::exec("DROP TABLE `usb_configs`"); if ($t1 === UPDATE_DONE || $t2 === UPDATE_DONE) { $ret = Database::exec('ALTER TABLE `usblockoff_hw` diff --git a/modules-available/usblockoff/lang/de/messages.json b/modules-available/usblockoff/lang/de/messages.json index 7ec920b2..4ff7bf68 100644 --- a/modules-available/usblockoff/lang/de/messages.json +++ b/modules-available/usblockoff/lang/de/messages.json @@ -1,4 +1,5 @@ { "config-deleted": "Konfiguration erfolgreich gelöscht.", - "config-saved": "Konfiguration erfolgreich gespeichert." + "config-saved": "Konfiguration erfolgreich gespeichert.", + "rule-deleted": "Regel erfolgreich gelöscht." }
\ No newline at end of file diff --git a/modules-available/usblockoff/lang/en/messages.json b/modules-available/usblockoff/lang/en/messages.json index 894ff608..c23afd78 100644 --- a/modules-available/usblockoff/lang/en/messages.json +++ b/modules-available/usblockoff/lang/en/messages.json @@ -1,4 +1,5 @@ { "config-deleted": "Config successfully deleted.", - "config-saved": "Config successfully saved." + "config-saved": "Config successfully saved.", + "rule-deleted": "Rule successfully deleted." }
\ No newline at end of file diff --git a/modules-available/usblockoff/page.inc.php b/modules-available/usblockoff/page.inc.php index 5e1b27b4..5cfb0ec3 100644 --- a/modules-available/usblockoff/page.inc.php +++ b/modules-available/usblockoff/page.inc.php @@ -1,8 +1,4 @@ <?php -$glob3 = 'globale Variable 3'; -$name = 'testname'; -$logedIn = true; - class Page_usblockoff extends Page { @@ -22,8 +18,12 @@ class Page_usblockoff extends Page if ($this->action === 'updateConfig') { $this->updateConfig(); + } elseif ($this->action === 'addDevices') { + $this->addDevices(); } elseif ($this->action === 'deleteConfig') { $this->deleteConfig(); + } elseif ($this->action === 'deleteRule') { + $this->deleteRule(); } } @@ -50,7 +50,140 @@ class Page_usblockoff extends Page 'rulesConfigHtml' => $rulesConfigHtml, 'daemonConfigHtml' => $daemonConfigHtml )); + } else if ($show === "add-devices") { + $this->deviceList(); + } else if ($show === "add-generic-rule") { + $this->addGenericRule(); + } + } + + private function addDevices() + { + $configid = Request::any('configid', 0, 'int'); + + $rules = json_decode(Request::post('rules', '', 'string'), true); + foreach ($rules as $rule) { + $rid = (int)$rule['id']; + if($rid == 0) { + // New entry so insert only with new id. + $rid = Database::queryFirst("SELECT MAX(ruleid) AS ID FROM `usb_rule_prop`"); + $rid = $rid['ID']; + if ($rid == null) $rid = 1; + else $rid += 1; + } else { + // Old entry so delete all old ones and insert new ones. + Database::exec("DELETE FROM `usb_rule_prop` WHERE ruleid=:ruleid", array('ruleid' => $rid)); + } + + Database::exec("INSERT INTO `usb_rule_prop` (ruleid, prop, value) VALUES (:ruleid, :prop, :val)", array( + 'ruleid' => $rid, + 'prop' => 'target', + 'val' => $rule['target'] + )); + + foreach ($rule['attributes'] as $attribute) { + // TODO: Better in one query? + Database::exec("INSERT INTO `usb_rule_prop` (ruleid, prop, value) VALUES (:ruleid, :prop, :val)", array( + 'ruleid' => $rid, + 'prop' => $attribute['prop'], + 'val' => $attribute['value'] + )); + } + + // TODO: Add id at the end of the config entry. + $config = Database::queryFirst("SELECT rulesconfig FROM `usb_configs` WHERE configid=:configid", array( + 'configid' => $configid + )); + $rulesconfig = json_decode($config['rulesconfig'], true); + $rulesconfig[] = $rid; + Database::exec("UPDATE `usb_configs` SET rulesconfig = :rulesconfig WHERE configid=:configid", array( + 'configid' => $configid, + 'rulesconfig' => json_encode($rulesconfig) + )); + //$result['rules'][] = $rid; + } + + Util::redirect('?do=usblockoff&show=edit-config&configid=' . $configid); + } + + private function deviceList() + { + $configid = Request::get("configid", 0, 'int'); + $usbdevices = $this->getUsbDeviceList(); + + // TODO: Translate Operator Action etc.. + + $settings = array(); + $setting = array(); + $setting['title'] = "Action"; + $setting['select_list'] = array(array( + 'option' => 'allow', + 'active' => true, + ), + array( + 'option' => 'block', + 'active' => false, + ), + array( + 'option' => 'reject', + 'active' => false, + )); + $setting['helptext'] = array('helptext' => Dictionary::translateFile('rule', 'abr_helptext')); + $setting['property'] = 'action'; + $setting['settingHtml'] = Render::parse('server-prop-dropdown', (array)$setting); + $settings[] = $setting; + + $ruleValues = array('id' => true, + 'serial' => true, + 'name' => true, + //'hash' => false, + //'parent-hash' => false, + 'via-port' => false, + 'with-interface' => false); + foreach ($ruleValues as $key => $value) { + $settings[] = array( + 'settingHtml' => Render::parse('server-prop-bool', array('title' => Dictionary::translateFile('rule', $key), + 'helptext' => array('helptext' => Dictionary::translateFile('rule', $key . "_helptext")), + 'property' => $key, + 'currentvalue' => $value)), + ); } + Render::addTemplate('usb-device-list', array( + 'list' => array_values($usbdevices), + 'settings' => array_values($settings), + 'configid' => $configid + )); + } + + private function addGenericRule($target = 'allow') { + $settings = array(); + $configid = Request::get("configid", ""); + + // TODO: Translate Operator Action etc.. + + $setting = array(); + $setting['title'] = "Action"; + $setting['select_list'] = array(array( + 'option' => 'allow', + 'active' => ($target == 'allow' ? true : false), + ), + array( + 'option' => 'block', + 'active' => ($target == 'block' ? true : false), + ), + array( + 'option' => 'reject', + 'active' => ($target == 'reject' ? true : false), + )); + $setting['helptext'] = array('helptext' => Dictionary::translateFile('rule', 'abr_helptext')); + $setting['property'] = 'action'; + $setting['settingHtml'] = Render::parse('server-prop-dropdown', (array)$setting); + $settings[] = $setting; + + Render::addTemplate('usb-add-generic-rule', array( + 'settings' => array_values($settings), + 'configid' => $configid + )); } protected function loadConfigChooser() @@ -68,7 +201,6 @@ class Page_usblockoff extends Page protected function deleteConfig() { $configID = Request::any('id', 0, 'int'); - if ($configID != 0) { Database::exec("DELETE FROM `usb_configs` WHERE configid=:configid", array('configid' => $configID)); } @@ -77,6 +209,19 @@ class Page_usblockoff extends Page Util::redirect('?do=usblockoff'); } + protected function deleteRule() + { + $configid = Request::any('configid', 0, 'int'); + $ruleid = Request::any('id', 0, 'int'); + if ($ruleid != 0) { + Database::exec("DELETE FROM `usb_rule_prop` WHERE ruleid=:ruleid", array('ruleid' => $ruleid)); + } + + Message::addSuccess('rule-deleted'); + Util::redirect('?do=usblockoff&show=edit-config&configid=' . $configid); + } + + protected function updateConfig() { $result['saveAsNewConfig'] = Request::post('saveAsNewConfig', false, 'bool'); @@ -93,7 +238,7 @@ class Page_usblockoff extends Page $result['IPCAccessControlFiles'] = Request::post('IPCAccessControlFiles', '', 'string'); $result['DeviceRulesWithPort'] = Request::post('DeviceRulesWithPort', '', 'string'); $result['AuditFilePath'] = Request::post('AuditFilePath', '', 'string'); - $result['rules'] = Request::post('rules', '', 'string'); + $result['rules'] = json_decode(Request::post('rules', '', 'string'), true); $id = Request::post('id', 0, 'int'); $configname = Request::post('configName', '', 'string'); @@ -126,32 +271,66 @@ class Page_usblockoff extends Page if ($id == '0' || $result['saveAsNewConfig']) { $dbquery = Database::exec("INSERT INTO `usb_configs` (configname, rulesconfig, daemonconfig) VALUES (:configname, :rulesconfig, :daemonconfig)", array('configname' => $configname, - 'rulesconfig' => $result['rules'], + 'rulesconfig' => json_encode($result['rules']), 'daemonconfig' => implode($newDaemonConf))); } else { $dbquery = Database::exec("UPDATE `usb_configs` SET configname=:configname, rulesconfig=:rulesconfig, daemonconfig=:daemonconfig WHERE configid=:configid", array('configid' => $id, 'configname' => $configname, - 'rulesconfig' => $result['rules'], + 'rulesconfig' => json_encode($result['rules']), 'daemonconfig' => implode($newDaemonConf))); } Message::addSuccess('config-saved'); } - private function loadRulesConfig($id) { + private function loadRulesConfig($configid) { $rulesConf = null; - if ($id == 0) { + if ($configid == 0) { $currentdir = getcwd(); - + // TODO: No need for that with the new rule db structure. $rulesConf = file_get_contents($currentdir . '/modules/usblockoff/inc/default-configs/rules.conf'); } else { - $dbquery = Database::queryFirst("SELECT * FROM `usb_configs` WHERE configid=:id", array('id' => $id)); - $rulesConf = $dbquery['rulesconfig']; + $dbquery = Database::queryFirst("SELECT * FROM `usb_configs` WHERE configid=:id", array('id' => $configid)); + $ruleIds = json_decode($dbquery['rulesconfig'], true); } + + $rulesArray = []; + foreach ($ruleIds as $id) { + // TODO: Query rule and prepare array for the html file. + $dbq = Database::simpleQuery("SELECT * FROM `usb_rule_prop` WHERE ruleid=:id", array('id' => $id)); + $rule = []; + $rule['id'] = $id; + $rule['hasoverload'] = false; + $rule['num_overload'] = 0; + $rule['attributes'] = array(); + $rule['attributes_overload'] = ""; + while ($entry = $dbq->fetch(PDO::FETCH_ASSOC)) { + if ($entry['prop'] == "target") { + $rule['target'] = $entry['value']; + } else { + $attributes = []; + $attributes['prop'] = $entry['prop']; + $attributes['value'] = $entry['value']; + + if(sizeof($rule['attributes']) >= 3) { + $rule['hasoverload'] = true; + $rule['num_overload'] += 1; + $rule['attributes_overload'] .= $attributes['prop'] . ': ' . $attributes['value'] . "<br>"; + } else { + $rule['attributes'][] = $attributes; + } + } + } + + if (!empty($rule['target'])) { + $rulesArray[] = $rule; + } + } return Render::parse('usb-rules-config', array( - 'rules' => $rulesConf, + 'rules' => (array)$rulesArray, + 'configid' => $configid )); } @@ -168,7 +347,6 @@ class Page_usblockoff extends Page $dbquery = Database::queryFirst("SELECT * FROM `usb_configs` WHERE configid=:id", array('id' => $id)); $daemonConf = explode("\r\n", $dbquery['daemonconfig']); } - $element = array(); $hlptxt = ''; @@ -205,90 +383,11 @@ class Page_usblockoff extends Page die('Unauthorized'); } $action = Request::any('action'); - if ($action === 'deviceList') { - $this->ajaxDeviceList(); - } elseif ($action === 'genericRuleBuilder') { - $this->ajaxGenericRuleBuilder(); - } - } - - - - private function ajaxGenericRuleBuilder() { - $settings = array(); - - // TODO: Translate Operator Action etc.. - $setting = array(); - $setting['title'] = "Action"; - $setting['select_list'] = array(array( - 'option' => 'allow', - 'active' => true, - ), - array( - 'option' => 'block', - 'active' => false, - ), - array( - 'option' => 'reject', - 'active' => false, - )); - $setting['helptext'] = array('helptext' => Dictionary::translateFile('rule', 'abr_helptext')); - $setting['property'] = 'action'; - $setting['settingHtml'] = Render::parse('server-prop-dropdown', (array)$setting); - $settings[] = $setting; - - echo Render::parse('usb-add-generic-rule', array( - 'settings' => array_values($settings), - )); - } - - private function ajaxDeviceList() - { - $usbdevices = $this->getUsbDeviceList(); - - // TODO: Translate Operator Action etc.. - - $settings = array(); - $setting = array(); - $setting['title'] = "Action"; - $setting['select_list'] = array(array( - 'option' => 'allow', - 'active' => true, - ), - array( - 'option' => 'block', - 'active' => false, - ), - array( - 'option' => 'reject', - 'active' => false, - )); - $setting['helptext'] = array('helptext' => Dictionary::translateFile('rule', 'abr_helptext')); - $setting['property'] = 'action'; - $setting['settingHtml'] = Render::parse('server-prop-dropdown', (array)$setting); - $settings[] = $setting; - - $ruleValues = array('id' => true, - 'serial' => true, - 'name' => true, - 'hash' => false, - 'parent-hash' => false, - 'via-port' => false, - 'with-interface' => false, - 'interface-policy' => false); - foreach ($ruleValues as $key => $value) { - $settings[] = array( - 'settingHtml' => Render::parse('server-prop-bool', array('title' => Dictionary::translateFile('rule', $key), - 'helptext' => array('helptext' => Dictionary::translateFile('rule', $key . "_helptext")), - 'property' => $key, - 'currentvalue' => $value)), - ); + // TODO: Removed if not needed anymore. + if ($action === '') { + //$this->ajaxDeviceList(); } - echo Render::parse('usb-device-list', array( - 'list' => array_values($usbdevices), - 'settings' => array_values($settings) - )); } private function getUsbDeviceList() { diff --git a/modules-available/usblockoff/templates/usb-add-generic-rule.html b/modules-available/usblockoff/templates/usb-add-generic-rule.html index 07729db4..77b5f13e 100644 --- a/modules-available/usblockoff/templates/usb-add-generic-rule.html +++ b/modules-available/usblockoff/templates/usb-add-generic-rule.html @@ -18,8 +18,10 @@ <div class="panel panel-default"> <div class="panel-heading">{{lang_modeOptions}} + <!-- <input class="settings-bs-switch" id="expert_Switch" type="checkbox" name="expert_Switch" data-on-text="Expert" data-off-text="Casual" data-size="small"> + --> </div> <div class="panel-body"> <div class="list-group"> @@ -64,6 +66,7 @@ </div> + <!-- <div id="expertMode" style="display: none;"> <div class="list-group-item"> @@ -132,7 +135,7 @@ </div> </div> - +--> </div> </div> </div> @@ -140,16 +143,26 @@ </form> </div> -<script type="text/javascript"> - $('a.btn[title]').tooltip({placement: "auto", html: true}); +<div class="pull-right"> + <a href="?do=usblockoff&show=edit-config&configid={{configid}}" class="btn btn-default">Cancel</a> + <button type="submit" class="btn btn-primary"> + <span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}} + </button> +</div> - var contains = true; - var c = $('#contains'); - c.bootstrapSwitch(); - c.on('switchChange.bootstrapSwitch', function(event, state) { - contains = state; +<script type="text/javascript"> + document.addEventListener("DOMContentLoaded", function(event) { + $('a.btn[title]').tooltip({placement: "auto", html: true}); + + var contains = true; + var c = $('#contains'); + c.bootstrapSwitch(); + c.on('switchChange.bootstrapSwitch', function(event, state) { + contains = state; + }); }); + /* var s = $('#expert_Switch'); var mode = "casual"; s.bootstrapSwitch(); @@ -169,27 +182,17 @@ mode = "casual"; } }); - - // Add handler to the modal Button. - $('#myModalAddButton').unbind().click(addRule); - $('#myModalAddButtonText').text('{{lang_addRule}}'); - + */ function addRule() { - if ($('#rules').val() != "") { - $('#rules').val($('#rules').val() + "\r\n"); - } - if (mode == "casual") { - if (contains) { - $('#rules').val($('#rules').val() + $('#prop-action').val() + ' with-interface one-of' + ' { ' + - $('#casual_selected option:selected').val() + ' }'); - } else { - $('#rules').val($('#rules').val() + $('#prop-action').val() + ' with-interface ' + $('#casual_selected option:selected').val()); - } - } else { - $('#rules').val($('#rules').val() + $('#prop-action').val() + ' with-interface ' + $('#expert_selected option:selected').val() - + ' { ' + $("#input_deviceClass").val() + ":" + $("#input_deviceSubClass").val() + ":" - + $('#input_deviceProtocol').val() + ' }'); - } - $('#myModal').modal('hide'); + var rule = {}; + rule['target'] = $('#prop-action').val(); + rule['id'] = 0; + var attribute = {}; + attribute['prop'] = 'with-interface'; + attribute['value'] = $('#casual_selected option:selected').val(); + rule['attributes'] = []; + rule['attributes'].push(attribute); + + // TODO: SEND RULE TO PHO } </script>
\ No newline at end of file diff --git a/modules-available/usblockoff/templates/usb-configuration-table.html b/modules-available/usblockoff/templates/usb-configuration-table.html index eb3a8839..3ceebce5 100644 --- a/modules-available/usblockoff/templates/usb-configuration-table.html +++ b/modules-available/usblockoff/templates/usb-configuration-table.html @@ -6,6 +6,7 @@ </div> </div> </div> +<!-- <div class="row"> <div class="col-md-12"> <table id="configurationTable" class="table table-condensed table-hover stupidtable"> @@ -43,9 +44,83 @@ </a> </div> </div> + </div> --> +</div> + + +<ul class="nav nav-tabs"> + <li class="active"><a data-toggle="tab" href="#configTableMenu">{{lang_editConfig}}</a></li> + <li><a data-toggle="tab" href="#assignMenu">{{lang_assingMenu}}</a></li> +</ul> + +<div class="tab-content"> + <div id="configTableMenu" class="tab-pane fade in active"> + <div class="panel panel-default"> + <div class="panel-heading">{{lang_configurationTable}}</div> + <div class="panel-body"> + <div class="list-group"> + + <div class="row"> + <div class="col-md-12"> + <table id="configurationTable" class="table table-condensed table-hover stupidtable"> + <thead> + <tr> + <th data-sort="string">{{lang_serverName}}</th> + <th>{{lang_ruleInfoTODO}}</th> + <th>{{lang_edit}}</th> + <th>{{lang_delete}}</th> + </tr> + </thead> + <tbody> + {{#config_list}} + <tr> + <td data-sort-value="{{config_name}}">{{config_name}}</td> + <td>TODO: Show Rule information here</td> + <td> + <a class="btn btn-xs btn-info" href="?do=usblockoff&show=edit-config&configid={{config_id}}"> + <span class="glyphicon glyphicon-edit"></span> + </a> + </td> + <td> + <a class="btn btn-xs btn-danger" onclick="deleteConfig(event, {{config_id}});"> + <span class="glyphicon glyphicon-trash"></span> + </a> + </td> + </tr> + {{/config_list}} + </tbody> + </table> + <div class="buttonbar text-right"> + <a class="btn btn-success" href="?do=usblockoff&show=edit-config&configid=new-default"> + <span class="glyphicon glyphicon-plus"></span> + {{lang_configuration}} + </a> + </div> + </div> + </div> + + </div> + </div> + </div> + </div> + <div id="assignMenu" class="tab-pane fade"> + <div class="panel panel-default"> + <div class="panel-heading">{{lang_configurationTable}}</div> + <div class="panel-body"> + <div class="list-group"> + + <h3>Work in progress ...</h3> + <p>Todo: Implement this.</p> + <p>Or not.</p> + <p>¯\_(ツ)_/¯</p> + + </div> + </div> + </div> </div> </div> + <script> function deleteConfig(event, id) { event.preventDefault(); diff --git a/modules-available/usblockoff/templates/usb-device-list.html b/modules-available/usblockoff/templates/usb-device-list.html index a7c9afed..ea321008 100644 --- a/modules-available/usblockoff/templates/usb-device-list.html +++ b/modules-available/usblockoff/templates/usb-device-list.html @@ -1,79 +1,86 @@ -<div> - <form method="post" action="?do=usblockoff" id="addDevicesForm"> - <input type="hidden" name="token" value="{{token}}"> - <input type="hidden" name="action" value="addDevices"> - - <div class="input-group" id="search"> - <span class="input-group-addon"><i class="glyphicon glyphicon-search"></i></span> - <input type="text" id="myInput" class="form-control" onkeyup="search()" placeholder="Search for .." - style="font-size: 16px;"/> - <span class="input-group-addon" style="width:0px; padding-left:0px; padding-right:0px; border:none;"></span> - <select class="form-control" id="searchFor" style="font-size: 16px;" onchange="search()"> - <option value="0" select>Name</option> - <option value="1">Date / Time</option> - <option value="2">User Information</option> - <option value="3">USB Information</option> - <option value="4">Rules Information</option> - </select> - </div> - - <div style="max-height: 800px; overflow-x: auto;"> - <table class="table table-hover" id="myTable"> - <thead> - <tr> - <th width="1" style="text-align: center;">Name</th> - <th width="1" style="text-align: center;">Time</th> - <th width="1">User Info</th> - <th width="1">USB Info</th> - <th width="1">Rule Info</th> - </tr> - </thead> - {{#list}} - <input type="hidden" id="{{uid}}-prop-name" value="{{name}}"> - <input type="hidden" id="{{uid}}-prop-id" value="{{id}}"> - <input type="hidden" id="{{uid}}-prop-serial" value="{{serial}}"> - <input type="hidden" id="{{uid}}-prop-via-port" value="{{via-port}}"> - <input type="hidden" id="{{uid}}-prop-hash" value="{{hash}}"> - <input type="hidden" id="{{uid}}-prop-parent-hash" value="{{parent-hash}}"> - <input type="hidden" id="{{uid}}-prop-with-interface" value="{{with-interface}}"> - - <tbody onclick="clickRow(this, {{uid}});" id="{{uid}}"> - <tr> - <td nowrap align="center" style="vertical-align: middle;"><label>{{name}}</label></td> - <td nowrap align="center" style="vertical-align: middle;">{{time}}<br>{{date}}</td> - <td nowrap><font size="0">User: {{user}}<br>Location: {{location}}<br>Client: {{clientip}}</font></td> - <td nowrap><font size="0">id: {{id}}<br>Serial: {{serial}}<br>via-port: {{via-port}}</font></td> - <td nowrap><font size="0">hash: {{hash}}<br>parent-hash: {{parent-hash}}<br>with-interface: - {{with-interface}}</font></td> - </tr> - </tbody> - {{/list}} - </table> - </div> - - <div class="panel panel-default"> - <div class="panel-heading">{{lang_ruleOptions}}</div> - <div class="panel-body"> - <div class="list-group"> - <div id="settingsDIV"> - {{#settings}} - {{{settingHtml}}} - {{/settings}} - </div> +<form method="post" action="?do=usblockoff" id="addDevicesForm"> + <input type="hidden" name="token" value="{{token}}"> + <input type="hidden" name="action" value="addDevices"> + <input type="hidden" name="rules" value="" id="rules"> + <input type="hidden" name="configid" value="{{configid}}" id="configid"> + + <div class="input-group" id="search"> + <span class="input-group-addon"><i class="glyphicon glyphicon-search"></i></span> + <input type="text" id="myInput" class="form-control" onkeyup="search()" placeholder="Search for .." + style="font-size: 16px;"/> + <span class="input-group-addon" style="width:0px; padding-left:0px; padding-right:0px; border:none;"></span> + <select class="form-control" id="searchFor" style="font-size: 16px;" onchange="search()"> + <option value="0" select>Name</option> + <option value="1">Date / Time</option> + <option value="2">User Information</option> + <option value="3">USB Information</option> + <option value="4">Rules Information</option> + </select> + </div> + + <div style="max-height: 800px; overflow-x: auto;"> + <table class="table table-hover" id="myTable"> + <thead> + <tr> + <th width="1" style="text-align: center;">Name</th> + <th width="1" style="text-align: center;">Time</th> + <th width="1">User Info</th> + <th width="1">USB Info</th> + <th width="1">Rule Info</th> + </tr> + </thead> + {{#list}} + <input type="hidden" id="{{uid}}-prop-name" value="{{name}}"> + <input type="hidden" id="{{uid}}-prop-id" value="{{id}}"> + <input type="hidden" id="{{uid}}-prop-serial" value="{{serial}}"> + <input type="hidden" id="{{uid}}-prop-via-port" value="{{via-port}}"> + <input type="hidden" id="{{uid}}-prop-hash" value="{{hash}}"> + <input type="hidden" id="{{uid}}-prop-parent-hash" value="{{parent-hash}}"> + <input type="hidden" id="{{uid}}-prop-with-interface" value="{{with-interface}}"> + + <tbody onclick="clickRow(this, {{uid}});" id="{{uid}}"> + <tr> + <td nowrap align="center" style="vertical-align: middle;"><label>{{name}}</label></td> + <td nowrap align="center" style="vertical-align: middle;">{{time}}<br>{{date}}</td> + <td nowrap><font size="0">User: {{user}}<br>Location: {{location}}<br>Client: {{clientip}}</font></td> + <td nowrap><font size="0">id: {{id}}<br>Serial: {{serial}}<br>via-port: {{via-port}}</font></td> + <td nowrap><font size="0">hash: {{hash}}<br>parent-hash: {{parent-hash}}<br>with-interface: + {{with-interface}}</font></td> + </tr> + </tbody> + {{/list}} + </table> + </div> + + <div class="panel panel-default"> + <div class="panel-heading">{{lang_ruleOptions}}</div> + <div class="panel-body"> + <div class="list-group"> + <div id="settingsDIV"> + {{#settings}} + {{{settingHtml}}} + {{/settings}} </div> </div> </div> + </div> + <div class="pull-right"> + <a href="?do=usblockoff&show=edit-config&configid={{configid}}" class="btn btn-default">Cancel</a> + <button id="addButton" class="btn btn-success" type="submit" onclick="addDevices();"> + <span style="margin-right: 5px;" class="glyphicon glyphicon-plus"></span> + <span id="addButtonText"></span> + </button> + </div> - </form> -</div> +</form> <script type="text/javascript"> - $('a.btn[title]').tooltip(); - $('.settings-bs-switch').bootstrapSwitch({size: 'small'}); - countSelected(); - // Add handler to the modal Button. - $('#myModalAddButton').unbind().click(addDevices); + document.addEventListener("DOMContentLoaded", function(event) { + $('a.btn[title]').tooltip(); + $('.settings-bs-switch').bootstrapSwitch({size: 'small'}); + countSelected(); + }); function clickRow(tbody, uid) { $(tbody).toggleClass('selected'); @@ -83,14 +90,16 @@ function countSelected() { var numSelected = $('.selected').length; if (numSelected == 0) { - $('#myModalAddButton').prop('disabled', true); + $('#addButton').prop('disabled', true); + //$('#addButton').addClass('disabled'); } else { - $('#myModalAddButton').prop('disabled', false); + $('#addButton').prop('disabled', false); + //$('#addButton').removeClass('disabled'); } if (numSelected == 1) { - $('#myModalAddButtonText').text(' ' + numSelected + ' {{lang_device}}'); + $('#addButtonText').text(' ' + numSelected + ' {{lang_device}}'); } else { - $('#myModalAddButtonText').text(' ' + numSelected + ' {{lang_devices}}'); + $('#addButtonText').text(' ' + numSelected + ' {{lang_devices}}'); } } @@ -117,29 +126,27 @@ } function addDevices() { + var rules = []; $('.selected').each(function () { - var rule = $('#prop-action').val(); + var rule = {}; + rule['target'] = $('#prop-action').val(); + rule['id'] = 0; + rule['attributes'] = []; + var selected = $(this); $('#settingsDIV .settings-bs-switch').each(function () { if ($(this).is(":checked")) { - var settingname = $(this).attr('name').substring(5); - var info = $('#' + $(selected).attr('id') + '-' + $(this).attr('name')); - - if (settingname == 'id' || settingname == 'with-interface') { - rule += ' ' + settingname + ' ' + info.val(); - } else { - rule += ' ' + settingname + ' "' + info.val() + '"'; - } + var attr = {}; + attr['prop'] = $(this).attr('name').substring(5); + attr['value'] = $('#' + $(selected).attr('id') + '-' + $(this).attr('name')).val(); + + rule['attributes'].push(attr); } }); - if ($('#rules').val() != "") { - $('#rules').val($('#rules').val() + "\r\n"); - } - $('#rules').val($('#rules').val() + rule); + rules.push(rule); }); - $('#myModal').modal('toggle'); + $('#rules').val(JSON.stringify(rules)); } - </script> <style type='text/css'> diff --git a/modules-available/usblockoff/templates/usb-edit-config.html b/modules-available/usblockoff/templates/usb-edit-config.html index fc7aabfb..8e75b96d 100644 --- a/modules-available/usblockoff/templates/usb-edit-config.html +++ b/modules-available/usblockoff/templates/usb-edit-config.html @@ -14,7 +14,7 @@ <label>{{lang_configName}}</label> </div> <div class="col-sm-7"> - <input required class="form-control" name="configName" id="configName" value="{{configName}}"> + <input required class="form-control" name="configName" id="configName" maxlength="50" value="{{configName}}"> </div> <div class="col-sm-2"> <a class="btn btn-default" title="{{lang_configName_helptext}}"> @@ -31,7 +31,6 @@ <ul class="nav nav-tabs"> <li class="active"><a data-toggle="tab" href="#rulesConfigMenu">{{lang_rulesConfig}}</a></li> <li><a data-toggle="tab" href="#deamonConfigMenu">{{lang_daemonConfig}}</a></li> - <li><a data-toggle="tab" href="#assignMenu">{{lang_assignMenu}}</a></li> </ul> <div class="tab-content"> @@ -45,17 +44,11 @@ {{{daemonConfigHtml}} </div> </div> - <div id="assignMenu" class="tab-pane fade"> - <h3>Work in progress ...</h3> - <p>Todo: Implement this.</p> - <p>Or not.</p> - <p>¯\_(ツ)_/¯</p> - </div> </div> <div class="pull-right"> <!-- TODO: Reset Button should't call loadConfig instead do not reset the select input... but how? --> - <button class="btn btn-warning" type="reset" onclick="loadConfig($('#select_config'));"> + <button class="btn btn-warning" type="reset" onclick="location.reload();"> <!-- TODO: Add discardChanges to the main-> globalVariables --> <span class="glyphicon glyphicon-refresh"></span> {{lang_discardChanges}} </button> diff --git a/modules-available/usblockoff/templates/usb-rules-config.html b/modules-available/usblockoff/templates/usb-rules-config.html index 3827dc03..712eb2ab 100644 --- a/modules-available/usblockoff/templates/usb-rules-config.html +++ b/modules-available/usblockoff/templates/usb-rules-config.html @@ -1,105 +1,107 @@ <div class="panel panel-default"> - <div class="panel-heading">rules.conf - <input class="settings-bs-switch" id="rules_expert_Switch" type="checkbox" name="rules_expert_Switch" - data-on-text="Expert" data-off-text="Casual" data-size="small"> - </div> + <div class="panel-heading">rules.conf</div> <div class="panel-body" id="casualRules"> <div class="list-group"> - <!-- TEST_AREA --> - - <div> - Work in progress ... - </div> - - <!-- /TEST_AREA --> - - </div> - </div> + <input type="hidden" name="rules" value="" id="rules"> + <table id="rulesTable" class="table table-condensed table-hover"> + <thead> + <tr> + <th data-sort="string" width="20"><span class="glyphicon glyphicon-th-list"></span></th> + <th width="120">{{lang_target}}</th> + <th>{{lang_attributes}}</th> + <th>{{lang_edit}}</th> + <th>{{lang_delete}}</th> + </tr> + </thead> + <tbody id="tableBody" style="overflow: auto;"> - <div class="panel-body" id="expertRules" style="display: none;"> - <div class="list-group"> - <div class="form-group"> - <textarea class="form-control" rows="10" name="rules" id="rules">{{rules}}</textarea> - </div> + {{#rules}} + <tr id="{{id}}"> + <td class="drag-handler" style="cursor: pointer;text-align: center; vertical-align: middle;"> + <span class="glyphicon glyphicon-th-list"></span> + </td> + <td style="vertical-align: middle; text-align: center;">{{target}}</td> + <td> + {{#attributes}} + {{prop}}: {{value}}<br> + {{/attributes}} + {{#hasoverload}} + <a class="label label-default overload" style="background-color: #337ab7;" title="{{attributes_overload}}">+{{num_overload}}</a> + {{/hasoverload}} + </td> + <td> + <a class="btn btn-xs btn-info"> + <span class="glyphicon glyphicon-edit" onclick="alert('implement in new page');"></span> + </a> + </td> + <td> + <a class="btn btn-xs btn-danger" href="?do=usblockoff&action=deleteRule&id={{id}}&configid={{configid}}"> + <span class="glyphicon glyphicon-trash"></span> + </a> + </td> + </tr> + {{/rules}} + </tbody> + </table> <div class="pull-right"> - <a class="btn btn-default" title="{{lang_howToRuleLang}}" - href="https://usbguard.github.io/documentation/rule-language.html" - style="margin-right: -1px;" target="_blank"> - <span class="glyphicon glyphicon-question-sign"></span> - </a> - <a class="btn btn-success" onclick="loadAddGenericRuleModal();" - style="margin-right: 3px; float: none;"> - <span class="glyphicon glyphicon-plus"></span> + <a class="btn btn-success" href="?do=usblockoff&show=add-generic-rule&configid={{configid}}" + style="margin-right: 3px; float: right;"> + <span style="margin-right: 5px;" class="glyphicon glyphicon-plus"></span> <span>{{lang_genericRule}}</span> </a> - <a class="btn btn-success" style="float: right;" onclick="loadAddDeviceModal();"> + <a class="btn btn-success" href="?do=usblockoff&show=add-devices&configid={{configid}}" + style="margin-right: 3px;float: right;"> <span style="margin-right: 5px;" class="glyphicon glyphicon-plus"></span> <span>{{lang_devices}}</span> </a> </div> - </div></div> -</div> - -<div class="modal fade" id="myModal" tabindex="-1" role="dialog"> - <div class="modal-dialog"> - <div class="modal-content"> - <div class="modal-header" id="myModalHeader"></div> - <div class="modal-body" id="myModalBody"></div> - <div class="modal-footer"> - <a class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</a> - <button id="myModalAddButton" class="btn btn-success" type="button"> - <span style="margin-right: 5px;" class="glyphicon glyphicon-plus"></span> - <span id="myModalAddButtonText"></span> - </button> - </div> </div> + </div> </div> - <script type="text/javascript"> + var rules = []; + var oldIndex = -1; document.addEventListener("DOMContentLoaded", function(event) { $('a.btn[title]').tooltip({placement: "auto", html: true}); - var s = $('#rules_expert_Switch'); - var mode = "casual"; - s.bootstrapSwitch(); - s.parent().parent().addClass('pull-right'); - s.parent().parent().css("margin", "-5px"); + $("#tableBody tr").each(function() { + rules.push(Number(this.id)); + }); + $('#rules').val(JSON.stringify(rules)); - s.on('switchChange.bootstrapSwitch', function(event, state) { - if (state) { - // Expert mode. - $('#casualRules').hide(); - $('#expertRules').show(); - mode = "expert"; - } else { - // Casual mode. - $('#expertRules').hide(); - $('#casualRules').show(); - mode = "casual"; - } + $('#tableBody').sortable({ + opacity: 0.8, + handle: '.drag-handler', + start: function(evt, ui) { + oldIndex = ui.item.index(); + }, + stop: function(evt, ui) { + updateTable(ui.item.index()); + }, }); + + $('a.overload').tooltip({placement: "auto", html: true}); }); - function loadAddDeviceModal() { - $('#myModalHeader').text("{{lang_device-list}}").css("font-weight", "Bold"); - $('#myModalAddButton').attr("form", "addDevicesForm"); - $('#myModal .modal-dialog').css('width', '60%'); - $('#myModal .modal-dialog').css('min-width', '60%'); - $('#myModal').modal('show'); - $('#myModalBody').load("?do=usblockoff&action=deviceList"); - } - function loadAddGenericRuleModal() { - $('#myModalHeader').text("{{lang_add-generic-rule}}").css("font-weight", "Bold"); - $('#myModalAddButton').attr("form", "addGenericRuleForm"); - $('#myModal .modal-dialog').css('width', '60%'); - $('#myModal .modal-dialog').css('min-width', '60%'); - $('#myModal').modal('show'); - $('#myModalBody').load("?do=usblockoff&action=genericRuleBuilder"); + // Called after a drag & drop event is finished. + function updateTable(new_index) { + var old_i = -1; + if (oldIndex == -1) { + return; + } else { + old_i = oldIndex; + oldIndex = -1; + } + var rule = rules[old_i]; + rules.splice(old_i, 1); + rules.splice(new_index, 0, rule); + console.log(JSON.stringify(rules)); + $('#rules').val(JSON.stringify(rules)); } </script>
\ No newline at end of file |