diff options
Diffstat (limited to 'modules-available')
-rw-r--r-- | modules-available/debugconfig/config.json | 2 | ||||
-rw-r--r-- | modules-available/debugconfig/lang/de/messages.json | 2 | ||||
-rw-r--r-- | modules-available/debugconfig/lang/en/module.json | 4 | ||||
-rw-r--r-- | modules-available/debugconfig/lang/en/template-tags.json | 11 | ||||
-rw-r--r-- | modules-available/debugconfig/page.inc.php | 337 | ||||
-rw-r--r-- | modules-available/debugconfig/templates/_page.html | 138 | ||||
-rw-r--r-- | modules-available/debugconfig/templates/debugconfig.html | 40 |
7 files changed, 92 insertions, 442 deletions
diff --git a/modules-available/debugconfig/config.json b/modules-available/debugconfig/config.json index e4d906e1..b8d03278 100644 --- a/modules-available/debugconfig/config.json +++ b/modules-available/debugconfig/config.json @@ -1,4 +1,4 @@ { - "category": "main.settings-client", + "category": "main.settings-server", "dependencies" : ["js_selectize", "bootstrap_multiselect"] } diff --git a/modules-available/debugconfig/lang/de/messages.json b/modules-available/debugconfig/lang/de/messages.json index a0b8cdd4..bfa02332 100644 --- a/modules-available/debugconfig/lang/de/messages.json +++ b/modules-available/debugconfig/lang/de/messages.json @@ -2,4 +2,4 @@ "invalid-hook": "Ung\u00fcltiger Hook: {{0}}", "no-module-hook": "Modul {{0}} hat keinen Hook", "settings-updated": "Einstellungen wurden aktualisiert" -}
\ No newline at end of file +} diff --git a/modules-available/debugconfig/lang/en/module.json b/modules-available/debugconfig/lang/en/module.json index 48591f88..74dc16c6 100644 --- a/modules-available/debugconfig/lang/en/module.json +++ b/modules-available/debugconfig/lang/en/module.json @@ -1,3 +1,3 @@ { - "module_name": "Config variables" -}
\ No newline at end of file + "module_name": "Remote debugging" +} diff --git a/modules-available/debugconfig/lang/en/template-tags.json b/modules-available/debugconfig/lang/en/template-tags.json index 8e75e5ac..351dc0bc 100644 --- a/modules-available/debugconfig/lang/en/template-tags.json +++ b/modules-available/debugconfig/lang/en/template-tags.json @@ -1,7 +1,6 @@ { - "lang_basicConfiguration": "Basic Configuration", - "lang_clientRelatedConfig": "The options on this page are related to the bwLehrpool client machines.", - "lang_editOverrideNotice": "You're editing the settings of a sub-section", - "lang_enableOverride": "Override", - "lang_settingActive": "Setting active" -}
\ No newline at end of file + "lang_debugConfig": "Remote Debugging Configuration", + "lang_debugDescription": "Configure remote debugging options. If enabled, the satellite server will accept client requests and relay data to the debugging server.", + "lang_debuggingActive": "Remote debugging is enabled", + "lang_debuggingInactive": "Remote debugging is disabled" +} diff --git a/modules-available/debugconfig/page.inc.php b/modules-available/debugconfig/page.inc.php index 5e99f2a0..ca6ba136 100644 --- a/modules-available/debugconfig/page.inc.php +++ b/modules-available/debugconfig/page.inc.php @@ -1,342 +1,45 @@ <?php -class Page_BaseConfig extends Page +class Page_debugConfig extends Page { - private $qry_extra = array(); - private $categories; - /** - * @var bool|string in case we're in module mode, set to the id of the module - */ - private $targetModule = false; + const DEFAULT_CONFIG = array("enabled" => false, "debugServer" => "127.0.0.1"); protected function doPreprocess() { User::load(); - - // Determine if we're setting global or module specific - $this->getModuleSpecific(); - - $newValues = Request::post('setting'); - if (is_array($newValues)) { - if (!User::hasPermission('superadmin')) { - Message::addError('main.no-permission'); - Util::redirect('?do=baseconfig'); - } - // Build variables for specific sub-settings - if ($this->targetModule === false) { - // We're editing global settings - use the 'enabled' field - $qry_insert = ', enabled'; - $qry_values = ', :enabled'; - $qry_update = ', enabled = :enabled'; - $params = array(); - } elseif (empty($this->qry_extra['field'])) { - // Module specific, but module doesn't have an extra field - $qry_insert = ''; - $qry_values = ''; - $qry_update = ''; - } else { - // Module with extra field - $qry_insert = ', ' . $this->qry_extra['field']; - $qry_values = ', :field_value'; - $qry_update = ''; - $params = array('field_value' => $this->qry_extra['field_value']); - $delExtra = " AND {$this->qry_extra['field']} = :field_value "; - $delParams = array('field_value' => $this->qry_extra['field_value']); - // Not editing global settings - if ($this->getCurrentModuleName() === false) { - Message::addError('main.value-invalid', $this->qry_extra['field'], $this->qry_extra['field_value']); - Util::redirect('?do=BaseConfig'); - } - } - // Honor override/enabled checkbox - $override = Request::post('override', array()); - // Load all existing config options to validate input - $vars = BaseConfigUtil::getVariables(); - // First, handle shadowing so we don't create warnings for empty fields - BaseConfigUtil::markShadowedVars($vars, $newValues); - // Validate input - foreach ($vars as $key => $var) { - if (isset($var['shadowed'])) - continue; - if ($this->targetModule === false) { - // Global mode - $params['enabled'] = (is_array($override) && isset($override[$key]) && $override[$key] === 'on') ? 1 : 0; - } else { - // Module mode - if (is_array($override) && (!isset($override[$key]) || $override[$key] !== 'on')) { - // override not set - delete - $delParams['key'] = $key; - Database::exec("DELETE FROM {$this->qry_extra['table']} WHERE setting = :key $delExtra", $delParams); - continue; - } - } - $validator = $var['validator']; - $displayValue = (isset($newValues[$key]) ? $newValues[$key] : ''); - // Validate data first! - $mangledValue = Validator::validate($validator, $displayValue); - if ($mangledValue === false) { - Message::addWarning('main.value-invalid', $key, $displayValue); - continue; - } - // Now put into DB - Database::exec("INSERT INTO {$this->qry_extra['table']} (setting, value, displayvalue $qry_insert)" - . " VALUES (:key, :value, :displayvalue $qry_values)" - . " ON DUPLICATE KEY UPDATE value = :value, displayvalue = :displayvalue $qry_update", - array( - 'key' => $key, - 'value' => $mangledValue, - 'displayvalue' => $displayValue - ) + $params - ); - } - Message::addSuccess('settings-updated'); - if ($this->targetModule === false) { - Util::redirect('?do=BaseConfig'); - } elseif (empty($this->qry_extra['field'])) { - Util::redirect('?do=BaseConfig&module=' . $this->targetModule); - } else { - Util::redirect('?do=BaseConfig&module=' . $this->targetModule . '&' . $this->qry_extra['field'] . '=' . $this->qry_extra['field_value']); - } - } - // Load categories so we can define them as sub menu items - $this->categories = BaseConfigUtil::getCategories(); - asort($this->categories, SORT_DESC); - foreach ($this->categories as $catid => $val) { - Dashboard::addSubmenu( - '#category_' . $catid, - Dictionary::translateFileModule($this->categories[$catid]['module'], 'config-variable-categories', $catid, true) - ); - } - } - - protected function doRender() - { if (!User::hasPermission('superadmin')) { Message::addError('main.no-permission'); Util::redirect('?do=Main'); } - // Check if valid submodule mode, store name if any - if ($this->targetModule !== false) { - $this->qry_extra['subheading'] = $this->getCurrentModuleName(); - if ($this->qry_extra['subheading'] === false) { - Message::addError('main.value-invalid', $this->qry_extra['field'], $this->qry_extra['field_value']); - Util::redirect('?do=BaseConfig'); - } - } - // List config options - $settings = array(); - $vars = BaseConfigUtil::getVariables(); - // Get stuff that's set in DB already - if ($this->targetModule === false) { - $fields = ', enabled'; - $where = ''; - $params = array(); - } elseif (isset($this->qry_extra['field'])) { - $fields = ''; - $where = " WHERE {$this->qry_extra['field']} = :field_value"; - $params = array('field_value' => $this->qry_extra['field_value']); - } else { - $fields = ''; - $where = ''; - $params = array(); - } - // Populate structure with existing config from db - $res = Database::simpleQuery("SELECT setting, value, displayvalue $fields FROM {$this->qry_extra['table']} " - . " {$where} ORDER BY setting ASC", $params); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - if (!isset($vars[$row['setting']]) || !is_array($vars[$row['setting']])) { - $unknown[] = $row['setting']; - continue; - } - $row += $vars[$row['setting']]; - if (!isset($row['catid'])) { - $row['catid'] = 'unknown'; - } - $settings[$row['catid']]['settings'][$row['setting']] = $row; - } - // Add entries that weren't in the db (global), setup override checkbox (module specific) - foreach ($vars as $key => $var) { - if ($this->targetModule === false) { - // Global settings - honor enabled field in db - if (!isset($settings[$var['catid']]['settings'][$key]['enabled']) || $settings[$var['catid']]['settings'][$key]['enabled'] == 1) { - $settings[$var['catid']]['settings'][$key]['checked'] = 'checked'; - } - } elseif (isset($settings[$var['catid']]['settings'][$key])) { - // Module specific - value is set in DB - $settings[$var['catid']]['settings'][$key]['checked'] = 'checked'; - } else { - // Module specific - value is not set in DB - $settings[$var['catid']]['settings'][$key] = $var + array( - 'setting' => $key - ); - } - if (!isset($settings[$var['catid']]['settings'][$key]['displayvalue'])) { - $settings[$var['catid']]['settings'][$key]['displayvalue'] = $var['defaultvalue']; - } - if (!isset($settings[$var['catid']]['settings'][$key]['shadows'])) { - $settings[$var['catid']]['settings'][$key]['shadows'] = null; - } - //echo "<pre>"; - //var_dump($settings[$var['catid']]['settings'][$key]); - //echo "</pre>"; - $settings[$var['catid']]['settings'][$key] += array( - 'item' => $this->makeInput( - $var['validator'], - $key, - $settings[$var['catid']]['settings'][$key]['displayvalue'], - $settings[$var['catid']]['settings'][$key]['shadows'] - ), - 'description' => Util::markup(Dictionary::translateFileModule($var['module'], 'config-variables', $key)), - 'setting' => $key, - ); - } - //die(); - - - // Sort categories - $sortvals = array(); - foreach ($settings as $catid => &$setting) { - $sortvals[] = isset($this->categories[$catid]) ? (int)$this->categories[$catid]['sortpos'] : 99999; - $setting['category_id'] = $catid; - $setting['category_name'] = Dictionary::translateFileModule($this->categories[$catid]['module'], 'config-variable-categories', $catid); - if ($setting['category_name'] === false) { - $setting['category_name'] = $catid; - } - ksort($setting['settings']); - $setting['settings'] = array_values($setting['settings']); + if (!filter_var(Request::get('debugServer'), FILTER_VALIDATE_IP)) { + return; } - unset($setting); - array_multisort($sortvals, SORT_ASC, SORT_NUMERIC, $settings); - Render::addTemplate('_page', array( - 'override' => $this->targetModule !== false, - 'categories' => array_values($settings), - 'target_module' => $this->targetModule, - ) + $this->qry_extra); - Module::isAvailable('bootstrap_switch'); } - private function getCurrentModuleName() + protected function doRender() { - if (isset($this->qry_extra['tostring'])) { - $method = explode('::', $this->qry_extra['tostring']); - return call_user_func($method, $this->qry_extra['field_value']); - } - if (isset($this->qry_extra['field'])) { - return $this->targetModule . ' // ' . $this->qry_extra['field'] . '=' . $this->qry_extra['field_value']; - } - return $this->targetModule; + $debug_config = $this->getConfig(); + Render::addTemplate('debugconfig', array("debugEnabled" => $debug_config["enabled"], "debugServer" => $debug_config["debugServer"])); } - - private function getModuleSpecific() + + private function getConfig() { - $module = Request::any('module', '', 'string'); - if ($module === '') { - $this->qry_extra = array( - 'table' => 'setting_global', - ); - return; - } - //\\//\\//\\ - if (!Module::isAvailable($module)) { - Message::addError('main.no-such-module', $module); - Util::redirect('?do=baseconfig'); + if (Property::getRemoteDebugConfig() == Null) { + Property::setRemoteDebugConfig(self::DEFAULT_CONFIG); } - $file = 'modules/' . $module . '/baseconfig/hook.json'; - if (!file_exists($file)) { - Message::addError('no-module-hook', $module); - Util::redirect('?do=baseconfig'); - } - $hook = json_decode(file_get_contents($file), true); - if (empty($hook['table'])) { - Message::addError('invalid-hook', $module); - Util::redirect('?do=baseconfig'); - } - if (isset($hook['field'])) { - $hook['field_value'] = Request::any($hook['field'], '0', 'string'); - } - $this->targetModule = $module; - $this->qry_extra = $hook; + return Property::getRemoteDebugConfig(); } - /** - * Create html snippet for setting, based on given validator - * @param type $validator - * @return boolean - */ - private function makeInput($validator, $setting, $current, $shadows) + private function setConfig() { - /* for the html snippet we need: */ - $args = array('class' => 'form-control', 'name' => "setting[$setting]", 'id' => $setting); - if (!empty($shadows)) { - $args['data-shadows'] = json_encode($shadows); - } - $inner = ""; - /* -- */ - - $parts = explode(':', $validator, 2); - - if ($parts[0] === 'list') { - - $items = explode('|', $parts[1]); - foreach ($items as $item) { - if ($item === $current) { - $inner .= "<option selected=\"selected\" value=\"$item\"> $item </option>"; - } else { - $inner .= "<option value=\"$item\"> $item </option>"; - } - } - - $tag = 'select'; - unset($args['type']); - $current = ''; - - } elseif ($parts[0] == 'multilist') { - - $items = explode('|', $parts[1]); - $args['multiple'] = 'multiple'; - $args['class'] .= " multilist"; - $args['name'] .= '[]'; - - $selected = explode(' ', $current); - - foreach ($items as $item) { - if (in_array($item, $selected)) { - $inner .= "<option selected=\"selected\" value=\"$item\"> $item </option>"; - } else { - $inner .= "<option value=\"$item\"> $item </option>"; - } - } - $tag = 'select'; - unset($args['type']); - $current = ''; + error_log("here"); + if (Request::get('toggleDebug' === 'enable')) { + $enabled = true; } else { - // Everything else is a text input for now - $tag = 'input'; - $args['value'] = $current; - $args['type'] = 'text'; - /* Password field guessing */ - if (stripos($validator, 'password') !== false) { - $args['type'] = Property::getPasswordFieldType(); - } - } - - /* multiinput: enter multiple free-form strings*/ - if ($validator === 'multiinput') { - $args['class'] .= " multiinput"; + $enabled = false; } - - $output = "<$tag "; - foreach ($args as $key => $val) { - $output .= "$key=\"" . htmlspecialchars($val) . '" '; - } - if (empty($inner)) { - $output .= '/>'; - } else { - $output .= '>' . $inner . "</$tag>"; - } - - return $output; - } - + Property::setRemoteDebugConfig(array('enabled' => $enabled, 'debugServer' => Request::get('debugServer'))); + } } + diff --git a/modules-available/debugconfig/templates/_page.html b/modules-available/debugconfig/templates/_page.html index 7f380495..2823d77c 100644 --- a/modules-available/debugconfig/templates/_page.html +++ b/modules-available/debugconfig/templates/_page.html @@ -1,122 +1,30 @@ -<h1>{{lang_basicConfiguration}}</h1> -{{#override}} -<h2>{{subheading}}</h2> -<div class="alert alert-info">{{lang_editOverrideNotice}}</div> -{{/override}} -<p>{{lang_clientRelatedConfig}}</p> -<form action="?do=BaseConfig" method="post"> +<form action="?do=DebugConfig" method="post"> <input type="hidden" name="token" value="{{token}}"> - {{#override}} - <input name="module" type="hidden" value="{{target_module}}"> - <input name="{{field}}" type="hidden" value="{{field_value}}"> - {{/override}} - <input type="text" name="prevent_autofill" id="prevent_autofill" value="" style="position:absolute;top:-2000px" tabindex="-1"> - <input type="password" name="password_fake" id="password_fake" value="" style="position:absolute;top:-2000px" tabindex="-1"> - {{#categories}} + <input type="hidden" name="action" value="debugconfig"> <div class="panel panel-default"> - <div class="panel-heading" role="tab" id="heading{{category_id}}"> - <a name="category_{{category_id}}"></a> - {{category_name}} - </div> + <div class="panel-heading">{{lang_debugConfig}}</div> <div class="panel-body"> - <div class="list-group"> - {{#settings}} - <div class="list-group-item"> - <div class="row"> - <div class="col-md-5 slx-cfg-toggle"> - <div>{{setting}}</div> - {{^override}} - <div class="slx-default"> - {{defaultvalue}} - </div> - <input class="bs-switch" name="override[{{setting}}]" id="CB_{{setting}}" type="checkbox" {{checked}}> <label for="CB_{{setting}}">{{lang_settingActive}}</label> - {{/override}} - {{#override}} - <input class="bs-switch" name="override[{{setting}}]" id="CB_{{setting}}" type="checkbox" {{checked}}> <label for="CB_{{setting}}">{{lang_enableOverride}}</label> - {{/override}} - </div> - <div class="col-md-5"> - {{{item}}} - </div> - <div class="col-md-2"> - <a class="btn btn-default" data-toggle="modal" data-target="#help-{{setting}}"><span class="glyphicon glyphicon-question-sign"></span></a> - </div> - </div> - </div> - <div class="modal fade" id="help-{{setting}}" tabindex="-1" role="dialog"> - <div class="modal-dialog"> - <div class="modal-content"> - <div class="modal-header">{{setting}}</div> - <div class="modal-body">{{{description}}}</div> - <div class="modal-footer"><a class="btn btn-primary" data-dismiss="modal">{{lang_close}}</a></div> - </div> - </div> - </div> - {{/settings}} + <p>{{lang_debugDescription}}</p> + {{^debugEnabled}} + <p>{{lang_debuggingIsDisabled}}</p> + {{/debugEnabled}} + {{#debugEnabled}} + <div class="input-group" onclick="$('#doff').prop('checked', true);"> + <span class="input-group-addon"><input id="doff" type="radio" name="mode" value="off"></span> + <span class="form-control"> + {{lang_debugOff}} + </span> + </div> + {{/debugEnabled}} + <div class="input-group" onclick="$('#don').prop('checked', true);"> + <span class="input-group-addon"><input id="don" type="radio" name="mode" value="random"></span> + <span class="form-control"> + {{lang_debugOn}} + </span> + </div> + <div class="pull-right"> + <button type="submit" class="btn btn-primary">{{lang_save}}</button> </div> </div> </div> - {{/categories}} - <button class="btn btn-primary" type="submit">{{lang_save}}</button> - <button class="btn btn-default" type="reset">{{lang_reset}}</button> - {{^override}} - <a class="btn btn-default" href="api.php?do=baseconfig&user={{userid}}">Download</a> - {{/override}} - {{#override}} - <a class="btn btn-default" href="api.php?do=baseconfig&user={{userid}}&module={{target_module}}&value={{field_value}}&force=1">Download</a> - {{/override}} </form> - -<script type="text/javascript"> - -function updateShadows(e) { - var rules = $(e).data('shadows'); - if (!rules) return; - var currentValue = $(e).val(); - for (var triggerVal in rules) { - var targets = rules[triggerVal]; - for (var i = 0; i < targets.length; ++i) { - var target = targets[i]; - var inp = $('#' + target); - var selitem = inp.data('selitem'); - - if (currentValue === triggerVal) { - inp.prop('disabled', true); - if (selitem) selitem.disable(); - $('#' + target + '.multilist').multiselect('disable'); - } else { - inp.prop('disabled', false); - if (selitem) selitem.enable(); - $('#' + target + '.multilist').multiselect('enable'); - } - } - } -} - - -document.addEventListener("DOMContentLoaded", function () { - /* apply selectize on all multiinput-selectize inputs */ - $("input.multiinput").each(function (idx, elem) { - var e = $(elem); - e.data('selitem', e.selectize({ - delimiter: ' ', - create: true, - plugins: ['restore_on_backspace', 'remove_button'], - maxItems: 10000 - - })[0].selectize); - }); - - var $multilists = $("select.multilist"); - $multilists.multiselect({ - includeSelectAllOption: true, - buttonWidth: '100%', - buttonClass: 'form-control' - }); - - /* data-shadowing bindings */ - $allShadowingFields = $('[data-shadows]'); - $allShadowingFields.on('change', function (event) { updateShadows(event.target); }); - $allShadowingFields.each(function (idx, elem) { updateShadows(elem); }); -}); -</script> diff --git a/modules-available/debugconfig/templates/debugconfig.html b/modules-available/debugconfig/templates/debugconfig.html new file mode 100644 index 00000000..4aa0b4e9 --- /dev/null +++ b/modules-available/debugconfig/templates/debugconfig.html @@ -0,0 +1,40 @@ +<form action="?do=DebugConfig" method="post"> + <input type="hidden" name="token" value="{{token}}"> + <input type="hidden" name="action" value="$this->setConfig()"> + <div class="panel panel-default"> + <div class="panel-heading">{{lang_debugConfig}}</div> + <div class="panel-body"> + <p>{{lang_debugDescription}}</p> + <div class="col-md-5 slx-cfg-toggle"> + <div>REMOTE_DBG_SERVER</div> + <div class="slx-default">master-ip</div> + {{#debugEnabled}} + <input class="bootstrap-switch" name="toggleDebug" value="enable" id="" type="checkbox" checked="true"><label style="margin-left: 10px;">{{lang_debuggingActive}}</label> + {{/debugEnabled}} + {{^debugEnabled}} + <input class="bootstrap-switch" name="toggleDebug" value="enable" id="" type="checkbox"><label style="margin-left: 10px;">{{lang_debuggingInactive}}</label> + {{/debugEnabled}} + </div> + <div class="col-md-5"> + <input name="debugServer" id="DBG_SERVER_ADDR" class="form-control" value="{{debugServer}}" type="text"/> + </div> + <div class="col-md-2"> + <a class="btn btn-default" data-toggle="modal" data-target="help-remoteDebugging"> + <span class="glyphicon glyphicon-question-sign"></span> + </a> + </div> + <div class="modal fade" id="help-remoteDebugging" tabindex="-1" role="dialog"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header">{{setting}}</div> + <div class="modal-body">{{{description}}}</div> + <div class="modal-footer"><a class="btn btn-primary" data-dismiss="modal">{{lang_close}}</a></div> + </div> + </div> + </div> + </div> + </div> + <div> + <button type="submit" class="btn btn-primary">{{lang_save}}</button> + </div> +</form> |