Skip to content

Commit

Permalink
extracted logic from stream_metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-donat committed Dec 30, 2014
1 parent 4614b5d commit 620ac3f
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 99 deletions.
21 changes: 21 additions & 0 deletions src/VirtualFileSystem/AccessDeniedException.php
@@ -0,0 +1,21 @@
<?php
/*
* This file is part of the php-vfs package.
*
* (c) Michael Donat <michael.donat@me.com>
*
* 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 <michael.donat@me.com>
* @package php-vfs
*/
class AccessDeniedException extends \Exception
{
}
4 changes: 2 additions & 2 deletions src/VirtualFileSystem/FileSystem.php
Expand Up @@ -121,7 +121,7 @@ public function path($path)
*
* @param string $path
* @param bool $recursive
* @param integer $mode
* @param integer|null $mode
*
* @return Directory
*/
Expand All @@ -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
*/
Expand Down
2 changes: 1 addition & 1 deletion src/VirtualFileSystem/Loader.php
Expand Up @@ -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()
{
Expand Down
206 changes: 111 additions & 95 deletions src/VirtualFileSystem/Wrapper.php
Expand Up @@ -45,7 +45,7 @@ class Wrapper
*
* @see http://php.net/stat
*
* @return array
* @return array<*,integer>
*/
protected function getStatArray()
{
Expand Down Expand Up @@ -231,7 +231,7 @@ public function stream_open($path, $mode, $options, &$openedPath)
*
* @param $data
*
* @return int
* @return false|integer
*/
public function stream_write($data)
{
Expand Down Expand Up @@ -264,7 +264,7 @@ public function stream_stat()
*
* @param string $path
*
* @return array|bool
* @return array|false
*/
public function url_stat($path)
{
Expand Down Expand Up @@ -292,7 +292,7 @@ public function url_stat($path)
*
* @param int $bytes
*
* @return string
* @return null|string
*/
public function stream_read($bytes)
{
Expand Down Expand Up @@ -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.
*
Expand All @@ -387,120 +486,37 @@ 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);
$permissionHelper = $container->getPermissionHelper($node);

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);
Expand Down
2 changes: 1 addition & 1 deletion src/VirtualFileSystem/Wrapper/PermissionHelper.php
Expand Up @@ -91,7 +91,7 @@ public function groupIsOwner()
/**
* Checks whether file is readable for group
*
* @return bool
* @return integer|null
*/
public function groupCanRead()
{
Expand Down

0 comments on commit 620ac3f

Please sign in to comment.