diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 4ec810a519..6f630c83a3 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -317,7 +317,7 @@ class Proxy extends \OC_FileProxy { public function postGetFileInfo($path, $data) { // if path is a folder do nothing - if (is_array($data) && array_key_exists('size', $data)) { + if (\OCP\App::isEnabled('files_encryption') && is_array($data) && array_key_exists('size', $data)) { // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php index 895d446a33..ffdcbf0510 100644 --- a/apps/files_sharing/appinfo/app.php +++ b/apps/files_sharing/appinfo/app.php @@ -7,6 +7,7 @@ OC::$CLASSPATH['OC\Files\Cache\Shared_Cache'] = 'files_sharing/lib/cache.php'; OC::$CLASSPATH['OC\Files\Cache\Shared_Permissions'] = 'files_sharing/lib/permissions.php'; OC::$CLASSPATH['OC\Files\Cache\Shared_Updater'] = 'files_sharing/lib/updater.php'; OC::$CLASSPATH['OC\Files\Cache\Shared_Watcher'] = 'files_sharing/lib/watcher.php'; +OC::$CLASSPATH['OCA\Files\Share\Api'] = 'files_sharing/lib/api.php'; OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup'); OCP\Share::registerBackend('file', 'OC_Share_Backend_File'); OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file'); diff --git a/apps/files_sharing/appinfo/routes.php b/apps/files_sharing/appinfo/routes.php index 02815b5eb4..3469829b6f 100644 --- a/apps/files_sharing/appinfo/routes.php +++ b/apps/files_sharing/appinfo/routes.php @@ -2,4 +2,33 @@ $this->create('core_ajax_public_preview', '/publicpreview.png')->action( function() { require_once __DIR__ . '/../ajax/publicpreview.php'; -}); \ No newline at end of file +}); + +// OCS API + +//TODO: SET: mail notification, waiting for PR #4689 to be accepted + +OC_API::register('get', + '/apps/files_sharing/api/v1/shares', + array('\OCA\Files\Share\Api', 'getAllShares'), + 'files_sharing'); + +OC_API::register('post', + '/apps/files_sharing/api/v1/shares', + array('\OCA\Files\Share\Api', 'createShare'), + 'files_sharing'); + +OC_API::register('get', + '/apps/files_sharing/api/v1/shares/{id}', + array('\OCA\Files\Share\Api', 'getShare'), + 'files_sharing'); + +OC_API::register('put', + '/apps/files_sharing/api/v1/shares/{id}', + array('\OCA\Files\Share\Api', 'updateShare'), + 'files_sharing'); + +OC_API::register('delete', + '/apps/files_sharing/api/v1/shares/{id}', + array('\OCA\Files\Share\Api', 'deleteShare'), + 'files_sharing'); diff --git a/apps/files_sharing/lib/api.php b/apps/files_sharing/lib/api.php new file mode 100644 index 0000000000..e662462489 --- /dev/null +++ b/apps/files_sharing/lib/api.php @@ -0,0 +1,467 @@ +. + * + */ + +namespace OCA\Files\Share; + +class Api { + + /** + * @brief get all shares + * + * @param array $params option 'file' to limit the result to a specific file/folder + * @return \OC_OCS_Result share information + */ + public static function getAllShares($params) { + + // if a file is specified, get the share for this file + if (isset($_GET['path'])) { + $params['itemSource'] = self::getFileId($_GET['path']); + $params['path'] = $_GET['path']; + if (isset($_GET['subfiles']) && $_GET['subfiles'] === 'true') { + return self::getSharesFromFolder($params); + } + return self::getShare($params); + } + + $share = \OCP\Share::getItemShared('file', null); + + if ($share === false) { + return new \OC_OCS_Result(null, 404, 'could not get shares'); + } else { + return new \OC_OCS_Result($share); + } + + } + + /** + * @brief get share information for a given share + * + * @param array $params which contains a 'id' + * @return \OC_OCS_Result share information + */ + public static function getShare($params) { + + // either the $params already contains a itemSource if we come from + // getAllShare() or we need to translate the shareID to a itemSource + if(isset($params['itemSource'])) { + $itemSource = $params['itemSource']; + $getSpecificShare = true; + } else { + $s = self::getShareFromId($params['id']); + $itemSource = $s['item_source']; + $getSpecificShare = false; + } + + if ($itemSource !== null) { + $shares = \OCP\Share::getItemShared('file', $itemSource); + // if a specific share was specified only return this one + if ($getSpecificShare === false) { + foreach ($shares as $share) { + if ($share['id'] === (int)$params['id']) { + $shares = array('element' => $share); + break; + } + } + } + } else { + $shares = null; + } + + if ($shares === null || empty($shares)) { + return new \OC_OCS_Result(null, 404, 'share doesn\'t exist'); + } else { + return new \OC_OCS_Result($shares); + } + } + + /** + * @brief get share from all files in a given folder (non-recursive) + * @param array $params contains 'path' to the folder + * @return \OC_OCS_Result + */ + private static function getSharesFromFolder($params) { + $path = $params['path']; + $view = new \OC\Files\View('/'.\OCP\User::getUser().'/files'); + + if(!$view->is_dir($path)) { + return new \OC_OCS_Result(null, 404, "not a directory"); + } + + $content = $view->getDirectoryContent($path); + + $result = array(); + foreach ($content as $file) { + $share = \OCP\Share::getItemShared('file', $file['fileid']); + if ($share) { + $share['filename'] = $file['name']; + $result[] = $share; + } + } + + return new \OC_OCS_Result($result); + } + + /** + * @breif create a new share + * @param array $params + * @return \OC_OCS_Result + */ + public static function createShare($params) { + + $path = isset($_POST['path']) ? $_POST['path'] : null; + + if($path === null) { + return new \OC_OCS_Result(null, 400, "please specify a file or folder path"); + } + + $itemSource = self::getFileId($path); + $itemType = self::getItemType($path); + + if($itemSource === null) { + return new \OC_OCS_Result(null, 404, "wrong path, file/folder doesn't exist."); + } + + $shareWith = isset($_POST['shareWith']) ? $_POST['shareWith'] : null; + $shareType = isset($_POST['shareType']) ? (int)$_POST['shareType'] : null; + + switch($shareType) { + case \OCP\Share::SHARE_TYPE_USER: + $permissions = isset($_POST['permissions']) ? (int)$_POST['permissions'] : 31; + break; + case \OCP\Share::SHARE_TYPE_GROUP: + $permissions = isset($_POST['permissions']) ? (int)$_POST['permissions'] : 31; + break; + case \OCP\Share::SHARE_TYPE_LINK: + //allow password protection + $shareWith = isset($_POST['password']) ? $_POST['password'] : null; + //check public link share + $publicUploadEnabled = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); + $encryptionEnabled = \OC_App::isEnabled('files_encryption'); + if(isset($_POST['publicUpload']) && + ($encryptionEnabled || $publicUploadEnabled !== 'yes')) { + return new \OC_OCS_Result(null, 404, "public upload disabled by the administrator"); + } + $publicUpload = isset($_POST['publicUpload']) ? $_POST['publicUpload'] : 'false'; + // read, create, update (7) if public upload is enabled or + // read (1) if public upload is disabled + $permissions = $publicUpload === 'true' ? 7 : 1; + break; + default: + return new \OC_OCS_Result(null, 404, "unknown share type"); + } + + try { + $token = \OCP\Share::shareItem( + $itemType, + $itemSource, + $shareType, + $shareWith, + $permissions + ); + } catch (\Exception $e) { + return new \OC_OCS_Result(null, 404, $e->getMessage()); + } + + if ($token) { + $data = array(); + $data['id'] = 'unknown'; + $shares = \OCP\Share::getItemShared('file', $itemSource); + if(is_string($token)) { //public link share + foreach ($shares as $share) { + if ($share['token'] === $token) { + $data['id'] = $share['id']; + break; + } + } + $url = \OCP\Util::linkToPublic('files&t='.$token); + $data['url'] = $url; // '&' gets encoded to $amp; + $data['token'] = $token; + + } else { + foreach ($shares as $share) { + if ($share['share_with'] === $shareWith && $share['share_type'] === $shareType) { + $data['id'] = $share['id']; + break; + } + } + } + return new \OC_OCS_Result($data); + } else { + return new \OC_OCS_Result(null, 404, "couldn't share file"); + } + } + + /** + * update shares, e.g. password, permissions, etc + * @param array $params shareId 'id' and the parameter we want to update + * currently supported: permissions, password, publicUpload + * @return \OC_OCS_Result + */ + public static function updateShare($params) { + + $share = self::getShareFromId($params['id']); + $itemSource = isset($share['item_source']) ? $share['item_source'] : null; + + if($itemSource === null) { + return new \OC_OCS_Result(null, 404, "wrong share Id, share doesn't exist."); + } + + try { + if(isset($params['_put']['permissions'])) { + return self::updatePermissions($share, $params); + } elseif (isset($params['_put']['password'])) { + return self::updatePassword($share, $params); + } elseif (isset($params['_put']['publicUpload'])) { + return self::updatePublicUpload($share, $params); + } + } catch (\Exception $e) { + return new \OC_OCS_Result(null, 400, $e->getMessage()); + } + + return new \OC_OCS_Result(null, 400, "Wrong or no update parameter given"); + + } + + /** + * @brief update permissions for a share + * @param array $share information about the share + * @param array $params contains 'permissions' + * @return \OC_OCS_Result + */ + private static function updatePermissions($share, $params) { + + $itemSource = $share['item_source']; + $itemType = $share['item_type']; + $shareWith = $share['share_with']; + $shareType = $share['share_type']; + $permissions = isset($params['_put']['permissions']) ? (int)$params['_put']['permissions'] : null; + + $publicUploadStatus = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); + $encryptionEnabled = \OC_App::isEnabled('files_encryption'); + $publicUploadEnabled = false; + if(!$encryptionEnabled && $publicUploadStatus === 'yes') { + $publicUploadEnabled = true; + } + + // only change permissions for public shares if public upload is enabled + // and we want to set permissions to 1 (read only) or 7 (allow upload) + if ( (int)$shareType === \OCP\Share::SHARE_TYPE_LINK ) { + if ($publicUploadEnabled === false || ($permissions !== 7 && $permissions !== 1)) { + return new \OC_OCS_Result(null, 400, "can't change permission for public link share"); + } + } + + try { + $return = \OCP\Share::setPermissions( + $itemType, + $itemSource, + $shareType, + $shareWith, + $permissions + ); + } catch (\Exception $e) { + return new \OC_OCS_Result(null, 404, $e->getMessage()); + } + + if ($return) { + return new \OC_OCS_Result(); + } else { + return new \OC_OCS_Result(null, 404, "couldn't set permissions"); + } + } + + /** + * @brief enable/disable public upload + * @param array $share information about the share + * @param array $params contains 'publicUpload' which can be 'yes' or 'no' + * @return \OC_OCS_Result + */ + private static function updatePublicUpload($share, $params) { + + $publicUploadEnabled = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); + $encryptionEnabled = \OC_App::isEnabled('files_encryption'); + if($encryptionEnabled || $publicUploadEnabled !== 'yes') { + return new \OC_OCS_Result(null, 404, "public upload disabled by the administrator"); + } + + if ($share['item_type'] !== 'folder' || + (int)$share['share_type'] !== \OCP\Share::SHARE_TYPE_LINK ) { + return new \OC_OCS_Result(null, 404, "public upload is only possible for public shared folders"); + } + + // read, create, update (7) if public upload is enabled or + // read (1) if public upload is disabled + $params['_put']['permissions'] = $params['_put']['publicUpload'] === 'true' ? 7 : 1; + + return self::updatePermissions($share, $params); + + } + + /** + * @brief update password for public link share + * @param array $share information about the share + * @param type $params 'password' + * @return \OC_OCS_Result + */ + private static function updatePassword($share, $params) { + + $itemSource = $share['item_source']; + $itemType = $share['item_type']; + + if( (int)$share['share_type'] !== \OCP\Share::SHARE_TYPE_LINK) { + return new \OC_OCS_Result(null, 400, "password protection is only supported for public shares"); + } + + $shareWith = isset($params['_put']['password']) ? $params['_put']['password'] : null; + + if($shareWith === '') { + $shareWith = null; + } + + $items = \OCP\Share::getItemShared($itemType, $itemSource); + + $checkExists = false; + foreach ($items as $item) { + if($item['share_type'] === \OCP\Share::SHARE_TYPE_LINK) { + $checkExists = true; + $permissions = $item['permissions']; + } + } + + if (!$checkExists) { + return new \OC_OCS_Result(null, 404, "share doesn't exists, can't change password"); + } + + $result = \OCP\Share::shareItem( + $itemType, + $itemSource, + \OCP\Share::SHARE_TYPE_LINK, + $shareWith, + $permissions + ); + if($result) { + return new \OC_OCS_Result(); + } + + return new \OC_OCS_Result(null, 404, "couldn't set password"); + } + + /** + * @brief unshare a file/folder + * @param array $params contains the shareID 'id' which should be unshared + * @return \OC_OCS_Result + */ + public static function deleteShare($params) { + + $share = self::getShareFromId($params['id']); + $itemSource = isset($share['item_source']) ? $share['item_source'] : null; + $itemType = isset($share['item_type']) ? $share['item_type'] : null;; + + if($itemSource === null) { + return new \OC_OCS_Result(null, 404, "wrong share ID, share doesn't exist."); + } + + $shareWith = isset($share['share_with']) ? $share['share_with'] : null; + $shareType = isset($share['share_type']) ? (int)$share['share_type'] : null; + + if( $shareType === \OCP\Share::SHARE_TYPE_LINK) { + $shareWith = null; + } + + try { + $return = \OCP\Share::unshare( + $itemType, + $itemSource, + $shareType, + $shareWith); + } catch (\Exception $e) { + return new \OC_OCS_Result(null, 404, $e->getMessage()); + } + + if ($return) { + return new \OC_OCS_Result(); + } else { + $msg = "Unshare Failed"; + return new \OC_OCS_Result(null, 404, $msg); + } + } + + /** + * @brief get file ID from a given path + * @param string $path + * @return string fileID or null + */ + private static function getFileId($path) { + + $view = new \OC\Files\View('/'.\OCP\User::getUser().'/files'); + $fileId = null; + + $fileInfo = $view->getFileInfo($path); + if ($fileInfo) { + $fileId = $fileInfo['fileid']; + } + + return $fileId; + } + + /** + * @brief get itemType + * @param string $path + * @return string type 'file', 'folder' or null of file/folder doesn't exists + */ + private static function getItemType($path) { + $view = new \OC\Files\View('/'.\OCP\User::getUser().'/files'); + $itemType = null; + + if ($view->is_dir($path)) { + $itemType = "folder"; + } elseif ($view->is_file($path)) { + $itemType = "file"; + } + + return $itemType; + } + + /** + * @brief get some information from a given share + * @param int $shareID + * @return array with: item_source, share_type, share_with, item_type, permissions + */ + private static function getShareFromId($shareID) { + $sql = 'SELECT `item_source`, `share_type`, `share_with`, `item_type`, `permissions` FROM `*PREFIX*share` WHERE `id` = ?'; + $args = array($shareID); + $query = \OCP\DB::prepare($sql); + $result = $query->execute($args); + + if (\OCP\DB::isError($result)) { + \OCP\Util::writeLog('files_sharing', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); + return null; + } + if ($share = $result->fetchRow()) { + return $share; + } + + return null; + + } + +} diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php new file mode 100644 index 0000000000..c55c186f08 --- /dev/null +++ b/apps/files_sharing/tests/api.php @@ -0,0 +1,537 @@ + + * + * 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 . + * + */ + +require_once __DIR__ . '/../../../lib/base.php'; + +use OCA\Files\Share; + +/** + * Class Test_Files_Sharing_Api + */ +class Test_Files_Sharing_Api extends \PHPUnit_Framework_TestCase { + + const TEST_FILES_SHARING_API_USER1 = "test-share-user1"; + const TEST_FILES_SHARING_API_USER2 = "test-share-user2"; + + public $stateFilesEncryption; + public $filename; + public $data; + /** + * @var OC_FilesystemView + */ + public $view; + public $folder; + + public static function setUpBeforeClass() { + // reset backend + \OC_User::clearBackends(); + \OC_User::useBackend('database'); + + // clear share hooks + \OC_Hook::clear('OCP\\Share'); + \OC::registerShareHooks(); + \OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup'); + + // create users + self::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1, true); + self::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, true); + + } + + function setUp() { + $this->data = 'foobar'; + $this->view = new \OC_FilesystemView('/' . \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1 . '/files'); + + $this->folder = '/folder_share_api_test'; + + $this->filename = 'share-api-test.txt'; + + // remember files_encryption state + $this->stateFilesEncryption = \OC_App::isEnabled('files_encryption'); + + //we don't want to tests with app files_encryption enabled + \OC_App::disable('files_encryption'); + + + $this->assertTrue(!\OC_App::isEnabled('files_encryption')); + + // save file with content + $this->view->file_put_contents($this->filename, $this->data); + $this->view->mkdir($this->folder); + $this->view->file_put_contents($this->folder.'/'.$this->filename, $this->data); + + } + + function tearDown() { + $this->view->unlink($this->filename); + $this->view->deleteAll($this->folder); + // reset app files_encryption + if ($this->stateFilesEncryption) { + \OC_App::enable('files_encryption'); + } else { + \OC_App::disable('files_encryption'); + } + } + + public static function tearDownAfterClass() { + + // cleanup users + \OC_User::deleteUser(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); + \OC_User::deleteUser(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); + } + + /** + * @medium + */ + function testCreateShare() { + + //login as user1 + \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); + + // share to user + + // simulate a post request + $_POST['path'] = $this->filename; + $_POST['shareWith'] = \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2; + $_POST['shareType'] = \OCP\Share::SHARE_TYPE_USER; + + $result = Share\Api::createShare(array()); + + $this->assertTrue($result->succeeded()); + $data = $result->getData(); + + $share = $this->getShareFromId($data['id']); + + $items = \OCP\Share::getItemShared('file', $share['item_source']); + + $this->assertTrue(!empty($items)); + + // share link + + // simulate a post request + $_POST['path'] = $this->folder; + $_POST['shareType'] = \OCP\Share::SHARE_TYPE_LINK; + + $result = Share\Api::createShare(array()); + + // check if API call was successful + $this->assertTrue($result->succeeded()); + + $data = $result->getData(); + + // check if we have a token + $this->assertTrue(is_string($data['token'])); + + $share = $this->getShareFromId($data['id']); + + $items = \OCP\Share::getItemShared('file', $share['item_source']); + + $this->assertTrue(!empty($items)); + + $fileinfo = $this->view->getFileInfo($this->filename); + + \OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); + + $fileinfo = $this->view->getFileInfo($this->folder); + + \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null); + + + + } + + /** + * @medium + * @depends testCreateShare + */ + function testGetAllShares() { + + $fileinfo = $this->view->getFileInfo($this->filename); + + \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); + + $result = Share\Api::getAllShares(array()); + + $this->assertTrue($result->succeeded()); + + // test should return two shares created from testCreateShare() + $this->assertTrue(count($result->getData()) === 1); + + \OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); + } + + /** + * @medium + * @depends testCreateShare + */ + function testGetShareFromSource() { + + $fileInfo = $this->view->getFileInfo($this->filename); + + \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); + + \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, + null, 1); + + $params = array('itemSource' => $fileInfo['fileid']); + + $result = Share\Api::getShare($params); + + $this->assertTrue($result->succeeded()); + + // test should return one share created from testCreateShare() + $this->assertTrue(count($result->getData()) === 2); + + \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); + + \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null); + + } + + /** + * @medium + * @depends testCreateShare + */ + function testGetShareFromId() { + + $fileInfo = $this->view->getFileInfo($this->filename); + + $result = \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); + + // share was successful? + $this->assertTrue($result); + + // get item to determine share ID + $result = \OCP\Share::getItemShared('file', $fileInfo['fileid']); + + $this->assertEquals(1, count($result)); + + // get first element + $share = reset($result); + + // call getShare() with share ID + $params = array('id' => $share['id']); + $result = Share\Api::getShare($params); + + $this->assertTrue($result->succeeded()); + + // test should return one share created from testCreateShare() + $this->assertEquals(1, count($result->getData())); + + \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); + + } + + /** + * @medium + */ + function testGetShareFromFolder() { + + $fileInfo1 = $this->view->getFileInfo($this->filename); + $fileInfo2 = $this->view->getFileInfo($this->folder.'/'.$this->filename); + + $result = \OCP\Share::shareItem('file', $fileInfo1['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); + + // share was successful? + $this->assertTrue($result); + + $result = \OCP\Share::shareItem('folder', $fileInfo2['fileid'], \OCP\Share::SHARE_TYPE_LINK, + null, 1); + + // share was successful? + $this->assertTrue(is_string($result)); + + $_GET['path'] = $this->folder; + $_GET['subfiles'] = 'true'; + + $result = Share\Api::getAllShares(array()); + + $this->assertTrue($result->succeeded()); + + // test should return one share within $this->folder + $this->assertTrue(count($result->getData()) === 1); + + \OCP\Share::unshare('file', $fileInfo1['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); + + \OCP\Share::unshare('folder', $fileInfo2['fileid'], \OCP\Share::SHARE_TYPE_LINK, null); + + } + + /** + * @medium + */ + function testGetShareFromUnknownId() { + + $params = array('id' => 0); + + $result = Share\Api::getShare($params); + + $this->assertEquals(404, $result->getStatusCode()); + $this->assertEquals('share doesn\'t exist', $result->getMeta()['message']); + + } + + /** + * @medium + * @depends testCreateShare + */ + function testUpdateShare() { + + $fileInfo = $this->view->getFileInfo($this->filename); + + $result = \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); + + // share was successful? + $this->assertTrue($result); + + $result = \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, + null, 1); + + // share was successful? + $this->assertTrue(is_string($result)); + + $items = \OCP\Share::getItemShared('file', null); + + // make sure that we found a link share and a user share + $this->assertEquals(count($items), 2); + + $linkShare = null; + $userShare = null; + + foreach ($items as $item) { + if ($item['share_type'] === \OCP\Share::SHARE_TYPE_LINK) { + $linkShare = $item; + } + if ($item['share_type'] === \OCP\Share::SHARE_TYPE_USER) { + $userShare = $item; + } + } + + // make sure that we found a link share and a user share + $this->assertTrue(is_array($linkShare)); + $this->assertTrue(is_array($userShare)); + + // update permissions + + $this->assertEquals('31', $userShare['permissions']); + + $params = array(); + $params['id'] = $userShare['id']; + $params['_put'] = array(); + $params['_put']['permissions'] = 1; + + $result = Share\Api::updateShare($params); + + $this->assertTrue($result->succeeded(), $result->getMeta()['message']); + + $items = \OCP\Share::getItemShared('file', $userShare['file_source']); + + $newUserShare = null; + foreach ($items as $item) { + if ($item['share_with'] === \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2) { + $newUserShare = $item; + break; + } + } + + $this->assertTrue(is_array($newUserShare)); + + $this->assertEquals('1', $newUserShare['permissions']); + + // update password for link share + + $this->assertTrue(empty($linkShare['share_with'])); + + $params = array(); + $params['id'] = $linkShare['id']; + $params['_put'] = array(); + $params['_put']['password'] = 'foo'; + + $result = Share\Api::updateShare($params); + + $this->assertTrue($result->succeeded()); + + $items = \OCP\Share::getItemShared('file', $linkShare['file_source']); + + $newLinkShare = null; + foreach ($items as $item) { + if ($item['share_type'] === \OCP\Share::SHARE_TYPE_LINK) { + $newLinkShare = $item; + break; + } + } + + $this->assertTrue(is_array($newLinkShare)); + $this->assertTrue(!empty($newLinkShare['share_with'])); + + \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); + + \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null); + + } + + /** + * @medium + */ + function testUpdateShareUpload() { + + $fileInfo = $this->view->getFileInfo($this->folder); + + $result = \OCP\Share::shareItem('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, + null, 1); + + // share was successful? + $this->assertTrue(is_string($result)); + + $items = \OCP\Share::getItemShared('file', null); + + // make sure that we found a link share and a user share + $this->assertEquals(count($items), 1); + + $linkShare = null; + + foreach ($items as $item) { + if ($item['share_type'] === \OCP\Share::SHARE_TYPE_LINK) { + $linkShare = $item; + } + } + + // make sure that we found a link share + $this->assertTrue(is_array($linkShare)); + + // update public upload + + $params = array(); + $params['id'] = $linkShare['id']; + $params['_put'] = array(); + $params['_put']['publicUpload'] = 'true'; + + $result = Share\Api::updateShare($params); + + $this->assertTrue($result->succeeded()); + + $items = \OCP\Share::getItemShared('file', $linkShare['file_source']); + + $updatedLinkShare = null; + foreach ($items as $item) { + if ($item['share_type'] === \OCP\Share::SHARE_TYPE_LINK) { + $updatedLinkShare = $item; + break; + } + } + + $this->assertTrue(is_array($updatedLinkShare)); + $this->assertEquals(7, $updatedLinkShare['permissions']); + + // cleanup + + \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null); + + } + + /** + * @medium + * @depends testCreateShare + */ + function testDeleteShare() { + + $fileInfo = $this->view->getFileInfo($this->filename); + + \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); + + \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, + null, 1); + + $items = \OCP\Share::getItemShared('file', null); + + $this->assertEquals(2, count($items)); + + foreach ($items as $item) { + $result = Share\Api::deleteShare(array('id' => $item['id'])); + + $this->assertTrue($result->succeeded()); + } + + $itemsAfterDelete = \OCP\Share::getItemShared('file', null); + + $this->assertTrue(empty($itemsAfterDelete)); + + } + + /** + * @param $user + * @param bool $create + * @param bool $password + */ + private static function loginHelper($user, $create = false, $password = false) { + if ($create) { + \OC_User::createUser($user, $user); + } + + if ($password === false) { + $password = $user; + } + + \OC_Util::tearDownFS(); + \OC_User::setUserId(''); + \OC\Files\Filesystem::tearDown(); + \OC_Util::setupFS($user); + \OC_User::setUserId($user); + + $params['uid'] = $user; + $params['password'] = $password; + } + + /** + * @brief get some information from a given share + * @param int $shareID + * @return array with: item_source, share_type, share_with, item_type, permissions + */ + private function getShareFromId($shareID) { + $sql = 'SELECT `item_source`, `share_type`, `share_with`, `item_type`, `permissions` FROM `*PREFIX*share` WHERE `id` = ?'; + $args = array($shareID); + $query = \OCP\DB::prepare($sql); + $result = $query->execute($args); + + $share = Null; + + if ($result && $result->numRows() > 0) { + $share = $result->fetchRow(); + } + + return $share; + + } + +} diff --git a/tests/enable_all.php b/tests/enable_all.php index 111ed0e135..43ee16a72f 100644 --- a/tests/enable_all.php +++ b/tests/enable_all.php @@ -8,6 +8,7 @@ require_once __DIR__.'/../lib/base.php'; +OC_App::enable('files_sharing'); OC_App::enable('files_encryption'); OC_App::enable('calendar'); OC_App::enable('contacts');