Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/files_excludedirs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Appelman <robin@icewind.nl>2017-03-25 00:34:02 +0300
committerRobin Appelman <robin@icewind.nl>2017-03-25 00:34:02 +0300
commit4e3c8d2c4b898d8d1e0e70631d847aa2e6c4eb64 (patch)
treea7bc82ababf30cf5e447d03184dcdb1a4271e499
parent75f963be94e6025cc4aeedf8c3c1e2bbbfdc5e48 (diff)
filter opendir and accept glob patterns
-rw-r--r--.gitignore2
-rw-r--r--appinfo/app.php3
-rw-r--r--appinfo/info.xml3
-rw-r--r--composer.json5
-rw-r--r--lib/Wrapper/Exclude.php (renamed from wrapper/exclude.php)48
-rw-r--r--lib/Wrapper/Manager.php (renamed from wrapper/manager.php)0
-rw-r--r--tests/Wrapper/ExcludeTest.php114
7 files changed, 170 insertions, 5 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..987e2a2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+composer.lock
+vendor
diff --git a/appinfo/app.php b/appinfo/app.php
index a043ba1..8b26925 100644
--- a/appinfo/app.php
+++ b/appinfo/app.php
@@ -20,6 +20,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
+require_once __DIR__ . '/../vendor/autoload.php';
+
$manager = new \OCA\Files_ExcludeDirs\Wrapper\Manager();
OCP\Util::connectHook('OC_Filesystem', 'preSetup', $manager, 'setupStorageWrapper');
diff --git a/appinfo/info.xml b/appinfo/info.xml
index 9ea20db..670875b 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -6,8 +6,9 @@
<licence>AGPL</licence>
<author>Roeland Jago Douma</author>
<version>0.0.1</version>
+ <namespace>Files_ExcludeDirs</namespace>
<dependencies>
- <owncloud min-version="9.2" max-version="9.2" />
+ <nextcloud min-version="10" max-version="12" />
</dependencies>
<types>
<filesystem/>
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..70e258d
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,5 @@
+{
+ "require": {
+ "webmozart/glob": "^4.1"
+ }
+}
diff --git a/wrapper/exclude.php b/lib/Wrapper/Exclude.php
index a57c522..9caeb14 100644
--- a/wrapper/exclude.php
+++ b/lib/Wrapper/Exclude.php
@@ -20,9 +20,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OCA\Files_ExcludeDirs\Wrapper;
+use Icewind\Streams\IteratorDirectory;
use OC\Files\Storage\Wrapper\Wrapper;
+use Webmozart\Glob\Glob;
class Exclude extends Wrapper {
/**
@@ -49,24 +52,61 @@ class Exclude extends Wrapper {
return false;
}
- foreach ($this->exclude as $dir) {
- if (strpos($path, $dir) !== false) {
- return true;
+ foreach ($this->exclude as $rule) {
+ // glob requires all paths to be absolute so we put /'s in front of them
+ if (strpos($rule, '/') !== false) {
+ $rule = '/' . rtrim($rule, '/');
+ return Glob::match('/' . $path, $rule);
+ } else {
+ $parts = explode('/', $path);
+ $rule = '/' . $rule;
+ foreach ($parts as $part) {
+ if (Glob::match('/' . $part, $rule)) {
+ return true;
+ }
+ }
}
}
return false;
}
+ public function file_exists($path) {
+ if ($this->excludedPath($path)) {
+ return false;
+ }
+
+ return parent::file_exists($path);
+ }
+
/**
* {@inheritdoc}
*/
public function opendir($path) {
+ $directoryIterator = $this->iterateDirectory($path);
+
+ if ($directoryIterator) {
+ $filteredDirectory = new \CallbackFilterIterator($directoryIterator, function ($name) use ($path) {
+ return !$this->excludedPath($path . '/' . $name);
+ });
+ $filteredDirectory->rewind();
+ return IteratorDirectory::wrap($filteredDirectory);
+ }
+
+ return false;
+ }
+
+ private function iterateDirectory($path) {
if ($this->excludedPath($path)) {
return false;
}
- return $this->storage->opendir($path);
+ $handle = $this->storage->opendir($path);
+ while ($file = readdir($handle)) {
+ if ($file !== '.' && $file !== '..') {
+ yield $file;
+ }
+ }
}
/**
diff --git a/wrapper/manager.php b/lib/Wrapper/Manager.php
index 1cabea3..1cabea3 100644
--- a/wrapper/manager.php
+++ b/lib/Wrapper/Manager.php
diff --git a/tests/Wrapper/ExcludeTest.php b/tests/Wrapper/ExcludeTest.php
new file mode 100644
index 0000000..c2aa8dd
--- /dev/null
+++ b/tests/Wrapper/ExcludeTest.php
@@ -0,0 +1,114 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Files_ExcludeDirs\Test\Wrapper;
+
+use OC\Files\Storage\Local;
+use OC\Files\Storage\Temporary;
+use OCA\Files_ExcludeDirs\Wrapper\Exclude;
+use Test\TestCase;
+
+\OC_App::loadApp('files_excludedirs');
+
+class ExcludeTest extends TestCase {
+ /** @var Local */
+ private $sourceStorage;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->sourceStorage = new Temporary();
+ }
+
+ private function setupParentFolders($path) {
+ $parts = explode('/', $path);
+ array_pop($parts);
+ $subPath = '';
+ foreach ($parts as $part) {
+ $subPath .= $part;
+ $this->sourceStorage->mkdir($subPath);
+ $subPath .= '/';
+ }
+ }
+
+ public function testFileExistsProvider() {
+ return [
+ ['foo', [], true],
+ ['foo', ['foo'], false],
+ ['bar', ['foo'], true],
+ ['bar/foo', ['foo'], false],
+ ['bar/foobar', ['foo'], true],
+ ['foo/foobar', ['foo'], false],
+ ['bar/foobar', ['foo*'], false],
+ ['bar/foobar', ['/foo*'], true],
+ ['bar/foo', ['bar/*'], false],
+ ['bar/foo/asd', ['bar/*'], true],
+ ['bar/foo/asd', ['bar/*/asd'], false],
+ ['bar/foo/qwerty/asd', ['bar/*/asd'], true],
+ ['bar/foo/qwerty/asd', ['bar/**/asd'], false],
+ ];
+ }
+
+ /**
+ * @dataProvider testFileExistsProvider
+ *
+ * @param string $path
+ * @param string[] $exclude
+ * @param bool $expected
+ */
+ public function testFileExists($path, $exclude, $expected) {
+ $this->setupParentFolders($path);
+ $this->sourceStorage->file_put_contents($path, 'dummy');
+
+
+ $storage = new Exclude([
+ 'storage' => $this->sourceStorage,
+ 'exclude' => $exclude
+ ]);
+
+ $this->assertEquals($expected, $storage->file_exists($path));
+ }
+
+ public function testOpenDir() {
+ $this->sourceStorage->mkdir('root');
+ $this->sourceStorage->file_put_contents('root/asd', '');
+ $this->sourceStorage->file_put_contents('root/bar', '');
+ $this->sourceStorage->file_put_contents('root/foo', '');
+
+ $storage = new Exclude([
+ 'storage' => $this->sourceStorage,
+ 'exclude' => [
+ 'asd',
+ 'root/bar',
+ 'folder/foo'
+ ]
+ ]);
+
+ $dh = $storage->opendir('root');
+
+ $content = [];
+ while ($file = readdir($dh)) {
+ $content[] = $file;
+ }
+
+ $this->assertEquals(['foo'], $content);
+ }
+}