Merge pull request #12426 from owncloud/jail-mask-wrappers
Add Jail and PermissionsMask storage wrappers
This commit is contained in:
commit
05a069c101
|
@ -585,7 +585,7 @@ class Cache {
|
|||
/**
|
||||
* find a folder in the cache which has not been fully scanned
|
||||
*
|
||||
* If multiply incomplete folders are in the cache, the one with the highest id will be returned,
|
||||
* If multiple incomplete folders are in the cache, the one with the highest id will be returned,
|
||||
* use the one with the highest id gives the best result with the background scanner, since that is most
|
||||
* likely the folder where we stopped scanning previously
|
||||
*
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace OC\Files\Cache\Wrapper;
|
||||
|
||||
/**
|
||||
* Jail to a subdirectory of the wrapped cache
|
||||
*/
|
||||
class CacheJail extends CacheWrapper {
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $root;
|
||||
|
||||
/**
|
||||
* @param \OC\Files\Cache\Cache $cache
|
||||
* @param string $root
|
||||
*/
|
||||
public function __construct($cache, $root) {
|
||||
parent::__construct($cache);
|
||||
$this->root = $root;
|
||||
}
|
||||
|
||||
protected function getSourcePath($path) {
|
||||
if ($path === '') {
|
||||
return $this->root;
|
||||
} else {
|
||||
return $this->root . '/' . $path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return null|string the jailed path or null if the path is outside the jail
|
||||
*/
|
||||
protected function getJailedPath($path) {
|
||||
$rootLength = strlen($this->root) + 1;
|
||||
if ($path === $this->root) {
|
||||
return '';
|
||||
} else if (substr($path, 0, $rootLength) === $this->root . '/') {
|
||||
return substr($path, $rootLength);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $entry
|
||||
* @return array
|
||||
*/
|
||||
protected function formatCacheEntry($entry) {
|
||||
if (isset($entry['path'])) {
|
||||
$entry['path'] = $this->getJailedPath($entry['path']);
|
||||
}
|
||||
return $entry;
|
||||
}
|
||||
|
||||
protected function filterCacheEntry($entry) {
|
||||
$rootLength = strlen($this->root) + 1;
|
||||
return ($entry['path'] === $this->root) or (substr($entry['path'], 0, $rootLength) === $this->root . '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* get the stored metadata of a file or folder
|
||||
*
|
||||
* @param string /int $file
|
||||
* @return array|false
|
||||
*/
|
||||
public function get($file) {
|
||||
if (is_string($file) or $file == '') {
|
||||
$file = $this->getSourcePath($file);
|
||||
}
|
||||
return parent::get($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* store meta data for a file or folder
|
||||
*
|
||||
* @param string $file
|
||||
* @param array $data
|
||||
*
|
||||
* @return int file id
|
||||
*/
|
||||
public function put($file, array $data) {
|
||||
return $this->cache->put($this->getSourcePath($file), $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* update the metadata in the cache
|
||||
*
|
||||
* @param int $id
|
||||
* @param array $data
|
||||
*/
|
||||
public function update($id, array $data) {
|
||||
$this->cache->update($this->getSourcePath($id), $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the file id for a file
|
||||
*
|
||||
* @param string $file
|
||||
* @return int
|
||||
*/
|
||||
public function getId($file) {
|
||||
return $this->cache->getId($this->getSourcePath($file));
|
||||
}
|
||||
|
||||
/**
|
||||
* get the id of the parent folder of a file
|
||||
*
|
||||
* @param string $file
|
||||
* @return int
|
||||
*/
|
||||
public function getParentId($file) {
|
||||
if ($file === '') {
|
||||
return -1;
|
||||
} else {
|
||||
return $this->cache->getParentId($this->getSourcePath($file));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a file is available in the cache
|
||||
*
|
||||
* @param string $file
|
||||
* @return bool
|
||||
*/
|
||||
public function inCache($file) {
|
||||
return $this->cache->inCache($this->getSourcePath($file));
|
||||
}
|
||||
|
||||
/**
|
||||
* remove a file or folder from the cache
|
||||
*
|
||||
* @param string $file
|
||||
*/
|
||||
public function remove($file) {
|
||||
$this->cache->remove($this->getSourcePath($file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a file or folder in the cache
|
||||
*
|
||||
* @param string $source
|
||||
* @param string $target
|
||||
*/
|
||||
public function move($source, $target) {
|
||||
$this->cache->move($this->getSourcePath($source), $this->getSourcePath($target));
|
||||
}
|
||||
|
||||
/**
|
||||
* remove all entries for files that are stored on the storage from the cache
|
||||
*/
|
||||
public function clear() {
|
||||
$this->cache->remove($this->root);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return int, Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE
|
||||
*/
|
||||
public function getStatus($file) {
|
||||
return $this->cache->getStatus($this->getSourcePath($file));
|
||||
}
|
||||
|
||||
private function formatSearchResults($results) {
|
||||
$results = array_filter($results, array($this, 'filterCacheEntry'));
|
||||
$results = array_values($results);
|
||||
return array_map(array($this, 'formatCacheEntry'), $results);
|
||||
}
|
||||
|
||||
/**
|
||||
* search for files matching $pattern
|
||||
*
|
||||
* @param string $pattern
|
||||
* @return array an array of file data
|
||||
*/
|
||||
public function search($pattern) {
|
||||
$results = $this->cache->search($pattern);
|
||||
return $this->formatSearchResults($results);
|
||||
}
|
||||
|
||||
/**
|
||||
* search for files by mimetype
|
||||
*
|
||||
* @param string $mimetype
|
||||
* @return array
|
||||
*/
|
||||
public function searchByMime($mimetype) {
|
||||
$results = $this->cache->searchByMime($mimetype);
|
||||
return $this->formatSearchResults($results);
|
||||
}
|
||||
|
||||
/**
|
||||
* update the folder size and the size of all parent folders
|
||||
*
|
||||
* @param string|boolean $path
|
||||
* @param array $data (optional) meta data of the folder
|
||||
*/
|
||||
public function correctFolderSize($path, $data = null) {
|
||||
$this->cache->correctFolderSize($this->getSourcePath($path), $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the size of a folder and set it in the cache
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $entry (optional) meta data of the folder
|
||||
* @return int
|
||||
*/
|
||||
public function calculateFolderSize($path, $entry = null) {
|
||||
return $this->cache->calculateFolderSize($this->getSourcePath($path), $entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* get all file ids on the files on the storage
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public function getAll() {
|
||||
// not supported
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* find a folder in the cache which has not been fully scanned
|
||||
*
|
||||
* If multiply incomplete folders are in the cache, the one with the highest id will be returned,
|
||||
* use the one with the highest id gives the best result with the background scanner, since that is most
|
||||
* likely the folder where we stopped scanning previously
|
||||
*
|
||||
* @return string|bool the path of the folder or false when no folder matched
|
||||
*/
|
||||
public function getIncomplete() {
|
||||
// not supported
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the path of a file on this storage by it's id
|
||||
*
|
||||
* @param int $id
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPathById($id) {
|
||||
$path = $this->cache->getPathById($id);
|
||||
return $this->getJailedPath($path);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace OC\Files\Cache\Wrapper;
|
||||
|
||||
class CachePermissionsMask extends CacheWrapper {
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $mask;
|
||||
|
||||
/**
|
||||
* @param \OC\Files\Cache\Cache $cache
|
||||
* @param int $mask
|
||||
*/
|
||||
public function __construct($cache, $mask) {
|
||||
parent::__construct($cache);
|
||||
$this->mask = $mask;
|
||||
}
|
||||
|
||||
protected function formatCacheEntry($entry) {
|
||||
if (isset($entry['permissions'])) {
|
||||
$entry['permissions'] &= $this->mask;
|
||||
}
|
||||
return $entry;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,247 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace OC\Files\Cache\Wrapper;
|
||||
|
||||
use OC\Files\Cache\Cache;
|
||||
|
||||
class CacheWrapper extends Cache {
|
||||
/**
|
||||
* @var \OC\Files\Cache\Cache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @param \OC\Files\Cache\Cache $cache
|
||||
*/
|
||||
public function __construct($cache) {
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make it easy for wrappers to modify every returned cache entry
|
||||
*
|
||||
* @param array $entry
|
||||
* @return array
|
||||
*/
|
||||
protected function formatCacheEntry($entry) {
|
||||
return $entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the stored metadata of a file or folder
|
||||
*
|
||||
* @param string /int $file
|
||||
* @return array|false
|
||||
*/
|
||||
public function get($file) {
|
||||
$result = $this->cache->get($file);
|
||||
if ($result) {
|
||||
$result = $this->formatCacheEntry($result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the metadata of all files stored in $folder
|
||||
*
|
||||
* @param string $folder
|
||||
* @return array
|
||||
*/
|
||||
public function getFolderContents($folder) {
|
||||
// cant do a simple $this->cache->.... call here since getFolderContentsById needs to be called on this
|
||||
// and not the wrapped cache
|
||||
$fileId = $this->getId($folder);
|
||||
return $this->getFolderContentsById($fileId);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the metadata of all files stored in $folder
|
||||
*
|
||||
* @param int $fileId the file id of the folder
|
||||
* @return array
|
||||
*/
|
||||
public function getFolderContentsById($fileId) {
|
||||
$results = $this->cache->getFolderContentsById($fileId);
|
||||
return array_map(array($this, 'formatCacheEntry'), $results);
|
||||
}
|
||||
|
||||
/**
|
||||
* store meta data for a file or folder
|
||||
*
|
||||
* @param string $file
|
||||
* @param array $data
|
||||
*
|
||||
* @return int file id
|
||||
*/
|
||||
public function put($file, array $data) {
|
||||
return $this->cache->put($file, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* update the metadata in the cache
|
||||
*
|
||||
* @param int $id
|
||||
* @param array $data
|
||||
*/
|
||||
public function update($id, array $data) {
|
||||
$this->cache->update($id, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the file id for a file
|
||||
*
|
||||
* @param string $file
|
||||
* @return int
|
||||
*/
|
||||
public function getId($file) {
|
||||
return $this->cache->getId($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the id of the parent folder of a file
|
||||
*
|
||||
* @param string $file
|
||||
* @return int
|
||||
*/
|
||||
public function getParentId($file) {
|
||||
return $this->cache->getParentId($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a file is available in the cache
|
||||
*
|
||||
* @param string $file
|
||||
* @return bool
|
||||
*/
|
||||
public function inCache($file) {
|
||||
return $this->cache->inCache($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove a file or folder from the cache
|
||||
*
|
||||
* @param string $file
|
||||
*/
|
||||
public function remove($file) {
|
||||
$this->cache->remove($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a file or folder in the cache
|
||||
*
|
||||
* @param string $source
|
||||
* @param string $target
|
||||
*/
|
||||
public function move($source, $target) {
|
||||
$this->cache->move($source, $target);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove all entries for files that are stored on the storage from the cache
|
||||
*/
|
||||
public function clear() {
|
||||
$this->cache->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return int, Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE
|
||||
*/
|
||||
public function getStatus($file) {
|
||||
return $this->cache->getStatus($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* search for files matching $pattern
|
||||
*
|
||||
* @param string $pattern
|
||||
* @return array an array of file data
|
||||
*/
|
||||
public function search($pattern) {
|
||||
$results = $this->cache->search($pattern);
|
||||
return array_map(array($this, 'formatCacheEntry'), $results);
|
||||
}
|
||||
|
||||
/**
|
||||
* search for files by mimetype
|
||||
*
|
||||
* @param string $mimetype
|
||||
* @return array
|
||||
*/
|
||||
public function searchByMime($mimetype) {
|
||||
$results = $this->cache->searchByMime($mimetype);
|
||||
return array_map(array($this, 'formatCacheEntry'), $results);
|
||||
}
|
||||
|
||||
/**
|
||||
* update the folder size and the size of all parent folders
|
||||
*
|
||||
* @param string|boolean $path
|
||||
* @param array $data (optional) meta data of the folder
|
||||
*/
|
||||
public function correctFolderSize($path, $data = null) {
|
||||
$this->cache->correctFolderSize($path, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the size of a folder and set it in the cache
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $entry (optional) meta data of the folder
|
||||
* @return int
|
||||
*/
|
||||
public function calculateFolderSize($path, $entry = null) {
|
||||
return $this->cache->calculateFolderSize($path, $entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* get all file ids on the files on the storage
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public function getAll() {
|
||||
return $this->cache->getAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* find a folder in the cache which has not been fully scanned
|
||||
*
|
||||
* If multiple incomplete folders are in the cache, the one with the highest id will be returned,
|
||||
* use the one with the highest id gives the best result with the background scanner, since that is most
|
||||
* likely the folder where we stopped scanning previously
|
||||
*
|
||||
* @return string|bool the path of the folder or false when no folder matched
|
||||
*/
|
||||
public function getIncomplete() {
|
||||
return $this->cache->getIncomplete();
|
||||
}
|
||||
|
||||
/**
|
||||
* get the path of a file on this storage by it's id
|
||||
*
|
||||
* @param int $id
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPathById($id) {
|
||||
return $this->cache->getPathById($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the storage id of the storage for a file and the internal path of the file
|
||||
* unlike getPathById this does not limit the search to files on this storage and
|
||||
* instead does a global search in the cache table
|
||||
*
|
||||
* @param int $id
|
||||
* @return array, first element holding the storage id, second the path
|
||||
*/
|
||||
static public function getById($id) {
|
||||
return parent::getById($id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,413 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace OC\Files\Storage\Wrapper;
|
||||
|
||||
use OC\Files\Cache\Wrapper\CacheJail;
|
||||
|
||||
/**
|
||||
* Jail to a subdirectory of the wrapped storage
|
||||
*
|
||||
* This restricts access to a subfolder of the wrapped storage with the subfolder becoming the root folder new storage
|
||||
*/
|
||||
class Jail extends Wrapper {
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $rootPath;
|
||||
|
||||
/**
|
||||
* @param array $arguments ['storage' => $storage, 'mask' => $root]
|
||||
*
|
||||
* $storage: The storage that will be wrapper
|
||||
* $root: The folder in the wrapped storage that will become the root folder of the wrapped storage
|
||||
*/
|
||||
public function __construct($arguments) {
|
||||
parent::__construct($arguments);
|
||||
$this->rootPath = $arguments['root'];
|
||||
}
|
||||
|
||||
protected function getSourcePath($path) {
|
||||
if ($path === '') {
|
||||
return $this->rootPath;
|
||||
} else {
|
||||
return $this->rootPath . '/' . $path;
|
||||
}
|
||||
}
|
||||
|
||||
public function getId() {
|
||||
return 'link:' . parent::getId() . ':' . $this->rootPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.mkdir.php
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function mkdir($path) {
|
||||
return $this->storage->mkdir($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.rmdir.php
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function rmdir($path) {
|
||||
return $this->storage->rmdir($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.opendir.php
|
||||
*
|
||||
* @param string $path
|
||||
* @return resource
|
||||
*/
|
||||
public function opendir($path) {
|
||||
return $this->storage->opendir($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.is_dir.php
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function is_dir($path) {
|
||||
return $this->storage->is_dir($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.is_file.php
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function is_file($path) {
|
||||
return $this->storage->is_file($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.stat.php
|
||||
* only the following keys are required in the result: size and mtime
|
||||
*
|
||||
* @param string $path
|
||||
* @return array
|
||||
*/
|
||||
public function stat($path) {
|
||||
return $this->storage->stat($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.filetype.php
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function filetype($path) {
|
||||
return $this->storage->filetype($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.filesize.php
|
||||
* The result for filesize when called on a folder is required to be 0
|
||||
*
|
||||
* @param string $path
|
||||
* @return int
|
||||
*/
|
||||
public function filesize($path) {
|
||||
return $this->storage->filesize($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a file can be created in $path
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function isCreatable($path) {
|
||||
return $this->storage->isCreatable($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a file can be read
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function isReadable($path) {
|
||||
return $this->storage->isReadable($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a file can be written to
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function isUpdatable($path) {
|
||||
return $this->storage->isUpdatable($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a file can be deleted
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function isDeletable($path) {
|
||||
return $this->storage->isDeletable($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a file can be shared
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function isSharable($path) {
|
||||
return $this->storage->isSharable($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* get the full permissions of a path.
|
||||
* Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php
|
||||
*
|
||||
* @param string $path
|
||||
* @return int
|
||||
*/
|
||||
public function getPermissions($path) {
|
||||
return $this->storage->getPermissions($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.file_exists.php
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function file_exists($path) {
|
||||
return $this->storage->file_exists($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.filemtime.php
|
||||
*
|
||||
* @param string $path
|
||||
* @return int
|
||||
*/
|
||||
public function filemtime($path) {
|
||||
return $this->storage->filemtime($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.file_get_contents.php
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public function file_get_contents($path) {
|
||||
return $this->storage->file_get_contents($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.file_put_contents.php
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $data
|
||||
* @return bool
|
||||
*/
|
||||
public function file_put_contents($path, $data) {
|
||||
return $this->storage->file_put_contents($this->getSourcePath($path), $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.unlink.php
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function unlink($path) {
|
||||
return $this->storage->unlink($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.rename.php
|
||||
*
|
||||
* @param string $path1
|
||||
* @param string $path2
|
||||
* @return bool
|
||||
*/
|
||||
public function rename($path1, $path2) {
|
||||
return $this->storage->rename($this->getSourcePath($path1), $this->getSourcePath($path2));
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.copy.php
|
||||
*
|
||||
* @param string $path1
|
||||
* @param string $path2
|
||||
* @return bool
|
||||
*/
|
||||
public function copy($path1, $path2) {
|
||||
return $this->storage->copy($this->getSourcePath($path1), $this->getSourcePath($path2));
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.fopen.php
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $mode
|
||||
* @return resource
|
||||
*/
|
||||
public function fopen($path, $mode) {
|
||||
return $this->storage->fopen($this->getSourcePath($path), $mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the mimetype for a file or folder
|
||||
* The mimetype for a folder is required to be "httpd/unix-directory"
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public function getMimeType($path) {
|
||||
return $this->storage->getMimeType($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.hash.php
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $path
|
||||
* @param bool $raw
|
||||
* @return string
|
||||
*/
|
||||
public function hash($type, $path, $raw = false) {
|
||||
return $this->storage->hash($type, $this->getSourcePath($path), $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.free_space.php
|
||||
*
|
||||
* @param string $path
|
||||
* @return int
|
||||
*/
|
||||
public function free_space($path) {
|
||||
return $this->storage->free_space($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* search for occurrences of $query in file names
|
||||
*
|
||||
* @param string $query
|
||||
* @return array
|
||||
*/
|
||||
public function search($query) {
|
||||
return $this->storage->search($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* see http://php.net/manual/en/function.touch.php
|
||||
* If the backend does not support the operation, false should be returned
|
||||
*
|
||||
* @param string $path
|
||||
* @param int $mtime
|
||||
* @return bool
|
||||
*/
|
||||
public function touch($path, $mtime = null) {
|
||||
return $this->storage->touch($this->getSourcePath($path), $mtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the path to a local version of the file.
|
||||
* The local version of the file can be temporary and doesn't have to be persistent across requests
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public function getLocalFile($path) {
|
||||
return $this->storage->getLocalFile($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* get the path to a local version of the folder.
|
||||
* The local version of the folder can be temporary and doesn't have to be persistent across requests
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public function getLocalFolder($path) {
|
||||
return $this->storage->getLocalFolder($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a file or folder has been updated since $time
|
||||
*
|
||||
* @param string $path
|
||||
* @param int $time
|
||||
* @return bool
|
||||
*
|
||||
* hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed.
|
||||
* returning true for other changes in the folder is optional
|
||||
*/
|
||||
public function hasUpdated($path, $time) {
|
||||
return $this->storage->hasUpdated($this->getSourcePath($path), $time);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a cache instance for the storage
|
||||
*
|
||||
* @param string $path
|
||||
* @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
|
||||
* @return \OC\Files\Cache\Cache
|
||||
*/
|
||||
public function getCache($path = '', $storage = null) {
|
||||
if (!$storage) {
|
||||
$storage = $this;
|
||||
}
|
||||
$sourceCache = $this->storage->getCache($this->getSourcePath($path), $storage);
|
||||
return new CacheJail($sourceCache, $this->rootPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the user id of the owner of a file or folder
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public function getOwner($path) {
|
||||
return $this->storage->getOwner($this->getSourcePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* get a watcher instance for the cache
|
||||
*
|
||||
* @param string $path
|
||||
* @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
|
||||
* @return \OC\Files\Cache\Watcher
|
||||
*/
|
||||
public function getWatcher($path = '', $storage = null) {
|
||||
if (!$storage) {
|
||||
$storage = $this;
|
||||
}
|
||||
return $this->storage->getWatcher($this->getSourcePath($path), $storage);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the ETag for a file or folder
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public function getETag($path) {
|
||||
return $this->storage->getETag($this->getSourcePath($path));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace OC\Files\Storage\Wrapper;
|
||||
|
||||
use OC\Files\Cache\Wrapper\CachePermissionsMask;
|
||||
use OCP\Constants;
|
||||
|
||||
/**
|
||||
* Mask the permissions of a storage
|
||||
*
|
||||
* This can be used to restrict update, create, delete and/or share permissions of a storage
|
||||
*
|
||||
* Note that the read permissions cant be masked
|
||||
*/
|
||||
class PermissionsMask extends Wrapper {
|
||||
/**
|
||||
* @var int the permissions bits we want to keep
|
||||
*/
|
||||
private $mask;
|
||||
|
||||
/**
|
||||
* @param array $arguments ['storage' => $storage, 'mask' => $mask]
|
||||
*
|
||||
* $storage: The storage the permissions mask should be applied on
|
||||
* $mask: The permission bits that should be kept, a combination of the \OCP\Constant::PERMISSION_ constants
|
||||
*/
|
||||
public function __construct($arguments) {
|
||||
parent::__construct($arguments);
|
||||
$this->mask = $arguments['mask'];
|
||||
}
|
||||
|
||||
private function checkMask($permissions) {
|
||||
return ($this->mask & $permissions) === $permissions;
|
||||
}
|
||||
|
||||
public function isUpdatable($path) {
|
||||
return $this->checkMask(Constants::PERMISSION_UPDATE) and parent::isUpdatable($path);
|
||||
}
|
||||
|
||||
public function isCreatable($path) {
|
||||
return $this->checkMask(Constants::PERMISSION_CREATE) and parent::isCreatable($path);
|
||||
}
|
||||
|
||||
public function isDeletable($path) {
|
||||
return $this->checkMask(Constants::PERMISSION_DELETE) and parent::isDeletable($path);
|
||||
}
|
||||
|
||||
public function getPermissions($path) {
|
||||
return $this->storage->getPermissions($path) & $this->mask;
|
||||
}
|
||||
|
||||
public function rename($path1, $path2) {
|
||||
return $this->checkMask(Constants::PERMISSION_UPDATE) and parent::rename($path1, $path2);
|
||||
}
|
||||
|
||||
public function copy($path1, $path2) {
|
||||
return $this->checkMask(Constants::PERMISSION_CREATE) and parent::copy($path1, $path2);
|
||||
}
|
||||
|
||||
public function touch($path, $mtime = null) {
|
||||
$permissions = $this->file_exists($path) ? Constants::PERMISSION_UPDATE : Constants::PERMISSION_CREATE;
|
||||
return $this->checkMask($permissions) and parent::touch($path, $mtime);
|
||||
}
|
||||
|
||||
public function mkdir($path) {
|
||||
return $this->checkMask(Constants::PERMISSION_CREATE) and parent::mkdir($path);
|
||||
}
|
||||
|
||||
public function rmdir($path) {
|
||||
return $this->checkMask(Constants::PERMISSION_DELETE) and parent::rmdir($path);
|
||||
}
|
||||
|
||||
public function unlink($path) {
|
||||
return $this->checkMask(Constants::PERMISSION_DELETE) and parent::unlink($path);
|
||||
}
|
||||
|
||||
public function file_put_contents($path, $data) {
|
||||
$permissions = $this->file_exists($path) ? Constants::PERMISSION_UPDATE : Constants::PERMISSION_CREATE;
|
||||
return $this->checkMask($permissions) and parent::file_put_contents($path, $data);
|
||||
}
|
||||
|
||||
public function fopen($path, $mode) {
|
||||
if ($mode === 'r' or $mode === 'rb') {
|
||||
return parent::fopen($path, $mode);
|
||||
} else {
|
||||
$permissions = $this->file_exists($path) ? Constants::PERMISSION_UPDATE : Constants::PERMISSION_CREATE;
|
||||
return $this->checkMask($permissions) ? parent::fopen($path, $mode) : false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get a cache instance for the storage
|
||||
*
|
||||
* @param string $path
|
||||
* @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
|
||||
* @return \OC\Files\Cache\Cache
|
||||
*/
|
||||
public function getCache($path = '', $storage = null) {
|
||||
if (!$storage) {
|
||||
$storage = $this;
|
||||
}
|
||||
$sourceCache = parent::getCache($path, $storage);
|
||||
return new CachePermissionsMask($sourceCache, $this->mask);
|
||||
}
|
||||
}
|
|
@ -20,20 +20,20 @@ class Cache extends \Test\TestCase {
|
|||
/**
|
||||
* @var \OC\Files\Storage\Temporary $storage ;
|
||||
*/
|
||||
private $storage;
|
||||
protected $storage;
|
||||
/**
|
||||
* @var \OC\Files\Storage\Temporary $storage2 ;
|
||||
*/
|
||||
private $storage2;
|
||||
protected $storage2;
|
||||
|
||||
/**
|
||||
* @var \OC\Files\Cache\Cache $cache
|
||||
*/
|
||||
private $cache;
|
||||
protected $cache;
|
||||
/**
|
||||
* @var \OC\Files\Cache\Cache $cache2
|
||||
*/
|
||||
private $cache2;
|
||||
protected $cache2;
|
||||
|
||||
public function testSimple() {
|
||||
$file1 = 'foo';
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace Test\Files\Cache\Wrapper;
|
||||
|
||||
use Test\Files\Cache\Cache;
|
||||
|
||||
class CacheJail extends Cache {
|
||||
/**
|
||||
* @var \OC\Files\Cache\Cache $sourceCache
|
||||
*/
|
||||
protected $sourceCache;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->storage->mkdir('foo');
|
||||
$this->sourceCache = $this->cache;
|
||||
$this->cache = new \OC\Files\Cache\Wrapper\CacheJail($this->sourceCache, 'foo');
|
||||
}
|
||||
|
||||
function testSearchOutsideJail() {
|
||||
$file1 = 'foo/foobar';
|
||||
$file2 = 'folder/foobar';
|
||||
$data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder');
|
||||
|
||||
$this->sourceCache->put($file1, $data1);
|
||||
$this->sourceCache->put($file2, $data1);
|
||||
|
||||
$this->assertCount(2, $this->sourceCache->search('%foobar'));
|
||||
|
||||
$result = $this->cache->search('%foobar%');
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertEquals('foobar', $result[0]['path']);
|
||||
}
|
||||
|
||||
function testClearKeepEntriesOutsideJail() {
|
||||
$file1 = 'foo/foobar';
|
||||
$file2 = 'foo/foobar/asd';
|
||||
$file3 = 'folder/foobar';
|
||||
$data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory');
|
||||
|
||||
$this->sourceCache->put('foo', $data1);
|
||||
$this->sourceCache->put($file1, $data1);
|
||||
$this->sourceCache->put($file2, $data1);
|
||||
$this->sourceCache->put($file3, $data1);
|
||||
|
||||
$this->cache->clear();
|
||||
|
||||
$this->assertFalse($this->cache->inCache('foobar'));
|
||||
$this->assertTrue($this->sourceCache->inCache('folder/foobar'));
|
||||
}
|
||||
|
||||
function testGetById() {
|
||||
//not supported
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
function testGetIncomplete() {
|
||||
//not supported
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace Test\Files\Cache\Wrapper;
|
||||
|
||||
use OCP\Constants;
|
||||
use Test\Files\Cache\Cache;
|
||||
|
||||
class CachePermissionsMask extends Cache {
|
||||
/**
|
||||
* @var \OC\Files\Cache\Cache $sourceCache
|
||||
*/
|
||||
protected $sourceCache;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->storage->mkdir('foo');
|
||||
$this->sourceCache = $this->cache;
|
||||
$this->cache = $this->getMaskedCached(Constants::PERMISSION_ALL);
|
||||
}
|
||||
|
||||
protected function getMaskedCached($mask) {
|
||||
return new \OC\Files\Cache\Wrapper\CachePermissionsMask($this->sourceCache, $mask);
|
||||
}
|
||||
|
||||
public function maskProvider() {
|
||||
return array(
|
||||
array(Constants::PERMISSION_ALL),
|
||||
array(Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE),
|
||||
array(Constants::PERMISSION_ALL - Constants::PERMISSION_UPDATE),
|
||||
array(Constants::PERMISSION_READ)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider maskProvider
|
||||
* @param int $mask
|
||||
*/
|
||||
public function testGetMasked($mask) {
|
||||
$cache = $this->getMaskedCached($mask);
|
||||
$data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain', 'permissions' => Constants::PERMISSION_ALL);
|
||||
$this->sourceCache->put('foo', $data);
|
||||
$result = $cache->get('foo');
|
||||
$this->assertEquals($mask, $result['permissions']);
|
||||
|
||||
$data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain', 'permissions' => Constants::PERMISSION_ALL - Constants::PERMISSION_DELETE);
|
||||
$this->sourceCache->put('bar', $data);
|
||||
$result = $cache->get('bar');
|
||||
$this->assertEquals($mask & ~Constants::PERMISSION_DELETE, $result['permissions']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider maskProvider
|
||||
* @param int $mask
|
||||
*/
|
||||
public function testGetFolderContentMasked($mask) {
|
||||
$this->storage->mkdir('foo');
|
||||
$this->storage->file_put_contents('foo/bar', 'asd');
|
||||
$this->storage->file_put_contents('foo/asd', 'bar');
|
||||
$this->storage->getScanner()->scan('');
|
||||
|
||||
$cache = $this->getMaskedCached($mask);
|
||||
$files = $cache->getFolderContents('foo');
|
||||
$this->assertCount(2, $files);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$this->assertEquals($mask & ~Constants::PERMISSION_CREATE, $file['permissions']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider maskProvider
|
||||
* @param int $mask
|
||||
*/
|
||||
public function testSearchMasked($mask) {
|
||||
$this->storage->mkdir('foo');
|
||||
$this->storage->file_put_contents('foo/bar', 'asd');
|
||||
$this->storage->file_put_contents('foo/foobar', 'bar');
|
||||
$this->storage->getScanner()->scan('');
|
||||
|
||||
$cache = $this->getMaskedCached($mask);
|
||||
$files = $cache->search('%bar');
|
||||
$this->assertCount(2, $files);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$this->assertEquals($mask & ~Constants::PERMISSION_CREATE, $file['permissions']);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace Test\Files\Storage\Wrapper;
|
||||
|
||||
class Jail extends \Test\Files\Storage\Storage {
|
||||
/**
|
||||
* @var string tmpDir
|
||||
*/
|
||||
private $tmpDir;
|
||||
|
||||
/**
|
||||
* @var \OC\Files\Storage\Temporary
|
||||
*/
|
||||
private $sourceStorage;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->sourceStorage = new \OC\Files\Storage\Temporary(array());
|
||||
$this->sourceStorage->mkdir('foo');
|
||||
$this->instance = new \OC\Files\Storage\Wrapper\Jail(array(
|
||||
'storage' => $this->sourceStorage,
|
||||
'root' => 'foo'
|
||||
));
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
// test that nothing outside our jail is touched
|
||||
$contents = array();
|
||||
$dh = $this->sourceStorage->opendir('');
|
||||
while ($file = readdir($dh)) {
|
||||
if ($file !== '.' and $file !== '..') {
|
||||
$contents[] = $file;
|
||||
}
|
||||
}
|
||||
$this->assertEquals(array('foo'), $contents);
|
||||
$this->sourceStorage->cleanUp();
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testMkDirRooted() {
|
||||
$this->instance->mkdir('bar');
|
||||
$this->assertTrue($this->sourceStorage->is_dir('foo/bar'));
|
||||
}
|
||||
|
||||
public function testFilePutContentsRooted() {
|
||||
$this->instance->file_put_contents('bar', 'asd');
|
||||
$this->assertEquals('asd', $this->sourceStorage->file_get_contents('foo/bar'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace Test\Files\Storage\Wrapper;
|
||||
|
||||
use OCP\Constants;
|
||||
|
||||
class PermissionsMask extends \Test\Files\Storage\Storage {
|
||||
|
||||
/**
|
||||
* @var \OC\Files\Storage\Temporary
|
||||
*/
|
||||
private $sourceStorage;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->sourceStorage = new \OC\Files\Storage\Temporary(array());
|
||||
$this->instance = $this->getMaskedStorage(Constants::PERMISSION_ALL);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
$this->sourceStorage->cleanUp();
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
protected function getMaskedStorage($mask) {
|
||||
return new \OC\Files\Storage\Wrapper\PermissionsMask(array(
|
||||
'storage' => $this->sourceStorage,
|
||||
'mask' => $mask
|
||||
));
|
||||
}
|
||||
|
||||
public function testMkdirNoCreate() {
|
||||
$storage = $this->getMaskedStorage(Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE);
|
||||
$this->assertFalse($storage->mkdir('foo'));
|
||||
$this->assertFalse($storage->file_exists('foo'));
|
||||
}
|
||||
|
||||
public function testRmdirNoDelete() {
|
||||
$storage = $this->getMaskedStorage(Constants::PERMISSION_ALL - Constants::PERMISSION_DELETE);
|
||||
$this->assertTrue($storage->mkdir('foo'));
|
||||
$this->assertTrue($storage->file_exists('foo'));
|
||||
$this->assertFalse($storage->rmdir('foo'));
|
||||
$this->assertTrue($storage->file_exists('foo'));
|
||||
}
|
||||
|
||||
public function testTouchNewFileNoCreate() {
|
||||
$storage = $this->getMaskedStorage(Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE);
|
||||
$this->assertFalse($storage->touch('foo'));
|
||||
$this->assertFalse($storage->file_exists('foo'));
|
||||
}
|
||||
|
||||
public function testTouchNewFileNoUpdate() {
|
||||
$storage = $this->getMaskedStorage(Constants::PERMISSION_ALL - Constants::PERMISSION_UPDATE);
|
||||
$this->assertTrue($storage->touch('foo'));
|
||||
$this->assertTrue($storage->file_exists('foo'));
|
||||
}
|
||||
|
||||
public function testTouchExistingFileNoUpdate() {
|
||||
$this->sourceStorage->touch('foo');
|
||||
$storage = $this->getMaskedStorage(Constants::PERMISSION_ALL - Constants::PERMISSION_UPDATE);
|
||||
$this->assertFalse($storage->touch('foo'));
|
||||
}
|
||||
|
||||
public function testUnlinkNoDelete() {
|
||||
$storage = $this->getMaskedStorage(Constants::PERMISSION_ALL - Constants::PERMISSION_DELETE);
|
||||
$this->assertTrue($storage->touch('foo'));
|
||||
$this->assertTrue($storage->file_exists('foo'));
|
||||
$this->assertFalse($storage->unlink('foo'));
|
||||
$this->assertTrue($storage->file_exists('foo'));
|
||||
}
|
||||
|
||||
public function testPutContentsNewFileNoUpdate() {
|
||||
$storage = $this->getMaskedStorage(Constants::PERMISSION_ALL - Constants::PERMISSION_UPDATE);
|
||||
$this->assertTrue($storage->file_put_contents('foo', 'bar'));
|
||||
$this->assertEquals('bar', $storage->file_get_contents('foo'));
|
||||
}
|
||||
|
||||
public function testPutContentsNewFileNoCreate() {
|
||||
$storage = $this->getMaskedStorage(Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE);
|
||||
$this->assertFalse($storage->file_put_contents('foo', 'bar'));
|
||||
}
|
||||
|
||||
public function testPutContentsExistingFileNoUpdate() {
|
||||
$this->sourceStorage->touch('foo');
|
||||
$storage = $this->getMaskedStorage(Constants::PERMISSION_ALL - Constants::PERMISSION_UPDATE);
|
||||
$this->assertFalse($storage->file_put_contents('foo', 'bar'));
|
||||
}
|
||||
|
||||
public function testFopenExistingFileNoUpdate() {
|
||||
$this->sourceStorage->touch('foo');
|
||||
$storage = $this->getMaskedStorage(Constants::PERMISSION_ALL - Constants::PERMISSION_UPDATE);
|
||||
$this->assertFalse($storage->fopen('foo', 'w'));
|
||||
}
|
||||
|
||||
public function testFopenNewFileNoCreate() {
|
||||
$storage = $this->getMaskedStorage(Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE);
|
||||
$this->assertFalse($storage->fopen('foo', 'w'));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue