From ccd68d2ca978ac1496d4539afc1fd8c1515cd270 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 13 Apr 2021 12:45:06 -0600 Subject: [PATCH 1/6] fixed changelog link --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0c65598..26379cfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 04/13/2021 1. [](#bugfix) - * **IMPORTANT** Fixed security vulnerability that allows installation of plugins with minimal admin privileges (GHSA-wg37-cf5x-55hq)[https://github.com/getgrav/grav-plugin-admin/security/advisories/GHSA-wg37-cf5x-55hq] + * **IMPORTANT** Fixed security vulnerability that allows installation of plugins with minimal admin privileges [GHSA-wg37-cf5x-55hq](https://github.com/getgrav/grav-plugin-admin/security/advisories/GHSA-wg37-cf5x-55hq) * Fixed `You have been logged out` message when entering to 2FA authentication due to `/admin/task:getNotifications` AJAX call * Fixed broken 2FA login when site is not configured to use Flex Users [#2109](https://github.com/getgrav/grav-plugin-admin/issues/2109) * Fixed error message when user clicks logout link after the session has been expired From 9383007b93676c284ee65293af0206cebd7c2203 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 14 Apr 2021 13:40:02 +0300 Subject: [PATCH 2/6] Better document admin tasks --- classes/plugin/AdminController.php | 64 +++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/classes/plugin/AdminController.php b/classes/plugin/AdminController.php index 1ada7163..69dc2f95 100644 --- a/classes/plugin/AdminController.php +++ b/classes/plugin/AdminController.php @@ -76,6 +76,8 @@ class AdminController extends AdminBaseController /** * Keep alive * + * Route: POST /task:keepAlive (AJAX call) + * * @return void */ protected function taskKeepAlive(): void @@ -89,6 +91,8 @@ class AdminController extends AdminBaseController /** * Clear the cache. * + * Route: GET /cache.json/task:clearCache (AJAX call) + * * @return bool True if the action was performed. */ protected function taskClearCache() @@ -133,6 +137,10 @@ class AdminController extends AdminBaseController /** * Handles form and saves the input data if its valid. * + * Route: POST /pages?task:save + * Route: POST /user?task:save + * Route: POST /*?task:save + * * @return bool True if the action was performed. */ public function taskSave() @@ -203,6 +211,9 @@ class AdminController extends AdminBaseController /** * Handle logout. * + * Route: GET /task:logout + * Route: POST ?task=logout + * * @return bool True if the action was performed. */ protected function taskLogout() @@ -215,6 +226,8 @@ class AdminController extends AdminBaseController } /** + * Route: POST /ajax.json/task:regenerate2FASecret (AJAX call) + * * @return bool */ public function taskRegenerate2FASecret() @@ -333,6 +346,8 @@ class AdminController extends AdminBaseController /** * Get Notifications * + * Route: POST /task:getNotifications (AJAX call) + * * @return never-return */ protected function taskGetNotifications(): void @@ -376,6 +391,8 @@ class AdminController extends AdminBaseController /** * Hide notifications. * + * Route: POST /notifications.json/task:hideNotification/notification_id:ID (AJAX call) + * * @return bool True if the action was performed. */ protected function taskHideNotification() @@ -412,6 +429,8 @@ class AdminController extends AdminBaseController /** * Get Newsfeeds * + * Route: POST /ajax.json/task:getNewsFeed (AJAX call) + * * @return never-return */ protected function taskGetNewsFeed(): void @@ -446,6 +465,8 @@ class AdminController extends AdminBaseController /** * Handle the backup action * + * Route: GET /backup.json/id:BACKUP_ID/task:backup (AJAX call) + * * @return bool True if the action was performed. */ protected function taskBackup() @@ -504,6 +525,8 @@ class AdminController extends AdminBaseController /** * Handle delete backup action * + * Route: GET /backup.json/backup:BACKUP_FILE/task:backupDelete (AJAX call) + * * @return bool */ protected function taskBackupDelete() @@ -546,7 +569,7 @@ class AdminController extends AdminBaseController /** * Enable a plugin. * - * Route: /plugins + * Route: GET /plugins/SLUG/task:enable * * @return bool True if the action was performed. */ @@ -576,7 +599,7 @@ class AdminController extends AdminBaseController /** * Disable a plugin. * - * Route: /plugins + * Route: GET /plugins/SLUG/task:disable * * @return bool True if the action was performed. */ @@ -606,7 +629,7 @@ class AdminController extends AdminBaseController /** * Set the default theme. * - * Route: /themes + * Route: GET /themes/SLUG/task:activate * * @return bool True if the action was performed. */ @@ -650,6 +673,8 @@ class AdminController extends AdminBaseController /** * Handles updating Grav * + * Route: GET /update.json/task:updategrav (AJAX call) + * * @return bool False if user has no permissions. */ public function taskUpdategrav() @@ -684,12 +709,8 @@ class AdminController extends AdminBaseController /** * Handles uninstalling plugins and themes * - * Route: /plugins - * Route: /themes - * - * @deprecated - * * @return bool True if the action was performed + * @deprecated Not being used anymore */ public function taskUninstall() { @@ -720,6 +741,8 @@ class AdminController extends AdminBaseController /** * Toggle the gpm.releases setting * + * Route: POST /ajax.json/task:gpmRelease (AJAX call) + * * @return bool */ protected function taskGpmRelease() @@ -763,6 +786,8 @@ class AdminController extends AdminBaseController /** * Get update status from GPM * + * Request: POST /update.json/task:getUpdates (AJAX call) + * * @return bool */ protected function taskGetUpdates() @@ -835,7 +860,10 @@ class AdminController extends AdminBaseController } /** - * Handle getting a new package dependencies needed to be installed + * Handle getting a new package dependencies needed to be installed. + * + * Route: /plugins.json/task:getPackagesDependencies (AJAX call) + * Route: /themes.json/task:getPackagesDependencies (AJAX call) * * @return bool */ @@ -868,6 +896,9 @@ class AdminController extends AdminBaseController } /** + * Route: /plugins.json/task:installDependenciesOfPackages (AJAX call) + * Route: /themes.json/task:installDependenciesOfPackages (AJAX call) + * * @return bool */ protected function taskInstallDependenciesOfPackages() @@ -917,6 +948,9 @@ class AdminController extends AdminBaseController } /** + * Route: /plugins.json/task:installPackage (AJAX call) + * Route: /themes.json/task:installPackage (AJAX call) + * * @param bool $reinstall * @return bool */ @@ -973,6 +1007,9 @@ class AdminController extends AdminBaseController /** * Handle removing a package * + * Route: /plugins.json/task:removePackage (AJAX call) + * Route: /themes.json/task:removePackage (AJAX call) + * * @return bool */ protected function taskRemovePackage(): bool @@ -1046,6 +1083,9 @@ class AdminController extends AdminBaseController /** * Handle reinstalling a package * + * Route: /plugins.json/task:reinstallPackage (AJAX call) + * Route: /themes.json/task:reinstallPackage (AJAX call) + * * @return bool */ protected function taskReinstallPackage() @@ -1092,6 +1132,8 @@ class AdminController extends AdminBaseController /** * Handle direct install. * + * Request: POST /tools/direct-install?task=directInstall + * * @return bool */ protected function taskDirectInstall() @@ -2179,6 +2221,8 @@ class AdminController extends AdminBaseController } /** + * Request: POST .json/task:compileScss (AJAX call) + * * @return bool */ protected function taskCompileScss() @@ -2212,6 +2256,8 @@ class AdminController extends AdminBaseController } /** + * Request: POST .json/task:exportScss (AJAX call) + * * @return bool */ protected function taskExportScss() From cde46a2eb03d84aa02c8c27c47a8d95b3c121f88 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 14 Apr 2021 13:54:01 +0300 Subject: [PATCH 3/6] Regression: Fixed broken plugin/theme installer in admin --- CHANGELOG.md | 6 ++++++ classes/plugin/AdminController.php | 25 +++++++++++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26379cfb..b0b89b92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v1.10.12 +## 04/dd/2021 + +1. [](#bugfix) + * Regression: Fixed broken plugin/theme installer in admin + # v1.10.11 ## 04/13/2021 diff --git a/classes/plugin/AdminController.php b/classes/plugin/AdminController.php index 69dc2f95..e4c542d5 100644 --- a/classes/plugin/AdminController.php +++ b/classes/plugin/AdminController.php @@ -869,7 +869,12 @@ class AdminController extends AdminBaseController */ protected function taskGetPackagesDependencies() { - if (!$this->authorizeTask('dashboard', ['admin.plugins', 'admin.themes', 'admin.super'])) { + $type = $this->view; + if ($type !== 'plugins' && $type !== 'themes') { + return false; + } + + if (!$this->authorizeTask('get package dependencies', ['admin.' . $type, 'admin.super'])) { return false; } @@ -903,13 +908,12 @@ class AdminController extends AdminBaseController */ protected function taskInstallDependenciesOfPackages() { - $data = $this->post; - $type = $data['type'] ?? ''; + $type = $this->view; if ($type !== 'plugins' && $type !== 'themes') { return false; } - if (!$this->authorizeTask('install ' . $type, ['admin.' . $type, 'admin.super'])) { + if (!$this->authorizeTask('install dependencies', ['admin.' . $type, 'admin.super'])) { $this->admin->json_response = [ 'status' => 'error', 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') @@ -918,6 +922,7 @@ class AdminController extends AdminBaseController return false; } + $data = $this->post; $packages = isset($data['packages']) ? explode(',', $data['packages']) : ''; $packages = (array)$packages; @@ -956,8 +961,7 @@ class AdminController extends AdminBaseController */ protected function taskInstallPackage($reinstall = false) { - $data = $this->post; - $type = $data['type'] ?? ''; + $type = $this->view; if ($type !== 'plugins' && $type !== 'themes') { return false; } @@ -971,6 +975,7 @@ class AdminController extends AdminBaseController return false; } + $data = $this->post; $package = $data['package'] ?? ''; try { $result = Gpm::install($package, ['theme' => $type === 'theme']); @@ -1014,8 +1019,7 @@ class AdminController extends AdminBaseController */ protected function taskRemovePackage(): bool { - $data = $this->post; - $type = $data['type'] ?? ''; + $type = $this->view; if ($type !== 'plugins' && $type !== 'themes') { return false; } @@ -1029,6 +1033,7 @@ class AdminController extends AdminBaseController $this->sendJsonResponse($json_response, 403); } + $data = $this->post; $package = $data['package'] ?? ''; $result = false; @@ -1090,8 +1095,7 @@ class AdminController extends AdminBaseController */ protected function taskReinstallPackage() { - $data = $this->post; - $type = $data['type'] ?? ''; + $type = $this->view; if ($type !== 'plugins' && $type !== 'themes') { return false; } @@ -1105,6 +1109,7 @@ class AdminController extends AdminBaseController $this->sendJsonResponse($json_response, 403); } + $data = $this->post; $slug = $data['slug'] ?? ''; $package_name = $data['package_name'] ?? ''; $current_version = $data['current_version'] ?? ''; From 7ed36e462ea140ff4ed38ea07829c6e0ba102ea2 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 14 Apr 2021 21:43:40 +0300 Subject: [PATCH 4/6] Fixed error reporting for AJAX tasks if user has no permissions --- CHANGELOG.md | 1 + classes/plugin/AdminController.php | 112 +++++++++++++++++++++++++++-- 2 files changed, 107 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0b89b92..2d599c07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 1. [](#bugfix) * Regression: Fixed broken plugin/theme installer in admin + * Fixed error reporting for AJAX tasks if user has no permissions # v1.10.11 ## 04/13/2021 diff --git a/classes/plugin/AdminController.php b/classes/plugin/AdminController.php index e4c542d5..c689c4cb 100644 --- a/classes/plugin/AdminController.php +++ b/classes/plugin/AdminController.php @@ -98,6 +98,11 @@ class AdminController extends AdminBaseController protected function taskClearCache() { if (!$this->authorizeTask('clear cache', ['admin.cache', 'admin.maintenance', 'admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -233,6 +238,11 @@ class AdminController extends AdminBaseController public function taskRegenerate2FASecret() { if (!$this->authorizeTask('regenerate 2FA Secret', ['admin.login', 'admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -348,12 +358,17 @@ class AdminController extends AdminBaseController * * Route: POST /task:getNotifications (AJAX call) * - * @return never-return + * @return bool */ - protected function taskGetNotifications(): void + protected function taskGetNotifications() { if (!$this->authorizeTask('dashboard', ['admin.login', 'admin.super'])) { - $this->sendJsonResponse(['status' => 'error', 'message' => 'unauthorized']); + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + + return false; } // do we need to force a reload @@ -398,6 +413,11 @@ class AdminController extends AdminBaseController protected function taskHideNotification() { if (!$this->authorizeTask('hide notification', ['admin.login', 'admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -431,12 +451,17 @@ class AdminController extends AdminBaseController * * Route: POST /ajax.json/task:getNewsFeed (AJAX call) * - * @return never-return + * @return bool */ - protected function taskGetNewsFeed(): void + protected function taskGetNewsFeed() { if (!$this->authorizeTask('dashboard', ['admin.login', 'admin.super'])) { - $this->sendJsonResponse(['status' => 'error', 'message' => 'unauthorized']); + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + + return false; } $refresh = $this->data['refresh'] === 'true' ? true : false; @@ -472,6 +497,11 @@ class AdminController extends AdminBaseController protected function taskBackup() { if (!$this->authorizeTask('backup', ['admin.maintenance', 'admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -532,6 +562,11 @@ class AdminController extends AdminBaseController protected function taskBackupDelete() { if (!$this->authorizeTask('backup', ['admin.maintenance', 'admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -680,6 +715,11 @@ class AdminController extends AdminBaseController public function taskUpdategrav() { if (!$this->authorizeTask('install grav', ['admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -748,6 +788,11 @@ class AdminController extends AdminBaseController protected function taskGpmRelease() { if (!$this->authorizeTask('configuration', ['admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -797,6 +842,11 @@ class AdminController extends AdminBaseController } if (!$this->authorizeTask('dashboard', ['admin.plugins', 'admin.themes', 'admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -875,6 +925,11 @@ class AdminController extends AdminBaseController } if (!$this->authorizeTask('get package dependencies', ['admin.' . $type, 'admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -1777,6 +1832,11 @@ class AdminController extends AdminBaseController } if (!$this->authorizeTask('get childtypes', ['admin.pages', 'admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -1826,6 +1886,11 @@ class AdminController extends AdminBaseController } if (!$this->authorizeTask('filter pages', ['admin.pages', 'admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -1956,6 +2021,11 @@ class AdminController extends AdminBaseController protected function taskProcessMarkdown() { if (!$this->authorizeTask('process markdown', ['admin.pages', 'admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -2011,6 +2081,11 @@ class AdminController extends AdminBaseController } if (!$this->authorizeTask('list media', ['admin.pages', 'admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -2068,6 +2143,11 @@ class AdminController extends AdminBaseController } if (!$this->authorizeTask('add media', ['admin.pages', 'admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -2233,6 +2313,11 @@ class AdminController extends AdminBaseController protected function taskCompileScss() { if (!$this->authorizeTask('compile scss', ['admin.plugins', 'admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -2268,6 +2353,11 @@ class AdminController extends AdminBaseController protected function taskExportScss() { if (!$this->authorizeTask('export scss', ['admin.plugins', 'admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -2303,6 +2393,11 @@ class AdminController extends AdminBaseController } if (!$this->authorizeTask('delete media', ['admin.pages', 'admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } @@ -2885,6 +2980,11 @@ class AdminController extends AdminBaseController protected function taskConvertUrls() { if (!$this->authorizeTask('access page', ['admin.pages', 'admin.super'])) { + $this->admin->json_response = [ + 'status' => 'error', + 'message' => $this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') + ]; + return false; } From c097eee87f17d22bd05d92e7d40fb9581bd9c320 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 15 Apr 2021 10:11:04 +0300 Subject: [PATCH 5/6] Fixed error reporting for AJAX tasks if user has no permissions --- CHANGELOG.md | 1 + classes/plugin/Controllers/AdminController.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d599c07..b140580a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ 1. [](#bugfix) * Regression: Fixed broken plugin/theme installer in admin * Fixed error reporting for AJAX tasks if user has no permissions + * Fixed missing slash in password reset URL [#2119](https://github.com/getgrav/grav-plugin-admin/issues/2119) # v1.10.11 ## 04/13/2021 diff --git a/classes/plugin/Controllers/AdminController.php b/classes/plugin/Controllers/AdminController.php index 1a6db932..600cfb50 100644 --- a/classes/plugin/Controllers/AdminController.php +++ b/classes/plugin/Controllers/AdminController.php @@ -123,7 +123,7 @@ abstract class AdminController $pages = $this->grav['pages']; $admin = $this->getAdmin(); - return $pages->baseUrl($lang) . $admin->base . trim($route, '/'); + return $pages->baseUrl($lang) . $admin->base . $route; } /** @@ -137,7 +137,7 @@ abstract class AdminController $pages = $this->grav['pages']; $admin = $this->getAdmin(); - return $pages->baseUrl($lang, true) . $admin->base . trim($route, '/'); + return $pages->baseUrl($lang, true) . $admin->base . $route; } /** From 2ea4ed78abf9c3d23b4bdde53b94943c20796aa7 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 15 Apr 2021 12:01:26 -0600 Subject: [PATCH 6/6] prepare for release --- CHANGELOG.md | 2 +- blueprints.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b140580a..77e3a7e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # v1.10.12 -## 04/dd/2021 +## 04/15/2021 1. [](#bugfix) * Regression: Fixed broken plugin/theme installer in admin diff --git a/blueprints.yaml b/blueprints.yaml index 5fafbe95..ee46ce71 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -1,7 +1,7 @@ name: Admin Panel slug: admin type: plugin -version: 1.10.11 +version: 1.10.12 description: Adds an advanced administration panel to manage your site icon: empire author: