Completed
Pull Request — master (#8590)
by John
41:36 queued 25:27
created
apps/files_sharing/lib/Controller/ShareController.php 2 patches
Indentation   +595 added lines, -595 removed lines patch added patch discarded remove patch
@@ -70,603 +70,603 @@
 block discarded – undo
70 70
  */
71 71
 class ShareController extends Controller {
72 72
 
73
-	/** @var IConfig */
74
-	protected $config;
75
-	/** @var IURLGenerator */
76
-	protected $urlGenerator;
77
-	/** @var IUserManager */
78
-	protected $userManager;
79
-	/** @var ILogger */
80
-	protected $logger;
81
-	/** @var \OCP\Activity\IManager */
82
-	protected $activityManager;
83
-	/** @var \OCP\Share\IManager */
84
-	protected $shareManager;
85
-	/** @var ISession */
86
-	protected $session;
87
-	/** @var IPreview */
88
-	protected $previewManager;
89
-	/** @var IRootFolder */
90
-	protected $rootFolder;
91
-	/** @var FederatedShareProvider */
92
-	protected $federatedShareProvider;
93
-	/** @var EventDispatcherInterface */
94
-	protected $eventDispatcher;
95
-	/** @var IL10N */
96
-	protected $l10n;
97
-	/** @var Defaults */
98
-	protected $defaults;
99
-
100
-	/**
101
-	 * @param string $appName
102
-	 * @param IRequest $request
103
-	 * @param IConfig $config
104
-	 * @param IURLGenerator $urlGenerator
105
-	 * @param IUserManager $userManager
106
-	 * @param ILogger $logger
107
-	 * @param \OCP\Activity\IManager $activityManager
108
-	 * @param \OCP\Share\IManager $shareManager
109
-	 * @param ISession $session
110
-	 * @param IPreview $previewManager
111
-	 * @param IRootFolder $rootFolder
112
-	 * @param FederatedShareProvider $federatedShareProvider
113
-	 * @param EventDispatcherInterface $eventDispatcher
114
-	 * @param IL10N $l10n
115
-	 * @param Defaults $defaults
116
-	 */
117
-	public function __construct($appName,
118
-								IRequest $request,
119
-								IConfig $config,
120
-								IURLGenerator $urlGenerator,
121
-								IUserManager $userManager,
122
-								ILogger $logger,
123
-								\OCP\Activity\IManager $activityManager,
124
-								\OCP\Share\IManager $shareManager,
125
-								ISession $session,
126
-								IPreview $previewManager,
127
-								IRootFolder $rootFolder,
128
-								FederatedShareProvider $federatedShareProvider,
129
-								EventDispatcherInterface $eventDispatcher,
130
-								IL10N $l10n,
131
-								Defaults $defaults) {
132
-		parent::__construct($appName, $request);
133
-
134
-		$this->config = $config;
135
-		$this->urlGenerator = $urlGenerator;
136
-		$this->userManager = $userManager;
137
-		$this->logger = $logger;
138
-		$this->activityManager = $activityManager;
139
-		$this->shareManager = $shareManager;
140
-		$this->session = $session;
141
-		$this->previewManager = $previewManager;
142
-		$this->rootFolder = $rootFolder;
143
-		$this->federatedShareProvider = $federatedShareProvider;
144
-		$this->eventDispatcher = $eventDispatcher;
145
-		$this->l10n = $l10n;
146
-		$this->defaults = $defaults;
147
-	}
148
-
149
-	/**
150
-	 * @PublicPage
151
-	 * @NoCSRFRequired
152
-	 *
153
-	 * @param string $token
154
-	 * @return TemplateResponse|RedirectResponse
155
-	 */
156
-	public function showAuthenticate($token) {
157
-		$share = $this->shareManager->getShareByToken($token);
158
-
159
-		if($this->linkShareAuth($share)) {
160
-			return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token)));
161
-		}
162
-
163
-		return new TemplateResponse($this->appName, 'authenticate', array(), 'guest');
164
-	}
165
-
166
-	/**
167
-	 * @PublicPage
168
-	 * @UseSession
169
-	 * @BruteForceProtection(action=publicLinkAuth)
170
-	 *
171
-	 * Authenticates against password-protected shares
172
-	 * @param string $token
173
-	 * @param string $redirect
174
-	 * @param string $password
175
-	 * @return RedirectResponse|TemplateResponse|NotFoundResponse
176
-	 */
177
-	public function authenticate($token, $redirect = 'preview', $password = '') {
178
-
179
-		// Check whether share exists
180
-		try {
181
-			$share = $this->shareManager->getShareByToken($token);
182
-		} catch (ShareNotFound $e) {
183
-			return new NotFoundResponse();
184
-		}
185
-
186
-		$authenticate = $this->linkShareAuth($share, $password);
187
-
188
-		// if download was requested before auth, redirect to download
189
-		if ($authenticate === true && $redirect === 'download') {
190
-			return new RedirectResponse($this->urlGenerator->linkToRoute(
191
-				'files_sharing.sharecontroller.downloadShare',
192
-				array('token' => $token))
193
-			);
194
-		} else if ($authenticate === true) {
195
-			return new RedirectResponse($this->urlGenerator->linkToRoute(
196
-				'files_sharing.sharecontroller.showShare',
197
-				array('token' => $token))
198
-			);
199
-		}
200
-
201
-		$response = new TemplateResponse($this->appName, 'authenticate', array('wrongpw' => true), 'guest');
202
-		$response->throttle();
203
-		return $response;
204
-	}
205
-
206
-	/**
207
-	 * Authenticate a link item with the given password.
208
-	 * Or use the session if no password is provided.
209
-	 *
210
-	 * This is a modified version of Helper::authenticate
211
-	 * TODO: Try to merge back eventually with Helper::authenticate
212
-	 *
213
-	 * @param \OCP\Share\IShare $share
214
-	 * @param string|null $password
215
-	 * @return bool
216
-	 */
217
-	private function linkShareAuth(\OCP\Share\IShare $share, $password = null) {
218
-		if ($password !== null) {
219
-			if ($this->shareManager->checkPassword($share, $password)) {
220
-				$this->session->set('public_link_authenticated', (string)$share->getId());
221
-			} else {
222
-				$this->emitAccessShareHook($share, 403, 'Wrong password');
223
-				return false;
224
-			}
225
-		} else {
226
-			// not authenticated ?
227
-			if ( ! $this->session->exists('public_link_authenticated')
228
-				|| $this->session->get('public_link_authenticated') !== (string)$share->getId()) {
229
-				return false;
230
-			}
231
-		}
232
-		return true;
233
-	}
234
-
235
-	/**
236
-	 * throws hooks when a share is attempted to be accessed
237
-	 *
238
-	 * @param \OCP\Share\IShare|string $share the Share instance if available,
239
-	 * otherwise token
240
-	 * @param int $errorCode
241
-	 * @param string $errorMessage
242
-	 * @throws \OC\HintException
243
-	 * @throws \OC\ServerNotAvailableException
244
-	 */
245
-	protected function emitAccessShareHook($share, $errorCode = 200, $errorMessage = '') {
246
-		$itemType = $itemSource = $uidOwner = '';
247
-		$token = $share;
248
-		$exception = null;
249
-		if($share instanceof \OCP\Share\IShare) {
250
-			try {
251
-				$token = $share->getToken();
252
-				$uidOwner = $share->getSharedBy();
253
-				$itemType = $share->getNodeType();
254
-				$itemSource = $share->getNodeId();
255
-			} catch (\Exception $e) {
256
-				// we log what we know and pass on the exception afterwards
257
-				$exception = $e;
258
-			}
259
-		}
260
-		\OC_Hook::emit(Share::class, 'share_link_access', [
261
-			'itemType' => $itemType,
262
-			'itemSource' => $itemSource,
263
-			'uidOwner' => $uidOwner,
264
-			'token' => $token,
265
-			'errorCode' => $errorCode,
266
-			'errorMessage' => $errorMessage,
267
-		]);
268
-		if(!is_null($exception)) {
269
-			throw $exception;
270
-		}
271
-	}
272
-
273
-	/**
274
-	 * Validate the permissions of the share
275
-	 *
276
-	 * @param Share\IShare $share
277
-	 * @return bool
278
-	 */
279
-	private function validateShare(\OCP\Share\IShare $share) {
280
-		return $share->getNode()->isReadable() && $share->getNode()->isShareable();
281
-	}
282
-
283
-	/**
284
-	 * @PublicPage
285
-	 * @NoCSRFRequired
286
-	 *
287
-	 * @param string $token
288
-	 * @param string $path
289
-	 * @return TemplateResponse|RedirectResponse|NotFoundResponse
290
-	 * @throws NotFoundException
291
-	 * @throws \Exception
292
-	 */
293
-	public function showShare($token, $path = '') {
294
-		\OC_User::setIncognitoMode(true);
295
-
296
-		// Check whether share exists
297
-		try {
298
-			$share = $this->shareManager->getShareByToken($token);
299
-		} catch (ShareNotFound $e) {
300
-			$this->emitAccessShareHook($token, 404, 'Share not found');
301
-			return new NotFoundResponse();
302
-		}
303
-
304
-		// Share is password protected - check whether the user is permitted to access the share
305
-		if ($share->getPassword() !== null && !$this->linkShareAuth($share)) {
306
-			return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate',
307
-				array('token' => $token, 'redirect' => 'preview')));
308
-		}
309
-
310
-		if (!$this->validateShare($share)) {
311
-			throw new NotFoundException();
312
-		}
313
-		// We can't get the path of a file share
314
-		try {
315
-			if ($share->getNode() instanceof \OCP\Files\File && $path !== '') {
316
-				$this->emitAccessShareHook($share, 404, 'Share not found');
317
-				throw new NotFoundException();
318
-			}
319
-		} catch (\Exception $e) {
320
-			$this->emitAccessShareHook($share, 404, 'Share not found');
321
-			throw $e;
322
-		}
323
-
324
-		$shareTmpl = [];
325
-		$shareTmpl['displayName'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
326
-		$shareTmpl['owner'] = $share->getShareOwner();
327
-		$shareTmpl['filename'] = $share->getNode()->getName();
328
-		$shareTmpl['directory_path'] = $share->getTarget();
329
-		$shareTmpl['mimetype'] = $share->getNode()->getMimetype();
330
-		$shareTmpl['previewSupported'] = $this->previewManager->isMimeSupported($share->getNode()->getMimetype());
331
-		$shareTmpl['dirToken'] = $token;
332
-		$shareTmpl['sharingToken'] = $token;
333
-		$shareTmpl['server2serversharing'] = $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
334
-		$shareTmpl['protected'] = $share->getPassword() !== null ? 'true' : 'false';
335
-		$shareTmpl['dir'] = '';
336
-		$shareTmpl['nonHumanFileSize'] = $share->getNode()->getSize();
337
-		$shareTmpl['fileSize'] = \OCP\Util::humanFileSize($share->getNode()->getSize());
338
-
339
-		// Show file list
340
-		$hideFileList = false;
341
-		if ($share->getNode() instanceof \OCP\Files\Folder) {
342
-			/** @var \OCP\Files\Folder $rootFolder */
343
-			$rootFolder = $share->getNode();
344
-
345
-			try {
346
-				$folderNode = $rootFolder->get($path);
347
-			} catch (\OCP\Files\NotFoundException $e) {
348
-				$this->emitAccessShareHook($share, 404, 'Share not found');
349
-				throw new NotFoundException();
350
-			}
351
-
352
-			$shareTmpl['dir'] = $rootFolder->getRelativePath($folderNode->getPath());
353
-
354
-			/*
73
+    /** @var IConfig */
74
+    protected $config;
75
+    /** @var IURLGenerator */
76
+    protected $urlGenerator;
77
+    /** @var IUserManager */
78
+    protected $userManager;
79
+    /** @var ILogger */
80
+    protected $logger;
81
+    /** @var \OCP\Activity\IManager */
82
+    protected $activityManager;
83
+    /** @var \OCP\Share\IManager */
84
+    protected $shareManager;
85
+    /** @var ISession */
86
+    protected $session;
87
+    /** @var IPreview */
88
+    protected $previewManager;
89
+    /** @var IRootFolder */
90
+    protected $rootFolder;
91
+    /** @var FederatedShareProvider */
92
+    protected $federatedShareProvider;
93
+    /** @var EventDispatcherInterface */
94
+    protected $eventDispatcher;
95
+    /** @var IL10N */
96
+    protected $l10n;
97
+    /** @var Defaults */
98
+    protected $defaults;
99
+
100
+    /**
101
+     * @param string $appName
102
+     * @param IRequest $request
103
+     * @param IConfig $config
104
+     * @param IURLGenerator $urlGenerator
105
+     * @param IUserManager $userManager
106
+     * @param ILogger $logger
107
+     * @param \OCP\Activity\IManager $activityManager
108
+     * @param \OCP\Share\IManager $shareManager
109
+     * @param ISession $session
110
+     * @param IPreview $previewManager
111
+     * @param IRootFolder $rootFolder
112
+     * @param FederatedShareProvider $federatedShareProvider
113
+     * @param EventDispatcherInterface $eventDispatcher
114
+     * @param IL10N $l10n
115
+     * @param Defaults $defaults
116
+     */
117
+    public function __construct($appName,
118
+                                IRequest $request,
119
+                                IConfig $config,
120
+                                IURLGenerator $urlGenerator,
121
+                                IUserManager $userManager,
122
+                                ILogger $logger,
123
+                                \OCP\Activity\IManager $activityManager,
124
+                                \OCP\Share\IManager $shareManager,
125
+                                ISession $session,
126
+                                IPreview $previewManager,
127
+                                IRootFolder $rootFolder,
128
+                                FederatedShareProvider $federatedShareProvider,
129
+                                EventDispatcherInterface $eventDispatcher,
130
+                                IL10N $l10n,
131
+                                Defaults $defaults) {
132
+        parent::__construct($appName, $request);
133
+
134
+        $this->config = $config;
135
+        $this->urlGenerator = $urlGenerator;
136
+        $this->userManager = $userManager;
137
+        $this->logger = $logger;
138
+        $this->activityManager = $activityManager;
139
+        $this->shareManager = $shareManager;
140
+        $this->session = $session;
141
+        $this->previewManager = $previewManager;
142
+        $this->rootFolder = $rootFolder;
143
+        $this->federatedShareProvider = $federatedShareProvider;
144
+        $this->eventDispatcher = $eventDispatcher;
145
+        $this->l10n = $l10n;
146
+        $this->defaults = $defaults;
147
+    }
148
+
149
+    /**
150
+     * @PublicPage
151
+     * @NoCSRFRequired
152
+     *
153
+     * @param string $token
154
+     * @return TemplateResponse|RedirectResponse
155
+     */
156
+    public function showAuthenticate($token) {
157
+        $share = $this->shareManager->getShareByToken($token);
158
+
159
+        if($this->linkShareAuth($share)) {
160
+            return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token)));
161
+        }
162
+
163
+        return new TemplateResponse($this->appName, 'authenticate', array(), 'guest');
164
+    }
165
+
166
+    /**
167
+     * @PublicPage
168
+     * @UseSession
169
+     * @BruteForceProtection(action=publicLinkAuth)
170
+     *
171
+     * Authenticates against password-protected shares
172
+     * @param string $token
173
+     * @param string $redirect
174
+     * @param string $password
175
+     * @return RedirectResponse|TemplateResponse|NotFoundResponse
176
+     */
177
+    public function authenticate($token, $redirect = 'preview', $password = '') {
178
+
179
+        // Check whether share exists
180
+        try {
181
+            $share = $this->shareManager->getShareByToken($token);
182
+        } catch (ShareNotFound $e) {
183
+            return new NotFoundResponse();
184
+        }
185
+
186
+        $authenticate = $this->linkShareAuth($share, $password);
187
+
188
+        // if download was requested before auth, redirect to download
189
+        if ($authenticate === true && $redirect === 'download') {
190
+            return new RedirectResponse($this->urlGenerator->linkToRoute(
191
+                'files_sharing.sharecontroller.downloadShare',
192
+                array('token' => $token))
193
+            );
194
+        } else if ($authenticate === true) {
195
+            return new RedirectResponse($this->urlGenerator->linkToRoute(
196
+                'files_sharing.sharecontroller.showShare',
197
+                array('token' => $token))
198
+            );
199
+        }
200
+
201
+        $response = new TemplateResponse($this->appName, 'authenticate', array('wrongpw' => true), 'guest');
202
+        $response->throttle();
203
+        return $response;
204
+    }
205
+
206
+    /**
207
+     * Authenticate a link item with the given password.
208
+     * Or use the session if no password is provided.
209
+     *
210
+     * This is a modified version of Helper::authenticate
211
+     * TODO: Try to merge back eventually with Helper::authenticate
212
+     *
213
+     * @param \OCP\Share\IShare $share
214
+     * @param string|null $password
215
+     * @return bool
216
+     */
217
+    private function linkShareAuth(\OCP\Share\IShare $share, $password = null) {
218
+        if ($password !== null) {
219
+            if ($this->shareManager->checkPassword($share, $password)) {
220
+                $this->session->set('public_link_authenticated', (string)$share->getId());
221
+            } else {
222
+                $this->emitAccessShareHook($share, 403, 'Wrong password');
223
+                return false;
224
+            }
225
+        } else {
226
+            // not authenticated ?
227
+            if ( ! $this->session->exists('public_link_authenticated')
228
+                || $this->session->get('public_link_authenticated') !== (string)$share->getId()) {
229
+                return false;
230
+            }
231
+        }
232
+        return true;
233
+    }
234
+
235
+    /**
236
+     * throws hooks when a share is attempted to be accessed
237
+     *
238
+     * @param \OCP\Share\IShare|string $share the Share instance if available,
239
+     * otherwise token
240
+     * @param int $errorCode
241
+     * @param string $errorMessage
242
+     * @throws \OC\HintException
243
+     * @throws \OC\ServerNotAvailableException
244
+     */
245
+    protected function emitAccessShareHook($share, $errorCode = 200, $errorMessage = '') {
246
+        $itemType = $itemSource = $uidOwner = '';
247
+        $token = $share;
248
+        $exception = null;
249
+        if($share instanceof \OCP\Share\IShare) {
250
+            try {
251
+                $token = $share->getToken();
252
+                $uidOwner = $share->getSharedBy();
253
+                $itemType = $share->getNodeType();
254
+                $itemSource = $share->getNodeId();
255
+            } catch (\Exception $e) {
256
+                // we log what we know and pass on the exception afterwards
257
+                $exception = $e;
258
+            }
259
+        }
260
+        \OC_Hook::emit(Share::class, 'share_link_access', [
261
+            'itemType' => $itemType,
262
+            'itemSource' => $itemSource,
263
+            'uidOwner' => $uidOwner,
264
+            'token' => $token,
265
+            'errorCode' => $errorCode,
266
+            'errorMessage' => $errorMessage,
267
+        ]);
268
+        if(!is_null($exception)) {
269
+            throw $exception;
270
+        }
271
+    }
272
+
273
+    /**
274
+     * Validate the permissions of the share
275
+     *
276
+     * @param Share\IShare $share
277
+     * @return bool
278
+     */
279
+    private function validateShare(\OCP\Share\IShare $share) {
280
+        return $share->getNode()->isReadable() && $share->getNode()->isShareable();
281
+    }
282
+
283
+    /**
284
+     * @PublicPage
285
+     * @NoCSRFRequired
286
+     *
287
+     * @param string $token
288
+     * @param string $path
289
+     * @return TemplateResponse|RedirectResponse|NotFoundResponse
290
+     * @throws NotFoundException
291
+     * @throws \Exception
292
+     */
293
+    public function showShare($token, $path = '') {
294
+        \OC_User::setIncognitoMode(true);
295
+
296
+        // Check whether share exists
297
+        try {
298
+            $share = $this->shareManager->getShareByToken($token);
299
+        } catch (ShareNotFound $e) {
300
+            $this->emitAccessShareHook($token, 404, 'Share not found');
301
+            return new NotFoundResponse();
302
+        }
303
+
304
+        // Share is password protected - check whether the user is permitted to access the share
305
+        if ($share->getPassword() !== null && !$this->linkShareAuth($share)) {
306
+            return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate',
307
+                array('token' => $token, 'redirect' => 'preview')));
308
+        }
309
+
310
+        if (!$this->validateShare($share)) {
311
+            throw new NotFoundException();
312
+        }
313
+        // We can't get the path of a file share
314
+        try {
315
+            if ($share->getNode() instanceof \OCP\Files\File && $path !== '') {
316
+                $this->emitAccessShareHook($share, 404, 'Share not found');
317
+                throw new NotFoundException();
318
+            }
319
+        } catch (\Exception $e) {
320
+            $this->emitAccessShareHook($share, 404, 'Share not found');
321
+            throw $e;
322
+        }
323
+
324
+        $shareTmpl = [];
325
+        $shareTmpl['displayName'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
326
+        $shareTmpl['owner'] = $share->getShareOwner();
327
+        $shareTmpl['filename'] = $share->getNode()->getName();
328
+        $shareTmpl['directory_path'] = $share->getTarget();
329
+        $shareTmpl['mimetype'] = $share->getNode()->getMimetype();
330
+        $shareTmpl['previewSupported'] = $this->previewManager->isMimeSupported($share->getNode()->getMimetype());
331
+        $shareTmpl['dirToken'] = $token;
332
+        $shareTmpl['sharingToken'] = $token;
333
+        $shareTmpl['server2serversharing'] = $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
334
+        $shareTmpl['protected'] = $share->getPassword() !== null ? 'true' : 'false';
335
+        $shareTmpl['dir'] = '';
336
+        $shareTmpl['nonHumanFileSize'] = $share->getNode()->getSize();
337
+        $shareTmpl['fileSize'] = \OCP\Util::humanFileSize($share->getNode()->getSize());
338
+
339
+        // Show file list
340
+        $hideFileList = false;
341
+        if ($share->getNode() instanceof \OCP\Files\Folder) {
342
+            /** @var \OCP\Files\Folder $rootFolder */
343
+            $rootFolder = $share->getNode();
344
+
345
+            try {
346
+                $folderNode = $rootFolder->get($path);
347
+            } catch (\OCP\Files\NotFoundException $e) {
348
+                $this->emitAccessShareHook($share, 404, 'Share not found');
349
+                throw new NotFoundException();
350
+            }
351
+
352
+            $shareTmpl['dir'] = $rootFolder->getRelativePath($folderNode->getPath());
353
+
354
+            /*
355 355
 			 * The OC_Util methods require a view. This just uses the node API
356 356
 			 */
357
-			$freeSpace = $share->getNode()->getStorage()->free_space($share->getNode()->getInternalPath());
358
-			if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
359
-				$freeSpace = max($freeSpace, 0);
360
-			} else {
361
-				$freeSpace = (INF > 0) ? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
362
-			}
363
-
364
-			$hideFileList = !($share->getPermissions() & \OCP\Constants::PERMISSION_READ);
365
-			$maxUploadFilesize = $freeSpace;
366
-
367
-			$folder = new Template('files', 'list', '');
368
-			$folder->assign('dir', $rootFolder->getRelativePath($folderNode->getPath()));
369
-			$folder->assign('dirToken', $token);
370
-			$folder->assign('permissions', \OCP\Constants::PERMISSION_READ);
371
-			$folder->assign('isPublic', true);
372
-			$folder->assign('hideFileList', $hideFileList);
373
-			$folder->assign('publicUploadEnabled', 'no');
374
-			$folder->assign('uploadMaxFilesize', $maxUploadFilesize);
375
-			$folder->assign('uploadMaxHumanFilesize', \OCP\Util::humanFileSize($maxUploadFilesize));
376
-			$folder->assign('freeSpace', $freeSpace);
377
-			$folder->assign('usedSpacePercent', 0);
378
-			$folder->assign('trash', false);
379
-			$shareTmpl['folder'] = $folder->fetchPage();
380
-		}
381
-
382
-		$shareTmpl['hideFileList'] = $hideFileList;
383
-		$shareTmpl['shareOwner'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
384
-		$shareTmpl['downloadURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadShare', ['token' => $token]);
385
-		$shareTmpl['shareUrl'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $token]);
386
-		$shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10);
387
-		$shareTmpl['previewEnabled'] = $this->config->getSystemValue('enable_previews', true);
388
-		$shareTmpl['previewMaxX'] = $this->config->getSystemValue('preview_max_x', 1024);
389
-		$shareTmpl['previewMaxY'] = $this->config->getSystemValue('preview_max_y', 1024);
390
-		$shareTmpl['disclaimer'] = $this->config->getAppValue('core', 'shareapi_public_link_disclaimertext', null);
391
-		$shareTmpl['previewURL'] = $shareTmpl['downloadURL'];
392
-		$ogPreview = '';
393
-		if ($shareTmpl['previewSupported']) {
394
-			$shareTmpl['previewImage'] = $this->urlGenerator->linkToRouteAbsolute( 'files_sharing.PublicPreview.getPreview',
395
-				['x' => 200, 'y' => 200, 'file' => $shareTmpl['directory_path'], 't' => $shareTmpl['dirToken']]);
396
-			$ogPreview = $shareTmpl['previewImage'];
397
-
398
-			// We just have direct previews for image files
399
-			if ($share->getNode()->getMimePart() === 'image') {
400
-				$shareTmpl['previewURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.publicpreview.directLink', ['token' => $token]);
401
-
402
-				$ogPreview = $shareTmpl['previewURL'];
403
-
404
-				//Whatapp is kind of picky about their size requirements
405
-				if ($this->request->isUserAgent(['/^WhatsApp/'])) {
406
-					$ogPreview = $this->urlGenerator->linkToRouteAbsolute('files_sharing.PublicPreview.getPreview', [
407
-						't' => $token,
408
-						'x' => 256,
409
-						'y' => 256,
410
-						'a' => true,
411
-					]);
412
-				}
413
-			}
414
-		} else {
415
-			$shareTmpl['previewImage'] = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'favicon-fb.png'));
416
-			$ogPreview = $shareTmpl['previewImage'];
417
-		}
418
-
419
-		// Load files we need
420
-		\OCP\Util::addScript('files', 'file-upload');
421
-		\OCP\Util::addStyle('files_sharing', 'publicView');
422
-		\OCP\Util::addScript('files_sharing', 'public');
423
-		\OCP\Util::addScript('files', 'fileactions');
424
-		\OCP\Util::addScript('files', 'fileactionsmenu');
425
-		\OCP\Util::addScript('files', 'jquery.fileupload');
426
-		\OCP\Util::addScript('files_sharing', 'files_drop');
427
-
428
-		if (isset($shareTmpl['folder'])) {
429
-			// JS required for folders
430
-			\OCP\Util::addStyle('files', 'merged');
431
-			\OCP\Util::addScript('files', 'filesummary');
432
-			\OCP\Util::addScript('files', 'breadcrumb');
433
-			\OCP\Util::addScript('files', 'fileinfomodel');
434
-			\OCP\Util::addScript('files', 'newfilemenu');
435
-			\OCP\Util::addScript('files', 'files');
436
-			\OCP\Util::addScript('files', 'filelist');
437
-			\OCP\Util::addScript('files', 'keyboardshortcuts');
438
-		}
439
-
440
-		// OpenGraph Support: http://ogp.me/
441
-		\OCP\Util::addHeader('meta', ['property' => "og:title", 'content' => $shareTmpl['filename']]);
442
-		\OCP\Util::addHeader('meta', ['property' => "og:description", 'content' => $this->defaults->getName() . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : '')]);
443
-		\OCP\Util::addHeader('meta', ['property' => "og:site_name", 'content' => $this->defaults->getName()]);
444
-		\OCP\Util::addHeader('meta', ['property' => "og:url", 'content' => $shareTmpl['shareUrl']]);
445
-		\OCP\Util::addHeader('meta', ['property' => "og:type", 'content' => "object"]);
446
-		\OCP\Util::addHeader('meta', ['property' => "og:image", 'content' => $ogPreview]);
447
-
448
-		$this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts');
449
-
450
-		$csp = new \OCP\AppFramework\Http\ContentSecurityPolicy();
451
-		$csp->addAllowedFrameDomain('\'self\'');
452
-
453
-		$response = new PublicTemplateResponse($this->appName, 'public', $shareTmpl);
454
-		$response->setHeaderTitle($shareTmpl['filename']);
455
-		$response->setHeaderDetails($this->l10n->t('shared by %s', [$shareTmpl['displayName']]));
456
-		$response->setHeaderActions([
457
-			new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download-white', $shareTmpl['downloadURL'], 0),
458
-			new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download', $shareTmpl['downloadURL'], 10, $shareTmpl['fileSize']),
459
-			new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', $shareTmpl['previewURL']),
460
-			new ExternalShareMenuAction($this->l10n->t('Add to your Nextcloud'), 'icon-external', $shareTmpl['owner'], $shareTmpl['displayName'], $shareTmpl['filename']),
461
-		]);
462
-
463
-		$response->setContentSecurityPolicy($csp);
464
-
465
-		$this->emitAccessShareHook($share);
466
-
467
-		return $response;
468
-	}
469
-
470
-	/**
471
-	 * @PublicPage
472
-	 * @NoCSRFRequired
473
-	 *
474
-	 * @param string $token
475
-	 * @param string $files
476
-	 * @param string $path
477
-	 * @param string $downloadStartSecret
478
-	 * @return void|\OCP\AppFramework\Http\Response
479
-	 * @throws NotFoundException
480
-	 */
481
-	public function downloadShare($token, $files = null, $path = '', $downloadStartSecret = '') {
482
-		\OC_User::setIncognitoMode(true);
483
-
484
-		$share = $this->shareManager->getShareByToken($token);
485
-
486
-		if(!($share->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
487
-			return new \OCP\AppFramework\Http\DataResponse('Share is read-only');
488
-		}
489
-
490
-		// Share is password protected - check whether the user is permitted to access the share
491
-		if ($share->getPassword() !== null && !$this->linkShareAuth($share)) {
492
-			return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate',
493
-				['token' => $token, 'redirect' => 'download']));
494
-		}
495
-
496
-		$files_list = null;
497
-		if (!is_null($files)) { // download selected files
498
-			$files_list = json_decode($files);
499
-			// in case we get only a single file
500
-			if ($files_list === null) {
501
-				$files_list = [$files];
502
-			}
503
-			// Just in case $files is a single int like '1234'
504
-			if (!is_array($files_list)) {
505
-				$files_list = [$files_list];
506
-			}
507
-		}
508
-
509
-		$userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
510
-		$originalSharePath = $userFolder->getRelativePath($share->getNode()->getPath());
511
-
512
-		if (!$this->validateShare($share)) {
513
-			throw new NotFoundException();
514
-		}
515
-
516
-		// Single file share
517
-		if ($share->getNode() instanceof \OCP\Files\File) {
518
-			// Single file download
519
-			$this->singleFileDownloaded($share, $share->getNode());
520
-		}
521
-		// Directory share
522
-		else {
523
-			/** @var \OCP\Files\Folder $node */
524
-			$node = $share->getNode();
525
-
526
-			// Try to get the path
527
-			if ($path !== '') {
528
-				try {
529
-					$node = $node->get($path);
530
-				} catch (NotFoundException $e) {
531
-					$this->emitAccessShareHook($share, 404, 'Share not found');
532
-					return new NotFoundResponse();
533
-				}
534
-			}
535
-
536
-			$originalSharePath = $userFolder->getRelativePath($node->getPath());
537
-
538
-			if ($node instanceof \OCP\Files\File) {
539
-				// Single file download
540
-				$this->singleFileDownloaded($share, $share->getNode());
541
-			} else if (!empty($files_list)) {
542
-				$this->fileListDownloaded($share, $files_list, $node);
543
-			} else {
544
-				// The folder is downloaded
545
-				$this->singleFileDownloaded($share, $share->getNode());
546
-			}
547
-		}
548
-
549
-		/* FIXME: We should do this all nicely in OCP */
550
-		OC_Util::tearDownFS();
551
-		OC_Util::setupFS($share->getShareOwner());
552
-
553
-		/**
554
-		 * this sets a cookie to be able to recognize the start of the download
555
-		 * the content must not be longer than 32 characters and must only contain
556
-		 * alphanumeric characters
557
-		 */
558
-		if (!empty($downloadStartSecret)
559
-			&& !isset($downloadStartSecret[32])
560
-			&& preg_match('!^[a-zA-Z0-9]+$!', $downloadStartSecret) === 1) {
561
-
562
-			// FIXME: set on the response once we use an actual app framework response
563
-			setcookie('ocDownloadStarted', $downloadStartSecret, time() + 20, '/');
564
-		}
565
-
566
-		$this->emitAccessShareHook($share);
567
-
568
-		$server_params = array( 'head' => $this->request->getMethod() === 'HEAD' );
569
-
570
-		/**
571
-		 * Http range requests support
572
-		 */
573
-		if (isset($_SERVER['HTTP_RANGE'])) {
574
-			$server_params['range'] = $this->request->getHeader('Range');
575
-		}
576
-
577
-		// download selected files
578
-		if (!is_null($files) && $files !== '') {
579
-			// FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
580
-			// after dispatching the request which results in a "Cannot modify header information" notice.
581
-			OC_Files::get($originalSharePath, $files_list, $server_params);
582
-			exit();
583
-		} else {
584
-			// FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
585
-			// after dispatching the request which results in a "Cannot modify header information" notice.
586
-			OC_Files::get(dirname($originalSharePath), basename($originalSharePath), $server_params);
587
-			exit();
588
-		}
589
-	}
590
-
591
-	/**
592
-	 * create activity for every downloaded file
593
-	 *
594
-	 * @param Share\IShare $share
595
-	 * @param array $files_list
596
-	 * @param \OCP\Files\Folder $node
597
-	 */
598
-	protected function fileListDownloaded(Share\IShare $share, array $files_list, \OCP\Files\Folder $node) {
599
-		foreach ($files_list as $file) {
600
-			$subNode = $node->get($file);
601
-			$this->singleFileDownloaded($share, $subNode);
602
-		}
603
-
604
-	}
605
-
606
-	/**
607
-	 * create activity if a single file was downloaded from a link share
608
-	 *
609
-	 * @param Share\IShare $share
610
-	 */
611
-	protected function singleFileDownloaded(Share\IShare $share, \OCP\Files\Node $node) {
612
-
613
-		$fileId = $node->getId();
614
-
615
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
616
-		$userNodeList = $userFolder->getById($fileId);
617
-		$userNode = $userNodeList[0];
618
-		$ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
619
-		$userPath = $userFolder->getRelativePath($userNode->getPath());
620
-		$ownerPath = $ownerFolder->getRelativePath($node->getPath());
621
-
622
-		$parameters = [$userPath];
623
-
624
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
625
-			if ($node instanceof \OCP\Files\File) {
626
-				$subject = Downloads::SUBJECT_SHARED_FILE_BY_EMAIL_DOWNLOADED;
627
-			} else {
628
-				$subject = Downloads::SUBJECT_SHARED_FOLDER_BY_EMAIL_DOWNLOADED;
629
-			}
630
-			$parameters[] = $share->getSharedWith();
631
-		} else {
632
-			if ($node instanceof \OCP\Files\File) {
633
-				$subject = Downloads::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED;
634
-			} else {
635
-				$subject = Downloads::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED;
636
-			}
637
-		}
638
-
639
-		$this->publishActivity($subject, $parameters, $share->getSharedBy(), $fileId, $userPath);
640
-
641
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
642
-			$parameters[0] = $ownerPath;
643
-			$this->publishActivity($subject, $parameters, $share->getShareOwner(), $fileId, $ownerPath);
644
-		}
645
-	}
646
-
647
-	/**
648
-	 * publish activity
649
-	 *
650
-	 * @param string $subject
651
-	 * @param array $parameters
652
-	 * @param string $affectedUser
653
-	 * @param int $fileId
654
-	 * @param string $filePath
655
-	 */
656
-	protected function publishActivity($subject,
657
-										array $parameters,
658
-										$affectedUser,
659
-										$fileId,
660
-										$filePath) {
661
-
662
-		$event = $this->activityManager->generateEvent();
663
-		$event->setApp('files_sharing')
664
-			->setType('public_links')
665
-			->setSubject($subject, $parameters)
666
-			->setAffectedUser($affectedUser)
667
-			->setObject('files', $fileId, $filePath);
668
-		$this->activityManager->publish($event);
669
-	}
357
+            $freeSpace = $share->getNode()->getStorage()->free_space($share->getNode()->getInternalPath());
358
+            if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
359
+                $freeSpace = max($freeSpace, 0);
360
+            } else {
361
+                $freeSpace = (INF > 0) ? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
362
+            }
363
+
364
+            $hideFileList = !($share->getPermissions() & \OCP\Constants::PERMISSION_READ);
365
+            $maxUploadFilesize = $freeSpace;
366
+
367
+            $folder = new Template('files', 'list', '');
368
+            $folder->assign('dir', $rootFolder->getRelativePath($folderNode->getPath()));
369
+            $folder->assign('dirToken', $token);
370
+            $folder->assign('permissions', \OCP\Constants::PERMISSION_READ);
371
+            $folder->assign('isPublic', true);
372
+            $folder->assign('hideFileList', $hideFileList);
373
+            $folder->assign('publicUploadEnabled', 'no');
374
+            $folder->assign('uploadMaxFilesize', $maxUploadFilesize);
375
+            $folder->assign('uploadMaxHumanFilesize', \OCP\Util::humanFileSize($maxUploadFilesize));
376
+            $folder->assign('freeSpace', $freeSpace);
377
+            $folder->assign('usedSpacePercent', 0);
378
+            $folder->assign('trash', false);
379
+            $shareTmpl['folder'] = $folder->fetchPage();
380
+        }
381
+
382
+        $shareTmpl['hideFileList'] = $hideFileList;
383
+        $shareTmpl['shareOwner'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
384
+        $shareTmpl['downloadURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadShare', ['token' => $token]);
385
+        $shareTmpl['shareUrl'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $token]);
386
+        $shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10);
387
+        $shareTmpl['previewEnabled'] = $this->config->getSystemValue('enable_previews', true);
388
+        $shareTmpl['previewMaxX'] = $this->config->getSystemValue('preview_max_x', 1024);
389
+        $shareTmpl['previewMaxY'] = $this->config->getSystemValue('preview_max_y', 1024);
390
+        $shareTmpl['disclaimer'] = $this->config->getAppValue('core', 'shareapi_public_link_disclaimertext', null);
391
+        $shareTmpl['previewURL'] = $shareTmpl['downloadURL'];
392
+        $ogPreview = '';
393
+        if ($shareTmpl['previewSupported']) {
394
+            $shareTmpl['previewImage'] = $this->urlGenerator->linkToRouteAbsolute( 'files_sharing.PublicPreview.getPreview',
395
+                ['x' => 200, 'y' => 200, 'file' => $shareTmpl['directory_path'], 't' => $shareTmpl['dirToken']]);
396
+            $ogPreview = $shareTmpl['previewImage'];
397
+
398
+            // We just have direct previews for image files
399
+            if ($share->getNode()->getMimePart() === 'image') {
400
+                $shareTmpl['previewURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.publicpreview.directLink', ['token' => $token]);
401
+
402
+                $ogPreview = $shareTmpl['previewURL'];
403
+
404
+                //Whatapp is kind of picky about their size requirements
405
+                if ($this->request->isUserAgent(['/^WhatsApp/'])) {
406
+                    $ogPreview = $this->urlGenerator->linkToRouteAbsolute('files_sharing.PublicPreview.getPreview', [
407
+                        't' => $token,
408
+                        'x' => 256,
409
+                        'y' => 256,
410
+                        'a' => true,
411
+                    ]);
412
+                }
413
+            }
414
+        } else {
415
+            $shareTmpl['previewImage'] = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'favicon-fb.png'));
416
+            $ogPreview = $shareTmpl['previewImage'];
417
+        }
418
+
419
+        // Load files we need
420
+        \OCP\Util::addScript('files', 'file-upload');
421
+        \OCP\Util::addStyle('files_sharing', 'publicView');
422
+        \OCP\Util::addScript('files_sharing', 'public');
423
+        \OCP\Util::addScript('files', 'fileactions');
424
+        \OCP\Util::addScript('files', 'fileactionsmenu');
425
+        \OCP\Util::addScript('files', 'jquery.fileupload');
426
+        \OCP\Util::addScript('files_sharing', 'files_drop');
427
+
428
+        if (isset($shareTmpl['folder'])) {
429
+            // JS required for folders
430
+            \OCP\Util::addStyle('files', 'merged');
431
+            \OCP\Util::addScript('files', 'filesummary');
432
+            \OCP\Util::addScript('files', 'breadcrumb');
433
+            \OCP\Util::addScript('files', 'fileinfomodel');
434
+            \OCP\Util::addScript('files', 'newfilemenu');
435
+            \OCP\Util::addScript('files', 'files');
436
+            \OCP\Util::addScript('files', 'filelist');
437
+            \OCP\Util::addScript('files', 'keyboardshortcuts');
438
+        }
439
+
440
+        // OpenGraph Support: http://ogp.me/
441
+        \OCP\Util::addHeader('meta', ['property' => "og:title", 'content' => $shareTmpl['filename']]);
442
+        \OCP\Util::addHeader('meta', ['property' => "og:description", 'content' => $this->defaults->getName() . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : '')]);
443
+        \OCP\Util::addHeader('meta', ['property' => "og:site_name", 'content' => $this->defaults->getName()]);
444
+        \OCP\Util::addHeader('meta', ['property' => "og:url", 'content' => $shareTmpl['shareUrl']]);
445
+        \OCP\Util::addHeader('meta', ['property' => "og:type", 'content' => "object"]);
446
+        \OCP\Util::addHeader('meta', ['property' => "og:image", 'content' => $ogPreview]);
447
+
448
+        $this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts');
449
+
450
+        $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy();
451
+        $csp->addAllowedFrameDomain('\'self\'');
452
+
453
+        $response = new PublicTemplateResponse($this->appName, 'public', $shareTmpl);
454
+        $response->setHeaderTitle($shareTmpl['filename']);
455
+        $response->setHeaderDetails($this->l10n->t('shared by %s', [$shareTmpl['displayName']]));
456
+        $response->setHeaderActions([
457
+            new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download-white', $shareTmpl['downloadURL'], 0),
458
+            new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download', $shareTmpl['downloadURL'], 10, $shareTmpl['fileSize']),
459
+            new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', $shareTmpl['previewURL']),
460
+            new ExternalShareMenuAction($this->l10n->t('Add to your Nextcloud'), 'icon-external', $shareTmpl['owner'], $shareTmpl['displayName'], $shareTmpl['filename']),
461
+        ]);
462
+
463
+        $response->setContentSecurityPolicy($csp);
464
+
465
+        $this->emitAccessShareHook($share);
466
+
467
+        return $response;
468
+    }
469
+
470
+    /**
471
+     * @PublicPage
472
+     * @NoCSRFRequired
473
+     *
474
+     * @param string $token
475
+     * @param string $files
476
+     * @param string $path
477
+     * @param string $downloadStartSecret
478
+     * @return void|\OCP\AppFramework\Http\Response
479
+     * @throws NotFoundException
480
+     */
481
+    public function downloadShare($token, $files = null, $path = '', $downloadStartSecret = '') {
482
+        \OC_User::setIncognitoMode(true);
483
+
484
+        $share = $this->shareManager->getShareByToken($token);
485
+
486
+        if(!($share->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
487
+            return new \OCP\AppFramework\Http\DataResponse('Share is read-only');
488
+        }
489
+
490
+        // Share is password protected - check whether the user is permitted to access the share
491
+        if ($share->getPassword() !== null && !$this->linkShareAuth($share)) {
492
+            return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate',
493
+                ['token' => $token, 'redirect' => 'download']));
494
+        }
495
+
496
+        $files_list = null;
497
+        if (!is_null($files)) { // download selected files
498
+            $files_list = json_decode($files);
499
+            // in case we get only a single file
500
+            if ($files_list === null) {
501
+                $files_list = [$files];
502
+            }
503
+            // Just in case $files is a single int like '1234'
504
+            if (!is_array($files_list)) {
505
+                $files_list = [$files_list];
506
+            }
507
+        }
508
+
509
+        $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
510
+        $originalSharePath = $userFolder->getRelativePath($share->getNode()->getPath());
511
+
512
+        if (!$this->validateShare($share)) {
513
+            throw new NotFoundException();
514
+        }
515
+
516
+        // Single file share
517
+        if ($share->getNode() instanceof \OCP\Files\File) {
518
+            // Single file download
519
+            $this->singleFileDownloaded($share, $share->getNode());
520
+        }
521
+        // Directory share
522
+        else {
523
+            /** @var \OCP\Files\Folder $node */
524
+            $node = $share->getNode();
525
+
526
+            // Try to get the path
527
+            if ($path !== '') {
528
+                try {
529
+                    $node = $node->get($path);
530
+                } catch (NotFoundException $e) {
531
+                    $this->emitAccessShareHook($share, 404, 'Share not found');
532
+                    return new NotFoundResponse();
533
+                }
534
+            }
535
+
536
+            $originalSharePath = $userFolder->getRelativePath($node->getPath());
537
+
538
+            if ($node instanceof \OCP\Files\File) {
539
+                // Single file download
540
+                $this->singleFileDownloaded($share, $share->getNode());
541
+            } else if (!empty($files_list)) {
542
+                $this->fileListDownloaded($share, $files_list, $node);
543
+            } else {
544
+                // The folder is downloaded
545
+                $this->singleFileDownloaded($share, $share->getNode());
546
+            }
547
+        }
548
+
549
+        /* FIXME: We should do this all nicely in OCP */
550
+        OC_Util::tearDownFS();
551
+        OC_Util::setupFS($share->getShareOwner());
552
+
553
+        /**
554
+         * this sets a cookie to be able to recognize the start of the download
555
+         * the content must not be longer than 32 characters and must only contain
556
+         * alphanumeric characters
557
+         */
558
+        if (!empty($downloadStartSecret)
559
+            && !isset($downloadStartSecret[32])
560
+            && preg_match('!^[a-zA-Z0-9]+$!', $downloadStartSecret) === 1) {
561
+
562
+            // FIXME: set on the response once we use an actual app framework response
563
+            setcookie('ocDownloadStarted', $downloadStartSecret, time() + 20, '/');
564
+        }
565
+
566
+        $this->emitAccessShareHook($share);
567
+
568
+        $server_params = array( 'head' => $this->request->getMethod() === 'HEAD' );
569
+
570
+        /**
571
+         * Http range requests support
572
+         */
573
+        if (isset($_SERVER['HTTP_RANGE'])) {
574
+            $server_params['range'] = $this->request->getHeader('Range');
575
+        }
576
+
577
+        // download selected files
578
+        if (!is_null($files) && $files !== '') {
579
+            // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
580
+            // after dispatching the request which results in a "Cannot modify header information" notice.
581
+            OC_Files::get($originalSharePath, $files_list, $server_params);
582
+            exit();
583
+        } else {
584
+            // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
585
+            // after dispatching the request which results in a "Cannot modify header information" notice.
586
+            OC_Files::get(dirname($originalSharePath), basename($originalSharePath), $server_params);
587
+            exit();
588
+        }
589
+    }
590
+
591
+    /**
592
+     * create activity for every downloaded file
593
+     *
594
+     * @param Share\IShare $share
595
+     * @param array $files_list
596
+     * @param \OCP\Files\Folder $node
597
+     */
598
+    protected function fileListDownloaded(Share\IShare $share, array $files_list, \OCP\Files\Folder $node) {
599
+        foreach ($files_list as $file) {
600
+            $subNode = $node->get($file);
601
+            $this->singleFileDownloaded($share, $subNode);
602
+        }
603
+
604
+    }
605
+
606
+    /**
607
+     * create activity if a single file was downloaded from a link share
608
+     *
609
+     * @param Share\IShare $share
610
+     */
611
+    protected function singleFileDownloaded(Share\IShare $share, \OCP\Files\Node $node) {
612
+
613
+        $fileId = $node->getId();
614
+
615
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
616
+        $userNodeList = $userFolder->getById($fileId);
617
+        $userNode = $userNodeList[0];
618
+        $ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
619
+        $userPath = $userFolder->getRelativePath($userNode->getPath());
620
+        $ownerPath = $ownerFolder->getRelativePath($node->getPath());
621
+
622
+        $parameters = [$userPath];
623
+
624
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
625
+            if ($node instanceof \OCP\Files\File) {
626
+                $subject = Downloads::SUBJECT_SHARED_FILE_BY_EMAIL_DOWNLOADED;
627
+            } else {
628
+                $subject = Downloads::SUBJECT_SHARED_FOLDER_BY_EMAIL_DOWNLOADED;
629
+            }
630
+            $parameters[] = $share->getSharedWith();
631
+        } else {
632
+            if ($node instanceof \OCP\Files\File) {
633
+                $subject = Downloads::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED;
634
+            } else {
635
+                $subject = Downloads::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED;
636
+            }
637
+        }
638
+
639
+        $this->publishActivity($subject, $parameters, $share->getSharedBy(), $fileId, $userPath);
640
+
641
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
642
+            $parameters[0] = $ownerPath;
643
+            $this->publishActivity($subject, $parameters, $share->getShareOwner(), $fileId, $ownerPath);
644
+        }
645
+    }
646
+
647
+    /**
648
+     * publish activity
649
+     *
650
+     * @param string $subject
651
+     * @param array $parameters
652
+     * @param string $affectedUser
653
+     * @param int $fileId
654
+     * @param string $filePath
655
+     */
656
+    protected function publishActivity($subject,
657
+                                        array $parameters,
658
+                                        $affectedUser,
659
+                                        $fileId,
660
+                                        $filePath) {
661
+
662
+        $event = $this->activityManager->generateEvent();
663
+        $event->setApp('files_sharing')
664
+            ->setType('public_links')
665
+            ->setSubject($subject, $parameters)
666
+            ->setAffectedUser($affectedUser)
667
+            ->setObject('files', $fileId, $filePath);
668
+        $this->activityManager->publish($event);
669
+    }
670 670
 
