]> source.dussan.org Git - nextcloud-server.git/commitdiff
Work on post_share hook for files_encryption
authorSam Tuke <samtuke@owncloud.com>
Sat, 9 Feb 2013 18:39:32 +0000 (18:39 +0000)
committerSam Tuke <samtuke@owncloud.com>
Sat, 9 Feb 2013 18:39:32 +0000 (18:39 +0000)
New method in OCP\Share{}:: getUsersSharingFile()
Development shapshot

apps/files_encryption/hooks/hooks.php
apps/files_encryption/lib/keymanager.php
apps/files_encryption/lib/proxy.php
lib/public/share.php

index 8bdeee0937b811b56ef599dae766f002da2887f6..c6d4c16115aa24d2535d6c95f21d2a3b654eac99 100644 (file)
@@ -166,14 +166,77 @@ class Hooks {
         */\r
        public static function postShared( $params ) {\r
                \r
-               // Delete existing catfile\r
-               Keymanager::deleteFileKey(  );\r
+               // NOTE: $params is an array with these keys:\r
+               // itemSource -> int, filecache file ID\r
+               // shareWith -> string, uid of user being shared to\r
+               // fileTarget -> path of file being shared\r
+               // uidOwner -> owner of the original file being shared\r
                \r
-               // Generate new catfile and env keys\r
-               Crypt::multiKeyEncrypt( $plainContent, $publicKeys );\r
+               $view = new \OC_FilesystemView( '/' );\r
+               $userId = \OCP\User::getUser();\r
+               $util = new Util( $view, $userId );\r
+               \r
+               $shares = \OCP\Share::getUsersSharingFile( $params['fileTarget'] );\r
+               \r
+               $userIds = array();\r
+               \r
+               foreach ( $shares as $share ) {\r
+               \r
+                       $util = new Util( $view, $share['userId'] );\r
+                       \r
+                       // Check that the user is encryption capable\r
+                       if ( $util->ready() ) {\r
+               \r
+                               // Construct array of just UIDs for Keymanager{}\r
+                               $userIds[] = $share['userId'];\r
+                       \r
+                       } else {\r
+                       \r
+                               // Log warning; we can't do necessary setup here\r
+                               // because we don't have the user passphrase\r
+                               // TODO: Provide user feedback indicating that\r
+                               // sharing failed\r
+                               \OC_Log::write( 'Encryption library', 'File cannot be shared: user "'.$share['userId'].'" is not setup for encryption', \OC_Log::WARN );\r
+                               \r
+                       }\r
+               \r
+               }\r
+               \r
+               trigger_error("UIDS = ".var_export($userIds, 1));\r
+               \r
+               $userPubKeys = Keymanager::getPublicKeys( $view, $userIds );\r
+               \r
+//             trigger_error("PUB KEYS = ".var_export($userPubKeys, 1));\r
+               \r
+               // TODO: Fetch path from Crypt{} getter\r
+               $plainContent = $view->file_get_contents( $userId . '/' . 'files'. '/' . $params['fileTarget'] );\r
+               \r
+               // Generate new catfile and share keys\r
+               if ( ! $encrypted = Crypt::multiKeyEncrypt( $plainContent, $userPubKeys ) ) {\r
+               \r
+                       // If the re-encryption failed, don't risk deleting data\r
+                       return false;\r
+                       \r
+               }\r
+               \r
+               trigger_error("ENCRYPTED = ". var_export($encrypted, 1));\r
                \r
                // Save env keys to user folders\r
+               foreach ( $encrypted['keys'] as $key ) {\r
+               \r
+//                     Keymanager::setShareKey( $view, $params['fileTarget'], $userId, $key );\r
+               \r
+               }\r
                \r
+               // Delete existing catfile\r
+               // Check if keyfile exists (it won't if file has been shared before)\r
+               // Do this last to ensure file is recoverable in case of error\r
+               if ( $util->isEncryptedPath( $params['fileTarget'] ) ) {\r
+                       \r
+                       // NOTE: This will trigger an error if keyfile isn't found\r
+//                     Keymanager::deleteFileKey( $params['fileTarget'] );\r
+               \r
+               }\r
                \r
        }\r
        \r
index 0d0380db6ec401ff5571600025adbb054fdf3a3f..3160572ba1bab924a718a8dd7b18f86e64bb9c0e 100755 (executable)
-<?php
-
-/**
- * ownCloud
- *
- * @author Bjoern Schiessle
- * @copyright 2012 Bjoern Schiessle <schiessle@owncloud.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library 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 library.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-namespace OCA\Encryption;
-
-/**
- * @brief Class to manage storage and retrieval of encryption keys
- * @note Where a method requires a view object, it's root must be '/'
- */
-class Keymanager {
-               \r
-       /**
-        * @brief retrieve the ENCRYPTED private key from a user
-        * 
-        * @return string private key or false
-        * @note the key returned by this method must be decrypted before use
-        */
-       public static function getPrivateKey( \OC_FilesystemView $view, $user ) {
-       
-               $path =  '/' . $user . '/' . 'files_encryption' . '/' . $user.'.private.key';
-               
-               $key = $view->file_get_contents( $path );
-               
-               return $key;
-       }
-
-       /**
-        * @brief retrieve public key for a specified user
+<?php\r
+\r
+/**\r
+ * ownCloud\r
+ *\r
+ * @author Bjoern Schiessle\r
+ * @copyright 2012 Bjoern Schiessle <schiessle@owncloud.com>\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE\r
+ * License as published by the Free Software Foundation; either\r
+ * version 3 of the License, or any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.\r
+ *\r
+ * You should have received a copy of the GNU Affero General Public\r
+ * License along with this library.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+namespace OCA\Encryption;\r
+\r
+/**\r
+ * @brief Class to manage storage and retrieval of encryption keys\r
+ * @note Where a method requires a view object, it's root must be '/'\r
+ */\r
+class Keymanager {\r
+               \r
+       /**\r
+        * @brief retrieve the ENCRYPTED private key from a user\r
+        * \r
+        * @return string private key or false\r
+        * @note the key returned by this method must be decrypted before use\r
+        */\r
+       public static function getPrivateKey( \OC_FilesystemView $view, $user ) {\r
+       \r
+               $path =  '/' . $user . '/' . 'files_encryption' . '/' . $user.'.private.key';\r
+               \r
+               $key = $view->file_get_contents( $path );\r
+               \r
+               return $key;\r
+       }\r
+\r
+       /**\r
+        * @brief retrieve public key for a specified user\r
         * @param \OC_FilesystemView $view\r
         * @param $userId\r
-        * @return string public key or false
-        */
-       public static function getPublicKey( \OC_FilesystemView $view, $userId ) {
-               
-               return $view->file_get_contents( '/public-keys/' . '/' . $userId . '.public.key' );
-               
-       }
-       
-       /**
-        * @brief retrieve both keys from a user (private and public)
+        * @return string public key or false\r
+        */\r
+       public static function getPublicKey( \OC_FilesystemView $view, $userId ) {\r
+               \r
+               return $view->file_get_contents( '/public-keys/' . '/' . $userId . '.public.key' );\r
+               \r
+       }\r
+       \r
+       /**\r
+        * @brief Retrieve a user's public and private key\r
         * @param \OC_FilesystemView $view\r
         * @param $userId\r
-        * @return array keys: privateKey, publicKey
-        */
-       public static function getUserKeys( \OC_FilesystemView $view, $userId ) {
-       
-               return array(
-                       'publicKey' => self::getPublicKey( $view, $userId )
-                       , 'privateKey' => self::getPrivateKey( $view, $userId )
-               );
-       
-       }
-       
-       /**
-        * @brief Retrieve public keys of all users with access to a file
-        * @param string $path Path to file
-        * @return array of public keys for the given file
-        * @note Checks that the sharing app is enabled should be performed 
-        * by client code, that isn't checked here
-        */
-       public static function getPublicKeys( \OC_FilesystemView $view, $userId, $filePath ) {
-               
-               $path = ltrim( $path, '/' );
-               
-               $filepath = '/' . $userId . '/files/' . $filePath;
-               
-               // Check if sharing is enabled
-               if ( OC_App::isEnabled( 'files_sharing' ) ) {
-                       
-
-               
-               } else {
-               
-                       // check if it is a file owned by the user and not shared at all
-                       $userview = new \OC_FilesystemView( '/'.$userId.'/files/' );
-                       
-                       if ( $userview->file_exists( $path ) ) {
-                       
-                               $users[] = $userId;
-                               
-                       }
-                       
-               }
-               
-               $view = new \OC_FilesystemView( '/public-keys/' );
-               
-               $keylist = array();
-               
-               $count = 0;
-               
-               foreach ( $users as $user ) {
-               
-                       $keylist['key'.++$count] = $view->file_get_contents( $user.'.public.key' );
-                       
-               }
-               
-               return $keylist;
-               
-       }
-       
-       /**
-        * @brief store file encryption key
-        *
-        * @param string $path relative path of the file, including filename
-        * @param string $key
-        * @return bool true/false
-        * @note The keyfile is not encrypted here. Client code must 
-        * asymmetrically encrypt the keyfile before passing it to this method
-        */
-       public static function setFileKey( \OC_FilesystemView $view, $path, $userId, $catfile ) {
-               
-               $basePath = '/' . $userId . '/files_encryption/keyfiles';
-               
-               $targetPath = self::keySetPreparation( $view, $path, $basePath, $userId );
-               
-               if ( $view->is_dir( $basePath . '/' . $targetPath ) ) {
-               
-                       
-               
-               } else {
-
-                       // Save the keyfile in parallel directory
-                       return $view->file_put_contents( $basePath . '/' . $targetPath . '.key', $catfile );
-               
-               }
-               
-       }
-       
-       /**
-        * @brief retrieve keyfile for an encrypted file
+        * @return array keys: privateKey, publicKey\r
+        */\r
+       public static function getUserKeys( \OC_FilesystemView $view, $userId ) {\r
+       \r
+               return array(\r
+                       'publicKey' => self::getPublicKey( $view, $userId )\r
+                       , 'privateKey' => self::getPrivateKey( $view, $userId )\r
+               );\r
+       \r
+       }\r
+       \r
+       /**\r
+        * @brief Retrieve public keys for given users\r
+        * @param \OC_FilesystemView $view\r
+        * @param array $userIds\r
+        * @return array of public keys for the specified users\r
+        */\r
+       public static function getPublicKeys( \OC_FilesystemView $view, $userIds ) {\r
+               \r
+               $i = 0;\r
+               $keys = array();\r
+               \r
+               foreach ( $userIds as $userId ) {\r
+               \r
+                       $i++;\r
+                       $keys[$userId] = self::getPublicKey( $view, $userId );\r
+               \r
+               }\r
+               \r
+               $keys['total'] = $i;\r
+               \r
+               return $keys;\r
+               \r
+       }\r
+       \r
+       /**\r
+        * @brief store file encryption key\r
+        *\r
+        * @param string $path relative path of the file, including filename\r
+        * @param string $key\r
+        * @return bool true/false\r
+        * @note The keyfile is not encrypted here. Client code must \r
+        * asymmetrically encrypt the keyfile before passing it to this method\r
+        */\r
+       public static function setFileKey( \OC_FilesystemView $view, $path, $userId, $catfile ) {\r
+               \r
+               $basePath = '/' . $userId . '/files_encryption/keyfiles';\r
+               \r
+               $targetPath = self::keySetPreparation( $view, $path, $basePath, $userId );\r
+               \r
+               if ( $view->is_dir( $basePath . '/' . $targetPath ) ) {\r
+               \r
+                       \r
+               \r
+               } else {\r
+\r
+                       // Save the keyfile in parallel directory\r
+                       return $view->file_put_contents( $basePath . '/' . $targetPath . '.key', $catfile );\r
+               \r
+               }\r
+               \r
+       }\r
+       \r
+       /**\r
+        * @brief retrieve keyfile for an encrypted file\r
         * @param \OC_FilesystemView $view\r
         * @param $userId\r
         * @param $filePath\r
         * @internal param \OCA\Encryption\file $string name\r
         * @return string file key or false\r
-        * @note The keyfile returned is asymmetrically encrypted. Decryption
-        * of the keyfile must be performed by client code
-        */
-       public static function getFileKey( \OC_FilesystemView $view, $userId, $filePath ) {
-               
-               $filePath_f = ltrim( $filePath, '/' );
-               
-               $catfilePath = '/' . $userId . '/files_encryption/keyfiles/' . $filePath_f . '.key';
-               
-               if ( $view->file_exists( $catfilePath ) ) {
-
-                       return $view->file_get_contents( $catfilePath );
-                       
-               } else {
-               
-                       return false;
-                       
-               }
-               
-       }
-       
-       /**
-        * @brief Delete a keyfile
-        *
+        * @note The keyfile returned is asymmetrically encrypted. Decryption\r
+        * of the keyfile must be performed by client code\r
+        */\r
+       public static function getFileKey( \OC_FilesystemView $view, $userId, $filePath ) {\r
+               \r
+               $filePath_f = ltrim( $filePath, '/' );\r
+               \r
+               $catfilePath = '/' . $userId . '/files_encryption/keyfiles/' . $filePath_f . '.key';\r
+               \r
+               if ( $view->file_exists( $catfilePath ) ) {\r
+\r
+                       return $view->file_get_contents( $catfilePath );\r
+                       \r
+               } else {\r
+               \r
+                       return false;\r
+                       \r
+               }\r
+               \r
+       }\r
+       \r
+       /**\r
+        * @brief Delete a keyfile\r
+        *\r
         * @param OC_FilesystemView $view\r
         * @param string $userId username\r
         * @param string $path path of the file the key belongs to\r
         * @return bool Outcome of unlink operation\r
         * @note $path must be relative to data/user/files. e.g. mydoc.txt NOT\r
         *       /data/admin/files/mydoc.txt\r
-        */
-       public static function deleteFileKey( \OC_FilesystemView $view, $userId, $path ) {
-               
-               $trimmed = ltrim( $path, '/' );
-               $keyPath =  '/' . $userId . '/files_encryption/keyfiles/' . $trimmed . '.key';
-               
-               // Unlink doesn't tell us if file was deleted (not found returns
-               // true), so we perform our own test
-               if ( $view->file_exists( $keyPath ) ) {
-               
-                       return $view->unlink( $keyPath );
-                       
-               } else {
-                       
-                       \OC_Log::write( 'Encryption library', 'Could not delete keyfile; does not exist: "' . $keyPath, \OC_Log::ERROR );
-                       
-                       return false;
-                       
-               }
-               
-       }
-       
-       /**
-        * @brief store private key from the user
-        * @param string key
-        * @return bool
-        * @note Encryption of the private key must be performed by client code
-        * as no encryption takes place here
-        */
-       public static function setPrivateKey( $key ) {
-               
-               $user = \OCP\User::getUser();
-               
-               $view = new \OC_FilesystemView( '/' . $user . '/files_encryption' );
-               
-               \OC_FileProxy::$enabled = false;
-               
-               if ( !$view->file_exists( '' ) ) $view->mkdir( '' );
-               
-               return $view->file_put_contents( $user . '.private.key', $key );
-               
-               \OC_FileProxy::$enabled = true;
-               
-       }
-       
-       /**
-        * @brief store private keys from the user
-        *
-        * @param string privatekey
-        * @param string publickey
-        * @return bool true/false
-        */
-       public static function setUserKeys($privatekey, $publickey) {
-       
-               return ( self::setPrivateKey( $privatekey ) && self::setPublicKey( $publickey ) );
-       
-       }
-       
-       /**
-        * @brief store public key of the user
-        *
-        * @param string key
-        * @return bool true/false
-        */
-       public static function setPublicKey( $key ) {
-               
-               $view = new \OC_FilesystemView( '/public-keys' );
-               
-               \OC_FileProxy::$enabled = false;
-               
-               if ( !$view->file_exists( '' ) ) $view->mkdir( '' );
-               
-               return $view->file_put_contents( \OCP\User::getUser() . '.public.key', $key );
-               
-               \OC_FileProxy::$enabled = true;
-               
-       }
-       
-       /**
+        */\r
+       public static function deleteFileKey( \OC_FilesystemView $view, $userId, $path ) {\r
+               \r
+               $trimmed = ltrim( $path, '/' );\r
+               $keyPath =  '/' . $userId . '/files_encryption/keyfiles/' . $trimmed . '.key';\r
+               \r
+               // Unlink doesn't tell us if file was deleted (not found returns\r
+               // true), so we perform our own test\r
+               if ( $view->file_exists( $keyPath ) ) {\r
+               \r
+                       return $view->unlink( $keyPath );\r
+                       \r
+               } else {\r
+                       \r
+                       \OC_Log::write( 'Encryption library', 'Could not delete keyfile; does not exist: "' . $keyPath, \OC_Log::ERROR );\r
+                       \r
+                       return false;\r
+                       \r
+               }\r
+               \r
+       }\r
+       \r
+       /**\r
+        * @brief store private key from the user\r
+        * @param string key\r
+        * @return bool\r
+        * @note Encryption of the private key must be performed by client code\r
+        * as no encryption takes place here\r
+        */\r
+       public static function setPrivateKey( $key ) {\r
+               \r
+               $user = \OCP\User::getUser();\r
+               \r
+               $view = new \OC_FilesystemView( '/' . $user . '/files_encryption' );\r
+               \r
+               \OC_FileProxy::$enabled = false;\r
+               \r
+               if ( !$view->file_exists( '' ) ) $view->mkdir( '' );\r
+               \r
+               return $view->file_put_contents( $user . '.private.key', $key );\r
+               \r
+               \OC_FileProxy::$enabled = true;\r
+               \r
+       }\r
+       \r
+       /**\r
+        * @brief store private keys from the user\r
+        *\r
+        * @param string privatekey\r
+        * @param string publickey\r
+        * @return bool true/false\r
+        */\r
+       public static function setUserKeys($privatekey, $publickey) {\r
+       \r
+               return ( self::setPrivateKey( $privatekey ) && self::setPublicKey( $publickey ) );\r
+       \r
+       }\r
+       \r
+       /**\r
+        * @brief store public key of the user\r
+        *\r
+        * @param string key\r
+        * @return bool true/false\r
+        */\r
+       public static function setPublicKey( $key ) {\r
+               \r
+               $view = new \OC_FilesystemView( '/public-keys' );\r
+               \r
+               \OC_FileProxy::$enabled = false;\r
+               \r
+               if ( !$view->file_exists( '' ) ) $view->mkdir( '' );\r
+               \r
+               return $view->file_put_contents( \OCP\User::getUser() . '.public.key', $key );\r
+               \r
+               \OC_FileProxy::$enabled = true;\r
+               \r
+       }\r
+       \r
+       /**\r
         * @brief store file encryption key\r
         *\r
         * @param string $path relative path of the file, including filename\r
@@ -271,70 +248,70 @@ class Keymanager {
         * @return bool true/false\r
         * @note The keyfile is not encrypted here. Client code must\r
         * asymmetrically encrypt the keyfile before passing it to this method\r
-        */
-       public static function setShareKey( \OC_FilesystemView $view, $path, $userId, $shareKey ) {
-               
-               $basePath = '/' . $userId . '/files_encryption/share-keys';
-               
-               $shareKeyPath = self::keySetPreparation( $view, $path, $basePath, $userId );
-               
-               return $view->file_put_contents( $basePath . '/' . $shareKeyPath . '.shareKey', $shareKey );
-               
+        */\r
+       public static function setShareKey( \OC_FilesystemView $view, $path, $userId, $shareKey ) {\r
+               \r
+               $basePath = '/' . $userId . '/files_encryption/share-keys';\r
+               \r
+               $shareKeyPath = self::keySetPreparation( $view, $path, $basePath, $userId );\r
+               \r
+               return $view->file_put_contents( $basePath . '/' . $shareKeyPath . '.shareKey', $shareKey );\r
+               \r
        }\r
        \r
        /**\r
         * @brief Make preparations to vars and filesystem for saving a keyfile\r
         */\r
        public static function keySetPreparation( \OC_FilesystemView $view, $path, $basePath, $userId ) {\r
-               
-               $targetPath = ltrim( $path, '/' );
-               
-               $path_parts = pathinfo( $targetPath );
-               
-               // If the file resides within a subdirectory, create it
+               \r
+               $targetPath = ltrim( $path, '/' );\r
+               \r
+               $path_parts = pathinfo( $targetPath );\r
+               \r
+               // If the file resides within a subdirectory, create it\r
                if ( \r
                isset( $path_parts['dirname'] )\r
                && ! $view->file_exists( $basePath . '/' . $path_parts['dirname'] ) \r
-               ) {
-               
-                       $view->mkdir( $basePath . '/' . $path_parts['dirname'] );
-                       
-               }
-               
+               ) {\r
+               \r
+                       $view->mkdir( $basePath . '/' . $path_parts['dirname'] );\r
+                       \r
+               }\r
+               \r
                return $targetPath;\r
        \r
-       }
-       
-       /**
-        * @brief change password of private encryption key
-        *
-        * @param string $oldpasswd old password
-        * @param string $newpasswd new password
-        * @return bool true/false
-        */
-       public static function changePasswd($oldpasswd, $newpasswd) {
-               
-               if ( \OCP\User::checkPassword(\OCP\User::getUser(), $newpasswd) ) {
-                       return Crypt::changekeypasscode($oldpasswd, $newpasswd);
-               }
-               return false;
-               
-       }
-       
-       /**
-        * @brief Fetch the legacy encryption key from user files
-        * @param string $login used to locate the legacy key
-        * @param string $passphrase used to decrypt the legacy key
-        * @return true / false
-        *
-        * if the key is left out, the default handeler will be used
-        */
-       public function getLegacyKey() {
-               
-               $user = \OCP\User::getUser();
-               $view = new \OC_FilesystemView( '/' . $user );
-               return $view->file_get_contents( 'encryption.key' );
-               
-       }
-       
+       }\r
+       \r
+       /**\r
+        * @brief change password of private encryption key\r
+        *\r
+        * @param string $oldpasswd old password\r
+        * @param string $newpasswd new password\r
+        * @return bool true/false\r
+        */\r
+       public static function changePasswd($oldpasswd, $newpasswd) {\r
+               \r
+               if ( \OCP\User::checkPassword(\OCP\User::getUser(), $newpasswd) ) {\r
+                       return Crypt::changekeypasscode($oldpasswd, $newpasswd);\r
+               }\r
+               return false;\r
+               \r
+       }\r
+       \r
+       /**\r
+        * @brief Fetch the legacy encryption key from user files\r
+        * @param string $login used to locate the legacy key\r
+        * @param string $passphrase used to decrypt the legacy key\r
+        * @return true / false\r
+        *\r
+        * if the key is left out, the default handeler will be used\r
+        */\r
+       public function getLegacyKey() {\r
+               \r
+               $user = \OCP\User::getUser();\r
+               $view = new \OC_FilesystemView( '/' . $user );\r
+               return $view->file_get_contents( 'encryption.key' );\r
+               \r
+       }\r
+       \r
 }
\ No newline at end of file
index 7ae36e34ce18a4e7b0a2036d9cb22148393be6d2..58b9bc0725b458a222f1099489440fabd0cdbd9a 100644 (file)
@@ -95,7 +95,8 @@ class Proxy extends \OC_FileProxy {
                
                if ( self::shouldEncrypt( $path ) ) {
                
-                       if ( !is_resource( $data ) ) { //stream put contents should have been converted to fopen
+                       // Stream put contents should have been converted to fopen
+                       if ( !is_resource( $data ) ) {
                        
                                $userId = \OCP\USER::getUser();
                                
@@ -107,10 +108,33 @@ class Proxy extends \OC_FileProxy {
                                // Disable encryption proxy to prevent recursive calls
                                \OC_FileProxy::$enabled = false;
                                
-                               // TODO: Check if file is shared, if so, use multiKeyEncrypt
+                               $fileOwner = \OC\Files\Filesystem::getOwner( $path );
                                
-                               // Encrypt plain data and fetch key
-                               $encrypted = Crypt::keyEncryptKeyfile( $data, Keymanager::getPublicKey( $rootView, $userId ) );
+                               // Check if the keyfile needs to be shared
+                               if ( 
+                                       $fileOwner !== true
+                                       or $fileOwner !== $userId 
+                               ) {
+                                       
+                                       // Shared storage backend isn't loaded
+                                       
+                                       $users = \OCP\Share::getItemShared( 'file', $path, \OC_Share_backend_File::FORMAT_SHARED_STORAGE );
+//                                     
+                                       trigger_error("SHARE USERS = ". var_export($users, 1));
+//                                     
+//                                     $publicKeys = Keymanager::getPublicKeys( $rootView, $users);
+//                                     
+//                                     // Encrypt plain data to multiple users
+//                                     $encrypted = Crypt::multiKeyEncrypt( $data, $publicKeys );
+                               
+                               } else {
+                               
+                                       $publicKey = Keymanager::getPublicKey( $rootView, $userId );
+                               
+                                       // Encrypt plain data to a single user
+                                       $encrypted = Crypt::keyEncryptKeyfile( $data, $publicKey );
+                               
+                               }
                                
                                // Replace plain content with encrypted content by reference
                                $data = $encrypted['data'];
index af2a538e252d034aa837cba6b8c5ddbd09a7a58f..936f85021c00026e9e9535f74ffdd7d932905b42 100644 (file)
@@ -91,6 +91,60 @@ class Share {
                }
                return false;
        }
+       
+       /**
+       * @brief Find which users can access a shared item
+       * @param string Item type
+       * @param int Format (optional) Format type must be defined by the backend
+       * @param int Number of items to return (optional) Returns all by default
+       * @return Return depends on format
+       */
+       public static function getUsersSharingFile( $path ) {
+               
+               // Fetch all shares of this file path from DB
+               $query = \OC_DB::prepare( 
+                       'SELECT 
+                               share_type
+                               , share_with
+                               , permissions
+                       FROM 
+                               `*PREFIX*share` 
+                       WHERE 
+                               file_target = ?'
+                       );
+                       
+               $result = $query->execute( array( $path ) );
+               
+               if ( \OC_DB::isError( $result ) ) {
+               
+                       \OC_Log::write( 'OCP\Share', \OC_DB::getErrorMessage($result) . ', path=' . $path, \OC_Log::ERROR );
+               
+               }
+               
+               $shares = array();
+               
+               while( $row = $result->fetchRow() ) {
+               
+                       // Set helpful array keys
+                       $shares[] = array( 
+                               'userId' => $row['share_with']
+                               , 'shareType' => $row['share_type']
+                               , 'permissions' => $row['permissions']
+                       );
+                       
+               }
+               
+               if ( ! empty( $shares ) ) {
+               
+                       return $shares;
+                       
+               } else {
+               
+                       return false;
+                       
+               }
+       
+       }
 
        /**
        * @brief Get the items of item type shared with the current user