Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
100.00% |
1 / 1 |
|
100.00% |
18 / 18 |
CRAP | |
100.00% |
75 / 75 |
Environment | |
100.00% |
1 / 1 |
|
100.00% |
18 / 18 |
28 | |
100.00% |
75 / 75 |
__construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
7 / 7 |
|||
setTokenBasedEnv | |
100.00% |
1 / 1 |
1 | |
100.00% |
9 / 9 |
|||
setStandardEnv | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
isTokenBasedEnv | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getNodeFromVirtualRoot | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
getNodeFromUserFolder | |
100.00% |
1 / 1 |
3 | |
100.00% |
8 / 8 |
|||
getResourceFromId | |
100.00% |
1 / 1 |
3 | |
100.00% |
6 / 6 |
|||
getSharedNode | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getVirtualRootFolder | |
100.00% |
1 / 1 |
3 | |
100.00% |
8 / 8 |
|||
getUserId | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getDisplayName | |
100.00% |
1 / 1 |
3 | |
100.00% |
7 / 7 |
|||
getSharedFolderName | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getSharePassword | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getPathFromUserFolder | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
getPathFromVirtualRoot | |
100.00% |
1 / 1 |
2 | |
100.00% |
7 / 7 |
|||
getResourceFromFolderAndId | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
buildFromRootToFolder | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
getRelativePath | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
<?php | |
/** | |
* Gallery | |
* | |
* This file is licensed under the Affero General Public License version 3 or | |
* later. See the COPYING file. | |
* | |
* @author Olivier Paroz <galleryapps@oparoz.com> | |
* @author Authors of \OCA\Files_Sharing\Helper | |
* | |
* @copyright Olivier Paroz 2016 | |
* @copyright Authors of \OCA\Files_Sharing\Helper 2014-2016 | |
*/ | |
namespace OCA\Gallery\Environment; | |
use OCP\IUserManager; | |
use OCP\Share; | |
use OCP\Share\IShare; | |
use OCP\ILogger; | |
use OCP\Files\IRootFolder; | |
use OCP\Files\Folder; | |
use OCP\Files\Node; | |
use OCP\Files\File; | |
use OCP\Files\NotFoundException; | |
/** | |
* Builds the environment so that the services have access to the files and folders' owner | |
* | |
* @package OCA\Gallery\Environment | |
*/ | |
class Environment { | |
/** | |
* @var string | |
*/ | |
private $appName; | |
/** | |
* The userId of the logged-in user or the person sharing a folder publicly | |
* | |
* @var string | |
*/ | |
private $userId; | |
/** | |
* The userFolder of the logged-in user or the ORIGINAL owner of the files which are shared | |
* publicly | |
* | |
* A share needs to be tracked back to its original owner in order to be able to access the | |
* resource | |
* | |
* @var Folder|null | |
*/ | |
private $userFolder; | |
/** | |
* @var IUserManager | |
*/ | |
private $userManager; | |
/** | |
* @var int | |
*/ | |
private $sharedNodeId; | |
/** | |
* @var File|Folder | |
*/ | |
private $sharedNode; | |
/** | |
* @var IRootFolder | |
*/ | |
private $rootFolder; | |
/** | |
* @var ILogger | |
*/ | |
private $logger; | |
/** | |
* The path to the userFolder for users with accounts: /userId/files | |
* | |
* For public folders, it's the path from the shared folder to the root folder in the original | |
* owner's filesystem: /userId/files/parent_folder/shared_folder | |
* | |
* @var string | |
*/ | |
private $fromRootToFolder; | |
/** | |
* The name of the shared folder | |
* | |
* @var string | |
*/ | |
private $folderName; | |
/** | |
* @var string|null | |
*/ | |
private $sharePassword; | |
/*** | |
* Constructor | |
* | |
* @param string $appName | |
* @param string|null $userId | |
* @param Folder|null $userFolder | |
* @param IUserManager $userManager | |
* @param IRootFolder $rootFolder | |
* @param ILogger $logger | |
*/ | |
public function __construct( | |
$appName, | |
$userId, | |
$userFolder, | |
IUserManager $userManager, | |
IRootFolder $rootFolder, | |
ILogger $logger | |
) { | |
$this->appName = $appName; | |
$this->userId = $userId; | |
$this->userFolder = $userFolder; | |
$this->userManager = $userManager; | |
$this->rootFolder = $rootFolder; | |
$this->logger = $logger; | |
} | |
/** | |
* Creates the environment based on the share the token links to | |
* | |
* @param IShare $share | |
*/ | |
public function setTokenBasedEnv($share) { | |
$origShareOwnerId = $share->getShareOwner(); | |
$this->userFolder = $this->rootFolder->getUserFolder($origShareOwnerId); | |
$this->sharedNodeId = $share->getNodeId(); | |
$this->sharedNode = $share->getNode(); | |
$this->fromRootToFolder = $this->buildFromRootToFolder($this->sharedNodeId); | |
$this->folderName = $share->getTarget(); | |
$this->userId = $origShareOwnerId; | |
$this->sharePassword = $share->getPassword(); | |
} | |
/** | |
* Creates the environment for a logged-in user | |
* | |
* userId and userFolder are already known, we define fromRootToFolder | |
* so that the services can use one method to have access to resources | |
* without having to know whether they're private or public | |
*/ | |
public function setStandardEnv() { | |
$this->fromRootToFolder = $this->userFolder->getPath() . '/'; | |
} | |
/** | |
* Returns true if the environment has been setup using a token | |
* | |
* @return bool | |
*/ | |
public function isTokenBasedEnv() { | |
return !empty($this->sharedNodeId); | |
} | |
/** | |
* Returns the Node based on a path starting from the virtual root | |
* | |
* @param string $subPath | |
* | |
* @return File|Folder | |
*/ | |
public function getNodeFromVirtualRoot($subPath) { | |
$relativePath = $this->getRelativePath($this->fromRootToFolder); | |
$path = $relativePath . '/' . $subPath; | |
$node = $this->getNodeFromUserFolder($path); | |
return $this->getResourceFromId($node->getId()); | |
} | |
/** | |
* Returns the Node based on a path starting from the files' owner user folder | |
* | |
* When logged in, this is the current user's user folder | |
* When visiting a link, this is the sharer's user folder | |
* | |
* @param string $path | |
* | |
* @return File|Folder | |
* | |
* @throws NotFoundEnvException | |
*/ | |
public function getNodeFromUserFolder($path) { | |
$folder = $this->userFolder; | |
if ($folder === null) { | |
throw new NotFoundEnvException("Could not access the user's folder"); | |
} else { | |
try { | |
$node = $folder->get($path); | |
} catch (NotFoundException $exception) { | |
$message = 'Could not find anything at: ' . $exception->getMessage(); | |
throw new NotFoundEnvException($message); | |
} | |
} | |
return $node; | |
} | |
/** | |
* Returns the resource identified by the given ID | |
* | |
* @param int $resourceId | |
* | |
* @return Node | |
* | |
* @throws NotFoundEnvException | |
*/ | |
public function getResourceFromId($resourceId) { | |
if ($this->isTokenBasedEnv()) { | |
if ($this->sharedNode->getType() === 'dir') { | |
$resource = $this->getResourceFromFolderAndId($this->sharedNode, $resourceId); | |
} else { | |
$resource = $this->sharedNode; | |
} | |
} else { | |
$resource = $this->getResourceFromFolderAndId($this->userFolder, $resourceId); | |
} | |
return $resource; | |
} | |
/** | |
* Returns the shared node | |
* | |
* @return File|Folder | |
*/ | |
public function getSharedNode() { | |
return $this->getResourceFromId($this->sharedNodeId); | |
} | |
/** | |
* Returns the virtual root where the user lands after logging in or when following a link | |
* | |
* @return Folder | |
* @throws NotFoundEnvException | |
*/ | |
public function getVirtualRootFolder() { | |
$rootFolder = $this->userFolder; | |
if ($this->isTokenBasedEnv()) { | |
$node = $this->getSharedNode(); | |
$nodeType = $node->getType(); | |
if ($nodeType === 'dir') { | |
$rootFolder = $node; | |
} else { | |
throw new NotFoundEnvException($node->getPath() . ' is not a folder'); | |
} | |
} | |
return $rootFolder; | |
} | |
/** | |
* Returns the userId of the currently logged-in user or the sharer | |
* | |
* @return string | |
*/ | |
public function getUserId() { | |
return $this->userId; | |
} | |
/** | |
* Returns the name of the user sharing files publicly | |
* | |
* @return string | |
* @throws NotFoundEnvException | |
*/ | |
public function getDisplayName() { | |
$user = null; | |
$userId = $this->userId; | |
if (isset($userId)) { | |
$user = $this->userManager->get($userId); | |
} | |
if ($user === null) { | |
throw new NotFoundEnvException('Could not find user'); | |
} | |
return $user->getDisplayName(); | |
} | |
/** | |
* Returns the name of shared folder | |
* | |
* @return string | |
*/ | |
public function getSharedFolderName() { | |
return trim($this->folderName, '//'); | |
} | |
/** | |
* Returns the password for the share, if there is one | |
* | |
* @return string|null | |
*/ | |
public function getSharePassword() { | |
return $this->sharePassword; | |
} | |
/** | |
* Returns the path which goes from the file, up to the user folder, based on a node: | |
* parent_folder/current_folder/my_file | |
* | |
* This is used for the preview system, which needs a full path | |
* | |
* getPath() on the file produces a path like: | |
* '/userId/files/my_folder/my_sub_folder/my_file' | |
* | |
* So we substract the path to the folder, giving us a relative path | |
* 'my_folder/my_sub_folder/my_file' | |
* | |
* @param Node $file | |
* | |
* @return string | |
*/ | |
public function getPathFromUserFolder($file) { | |
$path = $file->getPath(); | |
return $this->getRelativePath($path); | |
} | |
/** | |
* Returns the path which goes from the file, up to the root folder of the Gallery: | |
* current_folder/my_file | |
* | |
* That root folder changes when folders are shared publicly | |
* | |
* @param File|Folder|Node $node | |
* | |
* @return string | |
*/ | |
public function getPathFromVirtualRoot($node) { | |
$path = $node->getPath(); | |
$nodeType = $node->getType(); | |
// Needed because fromRootToFolder always ends with a slash | |
if ($nodeType === 'dir') { | |
$path .= '/'; | |
} | |
$path = str_replace($this->fromRootToFolder, '', $path); | |
$path = rtrim($path, '/'); | |
return $path; | |
} | |
/** | |
* Returns the resource found in a specific folder and identified by the given ID | |
* | |
* @param Folder $folder | |
* @param int $resourceId | |
* | |
* @return Node | |
* @throws NotFoundEnvException | |
*/ | |
private function getResourceFromFolderAndId($folder, $resourceId) { | |
$resourcesArray = $folder->getById($resourceId); | |
if ($resourcesArray[0] === null) { | |
throw new NotFoundEnvException('Could not locate node linked to ID: ' . $resourceId); | |
} | |
return $resourcesArray[0]; | |
} | |
/** | |
* Returns the path from the shared folder to the root folder in the original | |
* owner's filesystem: /userId/files/parent_folder/shared_folder | |
* | |
* This cannot be calculated with paths and IDs, the share's file source is required | |
* | |
* @param string $fileSource | |
* | |
* @return string | |
*/ | |
private function buildFromRootToFolder($fileSource) { | |
$resource = $this->getResourceFromId($fileSource); | |
$fromRootToFolder = $resource->getPath() . '/'; | |
return $fromRootToFolder; | |
} | |
/** | |
* Returns the path which goes from the file, up to the user folder, based on a path: | |
* parent_folder/current_folder/my_file | |
* | |
* getPath() on the file produces a path like: | |
* '/userId/files/my_folder/my_sub_folder/my_file' | |
* | |
* So we substract the path to the user folder, giving us a relative path | |
* 'my_folder/my_sub_folder' | |
* | |
* @param string $fullPath | |
* | |
* @return string | |
*/ | |
private function getRelativePath($fullPath) { | |
$folderPath = $this->userFolder->getPath() . '/'; | |
$origShareRelPath = str_replace($folderPath, '', $fullPath); | |
return $origShareRelPath; | |
} | |
} |