[Pkg-owncloud-commits] [php-sabredav] 20/31: Unlocking nodes after they have been deleted.

David Prévot taffit at moszumanska.debian.org
Wed Aug 27 22:33:06 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository php-sabredav.

commit 3046aa4374d071e9028e0c25f7d5396b8daf276f
Author: Evert Pot <me at evertpot.com>
Date:   Mon Aug 18 17:26:39 2014 -0400

    Unlocking nodes after they have been deleted.
    
    Fixes #487.
---
 ChangeLog.md                                       |  1 +
 lib/DAV/Locks/Backend/File.php                     |  9 +--
 lib/DAV/Locks/Plugin.php                           | 18 ++++++
 .../Sabre/DAV/Locks/Backend/Mock.php               | 59 +++---------------
 tests/Sabre/DAV/Locks/Plugin2Test.php              | 69 ++++++++++++++++++++++
 tests/Sabre/DAVServerTest.php                      | 16 +++++
 6 files changed, 116 insertions(+), 56 deletions(-)

diff --git a/ChangeLog.md b/ChangeLog.md
index ff76b29..08781d7 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -5,6 +5,7 @@ ChangeLog
 ------------------
 
 * #483: typo in calendars creation for PostgreSQL.
+* #487: Locks are now automatically removed after a node has been deleted.
 
 2.0.3 (2014-07-14)
 ------------------
diff --git a/lib/DAV/Locks/Backend/File.php b/lib/DAV/Locks/Backend/File.php
index f87488e..17c40b8 100644
--- a/lib/DAV/Locks/Backend/File.php
+++ b/lib/DAV/Locks/Backend/File.php
@@ -5,12 +5,13 @@ namespace Sabre\DAV\Locks\Backend;
 use Sabre\DAV\Locks\LockInfo;
 
 /**
- * The Lock manager allows you to handle all file-locks centrally.
+ * This Locks backend stores all locking information in a single file.
  *
- * This Lock Manager stores all its data in a single file.
+ * Note that this is not nearly as robust as a database. If you are considering
+ * using this backend, keep in mind that the PDO backend can work with SqLite,
+ * which is designed to be a good file-based database.
  *
- * Note that this is not nearly as robust as a database, you are encouraged
- * to use the PDO backend instead.
+ * It literally solves the problem this class solves as well, but much better.
  *
  * @copyright Copyright (C) 2007-2014 fruux GmbH (https://fruux.com/).
  * @author Evert Pot (http://evertpot.com/)
diff --git a/lib/DAV/Locks/Plugin.php b/lib/DAV/Locks/Plugin.php
index 7ff5d4b..a745098 100644
--- a/lib/DAV/Locks/Plugin.php
+++ b/lib/DAV/Locks/Plugin.php
@@ -63,6 +63,7 @@ class Plugin extends DAV\ServerPlugin {
         $server->on('method:UNLOCK',  [$this, 'httpUnlock']);
         $server->on('validateTokens', [$this, 'validateTokens']);
         $server->on('propFind',       [$this, 'propFind']);
+        $server->on('afterUnbind',    [$this, 'afterUnbind']);
 
     }
 
@@ -315,6 +316,23 @@ class Plugin extends DAV\ServerPlugin {
     }
 
     /**
+     * This method is called after a node is deleted.
+     *
+     * We use this event to clean up any locks that still exist on the node.
+     *
+     * @param string $path
+     * @return void
+     */
+    public function afterUnbind($path) {
+
+        $locks = $this->getLocks($path, $includeChildren = true);
+        foreach($locks as $lock) {
+            $this->unlockNode($path, $lock);
+        }
+
+    }
+
+    /**
      * Locks a uri
      *
      * All the locking information is supplied in the lockInfo object. The object has a suggested timeout, but this can be safely ignored
diff --git a/lib/DAV/Locks/Backend/File.php b/tests/Sabre/DAV/Locks/Backend/Mock.php
similarity index 66%
copy from lib/DAV/Locks/Backend/File.php
copy to tests/Sabre/DAV/Locks/Backend/Mock.php
index f87488e..fbdc6f1 100644
--- a/lib/DAV/Locks/Backend/File.php
+++ b/tests/Sabre/DAV/Locks/Backend/Mock.php
@@ -5,36 +5,15 @@ namespace Sabre\DAV\Locks\Backend;
 use Sabre\DAV\Locks\LockInfo;
 
 /**
- * The Lock manager allows you to handle all file-locks centrally.
+ * Locks Mock backend.
  *
- * This Lock Manager stores all its data in a single file.
- *
- * Note that this is not nearly as robust as a database, you are encouraged
- * to use the PDO backend instead.
+ * This backend stores lock information in memory. Mainly useful for testing.
  *
  * @copyright Copyright (C) 2007-2014 fruux GmbH (https://fruux.com/).
  * @author Evert Pot (http://evertpot.com/)
  * @license http://sabre.io/license/ Modified BSD License
  */
