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