This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Gallery |
||
4 | * |
||
5 | * This file is licensed under the Affero General Public License version 3 or |
||
6 | * later. See the COPYING file. |
||
7 | * |
||
8 | * @author Olivier Paroz <[email protected]> |
||
9 | * @author Authors of \OCA\Files_Sharing\Helper |
||
10 | * |
||
11 | * @copyright Olivier Paroz 2016 |
||
12 | * @copyright Authors of \OCA\Files_Sharing\Helper 2014-2016 |
||
13 | */ |
||
14 | |||
15 | namespace OCA\Gallery\Environment; |
||
16 | |||
17 | use OCP\IUserManager; |
||
18 | use OCP\Share; |
||
19 | use OCP\Share\IShare; |
||
20 | use OCP\ILogger; |
||
21 | use OCP\Files\IRootFolder; |
||
22 | use OCP\Files\Folder; |
||
23 | use OCP\Files\Node; |
||
24 | use OCP\Files\File; |
||
25 | use OCP\Files\NotFoundException; |
||
26 | |||
27 | /** |
||
28 | * Builds the environment so that the services have access to the files and folders' owner |
||
29 | * |
||
30 | * @package OCA\Gallery\Environment |
||
31 | */ |
||
32 | class Environment { |
||
33 | |||
34 | /** |
||
35 | * @var string |
||
36 | */ |
||
37 | private $appName; |
||
38 | /** |
||
39 | * The userId of the logged-in user or the person sharing a folder publicly |
||
40 | * |
||
41 | * @var string |
||
42 | */ |
||
43 | private $userId; |
||
44 | /** |
||
45 | * The userFolder of the logged-in user or the ORIGINAL owner of the files which are shared |
||
46 | * publicly |
||
47 | * |
||
48 | * A share needs to be tracked back to its original owner in order to be able to access the |
||
49 | * resource |
||
50 | * |
||
51 | * @var Folder|null |
||
52 | */ |
||
53 | private $userFolder; |
||
54 | /** |
||
55 | * @var IUserManager |
||
56 | */ |
||
57 | private $userManager; |
||
58 | /** |
||
59 | * @var int |
||
60 | */ |
||
61 | private $sharedNodeId; |
||
62 | /** |
||
63 | * @var File|Folder |
||
64 | */ |
||
65 | private $sharedNode; |
||
66 | /** |
||
67 | * @var IRootFolder |
||
68 | */ |
||
69 | private $rootFolder; |
||
70 | /** |
||
71 | * @var ILogger |
||
72 | */ |
||
73 | private $logger; |
||
74 | /** |
||
75 | * The path to the userFolder for users with accounts: /userId/files |
||
76 | * |
||
77 | * For public folders, it's the path from the shared folder to the root folder in the original |
||
78 | * owner's filesystem: /userId/files/parent_folder/shared_folder |
||
79 | * |
||
80 | * @var string |
||
81 | */ |
||
82 | private $fromRootToFolder; |
||
83 | /** |
||
84 | * The name of the shared folder |
||
85 | * |
||
86 | * @var string |
||
87 | */ |
||
88 | private $folderName; |
||
89 | /** |
||
90 | * @var string|null |
||
91 | */ |
||
92 | private $sharePassword; |
||
93 | |||
94 | /*** |
||
95 | * Constructor |
||
96 | * |
||
97 | * @param string $appName |
||
98 | * @param string|null $userId |
||
99 | * @param Folder|null $userFolder |
||
100 | * @param IUserManager $userManager |
||
101 | * @param IRootFolder $rootFolder |
||
102 | * @param ILogger $logger |
||
103 | */ |
||
104 | public function __construct( |
||
105 | $appName, |
||
106 | $userId, |
||
107 | $userFolder, |
||
108 | IUserManager $userManager, |
||
109 | IRootFolder $rootFolder, |
||
110 | ILogger $logger |
||
111 | ) { |
||
112 | $this->appName = $appName; |
||
113 | $this->userId = $userId; |
||
114 | $this->userFolder = $userFolder; |
||
115 | $this->userManager = $userManager; |
||
116 | $this->rootFolder = $rootFolder; |
||
117 | $this->logger = $logger; |
||
118 | } |
||
119 | |||
120 | /** |
||
121 | * Creates the environment based on the share the token links to |
||
122 | * |
||
123 | * @param IShare $share |
||
124 | */ |
||
125 | public function setTokenBasedEnv($share) { |
||
126 | $origShareOwnerId = $share->getShareOwner(); |
||
127 | $this->userFolder = $this->rootFolder->getUserFolder($origShareOwnerId); |
||
128 | |||
129 | $this->sharedNodeId = $share->getNodeId(); |
||
130 | $this->sharedNode = $share->getNode(); |
||
131 | $this->fromRootToFolder = $this->buildFromRootToFolder($this->sharedNodeId); |
||
132 | |||
133 | $this->folderName = $share->getTarget(); |
||
134 | $this->userId = $origShareOwnerId; |
||
135 | $this->sharePassword = $share->getPassword(); |
||
136 | } |
||
137 | |||
138 | /** |
||
139 | * Creates the environment for a logged-in user |
||
140 | * |
||
141 | * userId and userFolder are already known, we define fromRootToFolder |
||
142 | * so that the services can use one method to have access to resources |
||
143 | * without having to know whether they're private or public |
||
144 | */ |
||
145 | public function setStandardEnv() { |
||
146 | $this->fromRootToFolder = $this->userFolder->getPath() . '/'; |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * Returns true if the environment has been setup using a token |
||
151 | * |
||
152 | * @return bool |
||
153 | */ |
||
154 | public function isTokenBasedEnv() { |
||
155 | return !empty($this->sharedNodeId); |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * Returns the Node based on a path starting from the virtual root |
||
160 | * |
||
161 | * @param string $subPath |
||
162 | * |
||
163 | * @return File|Folder |
||
0 ignored issues
–
show
|
|||
164 | */ |
||
165 | public function getNodeFromVirtualRoot($subPath) { |
||
166 | $relativePath = $this->getRelativePath($this->fromRootToFolder); |
||
167 | $path = $relativePath . '/' . $subPath; |
||
168 | $node = $this->getNodeFromUserFolder($path); |
||
169 | |||
170 | return $this->getResourceFromId($node->getId()); |
||
171 | } |
||
172 | |||
173 | /** |
||
174 | * Returns the Node based on a path starting from the files' owner user folder |
||
175 | * |
||
176 | * When logged in, this is the current user's user folder |
||
177 | * When visiting a link, this is the sharer's user folder |
||
178 | * |
||
179 | * @param string $path |
||
180 | * |
||
181 | * @return File|Folder |
||
182 | * |
||
183 | * @throws NotFoundEnvException |
||
184 | */ |
||
185 | public function getNodeFromUserFolder($path) { |
||
186 | $folder = $this->userFolder; |
||
187 | if ($folder === null) { |
||
188 | throw new NotFoundEnvException("Could not access the user's folder"); |
||
189 | } else { |
||
190 | try { |
||
191 | $node = $folder->get($path); |
||
192 | } catch (NotFoundException $exception) { |
||
0 ignored issues
–
show
The class
OCP\Files\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?
Scrutinizer analyzes your It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis. ![]() |
|||
193 | $message = 'Could not find anything at: ' . $exception->getMessage(); |
||
194 | throw new NotFoundEnvException($message); |
||
195 | } |
||
196 | } |
||
197 | |||
198 | return $node; |
||
199 | } |
||
200 | |||
201 | /** |
||
202 | * Returns the resource identified by the given ID |
||
203 | * |
||
204 | * @param int $resourceId |
||
205 | * |
||
206 | * @return Node |
||
207 | * |
||
208 | * @throws NotFoundEnvException |
||
209 | */ |
||
210 | public function getResourceFromId($resourceId) { |
||
211 | if ($this->isTokenBasedEnv()) { |
||
212 | if ($this->sharedNode->getType() === 'dir') { |
||
213 | $resource = $this->getResourceFromFolderAndId($this->sharedNode, $resourceId); |
||
214 | } else { |
||
215 | $resource = $this->sharedNode; |
||
216 | } |
||
217 | } else { |
||
218 | $resource = $this->getResourceFromFolderAndId($this->userFolder, $resourceId); |
||
0 ignored issues
–
show
It seems like
$this->userFolder can be null ; however, getResourceFromFolderAndId() does not accept null , maybe add an additional type check?
Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code: /** @return stdClass|null */
function mayReturnNull() { }
function doesNotAcceptNull(stdClass $x) { }
// With potential error.
function withoutCheck() {
$x = mayReturnNull();
doesNotAcceptNull($x); // Potential error here.
}
// Safe - Alternative 1
function withCheck1() {
$x = mayReturnNull();
if ( ! $x instanceof stdClass) {
throw new \LogicException('$x must be defined.');
}
doesNotAcceptNull($x);
}
// Safe - Alternative 2
function withCheck2() {
$x = mayReturnNull();
if ($x instanceof stdClass) {
doesNotAcceptNull($x);
}
}
![]() |
|||
219 | } |
||
220 | |||
221 | return $resource; |
||
222 | } |
||
223 | |||
224 | /** |
||
225 | * Returns the shared node |
||
226 | * |
||
227 | * @return File|Folder |
||
0 ignored issues
–
show
|
|||
228 | */ |
||
229 | public function getSharedNode() { |
||
230 | return $this->getResourceFromId($this->sharedNodeId); |
||
231 | } |
||
232 | |||
233 | /** |
||
234 | * Returns the virtual root where the user lands after logging in or when following a link |
||
235 | * |
||
236 | * @return Folder |
||
0 ignored issues
–
show
|
|||
237 | * @throws NotFoundEnvException |
||
238 | */ |
||
239 | public function getVirtualRootFolder() { |
||
240 | $rootFolder = $this->userFolder; |
||
241 | if ($this->isTokenBasedEnv()) { |
||
242 | $node = $this->getSharedNode(); |
||
243 | $nodeType = $node->getType(); |
||
244 | if ($nodeType === 'dir') { |
||
245 | $rootFolder = $node; |
||
246 | } else { |
||
247 | throw new NotFoundEnvException($node->getPath() . ' is not a folder'); |
||
248 | } |
||
249 | } |
||
250 | |||
251 | return $rootFolder; |
||
252 | } |
||
253 | |||
254 | /** |
||
255 | * Returns the userId of the currently logged-in user or the sharer |
||
256 | * |
||
257 | * @return string |
||
258 | */ |
||
259 | public function getUserId() { |
||
260 | return $this->userId; |
||
261 | } |
||
262 | |||
263 | /** |
||
264 | * Returns the name of the user sharing files publicly |
||
265 | * |
||
266 | * @return string |
||
267 | * @throws NotFoundEnvException |
||
268 | */ |
||
269 | public function getDisplayName() { |
||
270 | $user = null; |
||
271 | $userId = $this->userId; |
||
272 | |||
273 | if (isset($userId)) { |
||
274 | $user = $this->userManager->get($userId); |
||
275 | } |
||
276 | if ($user === null) { |
||
277 | throw new NotFoundEnvException('Could not find user'); |
||
278 | } |
||
279 | |||
280 | return $user->getDisplayName(); |
||
281 | } |
||
282 | |||
283 | /** |
||
284 | * Returns the name of shared folder |
||
285 | * |
||
286 | * @return string |
||
287 | */ |
||
288 | public function getSharedFolderName() { |
||
289 | return \trim($this->folderName, '//'); |
||
290 | } |
||
291 | |||
292 | /** |
||
293 | * Returns the password for the share, if there is one |
||
294 | * |
||
295 | * @return string|null |
||
296 | */ |
||
297 | public function getSharePassword() { |
||
298 | return $this->sharePassword; |
||
299 | } |
||
300 | |||
301 | /** |
||
302 | * Returns the path which goes from the file, up to the user folder, based on a node: |
||
303 | * parent_folder/current_folder/my_file |
||
304 | * |
||
305 | * This is used for the preview system, which needs a full path |
||
306 | * |
||
307 | * getPath() on the file produces a path like: |
||
308 | * '/userId/files/my_folder/my_sub_folder/my_file' |
||
309 | * |
||
310 | * So we substract the path to the folder, giving us a relative path |
||
311 | * 'my_folder/my_sub_folder/my_file' |
||
312 | * |
||
313 | * @param Node $file |
||
314 | * |
||
315 | * @return string |
||
316 | */ |
||
317 | public function getPathFromUserFolder($file) { |
||
318 | $path = $file->getPath(); |
||
319 | |||
320 | return $this->getRelativePath($path); |
||
321 | } |
||
322 | |||
323 | /** |
||
324 | * Returns the path which goes from the file, up to the root folder of the Gallery: |
||
325 | * current_folder/my_file |
||
326 | * |
||
327 | * That root folder changes when folders are shared publicly |
||
328 | * |
||
329 | * @param File|Folder|Node $node |
||
330 | * |
||
331 | * @return string |
||
332 | */ |
||
333 | public function getPathFromVirtualRoot($node) { |
||
334 | $path = $node->getPath(); |
||
335 | $nodeType = $node->getType(); |
||
336 | |||
337 | // Needed because fromRootToFolder always ends with a slash |
||
338 | if ($nodeType === 'dir') { |
||
339 | $path .= '/'; |
||
340 | } |
||
341 | |||
342 | $path = \str_replace($this->fromRootToFolder, '', $path); |
||
343 | $path = \rtrim($path, '/'); |
||
344 | |||
345 | return $path; |
||
346 | } |
||
347 | |||
348 | /** |
||
349 | * Returns the resource found in a specific folder and identified by the given ID |
||
350 | * |
||
351 | * @param Folder $folder |
||
352 | * @param int $resourceId |
||
353 | * |
||
354 | * @return Node |
||
355 | * @throws NotFoundEnvException |
||
356 | */ |
||
357 | private function getResourceFromFolderAndId($folder, $resourceId) { |
||
358 | $resourcesArray = $folder->getById($resourceId); |
||
359 | |||
360 | if ($resourcesArray[0] === null) { |
||
361 | throw new NotFoundEnvException('Could not locate node linked to ID: ' . $resourceId); |
||
362 | } |
||
363 | |||
364 | return $resourcesArray[0]; |
||
365 | } |
||
366 | |||
367 | /** |
||
368 | * Returns the path from the shared folder to the root folder in the original |
||
369 | * owner's filesystem: /userId/files/parent_folder/shared_folder |
||
370 | * |
||
371 | * This cannot be calculated with paths and IDs, the share's file source is required |
||
372 | * |
||
373 | * @param string $fileSource |
||
374 | * |
||
375 | * @return string |
||
376 | */ |
||
377 | private function buildFromRootToFolder($fileSource) { |
||
378 | $resource = $this->getResourceFromId($fileSource); |
||
379 | $fromRootToFolder = $resource->getPath() . '/'; |
||
380 | |||
381 | return $fromRootToFolder; |
||
382 | } |
||
383 | |||
384 | /** |
||
385 | * Returns the path which goes from the file, up to the user folder, based on a path: |
||
386 | * parent_folder/current_folder/my_file |
||
387 | * |
||
388 | * getPath() on the file produces a path like: |
||
389 | * '/userId/files/my_folder/my_sub_folder/my_file' |
||
390 | * |
||
391 | * So we substract the path to the user folder, giving us a relative path |
||
392 | * 'my_folder/my_sub_folder' |
||
393 | * |
||
394 | * @param string $fullPath |
||
395 | * |
||
396 | * @return string |
||
397 | */ |
||
398 | private function getRelativePath($fullPath) { |
||
399 | $folderPath = $this->userFolder->getPath() . '/'; |
||
400 | $origShareRelPath = \str_replace($folderPath, '', $fullPath); |
||
401 | |||
402 | return $origShareRelPath; |
||
403 | } |
||
404 | } |
||
405 |
This check compares the return type specified in the
@return
annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.