This commit is contained in:
scheibling 2022-04-14 10:47:20 -04:00 committed by GitHub
commit 192ca485cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 161 additions and 10 deletions

View File

@ -50,6 +50,8 @@ $sm_lang = array(
'no' => 'No',
'insert' => 'Insert',
'add_new' => 'Add new',
'export_config' => 'Export Configuration',
'import_config' => 'Import Configuration',
'update_available' => 'A new version ({version}) is available. Click <a href="https://github.com/phpservermon/phpservermon/releases/latest" target="_blank" rel="noopener">here</a> to download the update.',
'back_to_top' => 'Back to top',
'go_back' => 'Go back',

View File

@ -29,6 +29,9 @@
namespace psm\Module\Server\Controller;
use psm\Service\Database;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Server module. Add/edit/delete servers, show a list of all servers etc.
@ -50,12 +53,12 @@ class ServerController extends AbstractServerController
$this->setCSRFKey('server');
$this->setActions(array(
'index', 'edit', 'save', 'delete', 'view',
'index', 'edit', 'save', 'delete', 'view', 'export', 'import', 'importpost'
), 'index');
// make sure only admins are allowed to edit/delete servers:
$this->setMinUserLevelRequiredForAction(PSM_USER_ADMIN, array(
'delete', 'edit', 'save'
'delete', 'edit', 'save', 'export'
));
$this->twig->addGlobal('subtitle', psm_get_lang('menu', 'server'));
}
@ -86,6 +89,24 @@ class ServerController extends AbstractServerController
'success',
psm_get_lang('system', 'add_new')
);
$sidebar->addButton(
'export_config',
psm_get_lang('system', 'export_config'),
psm_build_url(array('mod' => 'server', 'action' => 'export')),
'arrow-down',
'success',
psm_get_lang('system', 'export_config')
);
$sidebar->addButton(
'import_config',
psm_get_lang('system', 'import_config'),
psm_build_url(array('mod' => 'server', 'action' => 'import')),
'arrow-up',
'success',
psm_get_lang('system', 'import_config')
);
}
$sidebar->addButton(
@ -268,13 +289,21 @@ class ServerController extends AbstractServerController
/**
* Executes the saving of one of the servers
*/
protected function executeSave()
protected function executeSave($internal = false)
{
if (empty($_POST)) {
// dont process anything if no data has been posted
return $this->executeIndex();
}
if ($internal) {
$this->server_id = (isset($_POST['server_id']) ? $_POST['server_id'] : 0);
if (empty($this->getServers($this->server_id))) {
$this->server_id = 0;
}
}
// We need the server id to encrypt the password. Encryption will be done after the server is added
$encrypted_password = '';
@ -283,6 +312,7 @@ class ServerController extends AbstractServerController
if ($this->server_id > 0) {
$edit_server = $this->getServers($this->server_id);
$hash = sha1($edit_server['website_password']);
if ($new_password == $hash) {
@ -293,7 +323,6 @@ class ServerController extends AbstractServerController
}
}
}
$clean = array(
'label' => trim(strip_tags(psm_POST('label', ''))),
'ip' => trim(strip_tags(psm_POST('ip', ''))),
@ -369,6 +398,7 @@ class ServerController extends AbstractServerController
// check for edit or add
if ($this->server_id > 0) {
// edit
$this->db->save(
PSM_DB_PREFIX . 'servers',
@ -415,13 +445,15 @@ class ServerController extends AbstractServerController
// add all new users
$this->db->insertMultiple(PSM_DB_PREFIX . 'users_servers', $user_idc_save);
}
$back_to = isset($_GET['back_to']) ? $_GET['back_to'] : 'index';
if ($back_to == 'view') {
return $this->runAction('view');
} else {
return $this->runAction('index');
if (!$internal) {
$back_to = isset($_GET['back_to']) ? $_GET['back_to'] : 'index';
if ($back_to == 'view') {
return $this->runAction('view');
} else {
return $this->runAction('index');
}
}
return true;
}
/**
@ -444,6 +476,89 @@ class ServerController extends AbstractServerController
}
return $this->runAction('index');
}
/**
* Exports a JSON file with the server configuration
*/
protected function executeExport()
{
$request = new Request();
$response = new Response(
json_encode($this->getServers()),
200,
array(
'Content-disposition' => 'attachment; filename=server_export.json',
'Content-Type' => 'application/json'
)
);
$response->prepare($request);
$response->send();
return exit;
}
/**
* Import settings page
*/
protected function executeImport($error = "")
{
$sidebar = new \psm\Util\Module\Sidebar($this->twig);
$this->setSidebar($sidebar);
if ($this->getUser()->getUserLevel() == PSM_USER_ADMIN) {
$modal = new \psm\Util\Module\Modal($this->twig, 'delete', \psm\Util\Module\Modal::MODAL_TYPE_DANGER);
$this->addModal($modal);
$modal->setTitle(psm_get_lang('servers', 'delete_title'));
$modal->setMessage(psm_get_lang('servers', 'delete_message'));
$modal->setOKButtonLabel(psm_get_lang('system', 'delete'));
$tpl_data = [
'label_upload' => 'Upload',
'error_message' => $error,
'url_save' => psm_build_url(array(
'mod' => 'server',
'action' => 'importpost',
'back_to' => ""
))
];
return $this->twig->render('module/server/server/import.tpl.html', $tpl_data);
}
else {
return $this->executeIndex();
}
}
/**
* Import post page
*/
protected function executeImportpost()
{
$temp_name = $_FILES['import_upload']['tmp_name'];
echo "Started decode";
$file = json_decode(
file_get_contents($temp_name),
true
);
if (!$file) {
echo "NoFile";
return $this->executeImport("Not a valid JSON file");
}
foreach ($file as $server) {
$_POST = $server;
$this->executeSave(true);
}
return $this->executeIndex();
/**
* - List all allowed fields
* - foreach (check if exists, else import)
*
* Check if exists based on?
*/
}
/**
* Prepare the view template

View File

@ -33,6 +33,22 @@
</div>
{% endmacro input_select %}
{% macro input_upload(id, name, label, help, help_label) %}
<div class="form-group">
<label for="{{ id }}">{{ label }}</label> <br \>
<input type="file" id="{{ id }}" name="{{ name }}"
{% if help %}aria-describedby="{{ help }}"{% endif %}>
{% if help %}
<small id="{{ help }}" class="form-text text-muted">{{
help_label|striptags('<a>,<b>,<br>')|raw }}</small>
{% endif %}
</div>
{% endmacro input_upload %}
{% macro input_select_multiple(id, name, label, placeholder, options, select_message) %}
<div class="form-group">
<label for="{{ id }}">{{ label }}</label>

View File

@ -0,0 +1,18 @@
{% import 'main/macros.tpl.html' as macro %}
<form name="importpost" action="{{ url_save|raw }}" class="col-md-6 pl-0 pr-0" id="importpost" method="post"
autocomplete="off" enctype="multipart/form-data">
<fieldset>
<legend>{{ titlemode }}</legend>
{% if error_message != "" %}
<div class="card text-white bg-danger px-3 pt-3 pb-2 mb-4"><h3>Error: {{ error_message }}</h3></div>
{% endif %}
<div class="col">
<!-- Label -->
{{ macro.input_upload("import_upload", "import_upload", "Upload Configuration", null, null) }}
<!-- Submit -->
<legend>{{ label_upload }}</legend>
{{ macro.button_save(null, label_upload) }}
<a class="btn" href="{{ url_go_back|raw }}">Go Back</a>
{{ macro.input_csrf() }}
</form>