Fixed lost user access when saving user profile without super user permissions [#1639]

This commit is contained in:
Matias Griese
2019-03-28 11:14:55 +02:00
parent f4c26b6715
commit 5c832dd376
4 changed files with 177 additions and 140 deletions

View File

@@ -7,6 +7,7 @@
1. [](#bugfix) 1. [](#bugfix)
* Fixed user edit links if Flex Objects plugin is installed but user isn't Flex User * Fixed user edit links if Flex Objects plugin is installed but user isn't Flex User
* Fixed deprecated `sameas()` Twig test * Fixed deprecated `sameas()` Twig test
* Regression: Fixed lost user access when saving user profile without super user permissions [#1639](https://github.com/getgrav/grav-plugin-admin/issues/1639)
# v1.9.0-rc.4 # v1.9.0-rc.4
## 03/20/2019 ## 03/20/2019

View File

@@ -650,19 +650,11 @@ class Admin
$obj->file($file); $obj->file($file);
$data[$type] = $obj; $data[$type] = $obj;
} elseif (preg_match('|users/|', $type)) { } elseif (preg_match('|users?/|', $type)) {
/** @var UserCollectionInterface $users */ /** @var UserCollectionInterface $users */
$users = $this->grav['accounts']; $users = $this->grav['accounts'];
$obj = $users->load(preg_replace('|users/|', '', $type)); $obj = $users->load(preg_replace('|users?/|', '', $type));
$obj->update($this->cleanUserPost($post));
$data[$type] = $obj;
} elseif (preg_match('|user/|', $type)) {
/** @var UserCollectionInterface $users */
$users = $this->grav['accounts'];
$obj = $users->load(preg_replace('|user/|', '', $type));
$obj->update($this->cleanUserPost($post)); $obj->update($this->cleanUserPost($post));
$data[$type] = $obj; $data[$type] = $obj;
@@ -714,15 +706,14 @@ class Admin
* @param array $post * @param array $post
* @return array * @return array
*/ */
protected function cleanUserPost($post) public function cleanUserPost($post)
{ {
// Clean fields for all users // Clean fields for all users
unset($post['hashed_password']); unset($post['hashed_password']);
// Clean field for users who shouldn't be able to modify these fields // Clean field for users who shouldn't be able to modify these fields
if (!$this->authorize(['admin.user', 'admin.super'])) { if (!$this->authorize(['admin.user', 'admin.super'])) {
unset($post['access']); unset($post['access'], $post['state']);
unset($post['state']);
} }
return $post; return $post;

View File

@@ -10,6 +10,7 @@ use Grav\Common\Media\Interfaces\MediaInterface;
use Grav\Common\Page\Interfaces\PageInterface; use Grav\Common\Page\Interfaces\PageInterface;
use Grav\Common\Page\Media; use Grav\Common\Page\Media;
use Grav\Common\Uri; use Grav\Common\Uri;
use Grav\Common\User\Interfaces\UserInterface;
use Grav\Common\Utils; use Grav\Common\Utils;
use Grav\Common\Plugin; use Grav\Common\Plugin;
use Grav\Common\Theme; use Grav\Common\Theme;
@@ -727,9 +728,9 @@ class AdminBaseController
} }
/** /**
* @param PageInterface|Data $obj * @param PageInterface|UserInterface|Data $obj
* *
* @return PageInterface|Data * @return PageInterface|UserInterface|Data
*/ */
protected function storeFiles($obj) protected function storeFiles($obj)
{ {

View File

@@ -556,33 +556,27 @@ class AdminController extends AdminBaseController
return false; return false;
} }
$this->grav['twig']->twig_vars['current_form_data'] = (array)$this->data;
switch ($this->view) {
case 'pages':
return $this->taskSavePage();
case 'user':
return $this->taskSaveUser();
default:
return $this->taskSaveDefault();
}
}
protected function taskSavePage()
{
$reorder = true; $reorder = true;
$data = (array)$this->data;
$this->grav['twig']->twig_vars['current_form_data'] = $data;
// Special handler for user data.
if ($this->view === 'user') {
if (!$this->grav['user']->exists()) {
$this->admin->setMessage($this->admin::translate('PLUGIN_ADMIN.NO_USER_EXISTS'),'error');
return false;
}
if (!$this->admin->authorize(['admin.super', 'admin.users'])) {
// no user file or not admin.super or admin.users
if ($this->prepareData($data)->username !== $this->grav['user']->username) {
$this->admin->setMessage($this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') . ' save.','error');
return false;
}
}
}
// Special handler for pages data.
if ($this->view === 'pages') {
/** @var Pages $pages */ /** @var Pages $pages */
$pages = $this->grav['pages']; $pages = $this->grav['pages'];
// Find new parent page in order to build the path. // Find new parent page in order to build the path.
$route = !isset($data['route']) ? dirname($this->admin->route) : $data['route']; $route = $data['route'] ?? dirname($this->admin->route);
/** @var PageInterface $obj */ /** @var PageInterface $obj */
$obj = $this->admin->page(true); $obj = $this->admin->page(true);
@@ -614,7 +608,6 @@ class AdminController extends AdminBaseController
} }
} }
$parent = $route && $route !== '/' && $route !== '.' && $route !== '/.' ? $pages->dispatch($route, true) : $pages->root(); $parent = $route && $route !== '/' && $route !== '.' && $route !== '/.' ? $pages->dispatch($route, true) : $pages->root();
$original_order = (int)trim($obj->order(), '.'); $original_order = (int)trim($obj->order(), '.');
@@ -651,21 +644,6 @@ class AdminController extends AdminBaseController
} }
} }
} else {
// Handle standard data types.
$obj = $this->prepareData($data);
try {
$obj->validate();
} catch (\Exception $e) {
$this->admin->setMessage($e->getMessage(), 'error');
return false;
}
$obj->filter();
}
$obj = $this->storeFiles($obj); $obj = $this->storeFiles($obj);
if ($obj) { if ($obj) {
@@ -676,26 +654,6 @@ class AdminController extends AdminBaseController
$this->grav->fireEvent('onAdminAfterSave', new Event(['object' => $obj])); $this->grav->fireEvent('onAdminAfterSave', new Event(['object' => $obj]));
} }
if ($this->view !== 'pages') {
// Force configuration reload.
/** @var Config $config */
$config = $this->grav['config'];
$config->reload();
if ($this->view === 'user') {
if ($obj->username === $this->grav['user']->username) {
/** @var UserCollectionInterface $users */
$users = $this->grav['accounts'];
//Editing current user. Reload user object
unset($this->grav['user']->avatar);
$this->grav['user']->merge($users->load($this->admin->route)->toArray());
}
}
}
// Always redirect if a page route was changed, to refresh it
if ($obj instanceof PageInterface) {
if (method_exists($obj, 'unsetRouteSlug')) { if (method_exists($obj, 'unsetRouteSlug')) {
$obj->unsetRouteSlug(); $obj->unsetRouteSlug();
} }
@@ -712,8 +670,94 @@ class AdminController extends AdminBaseController
$route = $obj->rawRoute(); $route = $obj->rawRoute();
$redirect_url = ($multilang ? '/' . $obj->language() : '') . $admin_route . '/' . $this->view . $route; $redirect_url = ($multilang ? '/' . $obj->language() : '') . $admin_route . '/' . $this->view . $route;
$this->setRedirect($redirect_url); $this->setRedirect($redirect_url);
return true;
} }
protected function taskSaveUser()
{
/** @var UserCollectionInterface $users */
$users = $this->grav['accounts'];
$user = $users->load($this->admin->route);
if (!$this->admin->authorize(['admin.super', 'admin.users'])) {
// no user file or not admin.super or admin.users
if ($user->username !== $this->grav['user']->username) {
$this->admin->setMessage($this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') . ' save.','error');
return false;
}
}
/** @var Data\Blueprint $blueprint */
$blueprint = $user->blueprints();
$data = $blueprint->processForm($this->admin->cleanUserPost((array)$this->data));
$data = new Data\Data($data, $blueprint);
try {
$data->validate();
$data->filter();
} catch (\Exception $e) {
$this->admin->setMessage($e->getMessage(), 'error');
return false;
}
$user->update($data->toArray());
$user = $this->storeFiles($user);
if ($user) {
// Event to manipulate data before saving the object
$this->grav->fireEvent('onAdminSave', new Event(['object' => &$user]));
$user->save();
$this->admin->setMessage($this->admin::translate('PLUGIN_ADMIN.SUCCESSFULLY_SAVED'), 'info');
$this->grav->fireEvent('onAdminAfterSave', new Event(['object' => $user]));
}
if ($user->username === $this->grav['user']->username) {
/** @var UserCollectionInterface $users */
$users = $this->grav['accounts'];
//Editing current user. Reload user object
unset($this->grav['user']->avatar);
$this->grav['user']->merge($users->load($this->admin->route)->toArray());
}
return true;
}
protected function taskSaveDefault()
{
// Handle standard data types.
$obj = $this->prepareData((array)$this->data);
try {
$obj->validate();
} catch (\Exception $e) {
$this->admin->setMessage($e->getMessage(), 'error');
return false;
}
$obj->filter();
$obj = $this->storeFiles($obj);
if ($obj) {
// Event to manipulate data before saving the object
$this->grav->fireEvent('onAdminSave', new Event(['object' => &$obj]));
$obj->save();
$this->admin->setMessage($this->admin::translate('PLUGIN_ADMIN.SUCCESSFULLY_SAVED'), 'info');
$this->grav->fireEvent('onAdminAfterSave', new Event(['object' => $obj]));
}
// Force configuration reload.
/** @var Config $config */
$config = $this->grav['config'];
$config->reload();
return true; return true;
} }