Skip to content

Commit 143ba57

Browse files
authored
Merge pull request #2056 from MightyMCoder/admidio-GHSA-hm42-q32m-vj4f
2 parents fa7ec82 + 36b1e39 commit 143ba57

3 files changed

Lines changed: 105 additions & 18 deletions

File tree

languages/en.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,14 +1241,17 @@
12411241
<string name="SYS_PIPE">Pipe (|)</string>
12421242
<string name="SYS_PLEASE_CHOOSE">Select option</string>
12431243
<string name="SYS_PLUGIN_INSTALL">Install plugin</string>
1244+
<string name="SYS_PLUGIN_INSTALLED">Plugin successfully installed.</string>
12441245
<string name="SYS_PLUGIN_MANAGER">Plugin Manager</string>
12451246
<string name="SYS_PLUGIN_MANAGER_DESC">Here you can manage the plugins of Admidio. Plugins are additional modules that can be installed to extend the functionality of Admidio. You can install, update or remove plugins.</string>
12461247
<string name="SYS_PLUGIN_NAME_MISSING">No plugin name specified.</string>
12471248
<string name="SYS_PLUGIN_NO_INTERFACE">The plugin has no interface.</string>
12481249
<string name="SYS_PLUGIN_NOT_INSTALLED">The plugin is not installed.</string>
12491250
<string name="SYS_PLUGIN_PREFERENCES">Plugin preferences</string>
12501251
<string name="SYS_PLUGIN_UNINSTALL">Uninstall plugin</string>
1252+
<string name="SYS_PLUGIN_UNINSTALLED">Plugin successfully uninstalled.</string>
12511253
<string name="SYS_PLUGIN_UPDATE">Update plugin</string>
1254+
<string name="SYS_PLUGIN_UPDATED">Plugin successfully updated.</string>
12521255
<string name="SYS_PLUGIN_VERSION">Plugin version</string>
12531256
<string name="SYS_PORT">Port</string>
12541257
<string name="SYS_PORTRAIT" description="Format for printing">Portrait</string>
@@ -1785,6 +1788,9 @@
17851788
<string name="SYS_WANT_DELETE_CATEGORY">Do you really want to delete category #VAR1_BOLD# ?</string>
17861789
<string name="SYS_WANT_DELETE_ENTRY">Do you want to delete the entry #VAR1_BOLD#?</string>
17871790
<string name="SYS_WANT_DELETE_PHOTO">Would you like to delete the selected photo?</string>
1791+
<string name="SYS_WANT_INSTALL_PLUGIN">Do you want to install the plugin #VAR1_BOLD#?</string>
1792+
<string name="SYS_WANT_UNINSTALL_PLUGIN">Do you want to uninstall the plugin #VAR1_BOLD#?</string>
1793+
<string name="SYS_WANT_UPDATE_PLUGIN">Do you want to update the plugin #VAR1_BOLD#?</string>
17881794
<string name="SYS_WARNING">Warning</string>
17891795
<string name="SYS_WEBLINK">Web link</string>
17901796
<string name="SYS_WEBLINKS">Web links</string>

modules/plugins.php

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030

3131
// Initialize and check the parameters
3232
$getMode = admFuncVariableIsValid($_GET, 'mode', 'string', array('defaultValue' => 'list', 'validValues' => array('list', 'install', 'uninstall', 'update', 'sequence')));
33-
$getPluginName = admFuncVariableIsValid($_GET, 'name', 'string', array('defaultValue' => ''));
34-
$getPluginId = admFuncVariableIsValid($_GET, 'uuid', 'int');
3533

