diff --git a/CHANGELOG.md b/CHANGELOG.md index cf85f9fdd..eb9e5a453 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * File `frontmatter.yaml` isn't part of media, ignore it 1. [](#bugfix) * Fixed missing styles when CSS/JS Pipeline is used and `asset://` folder is missing + * Fixed permission check when moving a page [#3382](https://github.com/getgrav/grav/issues/3382) # v1.7.16 ## 06/02/2021 diff --git a/system/src/Grav/Common/Flex/Types/Pages/PageObject.php b/system/src/Grav/Common/Flex/Types/Pages/PageObject.php index 914eb7f33..a8342d121 100644 --- a/system/src/Grav/Common/Flex/Types/Pages/PageObject.php +++ b/system/src/Grav/Common/Flex/Types/Pages/PageObject.php @@ -262,6 +262,24 @@ class PageObject extends FlexPageObject $this->getFlexDirectory()->reloadIndex(); } + /** + * @param UserInterface|null $user + */ + public function check(UserInterface $user = null): void + { + parent::check($user); + + if ($user && $this->isMoved()) { + $parentKey = $this->getProperty('parent_key'); + + /** @var PageObject|null $parent */ + $parent = $this->getFlexDirectory()->getObject($parentKey); + if (!$parent || !$parent->isAuthorized('create', null, $user)) { + throw new \RuntimeException('Forbidden', 403); + } + } + } + /** * @param array|bool $reorder * @return FlexObject|FlexObjectInterface @@ -357,6 +375,19 @@ class PageObject extends FlexPageObject return parent::isAuthorizedOverride($user, $action, $scope, $isMe); } + /** + * @return bool + */ + protected function isMoved(): bool + { + $storageKey = $this->getMasterKey(); + $filesystem = Filesystem::getInstance(false); + $oldParentKey = ltrim($filesystem->dirname("/{$storageKey}"), '/'); + $newParentKey = $this->getProperty('parent_key'); + + return $this->exists() && $oldParentKey !== $newParentKey; + } + /** * @param array $ordering * @return PageCollection|null @@ -364,10 +395,7 @@ class PageObject extends FlexPageObject protected function reorderSiblings(array $ordering) { $storageKey = $this->getMasterKey(); - $filesystem = Filesystem::getInstance(false); - $oldParentKey = ltrim($filesystem->dirname("/{$storageKey}"), '/'); - $newParentKey = $this->getProperty('parent_key'); - $isMoved = $this->exists() && $oldParentKey !== $newParentKey; + $isMoved = $this->isMoved(); $order = !$isMoved ? $this->order() : false; if ($order !== false) { $order = (int)$order; diff --git a/system/src/Grav/Framework/Flex/FlexObject.php b/system/src/Grav/Framework/Flex/FlexObject.php index d505e5603..06e383bff 100644 --- a/system/src/Grav/Framework/Flex/FlexObject.php +++ b/system/src/Grav/Framework/Flex/FlexObject.php @@ -691,6 +691,17 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface return $this->create($key); } + /** + * @param UserInterface|null $user + */ + public function check(UserInterface $user = null): void + { + // If user has been provided, check if the user has permissions to save this object. + if ($user && !$this->isAuthorized('save', null, $user)) { + throw new \RuntimeException('Forbidden', 403); + } + } + /** * {@inheritdoc} * @see FlexObjectInterface::save()