| 
									
										
										
										
											2013-09-24 03:39:05 +03:00
										 |  |  | <?php | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * ownCloud - Documents App | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @author Victor Dubiniuk | 
					
						
							|  |  |  |  * @copyright 2013 Victor Dubiniuk victor.dubiniuk@gmail.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 Lesser General Public  | 
					
						
							|  |  |  |  * License along with this library.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace OCA\Documents; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class File { | 
					
						
							|  |  |  | 	protected $fileId; | 
					
						
							| 
									
										
										
										
											2013-09-25 16:34:35 +03:00
										 |  |  | 	protected $owner; | 
					
						
							|  |  |  | 	protected $path; | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 	protected $sharing; | 
					
						
							| 
									
										
										
										
											2013-11-10 12:50:06 +03:00
										 |  |  | 	protected $passwordProtected = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public function __construct($fileId, $shareOps = null){ | 
					
						
							| 
									
										
										
										
											2013-09-24 03:39:05 +03:00
										 |  |  | 		if (!$fileId){ | 
					
						
							|  |  |  | 			throw new \Exception('No valid file has been passed'); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$this->fileId = $fileId; | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		//if you know how to get sharing info by fileId via API, 
 | 
					
						
							|  |  |  | 		//please send me a link to video tutorial :/
 | 
					
						
							| 
									
										
										
										
											2013-11-10 12:50:06 +03:00
										 |  |  | 		if (!is_null($shareOps)){ | 
					
						
							|  |  |  | 			$this->sharing = $shareOps; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			$this->sharing = $this->getSharingOps(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-09-24 03:39:05 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-09-25 16:34:35 +03:00
										 |  |  | 	public static function getByShareToken($token){ | 
					
						
							| 
									
										
										
										
											2014-03-05 18:47:06 +03:00
										 |  |  | 		$linkItem = \OCP\Share::getShareByToken($token, false); | 
					
						
							| 
									
										
										
										
											2013-09-25 16:34:35 +03:00
										 |  |  | 		if (is_array($linkItem) && isset($linkItem['uid_owner'])) { | 
					
						
							|  |  |  | 			// seems to be a valid share
 | 
					
						
							|  |  |  | 			$rootLinkItem = \OCP\Share::resolveReShare($linkItem); | 
					
						
							|  |  |  | 			$fileOwner = $rootLinkItem['uid_owner']; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			throw new \Exception('This file was probably unshared'); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2013-11-10 12:50:06 +03:00
										 |  |  | 		if (!isset($rootLinkItem['path']) && isset($rootLinkItem['file_target'])){ | 
					
						
							| 
									
										
										
										
											2013-12-18 22:22:32 +03:00
										 |  |  | 			$rootLinkItem['path'] = $rootLinkItem['file_target']; | 
					
						
							| 
									
										
										
										
											2013-11-10 12:50:06 +03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		$file = new File($rootLinkItem['file_source'], array($rootLinkItem)); | 
					
						
							| 
									
										
										
										
											2013-12-04 21:33:37 +03:00
										 |  |  | 		 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (isset($rootLinkItem['uid_owner'])){ | 
					
						
							|  |  |  | 			\OC_Util::tearDownFS(); | 
					
						
							|  |  |  | 			\OC_Util::setupFS($rootLinkItem['uid_owner']); | 
					
						
							|  |  |  | 			$file->setOwner($rootLinkItem['uid_owner']); | 
					
						
							| 
									
										
										
										
											2013-12-18 22:22:32 +03:00
										 |  |  | 			$file->setPath(\OC\Files\Filesystem::getPath($linkItem['file_source'])); | 
					
						
							| 
									
										
										
										
											2013-12-04 21:33:37 +03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2013-11-10 12:50:06 +03:00
										 |  |  | 		if (isset($linkItem['share_with']) && !empty($linkItem['share_with'])){ | 
					
						
							|  |  |  | 			$file->setPasswordProtected(true); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-09-25 16:34:35 +03:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		return $file; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public function getFileId(){ | 
					
						
							|  |  |  | 		return $this->fileId; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	public function setOwner($owner){ | 
					
						
							|  |  |  | 		$this->owner = $owner; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	public function setPath($path){ | 
					
						
							|  |  |  | 		$this->path = $path; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	public function isPublicShare(){ | 
					
						
							|  |  |  | 		foreach ($this->sharing as $share){ | 
					
						
							|  |  |  | 			if ( | 
					
						
							|  |  |  | 					$share['share_type'] == \OCP\Share::SHARE_TYPE_LINK  | 
					
						
							|  |  |  | 					|| $share['share_type'] == \OCP\Share::SHARE_TYPE_EMAIL | 
					
						
							|  |  |  | 				){ | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-11-10 12:50:06 +03:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	public function isPasswordProtected(){ | 
					
						
							|  |  |  | 		return $this->passwordProtected; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	public function checkPassword($password){ | 
					
						
							|  |  |  | 		$shareId  = $this->getShareId(); | 
					
						
							|  |  |  | 		if (!$this->isPasswordProtected() | 
					
						
							|  |  |  | 			|| (\OC::$session->exists('public_link_authenticated') | 
					
						
							|  |  |  | 				&& \OC::$session->get('public_link_authenticated') === $shareId)	 | 
					
						
							|  |  |  | 			){ | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		// Check Password
 | 
					
						
							|  |  |  | 		$forcePortable = (CRYPT_BLOWFISH != 1); | 
					
						
							|  |  |  | 		$hasher = new \PasswordHash(8, $forcePortable); | 
					
						
							|  |  |  | 		if ($hasher->CheckPassword($password.\OC_Config::getValue('passwordsalt', ''), | 
					
						
							|  |  |  | 									 $this->getPassword())) { | 
					
						
							|  |  |  | 			// Save item id in session for future request
 | 
					
						
							|  |  |  | 			\OC::$session->set('public_link_authenticated', $shareId); | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	public function setPasswordProtected($value){ | 
					
						
							|  |  |  | 		$this->passwordProtected = $value; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-12-05 01:02:08 +03:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	public function getPermissions(){ | 
					
						
							|  |  |  | 		if (count($this->sharing)){ | 
					
						
							|  |  |  | 			if ($this->isPublicShare()){ | 
					
						
							|  |  |  | 				$permissions = \OCP\PERMISSION_READ | \OCP\PERMISSION_UPDATE; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				$permissions = $this->sharing[0]['permissions']; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			list($owner, $path) = $this->getOwnerViewAndPath(); | 
					
						
							|  |  |  | 			$permissions = 0; | 
					
						
							|  |  |  | 			if (\OC\Files\Filesystem::isReadable($path)){ | 
					
						
							|  |  |  | 				$permissions |= \OCP\PERMISSION_READ; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (\OC\Files\Filesystem::isUpdatable($path)){ | 
					
						
							|  |  |  | 				$permissions |= \OCP\PERMISSION_UPDATE; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return $permissions; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-09-25 16:34:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-05 14:04:36 +01:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Rename this file to the given name | 
					
						
							|  |  |  | 	 * @param string $newName name to give (without path) | 
					
						
							|  |  |  | 	 * @return boolean true if rename succeeded, false otherwise | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	public function renameTo($newName) { | 
					
						
							|  |  |  | 		list($owner, $path) = $this->getOwnerViewAndPath(); | 
					
						
							|  |  |  | 		$newPath = dirname($path) . '/' . $newName; | 
					
						
							|  |  |  | 		return \OC\Files\Filesystem::rename($path, $newPath); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-24 03:39:05 +03:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 *  | 
					
						
							|  |  |  | 	 * @return string owner of the current file item | 
					
						
							|  |  |  | 	 * @throws \Exception | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	public function getOwnerViewAndPath(){ | 
					
						
							| 
									
										
										
										
											2013-12-18 22:22:32 +03:00
										 |  |  | 		if (!$this->owner || !$this->path){ | 
					
						
							|  |  |  | 			if ($this->isPublicShare()){ | 
					
						
							|  |  |  | 				list($owner, $path) = $this->getSharedFileOwnerAndPath(); | 
					
						
							| 
									
										
										
										
											2013-09-25 16:34:35 +03:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2013-12-18 22:22:32 +03:00
										 |  |  | 				$owner = \OCP\User::getUser(); | 
					
						
							|  |  |  | 				$path = Storage::resolvePath($this->fileId); | 
					
						
							|  |  |  | 				if (!$path){ | 
					
						
							|  |  |  | 					throw new \Exception($this->fileId . ' can not be resolved'); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-09-25 16:34:35 +03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			 | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 			$this->path = $path; | 
					
						
							| 
									
										
										
										
											2013-09-25 16:34:35 +03:00
										 |  |  | 			$this->owner = $owner; | 
					
						
							| 
									
										
										
										
											2013-09-24 03:39:05 +03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2013-12-18 22:22:32 +03:00
										 |  |  | 		$view = new View('/' . $this->owner . '/files'); | 
					
						
							|  |  |  | 		if (!$view->file_exists($this->path)){ | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 			throw new \Exception($this->path . ' doesn\'t exist'); | 
					
						
							| 
									
										
										
										
											2013-09-24 03:39:05 +03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-12-18 22:22:32 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		return array($view, $this->path); | 
					
						
							| 
									
										
										
										
											2013-09-24 03:39:05 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-24 03:39:05 +03:00
										 |  |  | 	public function getOwner(){ | 
					
						
							| 
									
										
										
										
											2013-09-25 16:34:35 +03:00
										 |  |  | 		if (!$this->owner){ | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 			$this->getOwnerViewAndPath(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return $this->owner; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-12-18 22:22:32 +03:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * public links only | 
					
						
							|  |  |  | 	 * @return array | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 	protected function getSharedFileOwnerAndPath(){ | 
					
						
							|  |  |  | 		foreach ($this->sharing as $share){ | 
					
						
							| 
									
										
										
										
											2013-12-18 22:22:32 +03:00
										 |  |  | 			$rootLinkItem = \OCP\Share::resolveReShare($share); | 
					
						
							|  |  |  | 			if (isset($rootLinkItem['uid_owner'])){ | 
					
						
							|  |  |  | 				$owner = $rootLinkItem['uid_owner']; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				$owner = false; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			\OC_Util::tearDownFS(); | 
					
						
							|  |  |  | 			\OC_Util::setupFS($owner); | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 			return array( | 
					
						
							| 
									
										
										
										
											2013-12-18 22:22:32 +03:00
										 |  |  | 					$owner, | 
					
						
							|  |  |  | 					\OC\Files\Filesystem::getPath($rootLinkItem['file_source']) | 
					
						
							|  |  |  |                 ); | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-12-18 22:22:32 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 		return $result; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-12-18 22:22:32 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 	protected function getLocalFileOwnerAndPath(){ | 
					
						
							|  |  |  | 		$fileInfo = \OC\Files\Cache\Cache::getById($this->fileId); | 
					
						
							|  |  |  | 		$owner = \OCP\User::getUser(); | 
					
						
							|  |  |  | 		if (!$owner){ | 
					
						
							|  |  |  | 			throw new Exception('Guest users can\'t access local files. This one was probably unshared recently.'); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-09-25 16:34:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 		return array ($owner, @$fileInfo[1]); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-11-10 12:50:06 +03:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	protected function getPassword(){ | 
					
						
							|  |  |  | 		return $this->sharing[0]['share_with']; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	protected function getShareId(){ | 
					
						
							|  |  |  | 		return $this->sharing[0]['id']; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-09-24 03:39:05 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 	protected function getSharingOps(){ | 
					
						
							| 
									
										
										
										
											2013-09-25 16:34:35 +03:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 		$where  = 'AND `file_source`=?'; | 
					
						
							|  |  |  | 		$values = array($this->fileId); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (\OCP\User::isLoggedIn()){ | 
					
						
							|  |  |  | 			$where .= ' AND ((`share_type`=' . \OCP\Share::SHARE_TYPE_USER . ' AND `share_with`=?) OR  `share_type`=' . \OCP\Share::SHARE_TYPE_LINK . ')'; | 
					
						
							|  |  |  | 			$values[] = \OCP\User::getUser(); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			$where .= ' AND (`share_type`=' . \OCP\Share::SHARE_TYPE_LINK . ')'; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		$query = \OC_DB::prepare('SELECT `*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, ' | 
					
						
							|  |  |  | 							.'`share_type`, `share_with`, `file_source`, `path`, `file_target`, ' | 
					
						
							|  |  |  | 							.'`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, ' | 
					
						
							|  |  |  | 							.'`name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`, `etag`'  | 
					
						
							| 
									
										
										
										
											2013-10-15 19:29:00 +03:00
										 |  |  | 							.'FROM `*PREFIX*share` INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` WHERE `item_type` = \'file\' ' . $where); | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 		$result = $query->execute($values); | 
					
						
							|  |  |  | 		$shares = $result->fetchAll(); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		$origins = array(); | 
					
						
							|  |  |  | 		if (is_array($shares)){ | 
					
						
							|  |  |  | 			foreach ($shares as $share){ | 
					
						
							| 
									
										
										
										
											2013-10-17 00:04:25 +03:00
										 |  |  | 				$origin = \OCP\Share::resolveReShare($share); | 
					
						
							|  |  |  | 				if (!isset($origin['path']) && isset($origin['file_target'])){ | 
					
						
							|  |  |  | 					$origin['path'] = 'files/' . $origin['file_target']; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				$origins[] = $origin; | 
					
						
							| 
									
										
										
										
											2013-09-25 16:34:35 +03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | 		return $origins; | 
					
						
							| 
									
										
										
										
											2013-09-24 03:39:05 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-09-26 21:01:41 +03:00
										 |  |  | } |