1<?php 2 3declare(strict_types=1); 4 5/** 6 * @copyright Copyright (c) 2016 Roeland Jago Douma <roeland@famdouma.nl> 7 * 8 * @author Christoph Wurst <christoph@winzerhof-wurst.at> 9 * @author Daniel Calviño Sánchez <danxuliu@gmail.com> 10 * @author Joas Schilling <coding@schilljs.com> 11 * @author John Molakvoæ <skjnldsv@protonmail.com> 12 * @author Julius Härtl <jus@bitgrid.net> 13 * @author Roeland Jago Douma <roeland@famdouma.nl> 14 * 15 * @license GNU AGPL version 3 or any later version 16 * 17 * This program is free software: you can redistribute it and/or modify 18 * it under the terms of the GNU Affero General Public License as 19 * published by the Free Software Foundation, either version 3 of the 20 * License, or (at your option) any later version. 21 * 22 * This program is distributed in the hope that it will be useful, 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * GNU Affero General Public License for more details. 26 * 27 * You should have received a copy of the GNU Affero General Public License 28 * along with this program. If not, see <http://www.gnu.org/licenses/>. 29 * 30 */ 31namespace OCA\Files_Sharing\Controller; 32 33use OCP\App\IAppManager; 34use OCP\AppFramework\Http\DataResponse; 35use OCP\AppFramework\OCS\OCSException; 36use OCP\AppFramework\OCS\OCSNotFoundException; 37use OCP\AppFramework\OCSController; 38use OCP\AppFramework\QueryException; 39use OCP\Files\IRootFolder; 40use OCP\Files\NotFoundException; 41use OCP\IGroupManager; 42use OCP\IRequest; 43use OCP\IServerContainer; 44use OCP\IUserManager; 45use OCP\Share\Exceptions\GenericShareException; 46use OCP\Share\Exceptions\ShareNotFound; 47use OCP\Share\IManager as ShareManager; 48use OCP\Share\IShare; 49 50class DeletedShareAPIController extends OCSController { 51 52 /** @var ShareManager */ 53 private $shareManager; 54 55 /** @var string */ 56 private $userId; 57 58 /** @var IUserManager */ 59 private $userManager; 60 61 /** @var IGroupManager */ 62 private $groupManager; 63 64 /** @var IRootFolder */ 65 private $rootFolder; 66 67 /** @var IAppManager */ 68 private $appManager; 69 70 /** @var IServerContainer */ 71 private $serverContainer; 72 73 public function __construct(string $appName, 74 IRequest $request, 75 ShareManager $shareManager, 76 string $UserId, 77 IUserManager $userManager, 78 IGroupManager $groupManager, 79 IRootFolder $rootFolder, 80 IAppManager $appManager, 81 IServerContainer $serverContainer) { 82 parent::__construct($appName, $request); 83 84 $this->shareManager = $shareManager; 85 $this->userId = $UserId; 86 $this->userManager = $userManager; 87 $this->groupManager = $groupManager; 88 $this->rootFolder = $rootFolder; 89 $this->appManager = $appManager; 90 $this->serverContainer = $serverContainer; 91 } 92 93 /** 94 * @suppress PhanUndeclaredClassMethod 95 */ 96 private function formatShare(IShare $share): array { 97 $result = [ 98 'id' => $share->getFullId(), 99 'share_type' => $share->getShareType(), 100 'uid_owner' => $share->getSharedBy(), 101 'displayname_owner' => $this->userManager->get($share->getSharedBy())->getDisplayName(), 102 'permissions' => 0, 103 'stime' => $share->getShareTime()->getTimestamp(), 104 'parent' => null, 105 'expiration' => null, 106 'token' => null, 107 'uid_file_owner' => $share->getShareOwner(), 108 'displayname_file_owner' => $this->userManager->get($share->getShareOwner())->getDisplayName(), 109 'path' => $share->getTarget(), 110 ]; 111 $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy()); 112 $nodes = $userFolder->getById($share->getNodeId()); 113 if (empty($nodes)) { 114 // fallback to guessing the path 115 $node = $userFolder->get($share->getTarget()); 116 if ($node === null || $share->getTarget() === '') { 117 throw new NotFoundException(); 118 } 119 } else { 120 $node = $nodes[0]; 121 } 122 123 $result['path'] = $userFolder->getRelativePath($node->getPath()); 124 if ($node instanceof \OCP\Files\Folder) { 125 $result['item_type'] = 'folder'; 126 } else { 127 $result['item_type'] = 'file'; 128 } 129 $result['mimetype'] = $node->getMimetype(); 130 $result['storage_id'] = $node->getStorage()->getId(); 131 $result['storage'] = $node->getStorage()->getCache()->getNumericStorageId(); 132 $result['item_source'] = $node->getId(); 133 $result['file_source'] = $node->getId(); 134 $result['file_parent'] = $node->getParent()->getId(); 135 $result['file_target'] = $share->getTarget(); 136 137 $expiration = $share->getExpirationDate(); 138 if ($expiration !== null) { 139 $result['expiration'] = $expiration->format('Y-m-d 00:00:00'); 140 } 141 142 if ($share->getShareType() === IShare::TYPE_GROUP) { 143 $group = $this->groupManager->get($share->getSharedWith()); 144 $result['share_with'] = $share->getSharedWith(); 145 $result['share_with_displayname'] = $group !== null ? $group->getDisplayName() : $share->getSharedWith(); 146 } elseif ($share->getShareType() === IShare::TYPE_ROOM) { 147 $result['share_with'] = $share->getSharedWith(); 148 $result['share_with_displayname'] = ''; 149 150 try { 151 $result = array_merge($result, $this->getRoomShareHelper()->formatShare($share)); 152 } catch (QueryException $e) { 153 } 154 } elseif ($share->getShareType() === IShare::TYPE_DECK) { 155 $result['share_with'] = $share->getSharedWith(); 156 $result['share_with_displayname'] = ''; 157 158 try { 159 $result = array_merge($result, $this->getDeckShareHelper()->formatShare($share)); 160 } catch (QueryException $e) { 161 } 162 } 163 164 return $result; 165 } 166 167 /** 168 * @NoAdminRequired 169 */ 170 public function index(): DataResponse { 171 $groupShares = $this->shareManager->getDeletedSharedWith($this->userId, IShare::TYPE_GROUP, null, -1, 0); 172 $roomShares = $this->shareManager->getDeletedSharedWith($this->userId, IShare::TYPE_ROOM, null, -1, 0); 173 $deckShares = $this->shareManager->getDeletedSharedWith($this->userId, IShare::TYPE_DECK, null, -1, 0); 174 175 $shares = array_merge($groupShares, $roomShares, $deckShares); 176 177 $shares = array_map(function (IShare $share) { 178 return $this->formatShare($share); 179 }, $shares); 180 181 return new DataResponse($shares); 182 } 183 184 /** 185 * @NoAdminRequired 186 * 187 * @throws OCSException 188 */ 189 public function undelete(string $id): DataResponse { 190 try { 191 $share = $this->shareManager->getShareById($id, $this->userId); 192 } catch (ShareNotFound $e) { 193 throw new OCSNotFoundException('Share not found'); 194 } 195 196 if ($share->getPermissions() !== 0) { 197 throw new OCSNotFoundException('No deleted share found'); 198 } 199 200 try { 201 $this->shareManager->restoreShare($share, $this->userId); 202 } catch (GenericShareException $e) { 203 throw new OCSException('Something went wrong'); 204 } 205 206 return new DataResponse([]); 207 } 208 209 /** 210 * Returns the helper of DeletedShareAPIController for room shares. 211 * 212 * If the Talk application is not enabled or the helper is not available 213 * a QueryException is thrown instead. 214 * 215 * @return \OCA\Talk\Share\Helper\DeletedShareAPIController 216 * @throws QueryException 217 */ 218 private function getRoomShareHelper() { 219 if (!$this->appManager->isEnabledForUser('spreed')) { 220 throw new QueryException(); 221 } 222 223 return $this->serverContainer->get('\OCA\Talk\Share\Helper\DeletedShareAPIController'); 224 } 225 226 /** 227 * Returns the helper of ShareAPIHelper for deck shares. 228 * 229 * If the Deck application is not enabled or the helper is not available 230 * a QueryException is thrown instead. 231 * 232 * @return \OCA\Deck\Sharing\ShareAPIHelper 233 * @throws QueryException 234 */ 235 private function getDeckShareHelper() { 236 if (!$this->appManager->isEnabledForUser('deck')) { 237 throw new QueryException(); 238 } 239 240 return $this->serverContainer->get('\OCA\Deck\Sharing\ShareAPIHelper'); 241 } 242} 243