Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
die_coolen_jungs
our_own_cloud_project
Commits
abb6e89c
Commit
abb6e89c
authored
Nov 10, 2014
by
Robin Appelman
Browse files
Add storage and cache wrappers to jail a storage to a subfolder
parent
a2172786
Changes
8
Hide whitespace changes
Inline
Side-by-side
lib/private/files/cache/cache.php
View file @
abb6e89c
...
...
@@ -585,7 +585,7 @@ class Cache {
/**
* find a folder in the cache which has not been fully scanned
*
* If multipl
y
incomplete folders are in the cache, the one with the highest id will be returned,
* If multipl
e
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
*
...
...
lib/private/files/cache/wrapper/cachejail.php
0 → 100644
View file @
abb6e89c
<?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
);
}
}
lib/private/files/cache/wrapper/cachewrapper.php
0 → 100644
View file @
abb6e89c
<?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
);
}
}
lib/private/files/storage/wrapper/jail.php
0 → 100644
View file @
abb6e89c
<?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
)
{