]> source.dussan.org Git - nextcloud-server.git/commitdiff
create backup from all keys before recovery
authorBjoern Schiessle <schiessle@owncloud.com>
Tue, 16 Sep 2014 13:16:27 +0000 (15:16 +0200)
committerBjoern Schiessle <schiessle@owncloud.com>
Mon, 22 Sep 2014 07:53:40 +0000 (09:53 +0200)
apps/files_encryption/hooks/hooks.php
apps/files_encryption/lib/util.php
apps/files_encryption/tests/util.php

index 8666e482d567863e0dcd7e8492d894a462008ac6..894ad3116168ec5157c3bbeabd85514909717d42 100644 (file)
@@ -228,6 +228,9 @@ class Hooks {
                                                || !$util->userKeysExists()\r
                                                || !$view->file_exists($user . '/files')) {\r
 \r
+                                       // backup old keys\r
+                                       $util->backupAllKeys('recovery');\r
+\r
                                        $newUserPassword = $params['password'];\r
 \r
                                        // make sure that the users home is mounted\r
index 22649fd770de737917c5bbea89ba24bd7b65c256..5b31d765fbad83a101adb929180cccd6da7262c6 100644 (file)
@@ -1770,6 +1770,50 @@ class Util {
        /**
         * @brief check if the file is stored on a system wide mount point
         * @param $path relative to /data/user with leading '/'
+        * create a backup of all keys from the user
+        *
+        * @param string $purpose (optional) define the purpose of the backup, will be part of the backup folder
+        */
+       public function backupAllKeys($purpose = '') {
+               \OC_FileProxy::$enabled = false;
+
+               $backupDir = $this->encryptionDir . '/backup.';
+               $backupDir .= ($purpose === '') ? date("Y-m-d_H-i-s") . '/' : $purpose . '.' . date("Y-m-d_H-i-s") . '/';
+               $this->view->mkdir($backupDir);
+               $this->copyRecursive($this->shareKeysPath, $backupDir . 'share-keys/');
+               $this->copyRecursive($this->keyfilesPath, $backupDir . 'keyfiles/');
+               $this->view->copy($this->privateKeyPath, $backupDir . $this->userId . '.private.key');
+               $this->view->copy($this->publicKeyPath, $backupDir . $this->userId . '.public.key');
+
+               \OC_FileProxy::$enabled = true;
+       }
+
+       /**
+        * helper method to copy a folder recursively, only needed in OC6.
+        * OC7 filesystem and newer can copy folder structures
+        *
+        * @param string $source
+        * @param string $target
+        */
+       private function copyRecursive($source, $target) {
+               if ($this->view->is_dir($source)) {
+                       $this->view->mkdir($target);
+                       $dir = $this->view->opendir($source);
+                       while ($file = readdir($dir)) {
+                               if(!\OC\Files\Filesystem::isIgnoredDir($file)) {
+                                       $this->copyRecursive($source . '/' . $file, $target . '/' . $file);
+                               }
+                       }
+                       closedir($dir);
+               } else {
+                       $this->view->copy($source, $target);
+               }
+       }
+
+
+       /**
+        * check if the file is stored on a system wide mount point
+        * @param string $path relative to /data/user with leading '/'
         * @return boolean
         */
        public function isSystemWideMountPoint($path) {
index c93e99fb07687eb5fba336560e098283ad5de697..2f371719803a6154379add3d431ce4bf3274fc6d 100755 (executable)
@@ -396,6 +396,56 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
 
        }
 
+       /**
+        * test if all keys get moved to the backup folder correctly
+        */
+       function testBackupAllKeys() {
+               self::loginHelper(self::TEST_ENCRYPTION_UTIL_USER1);
+
+               // create some dummy key files
+               $encPath = '/' . self::TEST_ENCRYPTION_UTIL_USER1 . '/files_encryption';
+               $this->view->file_put_contents($encPath . '/keyfiles/foo.key', 'key');
+               $this->view->file_put_contents($encPath . '/share-keys/foo.user1.shareKey', 'share key');
+               $this->view->mkdir($encPath . '/keyfiles/subfolder/');
+               $this->view->mkdir($encPath . '/share-keys/subfolder/');
+               $this->view->file_put_contents($encPath . '/keyfiles/subfolder/foo.key', 'key');
+               $this->view->file_put_contents($encPath . '/share-keys/subfolder/foo.user1.shareKey', 'share key');
+
+
+               $util = new \OCA\Encryption\Util($this->view, self::TEST_ENCRYPTION_UTIL_USER1);
+
+               $util->backupAllKeys('testing');
+
+               $encFolderContent = $this->view->getDirectoryContent($encPath);
+
+               $backupPath = '';
+               foreach ($encFolderContent as $c) {
+                       $name = $c['name'];
+                       if (substr($name, 0, strlen('backup'))  === 'backup') {
+                               $backupPath = $encPath . '/'. $c['name'];
+                               break;
+                       }
+               }
+
+               $this->assertTrue($backupPath !== '');
+
+               // check backupDir Content
+               $this->assertTrue($this->view->is_dir($backupPath . '/keyfiles'));
+               $this->assertTrue($this->view->is_dir($backupPath . '/share-keys'));
+               $this->assertTrue($this->view->file_exists($backupPath . '/keyfiles/foo.key'));
+               $this->assertTrue($this->view->file_exists($backupPath . '/share-keys/foo.user1.shareKey'));
+               $this->assertTrue($this->view->file_exists($backupPath . '/keyfiles/subfolder/foo.key'));
+               $this->assertTrue($this->view->file_exists($backupPath . '/share-keys/subfolder/foo.user1.shareKey'));
+               $this->assertTrue($this->view->file_exists($backupPath . '/' . self::TEST_ENCRYPTION_UTIL_USER1 . '.private.key'));
+               $this->assertTrue($this->view->file_exists($backupPath . '/' . self::TEST_ENCRYPTION_UTIL_USER1 . '.public.key'));
+
+               //cleanup
+               $this->view->deleteAll($backupPath);
+               $this->view->unlink($encPath . '/keyfiles/foo.key', 'key');
+               $this->view->unlink($encPath . '/share-keys/foo.user1.shareKey', 'share key');
+       }
+
+
        function testDescryptAllWithBrokenFiles() {
 
                $file1 = "/decryptAll1" . uniqid() . ".txt";