3634
// check rights to use this module
3735
if (!$gCurrentUser->isAdministrator()) {
@@ -49,32 +47,38 @@
4947

5048
case 'install':
5149
// install plugin
52-
if (!empty($getPluginName)) {
50+
SecurityUtils::validateCsrfToken($_POST['adm_csrf_token']);
51+
$pluginName = admFuncVariableIsValid($_POST, 'name', 'string', array('requireValue' => true));
52+
53+
if (!empty($pluginName)) {
5354
$pluginManager = new PluginManager();
54-
$plugin = $pluginManager->getPluginByName($getPluginName);
55+
$plugin = $pluginManager->getPluginByName($pluginName);
5556
if ($plugin) {
5657
$interface = $plugin instanceof PluginAbstract ? $plugin::getInstance() : null;
5758

5859
if ($interface != null) {
5960
if (!$interface->checkDependencies()) {
60-
throw new RuntimeException('Missing dependencies for ' . $getPluginName . ' plugin');
61+
throw new RuntimeException('Missing dependencies for ' . $pluginName . ' plugin');
6162
}
6263

6364
$interface->doInstall();
6465
}
6566
}
6667
$gNavigation->deleteLastUrl();
67-
admRedirect(SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php'));
68+
echo json_encode(array('status' => 'success', 'message' => $gL10n->get('SYS_PLUGIN_INSTALLED')));
6869
} else {
6970
throw new Exception('SYS_PLUGIN_NAME_MISSING');
7071
}
7172
break;
7273

7374
case 'uninstall':
7475
// uninstall plugin
75-
if (!empty($getPluginName)) {
76+
SecurityUtils::validateCsrfToken($_POST['adm_csrf_token']);
77+
$pluginName = admFuncVariableIsValid($_POST, 'name', 'string', array('requireValue' => true));
78+
79+
if (!empty($pluginName)) {
7680
$pluginManager = new PluginManager();
77-
$plugin = $pluginManager->getPluginByName($getPluginName);
81+
$plugin = $pluginManager->getPluginByName($pluginName);
7882
if ($plugin) {
7983
$interface = $plugin instanceof PluginAbstract ? $plugin::getInstance() : null;
8084

@@ -83,17 +87,20 @@
8387
}
8488
}
8589
$gNavigation->deleteLastUrl();
86-
admRedirect(SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php'));
90+
echo json_encode(array('status' => 'success', 'message' => $gL10n->get('SYS_PLUGIN_UNINSTALLED')));
8791
} else {
8892
throw new Exception('SYS_PLUGIN_NAME_MISSING');
8993
}
9094
break;
9195

9296
case 'update':
9397
// update plugin
94-
if (!empty($getPluginName)) {
98+
SecurityUtils::validateCsrfToken($_POST['adm_csrf_token']);
99+
$pluginName = admFuncVariableIsValid($_POST, 'name', 'string', array('requireValue' => true));
100+
101+
if (!empty($pluginName)) {
95102
$pluginManager = new PluginManager();
96-
$plugin = $pluginManager->getPluginByName($getPluginName);
103+
$plugin = $pluginManager->getPluginByName($pluginName);
97104
if ($plugin) {
98105
$interface = $plugin instanceof PluginAbstract ? $plugin::getInstance() : null;
99106

@@ -102,7 +109,7 @@
102109
}
103110
}
104111
$gNavigation->deleteLastUrl();
105-
admRedirect(SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php'));
112+
echo json_encode(array('status' => 'success', 'message' => $gL10n->get('SYS_PLUGIN_UPDATED')));
106113
} else {
107114
throw new Exception('SYS_PLUGIN_NAME_MISSING');
108115
}

src/UI/Presenter/PluginsPresenter.php

Lines changed: 80 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class PluginsPresenter extends PagePresenter
3535
*/
3636
public function createList(): void
3737
{
38-
global $gL10n, $gCurrentSession;
38+
global $gL10n;
3939

4040
$this->setHtmlID('adm_plugins');
4141
$this->setHeadline($gL10n->get('SYS_PLUGIN_MANAGER'));
@@ -50,6 +50,77 @@ public function createList(): void
5050
', true
5151
);
5252

53+
$this->addJavascript('
54+
function callPluginAction(url, csrfToken, pluginName) {
55+
$.post(url, {
56+
"adm_csrf_token": csrfToken,
57+
"name": pluginName
58+
}, function(data) {
59+
const messageText = $("#adm_status_message");
60+
61+
var returnStatus = "error";
62+
var returnMessage = "";
63+
64+
try {
65+
const returnData = JSON.parse(data);
66+
67+
returnStatus = returnData.status;
68+
69+
if (typeof returnData.message !== "undefined") {
70+
returnMessage = returnData.message;
71+
}
72+
} catch (e) {
73+
// fallback for old implementation without JSON response
74+
if (data === "done") {
75+
returnStatus = "success";
76+
} else {
77+
returnMessage = data;
78+
}
79+
}
80+
81+
if (returnStatus === "success") {
82+
if (returnMessage !== "") {
83+
messageText.html(
84+
"<div class=\"alert alert-success\">" +
85+
"<i class=\"bi bi-check-lg\"></i> " +
86+
returnMessage +
87+
"</div>"
88+
);
89+
}
90+
} else {
91+
if (returnMessage.length === 0) {
92+
returnMessage = "Error: Undefined error occurred!";
93+
}
94+
95+
messageText.html(
96+
"<div class=\"alert alert-danger\">" +
97+
"<i class=\"bi bi-exclamation-circle-fill\"></i> " +
98+
returnMessage +
99+
"</div>"
100+
);
101+
}
102+
103+
setTimeout(function() {
104+
$("#adm_modal").modal("hide");
105+
$("#adm_modal_messagebox").modal("hide");
106+
location.reload();
107+
}, 2000);
108+
});
109+
}
110+
111+
function callPluginInstall(url, csrfToken, pluginName) {
112+
callPluginAction(url, csrfToken, pluginName);
113+
}
114+
115+
function callPluginUpdate(url, csrfToken, pluginName) {
116+
callPluginAction(url, csrfToken, pluginName);
117+
}
118+
119+
function callPluginUninstall(url, csrfToken, pluginName) {
120+
callPluginAction(url, csrfToken, pluginName);
121+
}
122+
');
123+
53124
$this->smarty->assign('list', $this->templateData);
54125
$this->smarty->assign('l10n', $gL10n);
55126
try {
@@ -94,7 +165,7 @@ public function createCards(): void
94165
*/
95166
public function prepareData(): void
96167
{
97-
global $gL10n;
168+
global $gL10n, $gCurrentSession;
98169
$pluginManager = new PluginManager();
99170
$plugins = $pluginManager->getAvailablePlugins();
100171
$templateRowPluginParent['overview'] = array('id' => 'overview_plugins', 'name' => $gL10n->get('SYS_OVERVIEW_EXTENSIONS'), 'entries' => array());
@@ -142,23 +213,26 @@ public function prepareData(): void
142213
// add update action if an update is available
143214
if ($interface->isUpdateAvailable()) {
144215
$templateRow['actions'][] = array(
145-
'url' => SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php', array('mode' => 'update', 'name' => $pluginName)),
216+
'dataHref' => 'callPluginUpdate(\'' . SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php', array('mode' => 'update')) . '\', \'' . $gCurrentSession->getCsrfToken() . '\', \'' . addslashes($pluginName) . '\')',
217+
'dataMessage' => $gL10n->get('SYS_WANT_UPDATE_PLUGIN', array($pluginName)),
146218
'icon' => 'bi bi-arrow-clockwise',
147219
'tooltip' => $gL10n->get('SYS_PLUGIN_UPDATE')
148220
);
149221
}
150222
if (!$interface->isAdmidioPlugin()) {
151223
// add uninstall action
152224
$templateRow['actions'][] = array(
153-
'url' => SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php', array('mode' => 'uninstall', 'name' => $pluginName)),
225+
'dataHref' => 'callPluginUninstall(\'' . SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php', array('mode' => 'uninstall')) . '\', \'' . $gCurrentSession->getCsrfToken() . '\', \'' . addslashes($pluginName) . '\')',
226+
'dataMessage' => $gL10n->get('SYS_WANT_UNINSTALL_PLUGIN', array($pluginName)),
154227
'icon' => 'bi bi-trash',
155228
'tooltip' => $gL10n->get('SYS_PLUGIN_UNINSTALL')
156229
);
157230
}
158231
} else {
159232
// add install action
160233
$templateRow['actions'][] = array(
161-
'url' => SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php', array('mode' => 'install', 'name' => $pluginName)),
234+
'dataHref' => 'callPluginInstall(\'' . SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php', array('mode' => 'install')) . '\', \'' . $gCurrentSession->getCsrfToken() . '\', \'' . addslashes($pluginName) . '\')',
235+
'dataMessage' => $gL10n->get('SYS_WANT_INSTALL_PLUGIN', array($pluginName)),
162236
'icon' => 'bi bi-download',
163237
'tooltip' => $gL10n->get('SYS_PLUGIN_INSTALL')
164238
);
@@ -206,4 +280,4 @@ public function prepareData(): void
206280

207281
$this->templateData = $templateRowPluginParent;
208282
}
209-
}
283+
}

0 commit comments

Comments
 (0)