671 671
 
672 672
 }
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -156,7 +156,7 @@  discard block
 block discarded – undo
156 156
 	public function showAuthenticate($token) {
157 157
 		$share = $this->shareManager->getShareByToken($token);
158 158
 
159
-		if($this->linkShareAuth($share)) {
159
+		if ($this->linkShareAuth($share)) {
160 160
 			return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token)));
161 161
 		}
162 162
 
@@ -217,15 +217,15 @@  discard block
 block discarded – undo
217 217
 	private function linkShareAuth(\OCP\Share\IShare $share, $password = null) {
218 218
 		if ($password !== null) {
219 219
 			if ($this->shareManager->checkPassword($share, $password)) {
220
-				$this->session->set('public_link_authenticated', (string)$share->getId());
220
+				$this->session->set('public_link_authenticated', (string) $share->getId());
221 221
 			} else {
222 222
 				$this->emitAccessShareHook($share, 403, 'Wrong password');
223 223
 				return false;
224 224
 			}
225 225
 		} else {
226 226
 			// not authenticated ?
227
-			if ( ! $this->session->exists('public_link_authenticated')
228
-				|| $this->session->get('public_link_authenticated') !== (string)$share->getId()) {
227
+			if (!$this->session->exists('public_link_authenticated')
228
+				|| $this->session->get('public_link_authenticated') !== (string) $share->getId()) {
229 229
 				return false;
230 230
 			}
231 231
 		}
@@ -246,7 +246,7 @@  discard block
 block discarded – undo
246 246
 		$itemType = $itemSource = $uidOwner = '';
247 247
 		$token = $share;
248 248
 		$exception = null;
249
-		if($share instanceof \OCP\Share\IShare) {
249
+		if ($share instanceof \OCP\Share\IShare) {
250 250
 			try {
251 251
 				$token = $share->getToken();
252 252
 				$uidOwner = $share->getSharedBy();
@@ -265,7 +265,7 @@  discard block
 block discarded – undo
265 265
 			'errorCode' => $errorCode,
266 266
 			'errorMessage' => $errorMessage,
267 267
 		]);
268
-		if(!is_null($exception)) {
268
+		if (!is_null($exception)) {
269 269
 			throw $exception;
270 270
 		}
271 271
 	}
@@ -391,7 +391,7 @@  discard block
 block discarded – undo
391 391
 		$shareTmpl['previewURL'] = $shareTmpl['downloadURL'];
392 392
 		$ogPreview = '';
393 393
 		if ($shareTmpl['previewSupported']) {
394
-			$shareTmpl['previewImage'] = $this->urlGenerator->linkToRouteAbsolute( 'files_sharing.PublicPreview.getPreview',
394
+			$shareTmpl['previewImage'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.PublicPreview.getPreview',
395 395
 				['x' => 200, 'y' => 200, 'file' => $shareTmpl['directory_path'], 't' => $shareTmpl['dirToken']]);
396 396
 			$ogPreview = $shareTmpl['previewImage'];
397 397
 
@@ -439,7 +439,7 @@  discard block
 block discarded – undo
439 439
 
440 440
 		// OpenGraph Support: http://ogp.me/
441 441
 		\OCP\Util::addHeader('meta', ['property' => "og:title", 'content' => $shareTmpl['filename']]);
442
-		\OCP\Util::addHeader('meta', ['property' => "og:description", 'content' => $this->defaults->getName() . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : '')]);
442
+		\OCP\Util::addHeader('meta', ['property' => "og:description", 'content' => $this->defaults->getName().($this->defaults->getSlogan() !== '' ? ' - '.$this->defaults->getSlogan() : '')]);
443 443
 		\OCP\Util::addHeader('meta', ['property' => "og:site_name", 'content' => $this->defaults->getName()]);
444 444
 		\OCP\Util::addHeader('meta', ['property' => "og:url", 'content' => $shareTmpl['shareUrl']]);
445 445
 		\OCP\Util::addHeader('meta', ['property' => "og:type", 'content' => "object"]);
@@ -483,7 +483,7 @@  discard block
 block discarded – undo
483 483
 
484 484
 		$share = $this->shareManager->getShareByToken($token);
485 485
 
486
-		if(!($share->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
486
+		if (!($share->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
487 487
 			return new \OCP\AppFramework\Http\DataResponse('Share is read-only');
488 488
 		}
489 489
 
@@ -565,7 +565,7 @@  discard block
 block discarded – undo
565 565
 
566 566
 		$this->emitAccessShareHook($share);
567 567
 
568
-		$server_params = array( 'head' => $this->request->getMethod() === 'HEAD' );
568
+		$server_params = array('head' => $this->request->getMethod() === 'HEAD');
569 569
 
570 570
 		/**
571 571
 		 * Http range requests support
Please login to merge, or discard this patch.
core/routes.php 1 patch
Indentation   +79 added lines, -79 removed lines patch added patch discarded remove patch
@@ -36,44 +36,44 @@  discard block
 block discarded – undo
36 36
 
37 37
 $application = new Application();
38 38
 $application->registerRoutes($this, [
39
-	'routes' => [
40
-		['name' => 'lost#email', 'url' => '/lostpassword/email', 'verb' => 'POST'],
41
-		['name' => 'lost#resetform', 'url' => '/lostpassword/reset/form/{token}/{userId}', 'verb' => 'GET'],
42
-		['name' => 'lost#setPassword', 'url' => '/lostpassword/set/{token}/{userId}', 'verb' => 'POST'],
43
-		['name' => 'user#getDisplayNames', 'url' => '/displaynames', 'verb' => 'POST'],
44
-		['name' => 'avatar#getAvatar', 'url' => '/avatar/{userId}/{size}', 'verb' => 'GET'],
45
-		['name' => 'avatar#deleteAvatar', 'url' => '/avatar/', 'verb' => 'DELETE'],
46
-		['name' => 'avatar#postCroppedAvatar', 'url' => '/avatar/cropped', 'verb' => 'POST'],
47
-		['name' => 'avatar#getTmpAvatar', 'url' => '/avatar/tmp', 'verb' => 'GET'],
48
-		['name' => 'avatar#postAvatar', 'url' => '/avatar/', 'verb' => 'POST'],
49
-		['name' => 'login#tryLogin', 'url' => '/login', 'verb' => 'POST'],
50
-		['name' => 'login#confirmPassword', 'url' => '/login/confirm', 'verb' => 'POST'],
51
-		['name' => 'login#showLoginForm', 'url' => '/login', 'verb' => 'GET'],
52
-		['name' => 'login#logout', 'url' => '/logout', 'verb' => 'GET'],
53
-		['name' => 'ClientFlowLogin#showAuthPickerPage', 'url' => '/login/flow', 'verb' => 'GET'],
54
-		['name' => 'ClientFlowLogin#redirectPage', 'url' => '/login/flow/redirect', 'verb' => 'GET'],
55
-		['name' => 'ClientFlowLogin#generateAppPassword', 'url' => '/login/flow', 'verb' => 'POST'],
56
-		['name' => 'TwoFactorChallenge#selectChallenge', 'url' => '/login/selectchallenge', 'verb' => 'GET'],
57
-		['name' => 'TwoFactorChallenge#showChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'GET'],
58
-		['name' => 'TwoFactorChallenge#solveChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'POST'],
59
-		['name' => 'OCJS#getConfig', 'url' => '/core/js/oc.js', 'verb' => 'GET'],
60
-		['name' => 'Preview#getPreviewByFileId', 'url' => '/core/preview', 'verb' => 'GET'],
61
-		['name' => 'Preview#getPreview', 'url' => '/core/preview.png', 'verb' => 'GET'],
62
-		['name' => 'Css#getCss', 'url' => '/css/{appName}/{fileName}', 'verb' => 'GET'],
63
-		['name' => 'Js#getJs', 'url' => '/js/{appName}/{fileName}', 'verb' => 'GET'],
64
-		['name' => 'contactsMenu#index', 'url' => '/contactsmenu/contacts', 'verb' => 'POST'],
65
-		['name' => 'contactsMenu#findOne', 'url' => '/contactsmenu/findOne', 'verb' => 'POST'],
66
-		['name' => 'AutoComplete#get', 'url' => 'autocomplete/get', 'verb' => 'GET'],
67
-		['name' => 'WalledGarden#get', 'url' => '/204', 'verb' => 'GET'],
68
-	],
69
-	'ocs' => [
70
-		['root' => '/cloud', 'name' => 'OCS#getCapabilities', 'url' => '/capabilities', 'verb' => 'GET'],
71
-		['root' => '', 'name' => 'OCS#getConfig', 'url' => '/config', 'verb' => 'GET'],
72
-		['root' => '/person', 'name' => 'OCS#personCheck', 'url' => '/check', 'verb' => 'POST'],
73
-		['root' => '/identityproof', 'name' => 'OCS#getIdentityProof', 'url' => '/key/{cloudId}', 'verb' => 'GET'],
74
-		['root' => '/core', 'name' => 'Navigation#getAppsNavigation', 'url' => '/navigation/apps', 'verb' => 'GET'],
75
-		['root' => '/core', 'name' => 'Navigation#getSettingsNavigation', 'url' => '/navigation/settings', 'verb' => 'GET'],
76
-	],
39
+    'routes' => [
40
+        ['name' => 'lost#email', 'url' => '/lostpassword/email', 'verb' => 'POST'],
41
+        ['name' => 'lost#resetform', 'url' => '/lostpassword/reset/form/{token}/{userId}', 'verb' => 'GET'],
42
+        ['name' => 'lost#setPassword', 'url' => '/lostpassword/set/{token}/{userId}', 'verb' => 'POST'],
43
+        ['name' => 'user#getDisplayNames', 'url' => '/displaynames', 'verb' => 'POST'],
44
+        ['name' => 'avatar#getAvatar', 'url' => '/avatar/{userId}/{size}', 'verb' => 'GET'],
45
+        ['name' => 'avatar#deleteAvatar', 'url' => '/avatar/', 'verb' => 'DELETE'],
46
+        ['name' => 'avatar#postCroppedAvatar', 'url' => '/avatar/cropped', 'verb' => 'POST'],
47
+        ['name' => 'avatar#getTmpAvatar', 'url' => '/avatar/tmp', 'verb' => 'GET'],
48
+        ['name' => 'avatar#postAvatar', 'url' => '/avatar/', 'verb' => 'POST'],
49
+        ['name' => 'login#tryLogin', 'url' => '/login', 'verb' => 'POST'],
50
+        ['name' => 'login#confirmPassword', 'url' => '/login/confirm', 'verb' => 'POST'],
51
+        ['name' => 'login#showLoginForm', 'url' => '/login', 'verb' => 'GET'],
52
+        ['name' => 'login#logout', 'url' => '/logout', 'verb' => 'GET'],
53
+        ['name' => 'ClientFlowLogin#showAuthPickerPage', 'url' => '/login/flow', 'verb' => 'GET'],
54
+        ['name' => 'ClientFlowLogin#redirectPage', 'url' => '/login/flow/redirect', 'verb' => 'GET'],
55
+        ['name' => 'ClientFlowLogin#generateAppPassword', 'url' => '/login/flow', 'verb' => 'POST'],
56
+        ['name' => 'TwoFactorChallenge#selectChallenge', 'url' => '/login/selectchallenge', 'verb' => 'GET'],
57
+        ['name' => 'TwoFactorChallenge#showChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'GET'],
58
+        ['name' => 'TwoFactorChallenge#solveChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'POST'],
59
+        ['name' => 'OCJS#getConfig', 'url' => '/core/js/oc.js', 'verb' => 'GET'],
60
+        ['name' => 'Preview#getPreviewByFileId', 'url' => '/core/preview', 'verb' => 'GET'],
61
+        ['name' => 'Preview#getPreview', 'url' => '/core/preview.png', 'verb' => 'GET'],
62
+        ['name' => 'Css#getCss', 'url' => '/css/{appName}/{fileName}', 'verb' => 'GET'],
63
+        ['name' => 'Js#getJs', 'url' => '/js/{appName}/{fileName}', 'verb' => 'GET'],
64
+        ['name' => 'contactsMenu#index', 'url' => '/contactsmenu/contacts', 'verb' => 'POST'],
65
+        ['name' => 'contactsMenu#findOne', 'url' => '/contactsmenu/findOne', 'verb' => 'POST'],
66
+        ['name' => 'AutoComplete#get', 'url' => 'autocomplete/get', 'verb' => 'GET'],
67
+        ['name' => 'WalledGarden#get', 'url' => '/204', 'verb' => 'GET'],
68
+    ],
69
+    'ocs' => [
70
+        ['root' => '/cloud', 'name' => 'OCS#getCapabilities', 'url' => '/capabilities', 'verb' => 'GET'],
71
+        ['root' => '', 'name' => 'OCS#getConfig', 'url' => '/config', 'verb' => 'GET'],
72
+        ['root' => '/person', 'name' => 'OCS#personCheck', 'url' => '/check', 'verb' => 'POST'],
73
+        ['root' => '/identityproof', 'name' => 'OCS#getIdentityProof', 'url' => '/key/{cloudId}', 'verb' => 'GET'],
74
+        ['root' => '/core', 'name' => 'Navigation#getAppsNavigation', 'url' => '/navigation/apps', 'verb' => 'GET'],
75
+        ['root' => '/core', 'name' => 'Navigation#getSettingsNavigation', 'url' => '/navigation/settings', 'verb' => 'GET'],
76
+    ],
77 77
 ]);
78 78
 
79 79
 // Post installation check
@@ -82,15 +82,15 @@  discard block
 block discarded – undo
82 82
 // Core ajax actions
83 83
 // Search
84 84
 $this->create('search_ajax_search', '/core/search')
85
-	->actionInclude('core/search/ajax/search.php');
85
+    ->actionInclude('core/search/ajax/search.php');
86 86
 // Routing
87 87
 $this->create('core_ajax_update', '/core/ajax/update.php')
88
-	->actionInclude('core/ajax/update.php');
88
+    ->actionInclude('core/ajax/update.php');
89 89
 
90 90
 // File routes
91 91
 $this->create('files.viewcontroller.showFile', '/f/{fileid}')->action(function($urlParams) {
92
-	$app = new \OCA\Files\AppInfo\Application($urlParams);
93
-	$app->dispatch('ViewController', 'index');
92
+    $app = new \OCA\Files\AppInfo\Application($urlParams);
93
+    $app->dispatch('ViewController', 'index');
94 94
 });
95 95
 
96 96
 // Call routes
@@ -99,57 +99,57 @@  discard block
 block discarded – undo
99 99
  * @suppress PhanUndeclaredClassMethod
100 100
  */
101 101
 $this->create('spreed.pagecontroller.showCall', '/call/{token}')->action(function($urlParams) {
102
-	if (class_exists(\OCA\Spreed\AppInfo\Application::class, false)) {
103
-		$app = new \OCA\Spreed\AppInfo\Application($urlParams);
104
-		$app->dispatch('PageController', 'index');
105
-	} else {
106
-		throw new \OC\HintException('App spreed is not enabled');
107
-	}
102
+    if (class_exists(\OCA\Spreed\AppInfo\Application::class, false)) {
103
+        $app = new \OCA\Spreed\AppInfo\Application($urlParams);
104
+        $app->dispatch('PageController', 'index');
105
+    } else {
106
+        throw new \OC\HintException('App spreed is not enabled');
107
+    }
108 108
 });
109 109
 
110 110
 // Sharing routes
111 111
 $this->create('files_sharing.sharecontroller.showShare', '/s/{token}')->action(function($urlParams) {
112
-	if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
113
-		$app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
114
-		$app->dispatch('ShareController', 'showShare');
115
-	} else {
116
-		throw new \OC\HintException('App file sharing is not enabled');
117
-	}
112
+    if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
113
+        $app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
114
+        $app->dispatch('ShareController', 'showShare');
115
+    } else {
116
+        throw new \OC\HintException('App file sharing is not enabled');
117
+    }
118 118
 });
119 119
 $this->create('files_sharing.sharecontroller.authenticate', '/s/{token}/authenticate/{redirect}')->post()->action(function($urlParams) {
120
-	if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
121
-		$app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
122
-		$app->dispatch('ShareController', 'authenticate');
123
-	} else {
124
-		throw new \OC\HintException('App file sharing is not enabled');
125
-	}
120
+    if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
121
+        $app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
122
+        $app->dispatch('ShareController', 'authenticate');
123
+    } else {
124
+        throw new \OC\HintException('App file sharing is not enabled');
125
+    }
126 126
 });
127 127
 $this->create('files_sharing.sharecontroller.showAuthenticate', '/s/{token}/authenticate/{redirect}')->get()->action(function($urlParams) {
128
-	if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
129
-		$app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
130
-		$app->dispatch('ShareController', 'showAuthenticate');
131
-	} else {
132
-		throw new \OC\HintException('App file sharing is not enabled');
133
-	}
128
+    if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
129
+        $app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
130
+        $app->dispatch('ShareController', 'showAuthenticate');
131
+    } else {
132
+        throw new \OC\HintException('App file sharing is not enabled');
133
+    }
134 134
 });
135 135
 $this->create('files_sharing.sharecontroller.downloadShare', '/s/{token}/download')->get()->action(function($urlParams) {
136
-	if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
137
-		$app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
138
-		$app->dispatch('ShareController', 'downloadShare');
139
-	} else {
140
-		throw new \OC\HintException('App file sharing is not enabled');
141
-	}
136
+    if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
137
+        $app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
138
+        $app->dispatch('ShareController', 'downloadShare');
139
+    } else {
140
+        throw new \OC\HintException('App file sharing is not enabled');
141
+    }
142 142
 });
143 143
 $this->create('files_sharing.publicpreview.directLink', '/s/{token}/preview')->get()->action(function($urlParams) {
144
-	if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
145
-		$app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
146
-		$app->dispatch('PublicPreviewController', 'directLink');
147
-	} else {
148
-		throw new \OC\HintException('App file sharing is not enabled');
149
-	}
144
+    if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
145
+        $app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
146
+        $app->dispatch('PublicPreviewController', 'directLink');
147
+    } else {
148
+        throw new \OC\HintException('App file sharing is not enabled');
149
+    }
150 150
 });
151 151
 
152 152
 // used for heartbeat
153 153
 $this->create('heartbeat', '/heartbeat')->action(function(){
154
-	// do nothing
154
+    // do nothing
155 155
 });
Please login to merge, or discard this patch.