-class File extends AbstractBackend {
-
-    /**
-     * The storage file
-     *
-     * @var string
-     */
-    private $locksFile;
-
-    /**
-     * Constructor
-     *
-     * @param string $locksFile path to file
-     */
-    public function __construct($locksFile) {
-
-        $this->locksFile = $locksFile;
-
-    }
+class Mock extends AbstractBackend {
 
     /**
      * Returns a list of Sabre\DAV\Locks\LockInfo objects
@@ -132,6 +111,8 @@ class File extends AbstractBackend {
 
     }
 
+    protected $data = [];
+
     /**
      * Loads the lockdata from the filesystem.
      *
@@ -139,23 +120,7 @@ class File extends AbstractBackend {
      */
     protected function getData() {
 
-        if (!file_exists($this->locksFile)) return array();
-
-        // opening up the file, and creating a shared lock
-        $handle = fopen($this->locksFile,'r');
-        flock($handle,LOCK_SH);
-
-        // Reading data until the eof
-        $data = stream_get_contents($handle);
-
-        // We're all good
-        flock($handle,LOCK_UN);
-        fclose($handle);
-
-        // Unserializing and checking if the resource file contains data for this file
-        $data = unserialize($data);
-        if (!$data) return array();
-        return $data;
+        return $this->data;
 
     }
 
@@ -167,17 +132,7 @@ class File extends AbstractBackend {
      */
     protected function putData(array $newData) {
 
-        // opening up the file, and creating an exclusive lock
-        $handle = fopen($this->locksFile,'a+');
-        flock($handle,LOCK_EX);
-
-        // We can only truncate and rewind once the lock is acquired.
-        ftruncate($handle,0);
-        rewind($handle);
-
-        fwrite($handle,serialize($newData));
-        flock($handle,LOCK_UN);
-        fclose($handle);
+        $this->data = $newData;
 
     }
 
diff --git a/tests/Sabre/DAV/Locks/Plugin2Test.php b/tests/Sabre/DAV/Locks/Plugin2Test.php
new file mode 100644
index 0000000..7af4907
--- /dev/null
+++ b/tests/Sabre/DAV/Locks/Plugin2Test.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace Sabre\DAV\Locks;
+
+use Sabre\HTTP\Request;
+
+class Plugin2Test extends \Sabre\DAVServerTest {
+
+    public $setupLocks = true;
+
+    function setUpTree() {
+
+        $this->tree = new \Sabre\DAV\FS\Directory(SABRE_TEMPDIR);
+
+    }
+
+    function tearDown() {
+
+        \Sabre\TestUtil::clearTempDir();
+
+    }
+
+    /**
+     * This test first creates a file with LOCK and then deletes it.
+     *
+     * After deleting the file, the lock should no longer be in the lock
+     * backend.
+     *
+     * Reported in ticket #487
+     */
+    function testUnlockAfterDelete() {
+
+        $body = '<?xml version="1.0"?>
+<D:lockinfo xmlns:D="DAV:">
+    <D:lockscope><D:exclusive/></D:lockscope>
+    <D:locktype><D:write/></D:locktype>
+</D:lockinfo>';
+
+        $request = new Request(
+            'LOCK',
+            '/file.txt',
+            [],
+            $body
+        );
+        $response = $this->request($request);
+        $this->assertEquals(201, $response->getStatus(), $response->getBodyAsString());
+
+        $this->assertEquals(
+            1,
+            count($this->locksBackend->getLocks('file.txt', true))
+        );
+
+        $request = new Request(
+            'DELETE',
+            '/file.txt',
+            [
+                'If' => '(' . $response->getHeader('Lock-Token') . ')',
+            ]
+        );
+        $response = $this->request($request);
+        $this->assertEquals(204, $response->getStatus(), $response->getBodyAsString());
+
+        $this->assertEquals(
+            0,
+            count($this->locksBackend->getLocks('file.txt', true))
+        );
+    }
+
+}
diff --git a/tests/Sabre/DAVServerTest.php b/tests/Sabre/DAVServerTest.php
index 9fcc773..6cf9530 100644
--- a/tests/Sabre/DAVServerTest.php
+++ b/tests/Sabre/DAVServerTest.php
@@ -24,6 +24,7 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
     protected $setupACL = false;
     protected $setupCalDAVSharing = false;
     protected $setupCalDAVSubscriptions = false;
+    protected $setupLocks = false;
 
     protected $caldavCalendars = array();
     protected $caldavCalendarObjects = array();
@@ -40,6 +41,7 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
     protected $caldavBackend;
     protected $carddavBackend;
     protected $principalBackend;
+    protected $locksBackend;
 
     /**
      * @var Sabre\CalDAV\Plugin
@@ -67,6 +69,11 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
     protected $authPlugin;
 
     /**
+     * @var Sabre\DAV\Locks\Plugin
+     */
+    protected $locksPlugin;
+
+    /**
      * If this string is set, we will automatically log in the user with this
      * name.
      */
@@ -100,6 +107,12 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
             $this->aclPlugin = new DAVACL\Plugin();
             $this->server->addPlugin($this->aclPlugin);
         }
+        if ($this->setupLocks) {
+            $this->locksPlugin = new DAV\Locks\Plugin(
+                $this->locksBackend
+            );
+            $this->server->addPlugin($this->locksPlugin);
+        }
         if ($this->autoLogin) {
             $authBackend = new DAV\Auth\Backend\Mock();
             $authBackend->defaultUser = $this->autoLogin;
@@ -174,6 +187,9 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
         if ($this->setupCardDAV || $this->setupCalDAV) {
             $this->principalBackend = new DAVACL\PrincipalBackend\Mock();
         }
+        if ($this->setupLocks) {
+            $this->locksBackend = new DAV\Locks\Backend\Mock();
+        }
 
     }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/php-sabredav.git



More information about the Pkg-owncloud-commits mailing list