From 620ac3f1d14475cb4b563bc36d35895957fe8c7b Mon Sep 17 00:00:00 2001 From: Michael Donat Date: Tue, 30 Dec 2014 14:22:23 +0100 Subject: [PATCH] extracted logic from stream_metadata --- .../AccessDeniedException.php | 21 ++ src/VirtualFileSystem/FileSystem.php | 4 +- src/VirtualFileSystem/Loader.php | 2 +- src/VirtualFileSystem/Wrapper.php | 206 ++++++++++-------- .../Wrapper/PermissionHelper.php | 2 +- 5 files changed, 136 insertions(+), 99 deletions(-) create mode 100644 src/VirtualFileSystem/AccessDeniedException.php diff --git a/src/VirtualFileSystem/AccessDeniedException.php b/src/VirtualFileSystem/AccessDeniedException.php new file mode 100644 index 0000000..7e96219 --- /dev/null +++ b/src/VirtualFileSystem/AccessDeniedException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace VirtualFileSystem; + +/** + * Thrown when access to Node is denied. + * + * @author Michael Donat + * @package php-vfs + */ +class AccessDeniedException extends \Exception +{ +} diff --git a/src/VirtualFileSystem/FileSystem.php b/src/VirtualFileSystem/FileSystem.php index 0d2d4d3..1e08e79 100644 --- a/src/VirtualFileSystem/FileSystem.php +++ b/src/VirtualFileSystem/FileSystem.php @@ -121,7 +121,7 @@ public function path($path) * * @param string $path * @param bool $recursive - * @param integer $mode + * @param integer|null $mode * * @return Directory */ @@ -134,7 +134,7 @@ public function createDirectory($path, $recursive = false, $mode = null) * Creates and returns a file * * @param string $path - * @param string $data + * @param string|null $data * * @return File */ diff --git a/src/VirtualFileSystem/Loader.php b/src/VirtualFileSystem/Loader.php index 1444c29..195b4d8 100644 --- a/src/VirtualFileSystem/Loader.php +++ b/src/VirtualFileSystem/Loader.php @@ -77,7 +77,7 @@ public function setIncludePath($includePath) /** * Gets the base include path for all class files in the namespace of this class loader. * - * @return string $includePath + * @return null|string $includePath */ public function getIncludePath() { diff --git a/src/VirtualFileSystem/Wrapper.php b/src/VirtualFileSystem/Wrapper.php index f37ecb1..573cc55 100644 --- a/src/VirtualFileSystem/Wrapper.php +++ b/src/VirtualFileSystem/Wrapper.php @@ -45,7 +45,7 @@ class Wrapper * * @see http://php.net/stat * - * @return array + * @return array<*,integer> */ protected function getStatArray() { @@ -231,7 +231,7 @@ public function stream_open($path, $mode, $options, &$openedPath) * * @param $data * - * @return int + * @return false|integer */ public function stream_write($data) { @@ -264,7 +264,7 @@ public function stream_stat() * * @param string $path * - * @return array|bool + * @return array|false */ public function url_stat($path) { @@ -292,7 +292,7 @@ public function url_stat($path) * * @param int $bytes * - * @return string + * @return null|string */ public function stream_read($bytes) { @@ -368,6 +368,105 @@ public function mkdir($path, $mode, $options) return true; } + /** + * @param $path + * @param $container + * @param $strippedPath + * @return bool + */ + protected function metaTouch($path, $container, $strippedPath) + { + if (!$container->hasNodeAt($strippedPath)) { + try { + $container->createFile($strippedPath); + } catch (NotFoundException $e) { + trigger_error( + sprintf('touch: %s: No such file or directory.', $strippedPath), + E_USER_WARNING + ); + + return false; + } + } + $file = $container->nodeAt($strippedPath); + + $permissionHelper = $container->getPermissionHelper($file); + + if (!$permissionHelper->userIsOwner() && !$permissionHelper->isWritable()) { + trigger_error( + sprintf('touch: %s: Permission denied', $strippedPath), + E_USER_WARNING + ); + + return false; + } + + $file->setAccessTime(time()); + $file->setModificationTime(time()); + $file->setChangeTime(time()); + + clearstatcache(true, $path); + + return true; + } + + protected function metaAccess($node, $value, $container, $strippedPath, $permissionHelper) + { + if ($node instanceof Link) { + $node = $node->getDestination(); + $permissionHelper = $container->getPermissionHelper($node); + } + + if (!$permissionHelper->userIsOwner()) { + trigger_error( + sprintf('chmod: %s: Permission denied', $strippedPath), + E_USER_WARNING + ); + + throw new AccessDeniedException(sprintf('chmod: %s: Permission denied', $strippedPath)); + } + $node->chmod($value); + $node->setChangeTime(time()); + } + + protected function metaOwner($node, $ownerId, $ownerName, $container, $strippedPath, $permissionHelper) + { + if (!$permissionHelper->userIsRoot() && !$permissionHelper->userIsOwner()) { + trigger_error( + sprintf('chown: %s: Permission denied', $strippedPath), + E_USER_WARNING + ); + + throw new AccessDeniedException(sprintf('chown: %s: Permission denied', $strippedPath)); + } + + if (!is_null($ownerName)) { + $ownerId = function_exists('posix_getpwnam') ? posix_getpwnam($ownerName)['uid'] : 0; + } + + $node->chown($ownerId); + $node->setChangeTime(time()); + } + + protected function metaGroup($node, $groupId, $groupName, $container, $strippedPath, $permissionHelper) + { + if (!$permissionHelper->userIsRoot() && !$permissionHelper->userIsOwner()) { + trigger_error( + sprintf('chgrp: %s: Permission denied', $strippedPath), + E_USER_WARNING + ); + + throw new AccessDeniedException(sprintf('chgrp: %s: Permission denied', $strippedPath)); + } + + if (!is_null($groupName)) { + $groupId = function_exists('posix_getgrnam') ? posix_getgrnam($groupName)['gid'] : 0; + } + + $node->chgrp($groupId); + $node->setChangeTime(time()); + } + /** * Called in response to chown/chgrp/touch/chmod etc. * @@ -387,39 +486,7 @@ public function stream_metadata($path, $option, $value) try { if ($option == STREAM_META_TOUCH) { - if (!$container->hasNodeAt($strippedPath)) { - try { - $container->createFile($strippedPath); - } catch (NotFoundException $e) { - trigger_error( - sprintf('touch: %s: No such file or directory.', $strippedPath), - E_USER_WARNING - ); - - return false; - } - } - $file = $container->nodeAt($strippedPath); - - $permissionHelper = $container->getPermissionHelper($file); - - if (!$permissionHelper->userIsOwner() && !$permissionHelper->isWritable()) { - trigger_error( - sprintf('touch: %s: Permission denied', $strippedPath), - E_USER_WARNING - ); - - return false; - } - - $file->setAccessTime(time()); - $file->setModificationTime(time()); - $file->setChangeTime(time()); - - clearstatcache(true, $path); - - return true; - + return $this->metaTouch($path, $container, $strippedPath); } $node = $container->nodeAt($strippedPath); @@ -427,80 +494,29 @@ public function stream_metadata($path, $option, $value) switch ($option) { case STREAM_META_ACCESS: - - if ($node instanceof Link) { - $node = $node->getDestination(); - $permissionHelper = $container->getPermissionHelper($node); - } - - if (!$permissionHelper->userIsOwner()) { - trigger_error( - sprintf('chmod: %s: Permission denied', $strippedPath), - E_USER_WARNING - ); - - return false; - } - $node->chmod($value); - $node->setChangeTime(time()); + $this->metaAccess($node, $value, $container, $strippedPath, $permissionHelper); break; case STREAM_META_OWNER_NAME: - if (!$permissionHelper->userIsRoot() && !$permissionHelper->userIsOwner()) { - trigger_error( - sprintf('chown: %s: Permission denied', $strippedPath), - E_USER_WARNING - ); - - return false; - } - $uid = function_exists('posix_getpwnam') ? posix_getpwnam($value)['uid'] : 0; - $node->chown($uid); - $node->setChangeTime(time()); + $this->metaOwner($node, null, $value, $container, $strippedPath, $permissionHelper); break; case STREAM_META_OWNER: - if (!$permissionHelper->userIsRoot() && !$permissionHelper->userIsOwner()) { - trigger_error( - sprintf('chown: %s: Permission denied', $strippedPath), - E_USER_WARNING - ); - - return false; - } - $node->chown($value); - $node->setChangeTime(time()); + $this->metaOwner($node, $value, null, $container, $strippedPath, $permissionHelper); break; case STREAM_META_GROUP_NAME: - if (!$permissionHelper->userIsRoot() && !$permissionHelper->userIsOwner()) { - trigger_error( - sprintf('chgrp: %s: Permission denied', $strippedPath), - E_USER_WARNING - ); - - return false; - } - $gid = function_exists('posix_getgrnam') ? posix_getgrnam($value)['gid'] : 0; - $node->chgrp($gid); - $node->setChangeTime(time()); + $this->metaGroup($node, null, $value, $container, $strippedPath, $permissionHelper); break; case STREAM_META_GROUP: - if (!$permissionHelper->userIsRoot() && !$permissionHelper->userIsOwner()) { - trigger_error( - sprintf('chgrp: %s: Permission denied', $strippedPath), - E_USER_WARNING - ); - - return false; - } - $node->chgrp($value); - $node->setChangeTime(time()); + $this->metaGroup($node, $value, null, $container, $strippedPath, $permissionHelper); break; } } catch (NotFoundException $e) { return false; + } catch (AccessDeniedException $e) { + return false; } clearstatcache(true, $path); diff --git a/src/VirtualFileSystem/Wrapper/PermissionHelper.php b/src/VirtualFileSystem/Wrapper/PermissionHelper.php index 9ccace0..1e0ed3e 100644 --- a/src/VirtualFileSystem/Wrapper/PermissionHelper.php +++ b/src/VirtualFileSystem/Wrapper/PermissionHelper.php @@ -91,7 +91,7 @@ public function groupIsOwner() /** * Checks whether file is readable for group * - * @return bool + * @return integer|null */ public function groupCanRead() {