Passed
Push — master ( 3eb5ac...514185 )
by Roeland
15:00
created
core/Migrations/Version15000Date20181015062942.php 1 patch
Indentation   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -32,23 +32,23 @@
 block discarded – undo
32 32
 
33 33
 class Version15000Date20181015062942 extends SimpleMigrationStep {
34 34
 
35
-	/**
36
-	 * @param IOutput $output
37
-	 * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
38
-	 * @param array $options
39
-	 * @return null|ISchemaWrapper
40
-	 */
41
-	public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
42
-		/** @var ISchemaWrapper $schema */
43
-		$schema = $schemaClosure();
35
+    /**
36
+     * @param IOutput $output
37
+     * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
38
+     * @param array $options
39
+     * @return null|ISchemaWrapper
40
+     */
41
+    public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
42
+        /** @var ISchemaWrapper $schema */
43
+        $schema = $schemaClosure();
44 44
 
45
-		$table = $schema->getTable('share');
46
-		$table->addColumn('hide_download', 'smallint', [
47
-			'notnull' => true,
48
-			'length' => 1,
49
-			'default' => 0,
50
-		]);
45
+        $table = $schema->getTable('share');
46
+        $table->addColumn('hide_download', 'smallint', [
47
+            'notnull' => true,
48
+            'length' => 1,
49
+            'default' => 0,
50
+        ]);
51 51
 
52
-		return $schema;
53
-	}
52
+        return $schema;
53
+    }
54 54
 }
Please login to merge, or discard this patch.
apps/files_sharing/templates/public.php 1 patch
Braces   +10 added lines, -4 removed lines patch added patch discarded remove patch
@@ -50,17 +50,23 @@
 block discarded – undo
50 50
 		<div id="preview">
51 51
 			<?php if (isset($_['folder'])): ?>
52 52
 				<?php print_unescaped($_['folder']); ?>
53
-			<?php else: ?>
53
+			<?php else {
54
+    : ?>
54 55
 				<?php if ($_['previewEnabled'] && substr($_['mimetype'], 0, strpos($_['mimetype'], '/')) == 'audio'): ?>
55 56
 					<div id="imgframe">
56
-						<audio tabindex="0" controls="" preload="none" style="width: 100%; max-width: <?php p($_['previewMaxX']); ?>px; max-height: <?php p($_['previewMaxY']); ?>px">
57
+						<audio tabindex="0" controls="" preload="none" style="width: 100%; max-width: <?php p($_['previewMaxX']);
58
+}
59
+?>px; max-height: <?php p($_['previewMaxY']); ?>px">
57 60
 							<source src="<?php p($_['downloadURL']); ?>" type="<?php p($_['mimetype']); ?>" />
58 61
 						</audio>
59 62
 					</div>
60
-				<?php else: ?>
63
+				<?php else {
64
+    : ?>
61 65
 					<!-- Preview frame is filled via JS to support SVG images for modern browsers -->
62 66
 					<div id="imgframe"></div>
63
-				<?php endif; ?>
67
+				<?php endif;
68
+}
69
+?>
64 70
 				<?php if ($_['previewURL'] === $_['downloadURL'] && !$_['hideDownload']): ?>
65 71
 					<div class="directDownload">
66 72
 						<a href="<?php p($_['downloadURL']); ?>" id="downloadFile" class="button">
Please login to merge, or discard this patch.
apps/files_sharing/lib/Controller/ShareController.php 1 patch
Indentation   +581 added lines, -582 removed lines patch added patch discarded remove patch
@@ -73,590 +73,589 @@
 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
-			$csp->allowEvalScript(true);
168
-			$response->setContentSecurityPolicy($csp);
169
-		}
170
-
171
-		return $response;
172
-	}
173
-
174
-	/**
175
-	 * The template to show when authentication failed
176
-	 */
177
-	protected function showAuthFailed(): TemplateResponse {
178
-		$templateParameters = ['share' => $this->share, 'wrongpw' => true];
179
-
180
-		$event = new GenericEvent(null, $templateParameters);
181
-		$this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts::publicShareAuth', $event);
182
-
183
-		$response = new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
184
-		if ($this->share->getSendPasswordByTalk()) {
185
-			$csp = new ContentSecurityPolicy();
186
-			$csp->addAllowedConnectDomain('*');
187
-			$csp->addAllowedMediaDomain('blob:');
188
-			$csp->allowEvalScript(true);
189
-			$response->setContentSecurityPolicy($csp);
190
-		}
191
-
192
-		return $response;
193
-	}
194
-
195
-	protected function verifyPassword(string $password): bool {
196
-		return $this->shareManager->checkPassword($this->share, $password);
197
-	}
198
-
199
-	protected function getPasswordHash(): string {
200
-		return $this->share->getPassword();
201
-	}
202
-
203
-	public function isValidToken(): bool {
204
-		try {
205
-			$this->share = $this->shareManager->getShareByToken($this->getToken());
206
-		} catch (ShareNotFound $e) {
207
-			return false;
208
-		}
209
-
210
-		return true;
211
-	}
212
-
213
-	protected function isPasswordProtected(): bool {
214
-		return $this->share->getPassword() !== null;
215
-	}
216
-
217
-	protected function authSucceeded() {
218
-		// For share this was always set so it is still used in other apps
219
-		$this->session->set('public_link_authenticated', (string)$this->share->getId());
220
-	}
221
-
222
-	protected function authFailed() {
223
-		$this->emitAccessShareHook($this->share, 403, 'Wrong password');
224
-	}
225
-
226
-	/**
227
-	 * throws hooks when a share is attempted to be accessed
228
-	 *
229
-	 * @param \OCP\Share\IShare|string $share the Share instance if available,
230
-	 * otherwise token
231
-	 * @param int $errorCode
232
-	 * @param string $errorMessage
233
-	 * @throws \OC\HintException
234
-	 * @throws \OC\ServerNotAvailableException
235
-	 */
236
-	protected function emitAccessShareHook($share, $errorCode = 200, $errorMessage = '') {
237
-		$itemType = $itemSource = $uidOwner = '';
238
-		$token = $share;
239
-		$exception = null;
240
-		if($share instanceof \OCP\Share\IShare) {
241
-			try {
242
-				$token = $share->getToken();
243
-				$uidOwner = $share->getSharedBy();
244
-				$itemType = $share->getNodeType();
245
-				$itemSource = $share->getNodeId();
246
-			} catch (\Exception $e) {
247
-				// we log what we know and pass on the exception afterwards
248
-				$exception = $e;
249
-			}
250
-		}
251
-		\OC_Hook::emit(Share::class, 'share_link_access', [
252
-			'itemType' => $itemType,
253
-			'itemSource' => $itemSource,
254
-			'uidOwner' => $uidOwner,
255
-			'token' => $token,
256
-			'errorCode' => $errorCode,
257
-			'errorMessage' => $errorMessage,
258
-		]);
259
-		if(!is_null($exception)) {
260
-			throw $exception;
261
-		}
262
-	}
263
-
264
-	/**
265
-	 * Validate the permissions of the share
266
-	 *
267
-	 * @param Share\IShare $share
268
-	 * @return bool
269
-	 */
270
-	private function validateShare(\OCP\Share\IShare $share) {
271
-		return $share->getNode()->isReadable() && $share->getNode()->isShareable();
272
-	}
273
-
274
-	/**
275
-	 * @PublicPage
276
-	 * @NoCSRFRequired
277
-	 *
278
-
279
-	 * @param string $path
280
-	 * @return TemplateResponse
281
-	 * @throws NotFoundException
282
-	 * @throws \Exception
283
-	 */
284
-	public function showShare($path = ''): TemplateResponse {
285
-		\OC_User::setIncognitoMode(true);
286
-
287
-		// Check whether share exists
288
-		try {
289
-			$share = $this->shareManager->getShareByToken($this->getToken());
290
-		} catch (ShareNotFound $e) {
291
-			$this->emitAccessShareHook($this->getToken(), 404, 'Share not found');
292
-			throw new NotFoundException();
293
-		}
294
-
295
-		if (!$this->validateShare($share)) {
296
-			throw new NotFoundException();
297
-		}
298
-		// We can't get the path of a file share
299
-		try {
300
-			if ($share->getNode() 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'] = $share->getNode()->getName();
313
-		$shareTmpl['directory_path'] = $share->getTarget();
314
-		$shareTmpl['note'] = $share->getNote();
315
-		$shareTmpl['mimetype'] = $share->getNode()->getMimetype();
316
-		$shareTmpl['previewSupported'] = $this->previewManager->isMimeSupported($share->getNode()->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'] = $share->getNode()->getSize();
323
-		$shareTmpl['fileSize'] = \OCP\Util::humanFileSize($share->getNode()->getSize());
324
-		$shareTmpl['hideDownload'] = $share->getHideDownload();
325
-
326
-		// Show file list
327
-		$hideFileList = false;
328
-		if ($share->getNode() instanceof \OCP\Files\Folder) {
329
-			/** @var \OCP\Files\Folder $rootFolder */
330
-			$rootFolder = $share->getNode();
331
-
332
-			try {
333
-				$folderNode = $rootFolder->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'] = $rootFolder->getRelativePath($folderNode->getPath());
340
-
341
-			/*
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
+            $csp->allowEvalScript(true);
168
+            $response->setContentSecurityPolicy($csp);
169
+        }
170
+
171
+        return $response;
172
+    }
173
+
174
+    /**
175
+     * The template to show when authentication failed
176
+     */
177
+    protected function showAuthFailed(): TemplateResponse {
178
+        $templateParameters = ['share' => $this->share, 'wrongpw' => true];
179
+
180
+        $event = new GenericEvent(null, $templateParameters);
181
+        $this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts::publicShareAuth', $event);
182
+
183
+        $response = new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
184
+        if ($this->share->getSendPasswordByTalk()) {
185
+            $csp = new ContentSecurityPolicy();
186
+            $csp->addAllowedConnectDomain('*');
187
+            $csp->addAllowedMediaDomain('blob:');
188
+            $csp->allowEvalScript(true);
189
+            $response->setContentSecurityPolicy($csp);
190
+        }
191
+
192
+        return $response;
193
+    }
194
+
195
+    protected function verifyPassword(string $password): bool {
196
+        return $this->shareManager->checkPassword($this->share, $password);
197
+    }
198
+
199
+    protected function getPasswordHash(): string {
200
+        return $this->share->getPassword();
201
+    }
202
+
203
+    public function isValidToken(): bool {
204
+        try {
205
+            $this->share = $this->shareManager->getShareByToken($this->getToken());
206
+        } catch (ShareNotFound $e) {
207
+            return false;
208
+        }
209
+
210
+        return true;
211
+    }
212
+
213
+    protected function isPasswordProtected(): bool {
214
+        return $this->share->getPassword() !== null;
215
+    }
216
+
217
+    protected function authSucceeded() {
218
+        // For share this was always set so it is still used in other apps
219
+        $this->session->set('public_link_authenticated', (string)$this->share->getId());
220
+    }
221
+
222
+    protected function authFailed() {
223
+        $this->emitAccessShareHook($this->share, 403, 'Wrong password');
224
+    }
225
+
226
+    /**
227
+     * throws hooks when a share is attempted to be accessed
228
+     *
229
+     * @param \OCP\Share\IShare|string $share the Share instance if available,
230
+     * otherwise token
231
+     * @param int $errorCode
232
+     * @param string $errorMessage
233
+     * @throws \OC\HintException
234
+     * @throws \OC\ServerNotAvailableException
235
+     */
236
+    protected function emitAccessShareHook($share, $errorCode = 200, $errorMessage = '') {
237
+        $itemType = $itemSource = $uidOwner = '';
238
+        $token = $share;
239
+        $exception = null;
240
+        if($share instanceof \OCP\Share\IShare) {
241
+            try {
242
+                $token = $share->getToken();
243
+                $uidOwner = $share->getSharedBy();
244
+                $itemType = $share->getNodeType();
245
+                $itemSource = $share->getNodeId();
246
+            } catch (\Exception $e) {
247
+                // we log what we know and pass on the exception afterwards
248
+                $exception = $e;
249
+            }
250
+        }
251
+        \OC_Hook::emit(Share::class, 'share_link_access', [
252
+            'itemType' => $itemType,
253
+            'itemSource' => $itemSource,
254
+            'uidOwner' => $uidOwner,
255
+            'token' => $token,
256
+            'errorCode' => $errorCode,
257
+            'errorMessage' => $errorMessage,
258
+        ]);
259
+        if(!is_null($exception)) {
260
+            throw $exception;
261
+        }
262
+    }
263
+
264
+    /**
265
+     * Validate the permissions of the share
266
+     *
267
+     * @param Share\IShare $share
268
+     * @return bool
269
+     */
270
+    private function validateShare(\OCP\Share\IShare $share) {
271
+        return $share->getNode()->isReadable() && $share->getNode()->isShareable();
272
+    }
273
+
274
+    /**
275
+     * @PublicPage
276
+     * @NoCSRFRequired
277
+     *
278
+     * @param string $path
279
+     * @return TemplateResponse
280
+     * @throws NotFoundException
281
+     * @throws \Exception
282
+     */
283
+    public function showShare($path = ''): TemplateResponse {
284
+        \OC_User::setIncognitoMode(true);
285
+
286
+        // Check whether share exists
287
+        try {
288
+            $share = $this->shareManager->getShareByToken($this->getToken());
289
+        } catch (ShareNotFound $e) {
290
+            $this->emitAccessShareHook($this->getToken(), 404, 'Share not found');
291
+            throw new NotFoundException();
292
+        }
293
+
294
+        if (!$this->validateShare($share)) {
295
+            throw new NotFoundException();
296
+        }
297
+        // We can't get the path of a file share
298
+        try {
299
+            if ($share->getNode() instanceof \OCP\Files\File && $path !== '') {
300
+                $this->emitAccessShareHook($share, 404, 'Share not found');
301
+                throw new NotFoundException();
302
+            }
303
+        } catch (\Exception $e) {
304
+            $this->emitAccessShareHook($share, 404, 'Share not found');
305
+            throw $e;
306
+        }
307
+
308
+        $shareTmpl = [];
309
+        $shareTmpl['displayName'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
310
+        $shareTmpl['owner'] = $share->getShareOwner();
311
+        $shareTmpl['filename'] = $share->getNode()->getName();
312
+        $shareTmpl['directory_path'] = $share->getTarget();
313
+        $shareTmpl['note'] = $share->getNote();
314
+        $shareTmpl['mimetype'] = $share->getNode()->getMimetype();
315
+        $shareTmpl['previewSupported'] = $this->previewManager->isMimeSupported($share->getNode()->getMimetype());
316
+        $shareTmpl['dirToken'] = $this->getToken();
317
+        $shareTmpl['sharingToken'] = $this->getToken();
318
+        $shareTmpl['server2serversharing'] = $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
319
+        $shareTmpl['protected'] = $share->getPassword() !== null ? 'true' : 'false';
320
+        $shareTmpl['dir'] = '';
321
+        $shareTmpl['nonHumanFileSize'] = $share->getNode()->getSize();
322
+        $shareTmpl['fileSize'] = \OCP\Util::humanFileSize($share->getNode()->getSize());
323
+        $shareTmpl['hideDownload'] = $share->getHideDownload();
324
+
325
+        // Show file list
326
+        $hideFileList = false;
327
+        if ($share->getNode() instanceof \OCP\Files\Folder) {
328
+            /** @var \OCP\Files\Folder $rootFolder */
329
+            $rootFolder = $share->getNode();
330
+
331
+            try {
332
+                $folderNode = $rootFolder->get($path);
333
+            } catch (\OCP\Files\NotFoundException $e) {
334
+                $this->emitAccessShareHook($share, 404, 'Share not found');
335
+                throw new NotFoundException();
336
+            }
337
+
338
+            $shareTmpl['dir'] = $rootFolder->getRelativePath($folderNode->getPath());
339
+
340
+            /*
342 341
 			 * The OC_Util methods require a view. This just uses the node API
343 342
 			 */
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', $rootFolder->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
-			$folder->assign('showgridview', true);
362
-			$folder->assign('uploadMaxFilesize', $maxUploadFilesize);
363
-			$folder->assign('uploadMaxHumanFilesize', \OCP\Util::humanFileSize($maxUploadFilesize));
364
-			$folder->assign('freeSpace', $freeSpace);
365
-			$folder->assign('usedSpacePercent', 0);
366
-			$folder->assign('trash', false);
367
-			$shareTmpl['folder'] = $folder->fetchPage();
368
-		}
369
-
370
-		$shareTmpl['hideFileList'] = $hideFileList;
371
-		$shareTmpl['shareOwner'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
372
-		$shareTmpl['downloadURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadShare', ['token' => $this->getToken()]);
373
-		$shareTmpl['shareUrl'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $this->getToken()]);
374
-		$shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10);
375
-		$shareTmpl['previewEnabled'] = $this->config->getSystemValue('enable_previews', true);
376
-		$shareTmpl['previewMaxX'] = $this->config->getSystemValue('preview_max_x', 1024);
377
-		$shareTmpl['previewMaxY'] = $this->config->getSystemValue('preview_max_y', 1024);
378
-		$shareTmpl['disclaimer'] = $this->config->getAppValue('core', 'shareapi_public_link_disclaimertext', null);
379
-		$shareTmpl['previewURL'] = $shareTmpl['downloadURL'];
380
-		$ogPreview = '';
381
-		if ($shareTmpl['previewSupported']) {
382
-			$shareTmpl['previewImage'] = $this->urlGenerator->linkToRouteAbsolute( 'files_sharing.PublicPreview.getPreview',
383
-				['x' => 200, 'y' => 200, 'file' => $shareTmpl['directory_path'], 'token' => $shareTmpl['dirToken']]);
384
-			$ogPreview = $shareTmpl['previewImage'];
385
-
386
-			// We just have direct previews for image files
387
-			if ($share->getNode()->getMimePart() === 'image') {
388
-				$shareTmpl['previewURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.publicpreview.directLink', ['token' => $this->getToken()]);
389
-
390
-				$ogPreview = $shareTmpl['previewURL'];
391
-
392
-				//Whatapp is kind of picky about their size requirements
393
-				if ($this->request->isUserAgent(['/^WhatsApp/'])) {
394
-					$ogPreview = $this->urlGenerator->linkToRouteAbsolute('files_sharing.PublicPreview.getPreview', [
395
-						'token' => $this->getToken(),
396
-						'x' => 256,
397
-						'y' => 256,
398
-						'a' => true,
399
-					]);
400
-				}
401
-			}
402
-		} else {
403
-			$shareTmpl['previewImage'] = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'favicon-fb.png'));
404
-			$ogPreview = $shareTmpl['previewImage'];
405
-		}
406
-
407
-		// Load files we need
408
-		\OCP\Util::addScript('files', 'file-upload');
409
-		\OCP\Util::addStyle('files_sharing', 'publicView');
410
-		\OCP\Util::addScript('files_sharing', 'public');
411
-		\OCP\Util::addScript('files_sharing', 'templates');
412
-		\OCP\Util::addScript('files_sharing', 'public_note');
413
-		\OCP\Util::addScript('files', 'fileactions');
414
-		\OCP\Util::addScript('files', 'fileactionsmenu');
415
-		\OCP\Util::addScript('files', 'jquery.fileupload');
416
-		\OCP\Util::addScript('files_sharing', 'files_drop');
417
-
418
-		if (isset($shareTmpl['folder'])) {
419
-			// JS required for folders
420
-			\OCP\Util::addStyle('files', 'merged');
421
-			\OCP\Util::addScript('files', 'filesummary');
422
-			\OCP\Util::addScript('files', 'templates');
423
-			\OCP\Util::addScript('files', 'breadcrumb');
424
-			\OCP\Util::addScript('files', 'fileinfomodel');
425
-			\OCP\Util::addScript('files', 'newfilemenu');
426
-			\OCP\Util::addScript('files', 'files');
427
-			\OCP\Util::addScript('files', 'filemultiselectmenu');
428
-			\OCP\Util::addScript('files', 'filelist');
429
-			\OCP\Util::addScript('files', 'keyboardshortcuts');
430
-		}
431
-
432
-		// OpenGraph Support: http://ogp.me/
433
-		\OCP\Util::addHeader('meta', ['property' => "og:title", 'content' => $shareTmpl['filename']]);
434
-		\OCP\Util::addHeader('meta', ['property' => "og:description", 'content' => $this->defaults->getName() . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : '')]);
435
-		\OCP\Util::addHeader('meta', ['property' => "og:site_name", 'content' => $this->defaults->getName()]);
436
-		\OCP\Util::addHeader('meta', ['property' => "og:url", 'content' => $shareTmpl['shareUrl']]);
437
-		\OCP\Util::addHeader('meta', ['property' => "og:type", 'content' => "object"]);
438
-		\OCP\Util::addHeader('meta', ['property' => "og:image", 'content' => $ogPreview]);
439
-
440
-		$this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts');
441
-
442
-		$csp = new \OCP\AppFramework\Http\ContentSecurityPolicy();
443
-		$csp->addAllowedFrameDomain('\'self\'');
444
-
445
-		$response = new PublicTemplateResponse($this->appName, 'public', $shareTmpl);
446
-		$response->setHeaderTitle($shareTmpl['filename']);
447
-		$response->setHeaderDetails($this->l10n->t('shared by %s', [$shareTmpl['displayName']]));
448
-		if (!$share->getHideDownload()) {
449
-			$response->setHeaderActions([
450
-				new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download-white', $shareTmpl['downloadURL'], 0),
451
-				new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download', $shareTmpl['downloadURL'], 10, $shareTmpl['fileSize']),
452
-				new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', $shareTmpl['previewURL']),
453
-				new ExternalShareMenuAction($this->l10n->t('Add to your Nextcloud'), 'icon-external', $shareTmpl['owner'], $shareTmpl['displayName'], $shareTmpl['filename']),
454
-			]);
455
-		}
456
-
457
-		$response->setContentSecurityPolicy($csp);
458
-
459
-		$this->emitAccessShareHook($share);
460
-
461
-		return $response;
462
-	}
463
-
464
-	/**
465
-	 * @PublicPage
466
-	 * @NoCSRFRequired
467
-	 *
468
-	 * @param string $token
469
-	 * @param string $files
470
-	 * @param string $path
471
-	 * @param string $downloadStartSecret
472
-	 * @return void|\OCP\AppFramework\Http\Response
473
-	 * @throws NotFoundException
474
-	 */
475
-	public function downloadShare($token, $files = null, $path = '', $downloadStartSecret = '') {
476
-		\OC_User::setIncognitoMode(true);
477
-
478
-		$share = $this->shareManager->getShareByToken($token);
479
-
480
-		if(!($share->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
481
-			return new \OCP\AppFramework\Http\DataResponse('Share is read-only');
482
-		}
483
-
484
-		$files_list = null;
485
-		if (!is_null($files)) { // download selected files
486
-			$files_list = json_decode($files);
487
-			// in case we get only a single file
488
-			if ($files_list === null) {
489
-				$files_list = [$files];
490
-			}
491
-			// Just in case $files is a single int like '1234'
492
-			if (!is_array($files_list)) {
493
-				$files_list = [$files_list];
494
-			}
495
-		}
496
-
497
-
498
-		if (!$this->validateShare($share)) {
499
-			throw new NotFoundException();
500
-		}
501
-
502
-		$userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
503
-		$originalSharePath = $userFolder->getRelativePath($share->getNode()->getPath());
504
-
505
-
506
-		// Single file share
507
-		if ($share->getNode() instanceof \OCP\Files\File) {
508
-			// Single file download
509
-			$this->singleFileDownloaded($share, $share->getNode());
510
-		}
511
-		// Directory share
512
-		else {
513
-			/** @var \OCP\Files\Folder $node */
514
-			$node = $share->getNode();
515
-
516
-			// Try to get the path
517
-			if ($path !== '') {
518
-				try {
519
-					$node = $node->get($path);
520
-				} catch (NotFoundException $e) {
521
-					$this->emitAccessShareHook($share, 404, 'Share not found');
522
-					return new NotFoundResponse();
523
-				}
524
-			}
525
-
526
-			$originalSharePath = $userFolder->getRelativePath($node->getPath());
527
-
528
-			if ($node instanceof \OCP\Files\File) {
529
-				// Single file download
530
-				$this->singleFileDownloaded($share, $share->getNode());
531
-			} else if (!empty($files_list)) {
532
-				$this->fileListDownloaded($share, $files_list, $node);
533
-			} else {
534
-				// The folder is downloaded
535
-				$this->singleFileDownloaded($share, $share->getNode());
536
-			}
537
-		}
538
-
539
-		/* FIXME: We should do this all nicely in OCP */
540
-		OC_Util::tearDownFS();
541
-		OC_Util::setupFS($share->getShareOwner());
542
-
543
-		/**
544
-		 * this sets a cookie to be able to recognize the start of the download
545
-		 * the content must not be longer than 32 characters and must only contain
546
-		 * alphanumeric characters
547
-		 */
548
-		if (!empty($downloadStartSecret)
549
-			&& !isset($downloadStartSecret[32])
550
-			&& preg_match('!^[a-zA-Z0-9]+$!', $downloadStartSecret) === 1) {
551
-
552
-			// FIXME: set on the response once we use an actual app framework response
553
-			setcookie('ocDownloadStarted', $downloadStartSecret, time() + 20, '/');
554
-		}
555
-
556
-		$this->emitAccessShareHook($share);
557
-
558
-		$server_params = array( 'head' => $this->request->getMethod() === 'HEAD' );
559
-
560
-		/**
561
-		 * Http range requests support
562
-		 */
563
-		if (isset($_SERVER['HTTP_RANGE'])) {
564
-			$server_params['range'] = $this->request->getHeader('Range');
565
-		}
566
-
567
-		// download selected files
568
-		if (!is_null($files) && $files !== '') {
569
-			// FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
570
-			// after dispatching the request which results in a "Cannot modify header information" notice.
571
-			OC_Files::get($originalSharePath, $files_list, $server_params);
572
-			exit();
573
-		} else {
574
-			// FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
575
-			// after dispatching the request which results in a "Cannot modify header information" notice.
576
-			OC_Files::get(dirname($originalSharePath), basename($originalSharePath), $server_params);
577
-			exit();
578
-		}
579
-	}
580
-
581
-	/**
582
-	 * create activity for every downloaded file
583
-	 *
584
-	 * @param Share\IShare $share
585
-	 * @param array $files_list
586
-	 * @param \OCP\Files\Folder $node
587
-	 */
588
-	protected function fileListDownloaded(Share\IShare $share, array $files_list, \OCP\Files\Folder $node) {
589
-		foreach ($files_list as $file) {
590
-			$subNode = $node->get($file);
591
-			$this->singleFileDownloaded($share, $subNode);
592
-		}
593
-
594
-	}
595
-
596
-	/**
597
-	 * create activity if a single file was downloaded from a link share
598
-	 *
599
-	 * @param Share\IShare $share
600
-	 */
601
-	protected function singleFileDownloaded(Share\IShare $share, \OCP\Files\Node $node) {
602
-
603
-		$fileId = $node->getId();
604
-
605
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
606
-		$userNodeList = $userFolder->getById($fileId);
607
-		$userNode = $userNodeList[0];
608
-		$ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
609
-		$userPath = $userFolder->getRelativePath($userNode->getPath());
610
-		$ownerPath = $ownerFolder->getRelativePath($node->getPath());
611
-
612
-		$parameters = [$userPath];
613
-
614
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
615
-			if ($node instanceof \OCP\Files\File) {
616
-				$subject = Downloads::SUBJECT_SHARED_FILE_BY_EMAIL_DOWNLOADED;
617
-			} else {
618
-				$subject = Downloads::SUBJECT_SHARED_FOLDER_BY_EMAIL_DOWNLOADED;
619
-			}
620
-			$parameters[] = $share->getSharedWith();
621
-		} else {
622
-			if ($node instanceof \OCP\Files\File) {
623
-				$subject = Downloads::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED;
624
-			} else {
625
-				$subject = Downloads::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED;
626
-			}
627
-		}
628
-
629
-		$this->publishActivity($subject, $parameters, $share->getSharedBy(), $fileId, $userPath);
630
-
631
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
632
-			$parameters[0] = $ownerPath;
633
-			$this->publishActivity($subject, $parameters, $share->getShareOwner(), $fileId, $ownerPath);
634
-		}
635
-	}
636
-
637
-	/**
638
-	 * publish activity
639
-	 *
640
-	 * @param string $subject
641
-	 * @param array $parameters
642
-	 * @param string $affectedUser
643
-	 * @param int $fileId
644
-	 * @param string $filePath
645
-	 */
646
-	protected function publishActivity($subject,
647
-										array $parameters,
648
-										$affectedUser,
649
-										$fileId,
650
-										$filePath) {
651
-
652
-		$event = $this->activityManager->generateEvent();
653
-		$event->setApp('files_sharing')
654
-			->setType('public_links')
655
-			->setSubject($subject, $parameters)
656
-			->setAffectedUser($affectedUser)
657
-			->setObject('files', $fileId, $filePath);
658
-		$this->activityManager->publish($event);
659
-	}
343
+            $freeSpace = $share->getNode()->getStorage()->free_space($share->getNode()->getInternalPath());
344
+            if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
345
+                $freeSpace = max($freeSpace, 0);
346
+            } else {
347
+                $freeSpace = (INF > 0) ? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
348
+            }
349
+
350
+            $hideFileList = !($share->getPermissions() & \OCP\Constants::PERMISSION_READ);
351
+            $maxUploadFilesize = $freeSpace;
352
+
353
+            $folder = new Template('files', 'list', '');
354
+            $folder->assign('dir', $rootFolder->getRelativePath($folderNode->getPath()));
355
+            $folder->assign('dirToken', $this->getToken());
356
+            $folder->assign('permissions', \OCP\Constants::PERMISSION_READ);
357
+            $folder->assign('isPublic', true);
358
+            $folder->assign('hideFileList', $hideFileList);
359
+            $folder->assign('publicUploadEnabled', 'no');
360
+            $folder->assign('showgridview', true);
361
+            $folder->assign('uploadMaxFilesize', $maxUploadFilesize);
362
+            $folder->assign('uploadMaxHumanFilesize', \OCP\Util::humanFileSize($maxUploadFilesize));
363
+            $folder->assign('freeSpace', $freeSpace);
364
+            $folder->assign('usedSpacePercent', 0);
365
+            $folder->assign('trash', false);
366
+            $shareTmpl['folder'] = $folder->fetchPage();
367
+        }
368
+
369
+        $shareTmpl['hideFileList'] = $hideFileList;
370
+        $shareTmpl['shareOwner'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
371
+        $shareTmpl['downloadURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadShare', ['token' => $this->getToken()]);
372
+        $shareTmpl['shareUrl'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $this->getToken()]);
373
+        $shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10);
374
+        $shareTmpl['previewEnabled'] = $this->config->getSystemValue('enable_previews', true);
375
+        $shareTmpl['previewMaxX'] = $this->config->getSystemValue('preview_max_x', 1024);
376
+        $shareTmpl['previewMaxY'] = $this->config->getSystemValue('preview_max_y', 1024);
377
+        $shareTmpl['disclaimer'] = $this->config->getAppValue('core', 'shareapi_public_link_disclaimertext', null);
378
+        $shareTmpl['previewURL'] = $shareTmpl['downloadURL'];
379
+        $ogPreview = '';
380
+        if ($shareTmpl['previewSupported']) {
381
+            $shareTmpl['previewImage'] = $this->urlGenerator->linkToRouteAbsolute( 'files_sharing.PublicPreview.getPreview',
382
+                ['x' => 200, 'y' => 200, 'file' => $shareTmpl['directory_path'], 'token' => $shareTmpl['dirToken']]);
383
+            $ogPreview = $shareTmpl['previewImage'];
384
+
385
+            // We just have direct previews for image files
386
+            if ($share->getNode()->getMimePart() === 'image') {
387
+                $shareTmpl['previewURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.publicpreview.directLink', ['token' => $this->getToken()]);
388
+
389
+                $ogPreview = $shareTmpl['previewURL'];
390
+
391
+                //Whatapp is kind of picky about their size requirements
392
+                if ($this->request->isUserAgent(['/^WhatsApp/'])) {
393
+                    $ogPreview = $this->urlGenerator->linkToRouteAbsolute('files_sharing.PublicPreview.getPreview', [
394
+                        'token' => $this->getToken(),
395
+                        'x' => 256,
396
+                        'y' => 256,
397
+                        'a' => true,
398
+                    ]);
399
+                }
400
+            }
401
+        } else {
402
+            $shareTmpl['previewImage'] = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'favicon-fb.png'));
403
+            $ogPreview = $shareTmpl['previewImage'];
404
+        }
405
+
406
+        // Load files we need
407
+        \OCP\Util::addScript('files', 'file-upload');
408
+        \OCP\Util::addStyle('files_sharing', 'publicView');
409
+        \OCP\Util::addScript('files_sharing', 'public');
410
+        \OCP\Util::addScript('files_sharing', 'templates');
411
+        \OCP\Util::addScript('files_sharing', 'public_note');
412
+        \OCP\Util::addScript('files', 'fileactions');
413
+        \OCP\Util::addScript('files', 'fileactionsmenu');
414
+        \OCP\Util::addScript('files', 'jquery.fileupload');
415
+        \OCP\Util::addScript('files_sharing', 'files_drop');
416
+
417
+        if (isset($shareTmpl['folder'])) {
418
+            // JS required for folders
419
+            \OCP\Util::addStyle('files', 'merged');
420
+            \OCP\Util::addScript('files', 'filesummary');
421
+            \OCP\Util::addScript('files', 'templates');
422
+            \OCP\Util::addScript('files', 'breadcrumb');
423
+            \OCP\Util::addScript('files', 'fileinfomodel');
424
+            \OCP\Util::addScript('files', 'newfilemenu');
425
+            \OCP\Util::addScript('files', 'files');
426
+            \OCP\Util::addScript('files', 'filemultiselectmenu');
427
+            \OCP\Util::addScript('files', 'filelist');
428
+            \OCP\Util::addScript('files', 'keyboardshortcuts');
429
+        }
430
+
431
+        // OpenGraph Support: http://ogp.me/
432
+        \OCP\Util::addHeader('meta', ['property' => "og:title", 'content' => $shareTmpl['filename']]);
433
+        \OCP\Util::addHeader('meta', ['property' => "og:description", 'content' => $this->defaults->getName() . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : '')]);
434
+        \OCP\Util::addHeader('meta', ['property' => "og:site_name", 'content' => $this->defaults->getName()]);
435
+        \OCP\Util::addHeader('meta', ['property' => "og:url", 'content' => $shareTmpl['shareUrl']]);
436
+        \OCP\Util::addHeader('meta', ['property' => "og:type", 'content' => "object"]);
437
+        \OCP\Util::addHeader('meta', ['property' => "og:image", 'content' => $ogPreview]);
438
+
439
+        $this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts');
440
+
441
+        $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy();
442
+        $csp->addAllowedFrameDomain('\'self\'');
443
+
444
+        $response = new PublicTemplateResponse($this->appName, 'public', $shareTmpl);
445
+        $response->setHeaderTitle($shareTmpl['filename']);
446
+        $response->setHeaderDetails($this->l10n->t('shared by %s', [$shareTmpl['displayName']]));
447
+        if (!$share->getHideDownload()) {
448
+            $response->setHeaderActions([
449
+                new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download-white', $shareTmpl['downloadURL'], 0),
450
+                new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download', $shareTmpl['downloadURL'], 10, $shareTmpl['fileSize']),
451
+                new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', $shareTmpl['previewURL']),
452
+                new ExternalShareMenuAction($this->l10n->t('Add to your Nextcloud'), 'icon-external', $shareTmpl['owner'], $shareTmpl['displayName'], $shareTmpl['filename']),
453
+            ]);
454
+        }
455
+
456
+        $response->setContentSecurityPolicy($csp);
457
+
458
+        $this->emitAccessShareHook($share);
459
+
460
+        return $response;
461
+    }
462
+
463
+    /**
464
+     * @PublicPage
465
+     * @NoCSRFRequired
466
+     *
467
+     * @param string $token
468
+     * @param string $files
469
+     * @param string $path
470
+     * @param string $downloadStartSecret
471
+     * @return void|\OCP\AppFramework\Http\Response
472
+     * @throws NotFoundException
473
+     */
474
+    public function downloadShare($token, $files = null, $path = '', $downloadStartSecret = '') {
475
+        \OC_User::setIncognitoMode(true);
476
+
477
+        $share = $this->shareManager->getShareByToken($token);
478
+
479
+        if(!($share->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
480
+            return new \OCP\AppFramework\Http\DataResponse('Share is read-only');
481
+        }
482
+
483
+        $files_list = null;
484
+        if (!is_null($files)) { // download selected files
485
+            $files_list = json_decode($files);
486
+            // in case we get only a single file
487
+            if ($files_list === null) {
488
+                $files_list = [$files];
489
+            }
490
+            // Just in case $files is a single int like '1234'
491
+            if (!is_array($files_list)) {
492
+                $files_list = [$files_list];
493
+            }
494
+        }
495
+
496
+
497
+        if (!$this->validateShare($share)) {
498
+            throw new NotFoundException();
499
+        }
500
+
501
+        $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
502
+        $originalSharePath = $userFolder->getRelativePath($share->getNode()->getPath());
503
+
504
+
505
+        // Single file share
506
+        if ($share->getNode() instanceof \OCP\Files\File) {
507
+            // Single file download
508
+            $this->singleFileDownloaded($share, $share->getNode());
509
+        }
510
+        // Directory share
511
+        else {
512
+            /** @var \OCP\Files\Folder $node */
513
+            $node = $share->getNode();
514
+
515
+            // Try to get the path
516
+            if ($path !== '') {
517
+                try {
518
+                    $node = $node->get($path);
519
+                } catch (NotFoundException $e) {
520
+                    $this->emitAccessShareHook($share, 404, 'Share not found');
521
+                    return new NotFoundResponse();
522
+                }
523
+            }
524
+
525
+            $originalSharePath = $userFolder->getRelativePath($node->getPath());
526
+
527
+            if ($node instanceof \OCP\Files\File) {
528
+                // Single file download
529
+                $this->singleFileDownloaded($share, $share->getNode());
530
+            } else if (!empty($files_list)) {
531
+                $this->fileListDownloaded($share, $files_list, $node);
532
+            } else {
533
+                // The folder is downloaded
534
+                $this->singleFileDownloaded($share, $share->getNode());
535
+            }
536
+        }
537
+
538
+        /* FIXME: We should do this all nicely in OCP */
539
+        OC_Util::tearDownFS();
540
+        OC_Util::setupFS($share->getShareOwner());
541
+
542
+        /**
543
+         * this sets a cookie to be able to recognize the start of the download
544
+         * the content must not be longer than 32 characters and must only contain
545
+         * alphanumeric characters
546
+         */
547
+        if (!empty($downloadStartSecret)
548
+            && !isset($downloadStartSecret[32])
549
+            && preg_match('!^[a-zA-Z0-9]+$!', $downloadStartSecret) === 1) {
550
+
551
+            // FIXME: set on the response once we use an actual app framework response
552
+            setcookie('ocDownloadStarted', $downloadStartSecret, time() + 20, '/');
553
+        }
554
+
555
+        $this->emitAccessShareHook($share);
556
+
557
+        $server_params = array( 'head' => $this->request->getMethod() === 'HEAD' );
558
+
559
+        /**
560
+         * Http range requests support
561
+         */
562
+        if (isset($_SERVER['HTTP_RANGE'])) {
563
+            $server_params['range'] = $this->request->getHeader('Range');
564
+        }
565
+
566
+        // download selected files
567
+        if (!is_null($files) && $files !== '') {
568
+            // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
569
+            // after dispatching the request which results in a "Cannot modify header information" notice.
570
+            OC_Files::get($originalSharePath, $files_list, $server_params);
571
+            exit();
572
+        } else {
573
+            // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
574
+            // after dispatching the request which results in a "Cannot modify header information" notice.
575
+            OC_Files::get(dirname($originalSharePath), basename($originalSharePath), $server_params);
576
+            exit();
577
+        }
578
+    }
579
+
580
+    /**
581
+     * create activity for every downloaded file
582
+     *
583
+     * @param Share\IShare $share
584
+     * @param array $files_list
585
+     * @param \OCP\Files\Folder $node
586
+     */
587
+    protected function fileListDownloaded(Share\IShare $share, array $files_list, \OCP\Files\Folder $node) {
588
+        foreach ($files_list as $file) {
589
+            $subNode = $node->get($file);
590
+            $this->singleFileDownloaded($share, $subNode);
591
+        }
592
+
593
+    }
594
+
595
+    /**
596
+     * create activity if a single file was downloaded from a link share
597
+     *
598
+     * @param Share\IShare $share
599
+     */
600
+    protected function singleFileDownloaded(Share\IShare $share, \OCP\Files\Node $node) {
601
+
602
+        $fileId = $node->getId();
603
+
604
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
605
+        $userNodeList = $userFolder->getById($fileId);
606
+        $userNode = $userNodeList[0];
607
+        $ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
608
+        $userPath = $userFolder->getRelativePath($userNode->getPath());
609
+        $ownerPath = $ownerFolder->getRelativePath($node->getPath());
610
+
611
+        $parameters = [$userPath];
612
+
613
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
614
+            if ($node instanceof \OCP\Files\File) {
615
+                $subject = Downloads::SUBJECT_SHARED_FILE_BY_EMAIL_DOWNLOADED;
616
+            } else {
617
+                $subject = Downloads::SUBJECT_SHARED_FOLDER_BY_EMAIL_DOWNLOADED;
618
+            }
619
+            $parameters[] = $share->getSharedWith();
620
+        } else {
621
+            if ($node instanceof \OCP\Files\File) {
622
+                $subject = Downloads::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED;
623
+            } else {
624
+                $subject = Downloads::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED;
625
+            }
626
+        }
627
+
628
+        $this->publishActivity($subject, $parameters, $share->getSharedBy(), $fileId, $userPath);
629
+
630
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
631
+            $parameters[0] = $ownerPath;
632
+            $this->publishActivity($subject, $parameters, $share->getShareOwner(), $fileId, $ownerPath);
633
+        }
634
+    }
635
+
636
+    /**
637
+     * publish activity
638
+     *
639
+     * @param string $subject
640
+     * @param array $parameters
641
+     * @param string $affectedUser
642
+     * @param int $fileId
643
+     * @param string $filePath
644
+     */
645
+    protected function publishActivity($subject,
646
+                                        array $parameters,
647
+                                        $affectedUser,
648
+                                        $fileId,
649
+                                        $filePath) {
650
+
651
+        $event = $this->activityManager->generateEvent();
652
+        $event->setApp('files_sharing')
653
+            ->setType('public_links')
654
+            ->setSubject($subject, $parameters)
655
+            ->setAffectedUser($affectedUser)
656
+            ->setObject('files', $fileId, $filePath);
657
+        $this->activityManager->publish($event);
658
+    }
660 659
 
661 660
 
662 661
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/Controller/ShareAPIController.php 1 patch
Indentation   +1014 added lines, -1014 removed lines patch added patch discarded remove patch
@@ -66,1027 +66,1027 @@
 block discarded – undo
66 66
  */
67 67
 class ShareAPIController extends OCSController {
68 68
 
69
-	/** @var IManager */
70
-	private $shareManager;
71
-	/** @var IGroupManager */
72
-	private $groupManager;
73
-	/** @var IUserManager */
74
-	private $userManager;
75
-	/** @var IRootFolder */
76
-	private $rootFolder;
77
-	/** @var IURLGenerator */
78
-	private $urlGenerator;
79
-	/** @var string */
80
-	private $currentUser;
81
-	/** @var IL10N */
82
-	private $l;
83
-	/** @var \OCP\Files\Node */
84
-	private $lockedNode;
85
-	/** @var IConfig */
86
-	private $config;
87
-	/** @var IAppManager */
88
-	private $appManager;
89
-	/** @var IServerContainer */
90
-	private $serverContainer;
91
-
92
-	/**
93
-	 * Share20OCS constructor.
94
-	 *
95
-	 * @param string $appName
96
-	 * @param IRequest $request
97
-	 * @param IManager $shareManager
98
-	 * @param IGroupManager $groupManager
99
-	 * @param IUserManager $userManager
100
-	 * @param IRootFolder $rootFolder
101
-	 * @param IURLGenerator $urlGenerator
102
-	 * @param string $userId
103
-	 * @param IL10N $l10n
104
-	 * @param IConfig $config
105
-	 * @param IAppManager $appManager
106
-	 * @param IServerContainer $serverContainer
107
-	 */
108
-	public function __construct(
109
-		string $appName,
110
-		IRequest $request,
111
-		IManager $shareManager,
112
-		IGroupManager $groupManager,
113
-		IUserManager $userManager,
114
-		IRootFolder $rootFolder,
115
-		IURLGenerator $urlGenerator,
116
-		string $userId = null,
117
-		IL10N $l10n,
118
-		IConfig $config,
119
-		IAppManager $appManager,
120
-		IServerContainer $serverContainer
121
-	) {
122
-		parent::__construct($appName, $request);
123
-
124
-		$this->shareManager = $shareManager;
125
-		$this->userManager = $userManager;
126
-		$this->groupManager = $groupManager;
127
-		$this->request = $request;
128
-		$this->rootFolder = $rootFolder;
129
-		$this->urlGenerator = $urlGenerator;
130
-		$this->currentUser = $userId;
131
-		$this->l = $l10n;
132
-		$this->config = $config;
133
-		$this->appManager = $appManager;
134
-		$this->serverContainer = $serverContainer;
135
-	}
136
-
137
-	/**
138
-	 * Convert an IShare to an array for OCS output
139
-	 *
140
-	 * @param \OCP\Share\IShare $share
141
-	 * @param Node|null $recipientNode
142
-	 * @return array
143
-	 * @throws NotFoundException In case the node can't be resolved.
144
-	 *
145
-	 * @suppress PhanUndeclaredClassMethod
146
-	 */
147
-	protected function formatShare(\OCP\Share\IShare $share, Node $recipientNode = null): array {
148
-		$sharedBy = $this->userManager->get($share->getSharedBy());
149
-		$shareOwner = $this->userManager->get($share->getShareOwner());
150
-
151
-		$result = [
152
-			'id' => $share->getId(),
153
-			'share_type' => $share->getShareType(),
154
-			'uid_owner' => $share->getSharedBy(),
155
-			'displayname_owner' => $sharedBy !== null ? $sharedBy->getDisplayName() : $share->getSharedBy(),
156
-			'permissions' => $share->getPermissions(),
157
-			'stime' => $share->getShareTime()->getTimestamp(),
158
-			'parent' => null,
159
-			'expiration' => null,
160
-			'token' => null,
161
-			'uid_file_owner' => $share->getShareOwner(),
162
-			'note' => $share->getNote(),
163
-			'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
164
-		];
165
-
166
-		$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
167
-		if ($recipientNode) {
168
-			$node = $recipientNode;
169
-		} else {
170
-			$nodes = $userFolder->getById($share->getNodeId());
171
-			if (empty($nodes)) {
172
-				// fallback to guessing the path
173
-				$node = $userFolder->get($share->getTarget());
174
-				if ($node === null || $share->getTarget() === '') {
175
-					throw new NotFoundException();
176
-				}
177
-			} else {
178
-				$node = $nodes[0];
179
-			}
180
-		}
181
-
182
-		$result['path'] = $userFolder->getRelativePath($node->getPath());
183
-		if ($node instanceOf \OCP\Files\Folder) {
184
-			$result['item_type'] = 'folder';
185
-		} else {
186
-			$result['item_type'] = 'file';
187
-		}
188
-		$result['mimetype'] = $node->getMimetype();
189
-		$result['storage_id'] = $node->getStorage()->getId();
190
-		$result['storage'] = $node->getStorage()->getCache()->getNumericStorageId();
191
-		$result['item_source'] = $node->getId();
192
-		$result['file_source'] = $node->getId();
193
-		$result['file_parent'] = $node->getParent()->getId();
194
-		$result['file_target'] = $share->getTarget();
195
-
196
-		$expiration = $share->getExpirationDate();
197
-		if ($expiration !== null) {
198
-			$result['expiration'] = $expiration->format('Y-m-d 00:00:00');
199
-		}
200
-
201
-		if ($share->getShareType() === Share::SHARE_TYPE_USER) {
202
-			$sharedWith = $this->userManager->get($share->getSharedWith());
203
-			$result['share_with'] = $share->getSharedWith();
204
-			$result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith();
205
-		} else if ($share->getShareType() === Share::SHARE_TYPE_GROUP) {
206
-			$group = $this->groupManager->get($share->getSharedWith());
207
-			$result['share_with'] = $share->getSharedWith();
208
-			$result['share_with_displayname'] = $group !== null ? $group->getDisplayName() : $share->getSharedWith();
209
-		} else if ($share->getShareType() === Share::SHARE_TYPE_LINK) {
210
-
211
-			$result['share_with'] = $share->getPassword();
212
-			$result['share_with_displayname'] = $share->getPassword();
213
-
214
-			$result['token'] = $share->getToken();
215
-			$result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]);
216
-
217
-		} else if ($share->getShareType() === Share::SHARE_TYPE_REMOTE || $share->getShareType() === Share::SHARE_TYPE_REMOTE_GROUP) {
218
-			$result['share_with'] = $share->getSharedWith();
219
-			$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'CLOUD');
220
-			$result['token'] = $share->getToken();
221
-		} else if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) {
222
-			$result['share_with'] = $share->getSharedWith();
223
-			$result['password'] = $share->getPassword();
224
-			$result['send_password_by_talk'] = $share->getSendPasswordByTalk();
225
-			$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
226
-			$result['token'] = $share->getToken();
227
-		} else if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) {
228
-			// getSharedWith() returns either "name (type, owner)" or
229
-			// "name (type, owner) [id]", depending on the Circles app version.
230
-			$hasCircleId = (substr($share->getSharedWith(), -1) === ']');
231
-
232
-			$result['share_with_displayname'] = $share->getSharedWithDisplayName();
233
-			if (empty($result['share_with_displayname'])) {
234
-				$displayNameLength = ($hasCircleId? strrpos($share->getSharedWith(), ' '): strlen($share->getSharedWith()));
235
-				$result['share_with_displayname'] = substr($share->getSharedWith(), 0, $displayNameLength);
236
-			}
237
-
238
-			$result['share_with_avatar'] = $share->getSharedWithAvatar();
239
-
240
-			$shareWithStart = ($hasCircleId? strrpos($share->getSharedWith(), '[') + 1: 0);
241
-			$shareWithLength = ($hasCircleId? -1: strpos($share->getSharedWith(), ' '));
242
-			$result['share_with'] = substr($share->getSharedWith(), $shareWithStart, $shareWithLength);
243
-		} else if ($share->getShareType() === Share::SHARE_TYPE_ROOM) {
244
-			$result['share_with'] = $share->getSharedWith();
245
-			$result['share_with_displayname'] = '';
246
-
247
-			try {
248
-				$result = array_merge($result, $this->getRoomShareHelper()->formatShare($share));
249
-			} catch (QueryException $e) {
250
-			}
251
-		}
252
-
253
-
254
-		$result['mail_send'] = $share->getMailSend() ? 1 : 0;
255
-		$result['hide_download'] = $share->getHideDownload() ? 1 : 0;
256
-
257
-		return $result;
258
-	}
259
-
260
-	/**
261
-	 * Check if one of the users address books knows the exact property, if
262
-	 * yes we return the full name.
263
-	 *
264
-	 * @param string $query
265
-	 * @param string $property
266
-	 * @return string
267
-	 */
268
-	private function getDisplayNameFromAddressBook(string $query, string $property): string {
269
-		// FIXME: If we inject the contacts manager it gets initialized bofore any address books are registered
270
-		$result = \OC::$server->getContactsManager()->search($query, [$property]);
271
-		foreach ($result as $r) {
272
-			foreach($r[$property] as $value) {
273
-				if ($value === $query) {
274
-					return $r['FN'];
275
-				}
276
-			}
277
-		}
278
-
279
-		return $query;
280
-	}
281
-
282
-	/**
283
-	 * Get a specific share by id
284
-	 *
285
-	 * @NoAdminRequired
286
-	 *
287
-	 * @param string $id
288
-	 * @return DataResponse
289
-	 * @throws OCSNotFoundException
290
-	 */
291
-	public function getShare(string $id): DataResponse {
292
-		try {
293
-			$share = $this->getShareById($id);
294
-		} catch (ShareNotFound $e) {
295
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
296
-		}
297
-
298
-		if ($this->canAccessShare($share)) {
299
-			try {
300
-				$share = $this->formatShare($share);
301
-				return new DataResponse([$share]);
302
-			} catch (NotFoundException $e) {
303
-				//Fall trough
304
-			}
305
-		}
306
-
307
-		throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
308
-	}
309
-
310
-	/**
311
-	 * Delete a share
312
-	 *
313
-	 * @NoAdminRequired
314
-	 *
315
-	 * @param string $id
316
-	 * @return DataResponse
317
-	 * @throws OCSNotFoundException
318
-	 */
319
-	public function deleteShare(string $id): DataResponse {
320
-		try {
321
-			$share = $this->getShareById($id);
322
-		} catch (ShareNotFound $e) {
323
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
324
-		}
325
-
326
-		try {
327
-			$this->lock($share->getNode());
328
-		} catch (LockedException $e) {
329
-			throw new OCSNotFoundException($this->l->t('could not delete share'));
330
-		}
331
-
332
-		if (!$this->canAccessShare($share)) {
333
-			throw new OCSNotFoundException($this->l->t('Could not delete share'));
334
-		}
335
-
336
-		if (($share->getShareType() === Share::SHARE_TYPE_GROUP ||
337
-				$share->getShareType() === Share::SHARE_TYPE_ROOM) &&
338
-			$share->getShareOwner() !== $this->currentUser &&
339
-			$share->getSharedBy() !== $this->currentUser) {
340
-			$this->shareManager->deleteFromSelf($share, $this->currentUser);
341
-		} else {
342
-			$this->shareManager->deleteShare($share);
343
-		}
344
-
345
-		return new DataResponse();
346
-	}
347
-
348
-	/**
349
-	 * @NoAdminRequired
350
-	 *
351
-	 * @param string $path
352
-	 * @param int $permissions
353
-	 * @param int $shareType
354
-	 * @param string $shareWith
355
-	 * @param string $publicUpload
356
-	 * @param string $password
357
-	 * @param bool $sendPasswordByTalk
358
-	 * @param string $expireDate
359
-	 *
360
-	 * @return DataResponse
361
-	 * @throws OCSNotFoundException
362
-	 * @throws OCSForbiddenException
363
-	 * @throws OCSBadRequestException
364
-	 * @throws OCSException
365
-	 *
366
-	 * @suppress PhanUndeclaredClassMethod
367
-	 */
368
-	public function createShare(
369
-		string $path = null,
370
-		int $permissions = null,
371
-		int $shareType = -1,
372
-		string $shareWith = null,
373
-		string $publicUpload = 'false',
374
-		string $password = '',
375
-		string $sendPasswordByTalk = null,
376
-		string $expireDate = ''
377
-	): DataResponse {
378
-		$share = $this->shareManager->newShare();
379
-
380
-		if ($permissions === null) {
381
-			$permissions = $this->config->getAppValue('core', 'shareapi_default_permissions', Constants::PERMISSION_ALL);
382
-		}
383
-
384
-		// Verify path
385
-		if ($path === null) {
386
-			throw new OCSNotFoundException($this->l->t('Please specify a file or folder path'));
387
-		}
388
-
389
-		$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
390
-		try {
391
-			$path = $userFolder->get($path);
392
-		} catch (NotFoundException $e) {
393
-			throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
394
-		}
395
-
396
-		$share->setNode($path);
397
-
398
-		try {
399
-			$this->lock($share->getNode());
400
-		} catch (LockedException $e) {
401
-			throw new OCSNotFoundException($this->l->t('Could not create share'));
402
-		}
403
-
404
-		if ($permissions < 0 || $permissions > Constants::PERMISSION_ALL) {
405
-			throw new OCSNotFoundException($this->l->t('invalid permissions'));
406
-		}
407
-
408
-		// Shares always require read permissions
409
-		$permissions |= Constants::PERMISSION_READ;
410
-
411
-		if ($path instanceof \OCP\Files\File) {
412
-			// Single file shares should never have delete or create permissions
413
-			$permissions &= ~Constants::PERMISSION_DELETE;
414
-			$permissions &= ~Constants::PERMISSION_CREATE;
415
-		}
416
-
417
-		/*
69
+    /** @var IManager */
70
+    private $shareManager;
71
+    /** @var IGroupManager */
72
+    private $groupManager;
73
+    /** @var IUserManager */
74
+    private $userManager;
75
+    /** @var IRootFolder */
76
+    private $rootFolder;
77
+    /** @var IURLGenerator */
78
+    private $urlGenerator;
79
+    /** @var string */
80
+    private $currentUser;
81
+    /** @var IL10N */
82
+    private $l;
83
+    /** @var \OCP\Files\Node */
84
+    private $lockedNode;
85
+    /** @var IConfig */
86
+    private $config;
87
+    /** @var IAppManager */
88
+    private $appManager;
89
+    /** @var IServerContainer */
90
+    private $serverContainer;
91
+
92
+    /**
93
+     * Share20OCS constructor.
94
+     *
95
+     * @param string $appName
96
+     * @param IRequest $request
97
+     * @param IManager $shareManager
98
+     * @param IGroupManager $groupManager
99
+     * @param IUserManager $userManager
100
+     * @param IRootFolder $rootFolder
101
+     * @param IURLGenerator $urlGenerator
102
+     * @param string $userId
103
+     * @param IL10N $l10n
104
+     * @param IConfig $config
105
+     * @param IAppManager $appManager
106
+     * @param IServerContainer $serverContainer
107
+     */
108
+    public function __construct(
109
+        string $appName,
110
+        IRequest $request,
111
+        IManager $shareManager,
112
+        IGroupManager $groupManager,
113
+        IUserManager $userManager,
114
+        IRootFolder $rootFolder,
115
+        IURLGenerator $urlGenerator,
116
+        string $userId = null,
117
+        IL10N $l10n,
118
+        IConfig $config,
119
+        IAppManager $appManager,
120
+        IServerContainer $serverContainer
121
+    ) {
122
+        parent::__construct($appName, $request);
123
+
124
+        $this->shareManager = $shareManager;
125
+        $this->userManager = $userManager;
126
+        $this->groupManager = $groupManager;
127
+        $this->request = $request;
128
+        $this->rootFolder = $rootFolder;
129
+        $this->urlGenerator = $urlGenerator;
130
+        $this->currentUser = $userId;
131
+        $this->l = $l10n;
132
+        $this->config = $config;
133
+        $this->appManager = $appManager;
134
+        $this->serverContainer = $serverContainer;
135
+    }
136
+
137
+    /**
138
+     * Convert an IShare to an array for OCS output
139
+     *
140
+     * @param \OCP\Share\IShare $share
141
+     * @param Node|null $recipientNode
142
+     * @return array
143
+     * @throws NotFoundException In case the node can't be resolved.
144
+     *
145
+     * @suppress PhanUndeclaredClassMethod
146
+     */
147
+    protected function formatShare(\OCP\Share\IShare $share, Node $recipientNode = null): array {
148
+        $sharedBy = $this->userManager->get($share->getSharedBy());
149
+        $shareOwner = $this->userManager->get($share->getShareOwner());
150
+
151
+        $result = [
152
+            'id' => $share->getId(),
153
+            'share_type' => $share->getShareType(),
154
+            'uid_owner' => $share->getSharedBy(),
155
+            'displayname_owner' => $sharedBy !== null ? $sharedBy->getDisplayName() : $share->getSharedBy(),
156
+            'permissions' => $share->getPermissions(),
157
+            'stime' => $share->getShareTime()->getTimestamp(),
158
+            'parent' => null,
159
+            'expiration' => null,
160
+            'token' => null,
161
+            'uid_file_owner' => $share->getShareOwner(),
162
+            'note' => $share->getNote(),
163
+            'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
164
+        ];
165
+
166
+        $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
167
+        if ($recipientNode) {
168
+            $node = $recipientNode;
169
+        } else {
170
+            $nodes = $userFolder->getById($share->getNodeId());
171
+            if (empty($nodes)) {
172
+                // fallback to guessing the path
173
+                $node = $userFolder->get($share->getTarget());
174
+                if ($node === null || $share->getTarget() === '') {
175
+                    throw new NotFoundException();
176
+                }
177
+            } else {
178
+                $node = $nodes[0];
179
+            }
180
+        }
181
+
182
+        $result['path'] = $userFolder->getRelativePath($node->getPath());
183
+        if ($node instanceOf \OCP\Files\Folder) {
184
+            $result['item_type'] = 'folder';
185
+        } else {
186
+            $result['item_type'] = 'file';
187
+        }
188
+        $result['mimetype'] = $node->getMimetype();
189
+        $result['storage_id'] = $node->getStorage()->getId();
190
+        $result['storage'] = $node->getStorage()->getCache()->getNumericStorageId();
191
+        $result['item_source'] = $node->getId();
192
+        $result['file_source'] = $node->getId();
193
+        $result['file_parent'] = $node->getParent()->getId();
194
+        $result['file_target'] = $share->getTarget();
195
+
196
+        $expiration = $share->getExpirationDate();
197
+        if ($expiration !== null) {
198
+            $result['expiration'] = $expiration->format('Y-m-d 00:00:00');
199
+        }
200
+
201
+        if ($share->getShareType() === Share::SHARE_TYPE_USER) {
202
+            $sharedWith = $this->userManager->get($share->getSharedWith());
203
+            $result['share_with'] = $share->getSharedWith();
204
+            $result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith();
205
+        } else if ($share->getShareType() === Share::SHARE_TYPE_GROUP) {
206
+            $group = $this->groupManager->get($share->getSharedWith());
207
+            $result['share_with'] = $share->getSharedWith();
208
+            $result['share_with_displayname'] = $group !== null ? $group->getDisplayName() : $share->getSharedWith();
209
+        } else if ($share->getShareType() === Share::SHARE_TYPE_LINK) {
210
+
211
+            $result['share_with'] = $share->getPassword();
212
+            $result['share_with_displayname'] = $share->getPassword();
213
+
214
+            $result['token'] = $share->getToken();
215
+            $result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]);
216
+
217
+        } else if ($share->getShareType() === Share::SHARE_TYPE_REMOTE || $share->getShareType() === Share::SHARE_TYPE_REMOTE_GROUP) {
218
+            $result['share_with'] = $share->getSharedWith();
219
+            $result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'CLOUD');
220
+            $result['token'] = $share->getToken();
221
+        } else if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) {
222
+            $result['share_with'] = $share->getSharedWith();
223
+            $result['password'] = $share->getPassword();
224
+            $result['send_password_by_talk'] = $share->getSendPasswordByTalk();
225
+            $result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
226
+            $result['token'] = $share->getToken();
227
+        } else if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) {
228
+            // getSharedWith() returns either "name (type, owner)" or
229
+            // "name (type, owner) [id]", depending on the Circles app version.
230
+            $hasCircleId = (substr($share->getSharedWith(), -1) === ']');
231
+
232
+            $result['share_with_displayname'] = $share->getSharedWithDisplayName();
233
+            if (empty($result['share_with_displayname'])) {
234
+                $displayNameLength = ($hasCircleId? strrpos($share->getSharedWith(), ' '): strlen($share->getSharedWith()));
235
+                $result['share_with_displayname'] = substr($share->getSharedWith(), 0, $displayNameLength);
236
+            }
237
+
238
+            $result['share_with_avatar'] = $share->getSharedWithAvatar();
239
+
240
+            $shareWithStart = ($hasCircleId? strrpos($share->getSharedWith(), '[') + 1: 0);
241
+            $shareWithLength = ($hasCircleId? -1: strpos($share->getSharedWith(), ' '));
242
+            $result['share_with'] = substr($share->getSharedWith(), $shareWithStart, $shareWithLength);
243
+        } else if ($share->getShareType() === Share::SHARE_TYPE_ROOM) {
244
+            $result['share_with'] = $share->getSharedWith();
245
+            $result['share_with_displayname'] = '';
246
+
247
+            try {
248
+                $result = array_merge($result, $this->getRoomShareHelper()->formatShare($share));
249
+            } catch (QueryException $e) {
250
+            }
251
+        }
252
+
253
+
254
+        $result['mail_send'] = $share->getMailSend() ? 1 : 0;
255
+        $result['hide_download'] = $share->getHideDownload() ? 1 : 0;
256
+
257
+        return $result;
258
+    }
259
+
260
+    /**
261
+     * Check if one of the users address books knows the exact property, if
262
+     * yes we return the full name.
263
+     *
264
+     * @param string $query
265
+     * @param string $property
266
+     * @return string
267
+     */
268
+    private function getDisplayNameFromAddressBook(string $query, string $property): string {
269
+        // FIXME: If we inject the contacts manager it gets initialized bofore any address books are registered
270
+        $result = \OC::$server->getContactsManager()->search($query, [$property]);
271
+        foreach ($result as $r) {
272
+            foreach($r[$property] as $value) {
273
+                if ($value === $query) {
274
+                    return $r['FN'];
275
+                }
276
+            }
277
+        }
278
+
279
+        return $query;
280
+    }
281
+
282
+    /**
283
+     * Get a specific share by id
284
+     *
285
+     * @NoAdminRequired
286
+     *
287
+     * @param string $id
288
+     * @return DataResponse
289
+     * @throws OCSNotFoundException
290
+     */
291
+    public function getShare(string $id): DataResponse {
292
+        try {
293
+            $share = $this->getShareById($id);
294
+        } catch (ShareNotFound $e) {
295
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
296
+        }
297
+
298
+        if ($this->canAccessShare($share)) {
299
+            try {
300
+                $share = $this->formatShare($share);
301
+                return new DataResponse([$share]);
302
+            } catch (NotFoundException $e) {
303
+                //Fall trough
304
+            }
305
+        }
306
+
307
+        throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
308
+    }
309
+
310
+    /**
311
+     * Delete a share
312
+     *
313
+     * @NoAdminRequired
314
+     *
315
+     * @param string $id
316
+     * @return DataResponse
317
+     * @throws OCSNotFoundException
318
+     */
319
+    public function deleteShare(string $id): DataResponse {
320
+        try {
321
+            $share = $this->getShareById($id);
322
+        } catch (ShareNotFound $e) {
323
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
324
+        }
325
+
326
+        try {
327
+            $this->lock($share->getNode());
328
+        } catch (LockedException $e) {
329
+            throw new OCSNotFoundException($this->l->t('could not delete share'));
330
+        }
331
+
332
+        if (!$this->canAccessShare($share)) {
333
+            throw new OCSNotFoundException($this->l->t('Could not delete share'));
334
+        }
335
+
336
+        if (($share->getShareType() === Share::SHARE_TYPE_GROUP ||
337
+                $share->getShareType() === Share::SHARE_TYPE_ROOM) &&
338
+            $share->getShareOwner() !== $this->currentUser &&
339
+            $share->getSharedBy() !== $this->currentUser) {
340
+            $this->shareManager->deleteFromSelf($share, $this->currentUser);
341
+        } else {
342
+            $this->shareManager->deleteShare($share);
343
+        }
344
+
345
+        return new DataResponse();
346
+    }
347
+
348
+    /**
349
+     * @NoAdminRequired
350
+     *
351
+     * @param string $path
352
+     * @param int $permissions
353
+     * @param int $shareType
354
+     * @param string $shareWith
355
+     * @param string $publicUpload
356
+     * @param string $password
357
+     * @param bool $sendPasswordByTalk
358
+     * @param string $expireDate
359
+     *
360
+     * @return DataResponse
361
+     * @throws OCSNotFoundException
362
+     * @throws OCSForbiddenException
363
+     * @throws OCSBadRequestException
364
+     * @throws OCSException
365
+     *
366
+     * @suppress PhanUndeclaredClassMethod
367
+     */
368
+    public function createShare(
369
+        string $path = null,
370
+        int $permissions = null,
371
+        int $shareType = -1,
372
+        string $shareWith = null,
373
+        string $publicUpload = 'false',
374
+        string $password = '',
375
+        string $sendPasswordByTalk = null,
376
+        string $expireDate = ''
377
+    ): DataResponse {
378
+        $share = $this->shareManager->newShare();
379
+
380
+        if ($permissions === null) {
381
+            $permissions = $this->config->getAppValue('core', 'shareapi_default_permissions', Constants::PERMISSION_ALL);
382
+        }
383
+
384
+        // Verify path
385
+        if ($path === null) {
386
+            throw new OCSNotFoundException($this->l->t('Please specify a file or folder path'));
387
+        }
388
+
389
+        $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
390
+        try {
391
+            $path = $userFolder->get($path);
392
+        } catch (NotFoundException $e) {
393
+            throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
394
+        }
395
+
396
+        $share->setNode($path);
397
+
398
+        try {
399
+            $this->lock($share->getNode());
400
+        } catch (LockedException $e) {
401
+            throw new OCSNotFoundException($this->l->t('Could not create share'));
402
+        }
403
+
404
+        if ($permissions < 0 || $permissions > Constants::PERMISSION_ALL) {
405
+            throw new OCSNotFoundException($this->l->t('invalid permissions'));
406
+        }
407
+
408
+        // Shares always require read permissions
409
+        $permissions |= Constants::PERMISSION_READ;
410
+
411
+        if ($path instanceof \OCP\Files\File) {
412
+            // Single file shares should never have delete or create permissions
413
+            $permissions &= ~Constants::PERMISSION_DELETE;
414
+            $permissions &= ~Constants::PERMISSION_CREATE;
415
+        }
416
+
417
+        /*
418 418
 		 * Hack for https://github.com/owncloud/core/issues/22587
419 419
 		 * We check the permissions via webdav. But the permissions of the mount point
420 420
 		 * do not equal the share permissions. Here we fix that for federated mounts.
421 421
 		 */
422
-		if ($path->getStorage()->instanceOfStorage(Storage::class)) {
423
-			$permissions &= ~($permissions & ~$path->getPermissions());
424
-		}
425
-
426
-		if ($shareType === Share::SHARE_TYPE_USER) {
427
-			// Valid user is required to share
428
-			if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
429
-				throw new OCSNotFoundException($this->l->t('Please specify a valid user'));
430
-			}
431
-			$share->setSharedWith($shareWith);
432
-			$share->setPermissions($permissions);
433
-		} else if ($shareType === Share::SHARE_TYPE_GROUP) {
434
-			if (!$this->shareManager->allowGroupSharing()) {
435
-				throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator'));
436
-			}
437
-
438
-			// Valid group is required to share
439
-			if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
440
-				throw new OCSNotFoundException($this->l->t('Please specify a valid group'));
441
-			}
442
-			$share->setSharedWith($shareWith);
443
-			$share->setPermissions($permissions);
444
-		} else if ($shareType === Share::SHARE_TYPE_LINK) {
445
-			//Can we even share links?
446
-			if (!$this->shareManager->shareApiAllowLinks()) {
447
-				throw new OCSNotFoundException($this->l->t('Public link sharing is disabled by the administrator'));
448
-			}
449
-
450
-			/*
422
+        if ($path->getStorage()->instanceOfStorage(Storage::class)) {
423
+            $permissions &= ~($permissions & ~$path->getPermissions());
424
+        }
425
+
426
+        if ($shareType === Share::SHARE_TYPE_USER) {
427
+            // Valid user is required to share
428
+            if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
429
+                throw new OCSNotFoundException($this->l->t('Please specify a valid user'));
430
+            }
431
+            $share->setSharedWith($shareWith);
432
+            $share->setPermissions($permissions);
433
+        } else if ($shareType === Share::SHARE_TYPE_GROUP) {
434
+            if (!$this->shareManager->allowGroupSharing()) {
435
+                throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator'));
436
+            }
437
+
438
+            // Valid group is required to share
439
+            if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
440
+                throw new OCSNotFoundException($this->l->t('Please specify a valid group'));
441
+            }
442
+            $share->setSharedWith($shareWith);
443
+            $share->setPermissions($permissions);
444
+        } else if ($shareType === Share::SHARE_TYPE_LINK) {
445
+            //Can we even share links?
446
+            if (!$this->shareManager->shareApiAllowLinks()) {
447
+                throw new OCSNotFoundException($this->l->t('Public link sharing is disabled by the administrator'));
448
+            }
449
+
450
+            /*
451 451
 			 * For now we only allow 1 link share.
452 452
 			 * Return the existing link share if this is a duplicate
453 453
 			 */
454
-			$existingShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $path, false, 1, 0);
455
-			if (!empty($existingShares)) {
456
-				return new DataResponse($this->formatShare($existingShares[0]));
457
-			}
458
-
459
-			if ($publicUpload === 'true') {
460
-				// Check if public upload is allowed
461
-				if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
462
-					throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
463
-				}
464
-
465
-				// Public upload can only be set for folders
466
-				if ($path instanceof \OCP\Files\File) {
467
-					throw new OCSNotFoundException($this->l->t('Public upload is only possible for publicly shared folders'));
468
-				}
469
-
470
-				$share->setPermissions(
471
-					Constants::PERMISSION_READ |
472
-					Constants::PERMISSION_CREATE |
473
-					Constants::PERMISSION_UPDATE |
474
-					Constants::PERMISSION_DELETE
475
-				);
476
-			} else {
477
-				$share->setPermissions(Constants::PERMISSION_READ);
478
-			}
479
-
480
-			// Set password
481
-			if ($password !== '') {
482
-				$share->setPassword($password);
483
-			}
484
-
485
-			//Expire date
486
-			if ($expireDate !== '') {
487
-				try {
488
-					$expireDate = $this->parseDate($expireDate);
489
-					$share->setExpirationDate($expireDate);
490
-				} catch (\Exception $e) {
491
-					throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
492
-				}
493
-			}
494
-
495
-		} else if ($shareType === Share::SHARE_TYPE_REMOTE) {
496
-			if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
497
-				throw new OCSForbiddenException($this->l->t('Sharing %1$s failed because the back end does not allow shares from type %2$s', [$path->getPath(), $shareType]));
498
-			}
499
-
500
-			$share->setSharedWith($shareWith);
501
-			$share->setPermissions($permissions);
502
-		}  else if ($shareType === Share::SHARE_TYPE_REMOTE_GROUP) {
503
-			if (!$this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
504
-				throw new OCSForbiddenException($this->l->t('Sharing %1$s failed because the back end does not allow shares from type %2$s', [$path->getPath(), $shareType]));
505
-			}
506
-
507
-			$share->setSharedWith($shareWith);
508
-			$share->setPermissions($permissions);
509
-		} else if ($shareType === Share::SHARE_TYPE_EMAIL) {
510
-			if ($share->getNodeType() === 'file') {
511
-				$share->setPermissions(Constants::PERMISSION_READ);
512
-			} else {
513
-				$share->setPermissions($permissions);
514
-			}
515
-			$share->setSharedWith($shareWith);
516
-
517
-			if ($sendPasswordByTalk === 'true') {
518
-				if (!$this->appManager->isEnabledForUser('spreed')) {
519
-					throw new OCSForbiddenException($this->l->t('Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled', [$path->getPath()]));
520
-				}
521
-
522
-				$share->setSendPasswordByTalk(true);
523
-			}
524
-		} else if ($shareType === Share::SHARE_TYPE_CIRCLE) {
525
-			if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) {
526
-				throw new OCSNotFoundException($this->l->t('You cannot share to a Circle if the app is not enabled'));
527
-			}
528
-
529
-			$circle = \OCA\Circles\Api\v1\Circles::detailsCircle($shareWith);
530
-
531
-			// Valid circle is required to share
532
-			if ($circle === null) {
533
-				throw new OCSNotFoundException($this->l->t('Please specify a valid circle'));
534
-			}
535
-			$share->setSharedWith($shareWith);
536
-			$share->setPermissions($permissions);
537
-		} else if ($shareType === Share::SHARE_TYPE_ROOM) {
538
-			try {
539
-				$this->getRoomShareHelper()->createShare($share, $shareWith, $permissions, $expireDate);
540
-			} catch (QueryException $e) {
541
-				throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not support room shares', [$path->getPath()]));
542
-			}
543
-		} else {
544
-			throw new OCSBadRequestException($this->l->t('Unknown share type'));
545
-		}
546
-
547
-		$share->setShareType($shareType);
548
-		$share->setSharedBy($this->currentUser);
549
-
550
-		try {
551
-			$share = $this->shareManager->createShare($share);
552
-		} catch (GenericShareException $e) {
553
-			$code = $e->getCode() === 0 ? 403 : $e->getCode();
554
-			throw new OCSException($e->getHint(), $code);
555
-		} catch (\Exception $e) {
556
-			throw new OCSForbiddenException($e->getMessage(), $e);
557
-		}
558
-
559
-		$output = $this->formatShare($share);
560
-
561
-		return new DataResponse($output);
562
-	}
563
-
564
-	/**
565
-	 * @param \OCP\Files\File|\OCP\Files\Folder $node
566
-	 * @param boolean $includeTags
567
-	 * @return DataResponse
568
-	 */
569
-	private function getSharedWithMe($node = null, bool $includeTags): DataResponse {
570
-
571
-		$userShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_USER, $node, -1, 0);
572
-		$groupShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_GROUP, $node, -1, 0);
573
-		$circleShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_CIRCLE, $node, -1, 0);
574
-		$roomShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_ROOM, $node, -1, 0);
575
-
576
-		$shares = array_merge($userShares, $groupShares, $circleShares, $roomShares);
577
-
578
-		$shares = array_filter($shares, function (IShare $share) {
579
-			return $share->getShareOwner() !== $this->currentUser;
580
-		});
581
-
582
-		$formatted = [];
583
-		foreach ($shares as $share) {
584
-			if ($this->canAccessShare($share)) {
585
-				try {
586
-					$formatted[] = $this->formatShare($share);
587
-				} catch (NotFoundException $e) {
588
-					// Ignore this share
589
-				}
590
-			}
591
-		}
592
-
593
-		if ($includeTags) {
594
-			$formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
595
-		}
596
-
597
-		return new DataResponse($formatted);
598
-	}
599
-
600
-	/**
601
-	 * @param \OCP\Files\Folder $folder
602
-	 * @return DataResponse
603
-	 * @throws OCSBadRequestException
604
-	 */
605
-	private function getSharesInDir(Node $folder): DataResponse {
606
-		if (!($folder instanceof \OCP\Files\Folder)) {
607
-			throw new OCSBadRequestException($this->l->t('Not a directory'));
608
-		}
609
-
610
-		$nodes = $folder->getDirectoryListing();
611
-		/** @var \OCP\Share\IShare[] $shares */
612
-		$shares = [];
613
-		foreach ($nodes as $node) {
614
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $node, false, -1, 0));
615
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
616
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $node, false, -1, 0));
617
-			if($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
618
-				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $node, false, -1, 0));
619
-			}
620
-			if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
621
-				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE, $node, false, -1, 0));
622
-			}
623
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_ROOM, $node, false, -1, 0));
624
-		}
625
-
626
-		$formatted = [];
627
-		foreach ($shares as $share) {
628
-			try {
629
-				$formatted[] = $this->formatShare($share);
630
-			} catch (NotFoundException $e) {
631
-				//Ignore this share
632
-			}
633
-		}
634
-
635
-		return new DataResponse($formatted);
636
-	}
637
-
638
-	/**
639
-	 * The getShares function.
640
-	 *
641
-	 * @NoAdminRequired
642
-	 *
643
-	 * @param string $shared_with_me
644
-	 * @param string $reshares
645
-	 * @param string $subfiles
646
-	 * @param string $path
647
-	 *
648
-	 * - Get shares by the current user
649
-	 * - Get shares by the current user and reshares (?reshares=true)
650
-	 * - Get shares with the current user (?shared_with_me=true)
651
-	 * - Get shares for a specific path (?path=...)
652
-	 * - Get all shares in a folder (?subfiles=true&path=..)
653
-	 *
654
-	 * @return DataResponse
655
-	 * @throws OCSNotFoundException
656
-	 */
657
-	public function getShares(
658
-		string $shared_with_me = 'false',
659
-		string $reshares = 'false',
660
-		string $subfiles = 'false',
661
-		string $path = null,
662
-		string $include_tags = 'false'
663
-	): DataResponse {
664
-
665
-		if ($path !== null) {
666
-			$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
667
-			try {
668
-				$path = $userFolder->get($path);
669
-				$this->lock($path);
670
-			} catch (\OCP\Files\NotFoundException $e) {
671
-				throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
672
-			} catch (LockedException $e) {
673
-				throw new OCSNotFoundException($this->l->t('Could not lock path'));
674
-			}
675
-		}
676
-
677
-		$include_tags = $include_tags === 'true';
678
-
679
-		if ($shared_with_me === 'true') {
680
-			$result = $this->getSharedWithMe($path, $include_tags);
681
-			return $result;
682
-		}
683
-
684
-		if ($subfiles === 'true') {
685
-			$result = $this->getSharesInDir($path);
686
-			return $result;
687
-		}
688
-
689
-		if ($reshares === 'true') {
690
-			$reshares = true;
691
-		} else {
692
-			$reshares = false;
693
-		}
694
-
695
-		// Get all shares
696
-		$userShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $path, $reshares, -1, 0);
697
-		$groupShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0);
698
-		$linkShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0);
699
-		if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
700
-			$mailShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $path, $reshares, -1, 0);
701
-		} else {
702
-			$mailShares = [];
703
-		}
704
-		if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) {
705
-			$circleShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_CIRCLE, $path, $reshares, -1, 0);
706
-		} else {
707
-			$circleShares = [];
708
-		}
709
-		$roomShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_ROOM, $path, $reshares, -1, 0);
710
-
711
-		$shares = array_merge($userShares, $groupShares, $linkShares, $mailShares, $circleShares, $roomShares);
712
-
713
-		if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
714
-			$federatedShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0);
715
-			$shares = array_merge($shares, $federatedShares);
716
-		}
717
-
718
-		if ($this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
719
-			$federatedShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE_GROUP, $path, $reshares, -1, 0);
720
-			$shares = array_merge($shares, $federatedShares);
721
-		}
722
-
723
-		$formatted = [];
724
-		foreach ($shares as $share) {
725
-			try {
726
-				$formatted[] = $this->formatShare($share, $path);
727
-			} catch (NotFoundException $e) {
728
-				//Ignore share
729
-			}
730
-		}
731
-
732
-		if ($include_tags) {
733
-			$formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
734
-		}
735
-
736
-		return new DataResponse($formatted);
737
-	}
738
-
739
-	/**
740
-	 * @NoAdminRequired
741
-	 *
742
-	 * @param string $id
743
-	 * @param int $permissions
744
-	 * @param string $password
745
-	 * @param string $sendPasswordByTalk
746
-	 * @param string $publicUpload
747
-	 * @param string $expireDate
748
-	 * @param string $note
749
-	 * @param string $hideDownload
750
-	 * @return DataResponse
751
-	 * @throws LockedException
752
-	 * @throws NotFoundException
753
-	 * @throws OCSBadRequestException
754
-	 * @throws OCSForbiddenException
755
-	 * @throws OCSNotFoundException
756
-	 */
757
-	public function updateShare(
758
-		string $id,
759
-		int $permissions = null,
760
-		string $password = null,
761
-		string $sendPasswordByTalk = null,
762
-		string $publicUpload = null,
763
-		string $expireDate = null,
764
-		string $note = null,
765
-		string $hideDownload = null
766
-	): DataResponse {
767
-		try {
768
-			$share = $this->getShareById($id);
769
-		} catch (ShareNotFound $e) {
770
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
771
-		}
772
-
773
-		$this->lock($share->getNode());
774
-
775
-		if (!$this->canAccessShare($share, false)) {
776
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
777
-		}
778
-
779
-		if ($permissions === null && $password === null && $sendPasswordByTalk === null && $publicUpload === null && $expireDate === null && $note === null && $hideDownload === null) {
780
-			throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
781
-		}
782
-
783
-		if($note !== null) {
784
-			$share->setNote($note);
785
-		}
786
-
787
-		/*
454
+            $existingShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $path, false, 1, 0);
455
+            if (!empty($existingShares)) {
456
+                return new DataResponse($this->formatShare($existingShares[0]));
457
+            }
458
+
459
+            if ($publicUpload === 'true') {
460
+                // Check if public upload is allowed
461
+                if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
462
+                    throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
463
+                }
464
+
465
+                // Public upload can only be set for folders
466
+                if ($path instanceof \OCP\Files\File) {
467
+                    throw new OCSNotFoundException($this->l->t('Public upload is only possible for publicly shared folders'));
468
+                }
469
+
470
+                $share->setPermissions(
471
+                    Constants::PERMISSION_READ |
472
+                    Constants::PERMISSION_CREATE |
473
+                    Constants::PERMISSION_UPDATE |
474
+                    Constants::PERMISSION_DELETE
475
+                );
476
+            } else {
477
+                $share->setPermissions(Constants::PERMISSION_READ);
478
+            }
479
+
480
+            // Set password
481
+            if ($password !== '') {
482
+                $share->setPassword($password);
483
+            }
484
+
485
+            //Expire date
486
+            if ($expireDate !== '') {
487
+                try {
488
+                    $expireDate = $this->parseDate($expireDate);
489
+                    $share->setExpirationDate($expireDate);
490
+                } catch (\Exception $e) {
491
+                    throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
492
+                }
493
+            }
494
+
495
+        } else if ($shareType === Share::SHARE_TYPE_REMOTE) {
496
+            if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
497
+                throw new OCSForbiddenException($this->l->t('Sharing %1$s failed because the back end does not allow shares from type %2$s', [$path->getPath(), $shareType]));
498
+            }
499
+
500
+            $share->setSharedWith($shareWith);
501
+            $share->setPermissions($permissions);
502
+        }  else if ($shareType === Share::SHARE_TYPE_REMOTE_GROUP) {
503
+            if (!$this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
504
+                throw new OCSForbiddenException($this->l->t('Sharing %1$s failed because the back end does not allow shares from type %2$s', [$path->getPath(), $shareType]));
505
+            }
506
+
507
+            $share->setSharedWith($shareWith);
508
+            $share->setPermissions($permissions);
509
+        } else if ($shareType === Share::SHARE_TYPE_EMAIL) {
510
+            if ($share->getNodeType() === 'file') {
511
+                $share->setPermissions(Constants::PERMISSION_READ);
512
+            } else {
513
+                $share->setPermissions($permissions);
514
+            }
515
+            $share->setSharedWith($shareWith);
516
+
517
+            if ($sendPasswordByTalk === 'true') {
518
+                if (!$this->appManager->isEnabledForUser('spreed')) {
519
+                    throw new OCSForbiddenException($this->l->t('Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled', [$path->getPath()]));
520
+                }
521
+
522
+                $share->setSendPasswordByTalk(true);
523
+            }
524
+        } else if ($shareType === Share::SHARE_TYPE_CIRCLE) {
525
+            if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) {
526
+                throw new OCSNotFoundException($this->l->t('You cannot share to a Circle if the app is not enabled'));
527
+            }
528
+
529
+            $circle = \OCA\Circles\Api\v1\Circles::detailsCircle($shareWith);
530
+
531
+            // Valid circle is required to share
532
+            if ($circle === null) {
533
+                throw new OCSNotFoundException($this->l->t('Please specify a valid circle'));
534
+            }
535
+            $share->setSharedWith($shareWith);
536
+            $share->setPermissions($permissions);
537
+        } else if ($shareType === Share::SHARE_TYPE_ROOM) {
538
+            try {
539
+                $this->getRoomShareHelper()->createShare($share, $shareWith, $permissions, $expireDate);
540
+            } catch (QueryException $e) {
541
+                throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not support room shares', [$path->getPath()]));
542
+            }
543
+        } else {
544
+            throw new OCSBadRequestException($this->l->t('Unknown share type'));
545
+        }
546
+
547
+        $share->setShareType($shareType);
548
+        $share->setSharedBy($this->currentUser);
549
+
550
+        try {
551
+            $share = $this->shareManager->createShare($share);
552
+        } catch (GenericShareException $e) {
553
+            $code = $e->getCode() === 0 ? 403 : $e->getCode();
554
+            throw new OCSException($e->getHint(), $code);
555
+        } catch (\Exception $e) {
556
+            throw new OCSForbiddenException($e->getMessage(), $e);
557
+        }
558
+
559
+        $output = $this->formatShare($share);
560
+
561
+        return new DataResponse($output);
562
+    }
563
+
564
+    /**
565
+     * @param \OCP\Files\File|\OCP\Files\Folder $node
566
+     * @param boolean $includeTags
567
+     * @return DataResponse
568
+     */
569
+    private function getSharedWithMe($node = null, bool $includeTags): DataResponse {
570
+
571
+        $userShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_USER, $node, -1, 0);
572
+        $groupShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_GROUP, $node, -1, 0);
573
+        $circleShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_CIRCLE, $node, -1, 0);
574
+        $roomShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_ROOM, $node, -1, 0);
575
+
576
+        $shares = array_merge($userShares, $groupShares, $circleShares, $roomShares);
577
+
578
+        $shares = array_filter($shares, function (IShare $share) {
579
+            return $share->getShareOwner() !== $this->currentUser;
580
+        });
581
+
582
+        $formatted = [];
583
+        foreach ($shares as $share) {
584
+            if ($this->canAccessShare($share)) {
585
+                try {
586
+                    $formatted[] = $this->formatShare($share);
587
+                } catch (NotFoundException $e) {
588
+                    // Ignore this share
589
+                }
590
+            }
591
+        }
592
+
593
+        if ($includeTags) {
594
+            $formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
595
+        }
596
+
597
+        return new DataResponse($formatted);
598
+    }
599
+
600
+    /**
601
+     * @param \OCP\Files\Folder $folder
602
+     * @return DataResponse
603
+     * @throws OCSBadRequestException
604
+     */
605
+    private function getSharesInDir(Node $folder): DataResponse {
606
+        if (!($folder instanceof \OCP\Files\Folder)) {
607
+            throw new OCSBadRequestException($this->l->t('Not a directory'));
608
+        }
609
+
610
+        $nodes = $folder->getDirectoryListing();
611
+        /** @var \OCP\Share\IShare[] $shares */
612
+        $shares = [];
613
+        foreach ($nodes as $node) {
614
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $node, false, -1, 0));
615
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
616
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $node, false, -1, 0));
617
+            if($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
618
+                $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $node, false, -1, 0));
619
+            }
620
+            if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
621
+                $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE, $node, false, -1, 0));
622
+            }
623
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_ROOM, $node, false, -1, 0));
624
+        }
625
+
626
+        $formatted = [];
627
+        foreach ($shares as $share) {
628
+            try {
629
+                $formatted[] = $this->formatShare($share);
630
+            } catch (NotFoundException $e) {
631
+                //Ignore this share
632
+            }
633
+        }
634
+
635
+        return new DataResponse($formatted);
636
+    }
637
+
638
+    /**
639
+     * The getShares function.
640
+     *
641
+     * @NoAdminRequired
642
+     *
643
+     * @param string $shared_with_me
644
+     * @param string $reshares
645
+     * @param string $subfiles
646
+     * @param string $path
647
+     *
648
+     * - Get shares by the current user
649
+     * - Get shares by the current user and reshares (?reshares=true)
650
+     * - Get shares with the current user (?shared_with_me=true)
651
+     * - Get shares for a specific path (?path=...)
652
+     * - Get all shares in a folder (?subfiles=true&path=..)
653
+     *
654
+     * @return DataResponse
655
+     * @throws OCSNotFoundException
656
+     */
657
+    public function getShares(
658
+        string $shared_with_me = 'false',
659
+        string $reshares = 'false',
660
+        string $subfiles = 'false',
661
+        string $path = null,
662
+        string $include_tags = 'false'
663
+    ): DataResponse {
664
+
665
+        if ($path !== null) {
666
+            $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
667
+            try {
668
+                $path = $userFolder->get($path);
669
+                $this->lock($path);
670
+            } catch (\OCP\Files\NotFoundException $e) {
671
+                throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
672
+            } catch (LockedException $e) {
673
+                throw new OCSNotFoundException($this->l->t('Could not lock path'));
674
+            }
675
+        }
676
+
677
+        $include_tags = $include_tags === 'true';
678
+
679
+        if ($shared_with_me === 'true') {
680
+            $result = $this->getSharedWithMe($path, $include_tags);
681
+            return $result;
682
+        }
683
+
684
+        if ($subfiles === 'true') {
685
+            $result = $this->getSharesInDir($path);
686
+            return $result;
687
+        }
688
+
689
+        if ($reshares === 'true') {
690
+            $reshares = true;
691
+        } else {
692
+            $reshares = false;
693
+        }
694
+
695
+        // Get all shares
696
+        $userShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $path, $reshares, -1, 0);
697
+        $groupShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0);
698
+        $linkShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0);
699
+        if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
700
+            $mailShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $path, $reshares, -1, 0);
701
+        } else {
702
+            $mailShares = [];
703
+        }
704
+        if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) {
705
+            $circleShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_CIRCLE, $path, $reshares, -1, 0);
706
+        } else {
707
+            $circleShares = [];
708
+        }
709
+        $roomShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_ROOM, $path, $reshares, -1, 0);
710
+
711
+        $shares = array_merge($userShares, $groupShares, $linkShares, $mailShares, $circleShares, $roomShares);
712
+
713
+        if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
714
+            $federatedShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0);
715
+            $shares = array_merge($shares, $federatedShares);
716
+        }
717
+
718
+        if ($this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
719
+            $federatedShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE_GROUP, $path, $reshares, -1, 0);
720
+            $shares = array_merge($shares, $federatedShares);
721
+        }
722
+
723
+        $formatted = [];
724
+        foreach ($shares as $share) {
725
+            try {
726
+                $formatted[] = $this->formatShare($share, $path);
727
+            } catch (NotFoundException $e) {
728
+                //Ignore share
729
+            }
730
+        }
731
+
732
+        if ($include_tags) {
733
+            $formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
734
+        }
735
+
736
+        return new DataResponse($formatted);
737
+    }
738
+
739
+    /**
740
+     * @NoAdminRequired
741
+     *
742
+     * @param string $id
743
+     * @param int $permissions
744
+     * @param string $password
745
+     * @param string $sendPasswordByTalk
746
+     * @param string $publicUpload
747
+     * @param string $expireDate
748
+     * @param string $note
749
+     * @param string $hideDownload
750
+     * @return DataResponse
751
+     * @throws LockedException
752
+     * @throws NotFoundException
753
+     * @throws OCSBadRequestException
754
+     * @throws OCSForbiddenException
755
+     * @throws OCSNotFoundException
756
+     */
757
+    public function updateShare(
758
+        string $id,
759
+        int $permissions = null,
760
+        string $password = null,
761
+        string $sendPasswordByTalk = null,
762
+        string $publicUpload = null,
763
+        string $expireDate = null,
764
+        string $note = null,
765
+        string $hideDownload = null
766
+    ): DataResponse {
767
+        try {
768
+            $share = $this->getShareById($id);
769
+        } catch (ShareNotFound $e) {
770
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
771
+        }
772
+
773
+        $this->lock($share->getNode());
774
+
775
+        if (!$this->canAccessShare($share, false)) {
776
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
777
+        }
778
+
779
+        if ($permissions === null && $password === null && $sendPasswordByTalk === null && $publicUpload === null && $expireDate === null && $note === null && $hideDownload === null) {
780
+            throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
781
+        }
782
+
783
+        if($note !== null) {
784
+            $share->setNote($note);
785
+        }
786
+
787
+        /*
788 788
 		 * expirationdate, password and publicUpload only make sense for link shares
789 789
 		 */
790
-		if ($share->getShareType() === Share::SHARE_TYPE_LINK) {
791
-
792
-			// Update hide download state
793
-			if ($hideDownload === 'true') {
794
-				$share->setHideDownload(true);
795
-			} else if ($hideDownload === 'false') {
796
-				$share->setHideDownload(false);
797
-			}
798
-
799
-			$newPermissions = null;
800
-			if ($publicUpload === 'true') {
801
-				$newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
802
-			} else if ($publicUpload === 'false') {
803
-				$newPermissions = Constants::PERMISSION_READ;
804
-			}
805
-
806
-			if ($permissions !== null) {
807
-				$newPermissions = (int)$permissions;
808
-				$newPermissions = $newPermissions & ~Constants::PERMISSION_SHARE;
809
-			}
810
-
811
-			if ($newPermissions !== null &&
812
-				!in_array($newPermissions, [
813
-					Constants::PERMISSION_READ,
814
-					Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE, // legacy
815
-					Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE, // correct
816
-					Constants::PERMISSION_CREATE, // hidden file list
817
-					Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE, // allow to edit single files
818
-				], true)
819
-			) {
820
-				throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links'));
821
-			}
822
-
823
-			if (
824
-				// legacy
825
-				$newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE) ||
826
-				// correct
827
-				$newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE)
828
-			) {
829
-				if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
830
-					throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
831
-				}
832
-
833
-				if (!($share->getNode() instanceof \OCP\Files\Folder)) {
834
-					throw new OCSBadRequestException($this->l->t('Public upload is only possible for publicly shared folders'));
835
-				}
836
-
837
-				// normalize to correct public upload permissions
838
-				$newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
839
-			}
840
-
841
-			if ($newPermissions !== null) {
842
-				$share->setPermissions($newPermissions);
843
-				$permissions = $newPermissions;
844
-			}
845
-
846
-			if ($expireDate === '') {
847
-				$share->setExpirationDate(null);
848
-			} else if ($expireDate !== null) {
849
-				try {
850
-					$expireDate = $this->parseDate($expireDate);
851
-				} catch (\Exception $e) {
852
-					throw new OCSBadRequestException($e->getMessage(), $e);
853
-				}
854
-				$share->setExpirationDate($expireDate);
855
-			}
856
-
857
-			if ($password === '') {
858
-				$share->setPassword(null);
859
-			} else if ($password !== null) {
860
-				$share->setPassword($password);
861
-			}
862
-
863
-		} else {
864
-			if ($permissions !== null) {
865
-				$permissions = (int)$permissions;
866
-				$share->setPermissions($permissions);
867
-			}
868
-
869
-			if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) {
870
-				if ($password === '') {
871
-					$share->setPassword(null);
872
-				} else if ($password !== null) {
873
-					$share->setPassword($password);
874
-				}
875
-
876
-				if ($sendPasswordByTalk === 'true') {
877
-					if (!$this->appManager->isEnabledForUser('spreed')) {
878
-						throw new OCSForbiddenException($this->l->t('Sharing sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled'));
879
-					}
880
-
881
-					$share->setSendPasswordByTalk(true);
882
-				} else {
883
-					$share->setSendPasswordByTalk(false);
884
-				}
885
-			}
886
-
887
-			if ($expireDate === '') {
888
-				$share->setExpirationDate(null);
889
-			} else if ($expireDate !== null) {
890
-				try {
891
-					$expireDate = $this->parseDate($expireDate);
892
-				} catch (\Exception $e) {
893
-					throw new OCSBadRequestException($e->getMessage(), $e);
894
-				}
895
-				$share->setExpirationDate($expireDate);
896
-			}
897
-
898
-		}
899
-
900
-		if ($permissions !== null && $share->getShareOwner() !== $this->currentUser) {
901
-			/* Check if this is an incomming share */
902
-			$incomingShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_USER, $share->getNode(), -1, 0);
903
-			$incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0));
904
-			$incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_ROOM, $share->getNode(), -1, 0));
905
-
906
-			/** @var \OCP\Share\IShare[] $incomingShares */
907
-			if (!empty($incomingShares)) {
908
-				$maxPermissions = 0;
909
-				foreach ($incomingShares as $incomingShare) {
910
-					$maxPermissions |= $incomingShare->getPermissions();
911
-				}
912
-
913
-				if ($share->getPermissions() & ~$maxPermissions) {
914
-					throw new OCSNotFoundException($this->l->t('Cannot increase permissions'));
915
-				}
916
-			}
917
-		}
918
-
919
-
920
-		try {
921
-			$share = $this->shareManager->updateShare($share);
922
-		} catch (\Exception $e) {
923
-			throw new OCSBadRequestException($e->getMessage(), $e);
924
-		}
925
-
926
-		return new DataResponse($this->formatShare($share));
927
-	}
928
-
929
-	/**
930
-	 * @suppress PhanUndeclaredClassMethod
931
-	 */
932
-	protected function canAccessShare(\OCP\Share\IShare $share, bool $checkGroups = true): bool {
933
-		// A file with permissions 0 can't be accessed by us. So Don't show it
934
-		if ($share->getPermissions() === 0) {
935
-			return false;
936
-		}
937
-
938
-		// Owner of the file and the sharer of the file can always get share
939
-		if ($share->getShareOwner() === $this->currentUser ||
940
-			$share->getSharedBy() === $this->currentUser
941
-		) {
942
-			return true;
943
-		}
944
-
945
-		// If the share is shared with you (or a group you are a member of)
946
-		if ($share->getShareType() === Share::SHARE_TYPE_USER &&
947
-			$share->getSharedWith() === $this->currentUser
948
-		) {
949
-			return true;
950
-		}
951
-
952
-		if ($checkGroups && $share->getShareType() === Share::SHARE_TYPE_GROUP) {
953
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
954
-			$user = $this->userManager->get($this->currentUser);
955
-			if ($user !== null && $sharedWith !== null && $sharedWith->inGroup($user)) {
956
-				return true;
957
-			}
958
-		}
959
-
960
-		if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) {
961
-			// TODO: have a sanity check like above?
962
-			return true;
963
-		}
964
-
965
-		if ($share->getShareType() === Share::SHARE_TYPE_ROOM) {
966
-			try {
967
-				return $this->getRoomShareHelper()->canAccessShare($share, $this->currentUser);
968
-			} catch (QueryException $e) {
969
-				return false;
970
-			}
971
-		}
972
-
973
-		return false;
974
-	}
975
-
976
-	/**
977
-	 * Make sure that the passed date is valid ISO 8601
978
-	 * So YYYY-MM-DD
979
-	 * If not throw an exception
980
-	 *
981
-	 * @param string $expireDate
982
-	 *
983
-	 * @throws \Exception
984
-	 * @return \DateTime
985
-	 */
986
-	private function parseDate(string $expireDate): \DateTime {
987
-		try {
988
-			$date = new \DateTime($expireDate);
989
-		} catch (\Exception $e) {
990
-			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
991
-		}
992
-
993
-		if ($date === false) {
994
-			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
995
-		}
996
-
997
-		$date->setTime(0, 0, 0);
998
-
999
-		return $date;
1000
-	}
1001
-
1002
-	/**
1003
-	 * Since we have multiple providers but the OCS Share API v1 does
1004
-	 * not support this we need to check all backends.
1005
-	 *
1006
-	 * @param string $id
1007
-	 * @return \OCP\Share\IShare
1008
-	 * @throws ShareNotFound
1009
-	 */
1010
-	private function getShareById(string $id): IShare {
1011
-		$share = null;
1012
-
1013
-		// First check if it is an internal share.
1014
-		try {
1015
-			$share = $this->shareManager->getShareById('ocinternal:' . $id, $this->currentUser);
1016
-			return $share;
1017
-		} catch (ShareNotFound $e) {
1018
-			// Do nothing, just try the other share type
1019
-		}
1020
-
1021
-
1022
-		try {
1023
-			if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) {
1024
-				$share = $this->shareManager->getShareById('ocCircleShare:' . $id, $this->currentUser);
1025
-				return $share;
1026
-			}
1027
-		} catch (ShareNotFound $e) {
1028
-			// Do nothing, just try the other share type
1029
-		}
1030
-
1031
-		try {
1032
-			if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
1033
-				$share = $this->shareManager->getShareById('ocMailShare:' . $id, $this->currentUser);
1034
-				return $share;
1035
-			}
1036
-		} catch (ShareNotFound $e) {
1037
-			// Do nothing, just try the other share type
1038
-		}
1039
-
1040
-		try {
1041
-			$share = $this->shareManager->getShareById('ocRoomShare:' . $id, $this->currentUser);
1042
-			return $share;
1043
-		} catch (ShareNotFound $e) {
1044
-			// Do nothing, just try the other share type
1045
-		}
1046
-
1047
-		if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
1048
-			throw new ShareNotFound();
1049
-		}
1050
-		$share = $this->shareManager->getShareById('ocFederatedSharing:' . $id, $this->currentUser);
1051
-
1052
-		return $share;
1053
-	}
1054
-
1055
-	/**
1056
-	 * Lock a Node
1057
-	 *
1058
-	 * @param \OCP\Files\Node $node
1059
-	 * @throws LockedException
1060
-	 */
1061
-	private function lock(\OCP\Files\Node $node) {
1062
-		$node->lock(ILockingProvider::LOCK_SHARED);
1063
-		$this->lockedNode = $node;
1064
-	}
1065
-
1066
-	/**
1067
-	 * Cleanup the remaining locks
1068
-	 * @throws @LockedException
1069
-	 */
1070
-	public function cleanup() {
1071
-		if ($this->lockedNode !== null) {
1072
-			$this->lockedNode->unlock(ILockingProvider::LOCK_SHARED);
1073
-		}
1074
-	}
1075
-
1076
-	/**
1077
-	 * Returns the helper of ShareAPIController for room shares.
1078
-	 *
1079
-	 * If the Talk application is not enabled or the helper is not available
1080
-	 * a QueryException is thrown instead.
1081
-	 *
1082
-	 * @return \OCA\Spreed\Share\Helper\ShareAPIController
1083
-	 * @throws QueryException
1084
-	 */
1085
-	private function getRoomShareHelper() {
1086
-		if (!$this->appManager->isEnabledForUser('spreed')) {
1087
-			throw new QueryException();
1088
-		}
1089
-
1090
-		return $this->serverContainer->query('\OCA\Spreed\Share\Helper\ShareAPIController');
1091
-	}
790
+        if ($share->getShareType() === Share::SHARE_TYPE_LINK) {
791
+
792
+            // Update hide download state
793
+            if ($hideDownload === 'true') {
794
+                $share->setHideDownload(true);
795
+            } else if ($hideDownload === 'false') {
796
+                $share->setHideDownload(false);
797
+            }
798
+
799
+            $newPermissions = null;
800
+            if ($publicUpload === 'true') {
801
+                $newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
802
+            } else if ($publicUpload === 'false') {
803
+                $newPermissions = Constants::PERMISSION_READ;
804
+            }
805
+
806
+            if ($permissions !== null) {
807
+                $newPermissions = (int)$permissions;
808
+                $newPermissions = $newPermissions & ~Constants::PERMISSION_SHARE;
809
+            }
810
+
811
+            if ($newPermissions !== null &&
812
+                !in_array($newPermissions, [
813
+                    Constants::PERMISSION_READ,
814
+                    Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE, // legacy
815
+                    Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE, // correct
816
+                    Constants::PERMISSION_CREATE, // hidden file list
817
+                    Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE, // allow to edit single files
818
+                ], true)
819
+            ) {
820
+                throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links'));
821
+            }
822
+
823
+            if (
824
+                // legacy
825
+                $newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE) ||
826
+                // correct
827
+                $newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE)
828
+            ) {
829
+                if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
830
+                    throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
831
+                }
832
+
833
+                if (!($share->getNode() instanceof \OCP\Files\Folder)) {
834
+                    throw new OCSBadRequestException($this->l->t('Public upload is only possible for publicly shared folders'));
835
+                }
836
+
837
+                // normalize to correct public upload permissions
838
+                $newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
839
+            }
840
+
841
+            if ($newPermissions !== null) {
842
+                $share->setPermissions($newPermissions);
843
+                $permissions = $newPermissions;
844
+            }
845
+
846
+            if ($expireDate === '') {
847
+                $share->setExpirationDate(null);
848
+            } else if ($expireDate !== null) {
849
+                try {
850
+                    $expireDate = $this->parseDate($expireDate);
851
+                } catch (\Exception $e) {
852
+                    throw new OCSBadRequestException($e->getMessage(), $e);
853
+                }
854
+                $share->setExpirationDate($expireDate);
855
+            }
856
+
857
+            if ($password === '') {
858
+                $share->setPassword(null);
859
+            } else if ($password !== null) {
860
+                $share->setPassword($password);
861
+            }
862
+
863
+        } else {
864
+            if ($permissions !== null) {
865
+                $permissions = (int)$permissions;
866
+                $share->setPermissions($permissions);
867
+            }
868
+
869
+            if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) {
870
+                if ($password === '') {
871
+                    $share->setPassword(null);
872
+                } else if ($password !== null) {
873
+                    $share->setPassword($password);
874
+                }
875
+
876
+                if ($sendPasswordByTalk === 'true') {
877
+                    if (!$this->appManager->isEnabledForUser('spreed')) {
878
+                        throw new OCSForbiddenException($this->l->t('Sharing sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled'));
879
+                    }
880
+
881
+                    $share->setSendPasswordByTalk(true);
882
+                } else {
883
+                    $share->setSendPasswordByTalk(false);
884
+                }
885
+            }
886
+
887
+            if ($expireDate === '') {
888
+                $share->setExpirationDate(null);
889
+            } else if ($expireDate !== null) {
890
+                try {
891
+                    $expireDate = $this->parseDate($expireDate);
892
+                } catch (\Exception $e) {
893
+                    throw new OCSBadRequestException($e->getMessage(), $e);
894
+                }
895
+                $share->setExpirationDate($expireDate);
896
+            }
897
+
898
+        }
899
+
900
+        if ($permissions !== null && $share->getShareOwner() !== $this->currentUser) {
901
+            /* Check if this is an incomming share */
902
+            $incomingShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_USER, $share->getNode(), -1, 0);
903
+            $incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0));
904
+            $incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_ROOM, $share->getNode(), -1, 0));
905
+
906
+            /** @var \OCP\Share\IShare[] $incomingShares */
907
+            if (!empty($incomingShares)) {
908
+                $maxPermissions = 0;
909
+                foreach ($incomingShares as $incomingShare) {
910
+                    $maxPermissions |= $incomingShare->getPermissions();
911
+                }
912
+
913
+                if ($share->getPermissions() & ~$maxPermissions) {
914
+                    throw new OCSNotFoundException($this->l->t('Cannot increase permissions'));
915
+                }
916
+            }
917
+        }
918
+
919
+
920
+        try {
921
+            $share = $this->shareManager->updateShare($share);
922
+        } catch (\Exception $e) {
923
+            throw new OCSBadRequestException($e->getMessage(), $e);
924
+        }
925
+
926
+        return new DataResponse($this->formatShare($share));
927
+    }
928
+
929
+    /**
930
+     * @suppress PhanUndeclaredClassMethod
931
+     */
932
+    protected function canAccessShare(\OCP\Share\IShare $share, bool $checkGroups = true): bool {
933
+        // A file with permissions 0 can't be accessed by us. So Don't show it
934
+        if ($share->getPermissions() === 0) {
935
+            return false;
936
+        }
937
+
938
+        // Owner of the file and the sharer of the file can always get share
939
+        if ($share->getShareOwner() === $this->currentUser ||
940
+            $share->getSharedBy() === $this->currentUser
941
+        ) {
942
+            return true;
943
+        }
944
+
945
+        // If the share is shared with you (or a group you are a member of)
946
+        if ($share->getShareType() === Share::SHARE_TYPE_USER &&
947
+            $share->getSharedWith() === $this->currentUser
948
+        ) {
949
+            return true;
950
+        }
951
+
952
+        if ($checkGroups && $share->getShareType() === Share::SHARE_TYPE_GROUP) {
953
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
954
+            $user = $this->userManager->get($this->currentUser);
955
+            if ($user !== null && $sharedWith !== null && $sharedWith->inGroup($user)) {
956
+                return true;
957
+            }
958
+        }
959
+
960
+        if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) {
961
+            // TODO: have a sanity check like above?
962
+            return true;
963
+        }
964
+
965
+        if ($share->getShareType() === Share::SHARE_TYPE_ROOM) {
966
+            try {
967
+                return $this->getRoomShareHelper()->canAccessShare($share, $this->currentUser);
968
+            } catch (QueryException $e) {
969
+                return false;
970
+            }
971
+        }
972
+
973
+        return false;
974
+    }
975
+
976
+    /**
977
+     * Make sure that the passed date is valid ISO 8601
978
+     * So YYYY-MM-DD
979
+     * If not throw an exception
980
+     *
981
+     * @param string $expireDate
982
+     *
983
+     * @throws \Exception
984
+     * @return \DateTime
985
+     */
986
+    private function parseDate(string $expireDate): \DateTime {
987
+        try {
988
+            $date = new \DateTime($expireDate);
989
+        } catch (\Exception $e) {
990
+            throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
991
+        }
992
+
993
+        if ($date === false) {
994
+            throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
995
+        }
996
+
997
+        $date->setTime(0, 0, 0);
998
+
999
+        return $date;
1000
+    }
1001
+
1002
+    /**
1003
+     * Since we have multiple providers but the OCS Share API v1 does
1004
+     * not support this we need to check all backends.
1005
+     *
1006
+     * @param string $id
1007
+     * @return \OCP\Share\IShare
1008
+     * @throws ShareNotFound
1009
+     */
1010
+    private function getShareById(string $id): IShare {
1011
+        $share = null;
1012
+
1013
+        // First check if it is an internal share.
1014
+        try {
1015
+            $share = $this->shareManager->getShareById('ocinternal:' . $id, $this->currentUser);
1016
+            return $share;
1017
+        } catch (ShareNotFound $e) {
1018
+            // Do nothing, just try the other share type
1019
+        }
1020
+
1021
+
1022
+        try {
1023
+            if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) {
1024
+                $share = $this->shareManager->getShareById('ocCircleShare:' . $id, $this->currentUser);
1025
+                return $share;
1026
+            }
1027
+        } catch (ShareNotFound $e) {
1028
+            // Do nothing, just try the other share type
1029
+        }
1030
+
1031
+        try {
1032
+            if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
1033
+                $share = $this->shareManager->getShareById('ocMailShare:' . $id, $this->currentUser);
1034
+                return $share;
1035
+            }
1036
+        } catch (ShareNotFound $e) {
1037
+            // Do nothing, just try the other share type
1038
+        }
1039
+
1040
+        try {
1041
+            $share = $this->shareManager->getShareById('ocRoomShare:' . $id, $this->currentUser);
1042
+            return $share;
1043
+        } catch (ShareNotFound $e) {
1044
+            // Do nothing, just try the other share type
1045
+        }
1046
+
1047
+        if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
1048
+            throw new ShareNotFound();
1049
+        }
1050
+        $share = $this->shareManager->getShareById('ocFederatedSharing:' . $id, $this->currentUser);
1051
+
1052
+        return $share;
1053
+    }
1054
+
1055
+    /**
1056
+     * Lock a Node
1057
+     *
1058
+     * @param \OCP\Files\Node $node
1059
+     * @throws LockedException
1060
+     */
1061
+    private function lock(\OCP\Files\Node $node) {
1062
+        $node->lock(ILockingProvider::LOCK_SHARED);
1063
+        $this->lockedNode = $node;
1064
+    }
1065
+
1066
+    /**
1067
+     * Cleanup the remaining locks
1068
+     * @throws @LockedException
1069
+     */
1070
+    public function cleanup() {
1071
+        if ($this->lockedNode !== null) {
1072
+            $this->lockedNode->unlock(ILockingProvider::LOCK_SHARED);
1073
+        }
1074
+    }
1075
+
1076
+    /**
1077
+     * Returns the helper of ShareAPIController for room shares.
1078
+     *
1079
+     * If the Talk application is not enabled or the helper is not available
1080
+     * a QueryException is thrown instead.
1081
+     *
1082
+     * @return \OCA\Spreed\Share\Helper\ShareAPIController
1083
+     * @throws QueryException
1084
+     */
1085
+    private function getRoomShareHelper() {
1086
+        if (!$this->appManager->isEnabledForUser('spreed')) {
1087
+            throw new QueryException();
1088
+        }
1089
+
1090
+        return $this->serverContainer->query('\OCA\Spreed\Share\Helper\ShareAPIController');
1091
+    }
1092 1092
 }
Please login to merge, or discard this patch.
lib/private/Share20/Share.php 1 patch
Indentation   +493 added lines, -493 removed lines patch added patch discarded remove patch
@@ -34,497 +34,497 @@
 block discarded – undo
34 34
 
35 35
 class Share implements \OCP\Share\IShare {
36 36
 
37
-	/** @var string */
38
-	private $id;
39
-	/** @var string */
40
-	private $providerId;
41
-	/** @var Node */
42
-	private $node;
43
-	/** @var int */
44
-	private $fileId;
45
-	/** @var string */
46
-	private $nodeType;
47
-	/** @var int */
48
-	private $shareType;
49
-	/** @var string */
50
-	private $sharedWith;
51
-	/** @var string */
52
-	private $sharedWithDisplayName;
53
-	/** @var string */
54
-	private $sharedWithAvatar;
55
-	/** @var string */
56
-	private $sharedBy;
57
-	/** @var string */
58
-	private $shareOwner;
59
-	/** @var int */
60
-	private $permissions;
61
-	/** @var string */
62
-	private $note = '';
63
-	/** @var \DateTime */
64
-	private $expireDate;
65
-	/** @var string */
66
-	private $password;
67
-	/** @var bool */
68
-	private $sendPasswordByTalk = false;
69
-	/** @var string */
70
-	private $token;
71
-	/** @var int */
72
-	private $parent;
73
-	/** @var string */
74
-	private $target;
75
-	/** @var \DateTime */
76
-	private $shareTime;
77
-	/** @var bool */
78
-	private $mailSend;
79
-
80
-	/** @var IRootFolder */
81
-	private $rootFolder;
82
-
83
-	/** @var IUserManager */
84
-	private $userManager;
85
-
86
-	/** @var ICacheEntry|null */
87
-	private $nodeCacheEntry;
88
-
89
-	/** @var bool */
90
-	private $hideDownload = false;
91
-
92
-	public function __construct(IRootFolder $rootFolder, IUserManager $userManager) {
93
-		$this->rootFolder = $rootFolder;
94
-		$this->userManager = $userManager;
95
-	}
96
-
97
-	/**
98
-	 * @inheritdoc
99
-	 */
100
-	public function setId($id) {
101
-		if (is_int($id)) {
102
-			$id = (string)$id;
103
-		}
104
-
105
-		if(!is_string($id)) {
106
-			throw new \InvalidArgumentException('String expected.');
107
-		}
108
-
109
-		if ($this->id !== null) {
110
-			throw new IllegalIDChangeException('Not allowed to assign a new internal id to a share');
111
-		}
112
-
113
-		$this->id = trim($id);
114
-		return $this;
115
-	}
116
-
117
-	/**
118
-	 * @inheritdoc
119
-	 */
120
-	public function getId() {
121
-		return $this->id;
122
-	}
123
-
124
-	/**
125
-	 * @inheritdoc
126
-	 */
127
-	public function getFullId() {
128
-		if ($this->providerId === null || $this->id === null) {
129
-			throw new \UnexpectedValueException;
130
-		}
131
-		return $this->providerId . ':' . $this->id;
132
-	}
133
-
134
-	/**
135
-	 * @inheritdoc
136
-	 */
137
-	public function setProviderId($id) {
138
-		if(!is_string($id)) {
139
-			throw new \InvalidArgumentException('String expected.');
140
-		}
141
-
142
-		if ($this->providerId !== null) {
143
-			throw new IllegalIDChangeException('Not allowed to assign a new provider id to a share');
144
-		}
145
-
146
-		$this->providerId = trim($id);
147
-		return $this;
148
-	}
149
-
150
-	/**
151
-	 * @inheritdoc
152
-	 */
153
-	public function setNode(Node $node) {
154
-		$this->fileId = null;
155
-		$this->nodeType = null;
156
-		$this->node = $node;
157
-		return $this;
158
-	}
159
-
160
-	/**
161
-	 * @inheritdoc
162
-	 */
163
-	public function getNode() {
164
-		if ($this->node === null) {
165
-
166
-			if ($this->shareOwner === null || $this->fileId === null) {
167
-				throw new NotFoundException();
168
-			}
169
-
170
-			// for federated shares the owner can be a remote user, in this
171
-			// case we use the initiator
172
-			if($this->userManager->userExists($this->shareOwner)) {
173
-				$userFolder = $this->rootFolder->getUserFolder($this->shareOwner);
174
-			} else {
175
-				$userFolder = $this->rootFolder->getUserFolder($this->sharedBy);
176
-			}
177
-
178
-			$nodes = $userFolder->getById($this->fileId);
179
-			if (empty($nodes)) {
180
-				throw new NotFoundException('Node for share not found, fileid: ' . $this->fileId);
181
-			}
182
-
183
-			$this->node = $nodes[0];
184
-		}
185
-
186
-		return $this->node;
187
-	}
188
-
189
-	/**
190
-	 * @inheritdoc
191
-	 */
192
-	public function setNodeId($fileId) {
193
-		$this->node = null;
194
-		$this->fileId = $fileId;
195
-		return $this;
196
-	}
197
-
198
-	/**
199
-	 * @inheritdoc
200
-	 */
201
-	public function getNodeId() {
202
-		if ($this->fileId === null) {
203
-			$this->fileId = $this->getNode()->getId();
204
-		}
205
-
206
-		return $this->fileId;
207
-	}
208
-
209
-	/**
210
-	 * @inheritdoc
211
-	 */
212
-	public function setNodeType($type) {
213
-		if ($type !== 'file' && $type !== 'folder') {
214
-			throw new \InvalidArgumentException();
215
-		}
216
-
217
-		$this->nodeType = $type;
218
-		return $this;
219
-	}
220
-
221
-	/**
222
-	 * @inheritdoc
223
-	 */
224
-	public function getNodeType() {
225
-		if ($this->nodeType === null) {
226
-			$node = $this->getNode();
227
-			$this->nodeType = $node instanceof File ? 'file' : 'folder';
228
-		}
229
-
230
-		return $this->nodeType;
231
-	}
232
-
233
-	/**
234
-	 * @inheritdoc
235
-	 */
236
-	public function setShareType($shareType) {
237
-		$this->shareType = $shareType;
238
-		return $this;
239
-	}
240
-
241
-	/**
242
-	 * @inheritdoc
243
-	 */
244
-	public function getShareType() {
245
-		return $this->shareType;
246
-	}
247
-
248
-	/**
249
-	 * @inheritdoc
250
-	 */
251
-	public function setSharedWith($sharedWith) {
252
-		if (!is_string($sharedWith)) {
253
-			throw new \InvalidArgumentException();
254
-		}
255
-		$this->sharedWith = $sharedWith;
256
-		return $this;
257
-	}
258
-
259
-	/**
260
-	 * @inheritdoc
261
-	 */
262
-	public function getSharedWith() {
263
-		return $this->sharedWith;
264
-	}
265
-
266
-	/**
267
-	 * @inheritdoc
268
-	 */
269
-	public function setSharedWithDisplayName($displayName) {
270
-		if (!is_string($displayName)) {
271
-			throw new \InvalidArgumentException();
272
-		}
273
-		$this->sharedWithDisplayName = $displayName;
274
-		return $this;
275
-	}
276
-
277
-	/**
278
-	 * @inheritdoc
279
-	 */
280
-	public function getSharedWithDisplayName() {
281
-		return $this->sharedWithDisplayName;
282
-	}
283
-
284
-	/**
285
-	 * @inheritdoc
286
-	 */
287
-	public function setSharedWithAvatar($src) {
288
-		if (!is_string($src)) {
289
-			throw new \InvalidArgumentException();
290
-		}
291
-		$this->sharedWithAvatar = $src;
292
-		return $this;
293
-	}
294
-
295
-	/**
296
-	 * @inheritdoc
297
-	 */
298
-	public function getSharedWithAvatar() {
299
-		return $this->sharedWithAvatar;
300
-	}
301
-
302
-	/**
303
-	 * @inheritdoc
304
-	 */
305
-	public function setPermissions($permissions) {
306
-		//TODO checkes
307
-
308
-		$this->permissions = $permissions;
309
-		return $this;
310
-	}
311
-
312
-	/**
313
-	 * @inheritdoc
314
-	 */
315
-	public function getPermissions() {
316
-		return $this->permissions;
317
-	}
318
-
319
-	/**
320
-	 * @inheritdoc
321
-	 */
322
-	public function setNote($note) {
323
-		$this->note = $note;
324
-		return $this;
325
-	}
326
-
327
-	/**
328
-	 * @inheritdoc
329
-	 */
330
-	public function getNote() {
331
-		if (is_string($this->note)) {
332
-			return $this->note;
333
-		}
334
-		return '';
335
-	}
336
-
337
-	/**
338
-	 * @inheritdoc
339
-	 */
340
-	public function setExpirationDate($expireDate) {
341
-		//TODO checks
342
-
343
-		$this->expireDate = $expireDate;
344
-		return $this;
345
-	}
346
-
347
-	/**
348
-	 * @inheritdoc
349
-	 */
350
-	public function getExpirationDate() {
351
-		return $this->expireDate;
352
-	}
353
-
354
-	/**
355
-	 * @inheritdoc
356
-	 */
357
-	public function setSharedBy($sharedBy) {
358
-		if (!is_string($sharedBy)) {
359
-			throw new \InvalidArgumentException();
360
-		}
361
-		//TODO checks
362
-		$this->sharedBy = $sharedBy;
363
-
364
-		return $this;
365
-	}
366
-
367
-	/**
368
-	 * @inheritdoc
369
-	 */
370
-	public function getSharedBy() {
371
-		//TODO check if set
372
-		return $this->sharedBy;
373
-	}
374
-
375
-	/**
376
-	 * @inheritdoc
377
-	 */
378
-	public function setShareOwner($shareOwner) {
379
-		if (!is_string($shareOwner)) {
380
-			throw new \InvalidArgumentException();
381
-		}
382
-		//TODO checks
383
-
384
-		$this->shareOwner = $shareOwner;
385
-		return $this;
386
-	}
387
-
388
-	/**
389
-	 * @inheritdoc
390
-	 */
391
-	public function getShareOwner() {
392
-		//TODO check if set
393
-		return $this->shareOwner;
394
-	}
395
-
396
-	/**
397
-	 * @inheritdoc
398
-	 */
399
-	public function setPassword($password) {
400
-		$this->password = $password;
401
-		return $this;
402
-	}
403
-
404
-	/**
405
-	 * @inheritdoc
406
-	 */
407
-	public function getPassword() {
408
-		return $this->password;
409
-	}
410
-
411
-	/**
412
-	 * @inheritdoc
413
-	 */
414
-	public function setSendPasswordByTalk(bool $sendPasswordByTalk) {
415
-		$this->sendPasswordByTalk = $sendPasswordByTalk;
416
-		return $this;
417
-	}
418
-
419
-	/**
420
-	 * @inheritdoc
421
-	 */
422
-	public function getSendPasswordByTalk(): bool {
423
-		return $this->sendPasswordByTalk;
424
-	}
425
-
426
-	/**
427
-	 * @inheritdoc
428
-	 */
429
-	public function setToken($token) {
430
-		$this->token = $token;
431
-		return $this;
432
-	}
433
-
434
-	/**
435
-	 * @inheritdoc
436
-	 */
437
-	public function getToken() {
438
-		return $this->token;
439
-	}
440
-
441
-	/**
442
-	 * Set the parent of this share
443
-	 *
444
-	 * @param int parent
445
-	 * @return \OCP\Share\IShare
446
-	 * @deprecated The new shares do not have parents. This is just here for legacy reasons.
447
-	 */
448
-	public function setParent($parent) {
449
-		$this->parent = $parent;
450
-		return $this;
451
-	}
452
-
453
-	/**
454
-	 * Get the parent of this share.
455
-	 *
456
-	 * @return int
457
-	 * @deprecated The new shares do not have parents. This is just here for legacy reasons.
458
-	 */
459
-	public function getParent() {
460
-		return $this->parent;
461
-	}
462
-
463
-	/**
464
-	 * @inheritdoc
465
-	 */
466
-	public function setTarget($target) {
467
-		$this->target = $target;
468
-		return $this;
469
-	}
470
-
471
-	/**
472
-	 * @inheritdoc
473
-	 */
474
-	public function getTarget() {
475
-		return $this->target;
476
-	}
477
-
478
-	/**
479
-	 * @inheritdoc
480
-	 */
481
-	public function setShareTime(\DateTime $shareTime) {
482
-		$this->shareTime = $shareTime;
483
-		return $this;
484
-	}
485
-
486
-	/**
487
-	 * @inheritdoc
488
-	 */
489
-	public function getShareTime() {
490
-		return $this->shareTime;
491
-	}
492
-
493
-	/**
494
-	 * @inheritdoc
495
-	 */
496
-	public function setMailSend($mailSend) {
497
-		$this->mailSend = $mailSend;
498
-		return $this;
499
-	}
500
-
501
-	/**
502
-	 * @inheritdoc
503
-	 */
504
-	public function getMailSend() {
505
-		return $this->mailSend;
506
-	}
507
-
508
-	/**
509
-	 * @inheritdoc
510
-	 */
511
-	public function setNodeCacheEntry(ICacheEntry $entry) {
512
-		$this->nodeCacheEntry = $entry;
513
-	}
514
-
515
-	/**
516
-	 * @inheritdoc
517
-	 */
518
-	public function getNodeCacheEntry() {
519
-		return $this->nodeCacheEntry;
520
-	}
521
-
522
-	public function setHideDownload(bool $hide): IShare {
523
-		$this->hideDownload = $hide;
524
-		return $this;
525
-	}
526
-
527
-	public function getHideDownload(): bool {
528
-		return $this->hideDownload;
529
-	}
37
+    /** @var string */
38
+    private $id;
39
+    /** @var string */
40
+    private $providerId;
41
+    /** @var Node */
42
+    private $node;
43
+    /** @var int */
44
+    private $fileId;
45
+    /** @var string */
46
+    private $nodeType;
47
+    /** @var int */
48
+    private $shareType;
49
+    /** @var string */
50
+    private $sharedWith;
51
+    /** @var string */
52
+    private $sharedWithDisplayName;
53
+    /** @var string */
54
+    private $sharedWithAvatar;
55
+    /** @var string */
56
+    private $sharedBy;
57
+    /** @var string */
58
+    private $shareOwner;
59
+    /** @var int */
60
+    private $permissions;
61
+    /** @var string */
62
+    private $note = '';
63
+    /** @var \DateTime */
64
+    private $expireDate;
65
+    /** @var string */
66
+    private $password;
67
+    /** @var bool */
68
+    private $sendPasswordByTalk = false;
69
+    /** @var string */
70
+    private $token;
71
+    /** @var int */
72
+    private $parent;
73
+    /** @var string */
74
+    private $target;
75
+    /** @var \DateTime */
76
+    private $shareTime;
77
+    /** @var bool */
78
+    private $mailSend;
79
+
80
+    /** @var IRootFolder */
81
+    private $rootFolder;
82
+
83
+    /** @var IUserManager */
84
+    private $userManager;
85
+
86
+    /** @var ICacheEntry|null */
87
+    private $nodeCacheEntry;
88
+
89
+    /** @var bool */
90
+    private $hideDownload = false;
91
+
92
+    public function __construct(IRootFolder $rootFolder, IUserManager $userManager) {
93
+        $this->rootFolder = $rootFolder;
94
+        $this->userManager = $userManager;
95
+    }
96
+
97
+    /**
98
+     * @inheritdoc
99
+     */
100
+    public function setId($id) {
101
+        if (is_int($id)) {
102
+            $id = (string)$id;
103
+        }
104
+
105
+        if(!is_string($id)) {
106
+            throw new \InvalidArgumentException('String expected.');
107
+        }
108
+
109
+        if ($this->id !== null) {
110
+            throw new IllegalIDChangeException('Not allowed to assign a new internal id to a share');
111
+        }
112
+
113
+        $this->id = trim($id);
114
+        return $this;
115
+    }
116
+
117
+    /**
118
+     * @inheritdoc
119
+     */
120
+    public function getId() {
121
+        return $this->id;
122
+    }
123
+
124
+    /**
125
+     * @inheritdoc
126
+     */
127
+    public function getFullId() {
128
+        if ($this->providerId === null || $this->id === null) {
129
+            throw new \UnexpectedValueException;
130
+        }
131
+        return $this->providerId . ':' . $this->id;
132
+    }
133
+
134
+    /**
135
+     * @inheritdoc
136
+     */
137
+    public function setProviderId($id) {
138
+        if(!is_string($id)) {
139
+            throw new \InvalidArgumentException('String expected.');
140
+        }
141
+
142
+        if ($this->providerId !== null) {
143
+            throw new IllegalIDChangeException('Not allowed to assign a new provider id to a share');
144
+        }
145
+
146
+        $this->providerId = trim($id);
147
+        return $this;
148
+    }
149
+
150
+    /**
151
+     * @inheritdoc
152
+     */
153
+    public function setNode(Node $node) {
154
+        $this->fileId = null;
155
+        $this->nodeType = null;
156
+        $this->node = $node;
157
+        return $this;
158
+    }
159
+
160
+    /**
161
+     * @inheritdoc
162
+     */
163
+    public function getNode() {
164
+        if ($this->node === null) {
165
+
166
+            if ($this->shareOwner === null || $this->fileId === null) {
167
+                throw new NotFoundException();
168
+            }
169
+
170
+            // for federated shares the owner can be a remote user, in this
171
+            // case we use the initiator
172
+            if($this->userManager->userExists($this->shareOwner)) {
173
+                $userFolder = $this->rootFolder->getUserFolder($this->shareOwner);
174
+            } else {
175
+                $userFolder = $this->rootFolder->getUserFolder($this->sharedBy);
176
+            }
177
+
178
+            $nodes = $userFolder->getById($this->fileId);
179
+            if (empty($nodes)) {
180
+                throw new NotFoundException('Node for share not found, fileid: ' . $this->fileId);
181
+            }
182
+
183
+            $this->node = $nodes[0];
184
+        }
185
+
186
+        return $this->node;
187
+    }
188
+
189
+    /**
190
+     * @inheritdoc
191
+     */
192
+    public function setNodeId($fileId) {
193
+        $this->node = null;
194
+        $this->fileId = $fileId;
195
+        return $this;
196
+    }
197
+
198
+    /**
199
+     * @inheritdoc
200
+     */
201
+    public function getNodeId() {
202
+        if ($this->fileId === null) {
203
+            $this->fileId = $this->getNode()->getId();
204
+        }
205
+
206
+        return $this->fileId;
207
+    }
208
+
209
+    /**
210
+     * @inheritdoc
211
+     */
212
+    public function setNodeType($type) {
213
+        if ($type !== 'file' && $type !== 'folder') {
214
+            throw new \InvalidArgumentException();
215
+        }
216
+
217
+        $this->nodeType = $type;
218
+        return $this;
219
+    }
220
+
221
+    /**
222
+     * @inheritdoc
223
+     */
224
+    public function getNodeType() {
225
+        if ($this->nodeType === null) {
226
+            $node = $this->getNode();
227
+            $this->nodeType = $node instanceof File ? 'file' : 'folder';
228
+        }
229
+
230
+        return $this->nodeType;
231
+    }
232
+
233
+    /**
234
+     * @inheritdoc
235
+     */
236
+    public function setShareType($shareType) {
237
+        $this->shareType = $shareType;
238
+        return $this;
239
+    }
240
+
241
+    /**
242
+     * @inheritdoc
243
+     */
244
+    public function getShareType() {
245
+        return $this->shareType;
246
+    }
247
+
248
+    /**
249
+     * @inheritdoc
250
+     */
251
+    public function setSharedWith($sharedWith) {
252
+        if (!is_string($sharedWith)) {
253
+            throw new \InvalidArgumentException();
254
+        }
255
+        $this->sharedWith = $sharedWith;
256
+        return $this;
257
+    }
258
+
259
+    /**
260
+     * @inheritdoc
261
+     */
262
+    public function getSharedWith() {
263
+        return $this->sharedWith;
264
+    }
265
+
266
+    /**
267
+     * @inheritdoc
268
+     */
269
+    public function setSharedWithDisplayName($displayName) {
270
+        if (!is_string($displayName)) {
271
+            throw new \InvalidArgumentException();
272
+        }
273
+        $this->sharedWithDisplayName = $displayName;
274
+        return $this;
275
+    }
276
+
277
+    /**
278
+     * @inheritdoc
279
+     */
280
+    public function getSharedWithDisplayName() {
281
+        return $this->sharedWithDisplayName;
282
+    }
283
+
284
+    /**
285
+     * @inheritdoc
286
+     */
287
+    public function setSharedWithAvatar($src) {
288
+        if (!is_string($src)) {
289
+            throw new \InvalidArgumentException();
290
+        }
291
+        $this->sharedWithAvatar = $src;
292
+        return $this;
293
+    }
294
+
295
+    /**
296
+     * @inheritdoc
297
+     */
298
+    public function getSharedWithAvatar() {
299
+        return $this->sharedWithAvatar;
300
+    }
301
+
302
+    /**
303
+     * @inheritdoc
304
+     */
305
+    public function setPermissions($permissions) {
306
+        //TODO checkes
307
+
308
+        $this->permissions = $permissions;
309
+        return $this;
310
+    }
311
+
312
+    /**
313
+     * @inheritdoc
314
+     */
315
+    public function getPermissions() {
316
+        return $this->permissions;
317
+    }
318
+
319
+    /**
320
+     * @inheritdoc
321
+     */
322
+    public function setNote($note) {
323
+        $this->note = $note;
324
+        return $this;
325
+    }
326
+
327
+    /**
328
+     * @inheritdoc
329
+     */
330
+    public function getNote() {
331
+        if (is_string($this->note)) {
332
+            return $this->note;
333
+        }
334
+        return '';
335
+    }
336
+
337
+    /**
338
+     * @inheritdoc
339
+     */
340
+    public function setExpirationDate($expireDate) {
341
+        //TODO checks
342
+
343
+        $this->expireDate = $expireDate;
344
+        return $this;
345
+    }
346
+
347
+    /**
348
+     * @inheritdoc
349
+     */
350
+    public function getExpirationDate() {
351
+        return $this->expireDate;
352
+    }
353
+
354
+    /**
355
+     * @inheritdoc
356
+     */
357
+    public function setSharedBy($sharedBy) {
358
+        if (!is_string($sharedBy)) {
359
+            throw new \InvalidArgumentException();
360
+        }
361
+        //TODO checks
362
+        $this->sharedBy = $sharedBy;
363
+
364
+        return $this;
365
+    }
366
+
367
+    /**
368
+     * @inheritdoc
369
+     */
370
+    public function getSharedBy() {
371
+        //TODO check if set
372
+        return $this->sharedBy;
373
+    }
374
+
375
+    /**
376
+     * @inheritdoc
377
+     */
378
+    public function setShareOwner($shareOwner) {
379
+        if (!is_string($shareOwner)) {
380
+            throw new \InvalidArgumentException();
381
+        }
382
+        //TODO checks
383
+
384
+        $this->shareOwner = $shareOwner;
385
+        return $this;
386
+    }
387
+
388
+    /**
389
+     * @inheritdoc
390
+     */
391
+    public function getShareOwner() {
392
+        //TODO check if set
393
+        return $this->shareOwner;
394
+    }
395
+
396
+    /**
397
+     * @inheritdoc
398
+     */
399
+    public function setPassword($password) {
400
+        $this->password = $password;
401
+        return $this;
402
+    }
403
+
404
+    /**
405
+     * @inheritdoc
406
+     */
407
+    public function getPassword() {
408
+        return $this->password;
409
+    }
410
+
411
+    /**
412
+     * @inheritdoc
413
+     */
414
+    public function setSendPasswordByTalk(bool $sendPasswordByTalk) {
415
+        $this->sendPasswordByTalk = $sendPasswordByTalk;
416
+        return $this;
417
+    }
418
+
419
+    /**
420
+     * @inheritdoc
421
+     */
422
+    public function getSendPasswordByTalk(): bool {
423
+        return $this->sendPasswordByTalk;
424
+    }
425
+
426
+    /**
427
+     * @inheritdoc
428
+     */
429
+    public function setToken($token) {
430
+        $this->token = $token;
431
+        return $this;
432
+    }
433
+
434
+    /**
435
+     * @inheritdoc
436
+     */
437
+    public function getToken() {
438
+        return $this->token;
439
+    }
440
+
441
+    /**
442
+     * Set the parent of this share
443
+     *
444
+     * @param int parent
445
+     * @return \OCP\Share\IShare
446
+     * @deprecated The new shares do not have parents. This is just here for legacy reasons.
447
+     */
448
+    public function setParent($parent) {
449
+        $this->parent = $parent;
450
+        return $this;
451
+    }
452
+
453
+    /**
454
+     * Get the parent of this share.
455
+     *
456
+     * @return int
457
+     * @deprecated The new shares do not have parents. This is just here for legacy reasons.
458
+     */
459
+    public function getParent() {
460
+        return $this->parent;
461
+    }
462
+
463
+    /**
464
+     * @inheritdoc
465
+     */
466
+    public function setTarget($target) {
467
+        $this->target = $target;
468
+        return $this;
469
+    }
470
+
471
+    /**
472
+     * @inheritdoc
473
+     */
474
+    public function getTarget() {
475
+        return $this->target;
476
+    }
477
+
478
+    /**
479
+     * @inheritdoc
480
+     */
481
+    public function setShareTime(\DateTime $shareTime) {
482
+        $this->shareTime = $shareTime;
483
+        return $this;
484
+    }
485
+
486
+    /**
487
+     * @inheritdoc
488
+     */
489
+    public function getShareTime() {
490
+        return $this->shareTime;
491
+    }
492
+
493
+    /**
494
+     * @inheritdoc
495
+     */
496
+    public function setMailSend($mailSend) {
497
+        $this->mailSend = $mailSend;
498
+        return $this;
499
+    }
500
+
501
+    /**
502
+     * @inheritdoc
503
+     */
504
+    public function getMailSend() {
505
+        return $this->mailSend;
506
+    }
507
+
508
+    /**
509
+     * @inheritdoc
510
+     */
511
+    public function setNodeCacheEntry(ICacheEntry $entry) {
512
+        $this->nodeCacheEntry = $entry;
513
+    }
514
+
515
+    /**
516
+     * @inheritdoc
517
+     */
518
+    public function getNodeCacheEntry() {
519
+        return $this->nodeCacheEntry;
520
+    }
521
+
522
+    public function setHideDownload(bool $hide): IShare {
523
+        $this->hideDownload = $hide;
524
+        return $this;
525
+    }
526
+
527
+    public function getHideDownload(): bool {
528
+        return $this->hideDownload;
529
+    }
530 530
 }
Please login to merge, or discard this patch.
lib/private/Share20/DefaultShareProvider.php 2 patches
Indentation   +1273 added lines, -1273 removed lines patch added patch discarded remove patch
@@ -58,1310 +58,1310 @@
 block discarded – undo
58 58
  */
59 59
 class DefaultShareProvider implements IShareProvider {
60 60
 
61
-	// Special share type for user modified group shares
62
-	const SHARE_TYPE_USERGROUP = 2;
63
-
64
-	/** @var IDBConnection */
65
-	private $dbConn;
66
-
67
-	/** @var IUserManager */
68
-	private $userManager;
69
-
70
-	/** @var IGroupManager */
71
-	private $groupManager;
72
-
73
-	/** @var IRootFolder */
74
-	private $rootFolder;
75
-
76
-	/** @var IMailer */
77
-	private $mailer;
78
-
79
-	/** @var Defaults */
80
-	private $defaults;
81
-
82
-	/** @var IL10N */
83
-	private $l;
84
-
85
-	/** @var IURLGenerator */
86
-	private $urlGenerator;
87
-
88
-	/**
89
-	 * DefaultShareProvider constructor.
90
-	 *
91
-	 * @param IDBConnection $connection
92
-	 * @param IUserManager $userManager
93
-	 * @param IGroupManager $groupManager
94
-	 * @param IRootFolder $rootFolder
95
-	 * @param IMailer $mailer ;
96
-	 * @param Defaults $defaults
97
-	 * @param IL10N $l
98
-	 * @param IURLGenerator $urlGenerator
99
-	 */
100
-	public function __construct(
101
-			IDBConnection $connection,
102
-			IUserManager $userManager,
103
-			IGroupManager $groupManager,
104
-			IRootFolder $rootFolder,
105
-			IMailer $mailer,
106
-			Defaults $defaults,
107
-			IL10N $l,
108
-			IURLGenerator $urlGenerator) {
109
-		$this->dbConn = $connection;
110
-		$this->userManager = $userManager;
111
-		$this->groupManager = $groupManager;
112
-		$this->rootFolder = $rootFolder;
113
-		$this->mailer = $mailer;
114
-		$this->defaults = $defaults;
115
-		$this->l = $l;
116
-		$this->urlGenerator = $urlGenerator;
117
-	}
118
-
119
-	/**
120
-	 * Return the identifier of this provider.
121
-	 *
122
-	 * @return string Containing only [a-zA-Z0-9]
123
-	 */
124
-	public function identifier() {
125
-		return 'ocinternal';
126
-	}
127
-
128
-	/**
129
-	 * Share a path
130
-	 *
131
-	 * @param \OCP\Share\IShare $share
132
-	 * @return \OCP\Share\IShare The share object
133
-	 * @throws ShareNotFound
134
-	 * @throws \Exception
135
-	 */
136
-	public function create(\OCP\Share\IShare $share) {
137
-		$qb = $this->dbConn->getQueryBuilder();
138
-
139
-		$qb->insert('share');
140
-		$qb->setValue('share_type', $qb->createNamedParameter($share->getShareType()));
141
-
142
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
143
-			//Set the UID of the user we share with
144
-			$qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
145
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
146
-			//Set the GID of the group we share with
147
-			$qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
148
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
149
-			//Set the token of the share
150
-			$qb->setValue('token', $qb->createNamedParameter($share->getToken()));
151
-
152
-			//If a password is set store it
153
-			if ($share->getPassword() !== null) {
154
-				$qb->setValue('password', $qb->createNamedParameter($share->getPassword()));
155
-			}
156
-
157
-			//If an expiration date is set store it
158
-			if ($share->getExpirationDate() !== null) {
159
-				$qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
160
-			}
161
-
162
-			if (method_exists($share, 'getParent')) {
163
-				$qb->setValue('parent', $qb->createNamedParameter($share->getParent()));
164
-			}
165
-		} else {
166
-			throw new \Exception('invalid share type!');
167
-		}
168
-
169
-		// Set what is shares
170
-		$qb->setValue('item_type', $qb->createParameter('itemType'));
171
-		if ($share->getNode() instanceof \OCP\Files\File) {
172
-			$qb->setParameter('itemType', 'file');
173
-		} else {
174
-			$qb->setParameter('itemType', 'folder');
175
-		}
176
-
177
-		// Set the file id
178
-		$qb->setValue('item_source', $qb->createNamedParameter($share->getNode()->getId()));
179
-		$qb->setValue('file_source', $qb->createNamedParameter($share->getNode()->getId()));
180
-
181
-		// set the permissions
182
-		$qb->setValue('permissions', $qb->createNamedParameter($share->getPermissions()));
183
-
184
-		// Set who created this share
185
-		$qb->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()));
186
-
187
-		// Set who is the owner of this file/folder (and this the owner of the share)
188
-		$qb->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()));
189
-
190
-		// Set the file target
191
-		$qb->setValue('file_target', $qb->createNamedParameter($share->getTarget()));
192
-
193
-		// Set the time this share was created
194
-		$qb->setValue('stime', $qb->createNamedParameter(time()));
195
-
196
-		// insert the data and fetch the id of the share
197
-		$this->dbConn->beginTransaction();
198
-		$qb->execute();
199
-		$id = $this->dbConn->lastInsertId('*PREFIX*share');
200
-
201
-		// Now fetch the inserted share and create a complete share object
202
-		$qb = $this->dbConn->getQueryBuilder();
203
-		$qb->select('*')
204
-			->from('share')
205
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
206
-
207
-		$cursor = $qb->execute();
208
-		$data = $cursor->fetch();
209
-		$this->dbConn->commit();
210
-		$cursor->closeCursor();
211
-
212
-		if ($data === false) {
213
-			throw new ShareNotFound();
214
-		}
215
-
216
-		$mailSendValue = $share->getMailSend();
217
-		$data['mail_send'] = ($mailSendValue === null) ? true : $mailSendValue;
218
-
219
-		$share = $this->createShare($data);
220
-		return $share;
221
-	}
222
-
223
-	/**
224
-	 * Update a share
225
-	 *
226
-	 * @param \OCP\Share\IShare $share
227
-	 * @return \OCP\Share\IShare The share object
228
-	 */
229
-	public function update(\OCP\Share\IShare $share) {
230
-
231
-		$originalShare = $this->getShareById($share->getId());
232
-
233
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
234
-			/*
61
+    // Special share type for user modified group shares
62
+    const SHARE_TYPE_USERGROUP = 2;
63
+
64
+    /** @var IDBConnection */
65
+    private $dbConn;
66
+
67
+    /** @var IUserManager */
68
+    private $userManager;
69
+
70
+    /** @var IGroupManager */
71
+    private $groupManager;
72
+
73
+    /** @var IRootFolder */
74
+    private $rootFolder;
75
+
76
+    /** @var IMailer */
77
+    private $mailer;
78
+
79
+    /** @var Defaults */
80
+    private $defaults;
81
+
82
+    /** @var IL10N */
83
+    private $l;
84
+
85
+    /** @var IURLGenerator */
86
+    private $urlGenerator;
87
+
88
+    /**
89
+     * DefaultShareProvider constructor.
90
+     *
91
+     * @param IDBConnection $connection
92
+     * @param IUserManager $userManager
93
+     * @param IGroupManager $groupManager
94
+     * @param IRootFolder $rootFolder
95
+     * @param IMailer $mailer ;
96
+     * @param Defaults $defaults
97
+     * @param IL10N $l
98
+     * @param IURLGenerator $urlGenerator
99
+     */
100
+    public function __construct(
101
+            IDBConnection $connection,
102
+            IUserManager $userManager,
103
+            IGroupManager $groupManager,
104
+            IRootFolder $rootFolder,
105
+            IMailer $mailer,
106
+            Defaults $defaults,
107
+            IL10N $l,
108
+            IURLGenerator $urlGenerator) {
109
+        $this->dbConn = $connection;
110
+        $this->userManager = $userManager;
111
+        $this->groupManager = $groupManager;
112
+        $this->rootFolder = $rootFolder;
113
+        $this->mailer = $mailer;
114
+        $this->defaults = $defaults;
115
+        $this->l = $l;
116
+        $this->urlGenerator = $urlGenerator;
117
+    }
118
+
119
+    /**
120
+     * Return the identifier of this provider.
121
+     *
122
+     * @return string Containing only [a-zA-Z0-9]
123
+     */
124
+    public function identifier() {
125
+        return 'ocinternal';
126
+    }
127
+
128
+    /**
129
+     * Share a path
130
+     *
131
+     * @param \OCP\Share\IShare $share
132
+     * @return \OCP\Share\IShare The share object
133
+     * @throws ShareNotFound
134
+     * @throws \Exception
135
+     */
136
+    public function create(\OCP\Share\IShare $share) {
137
+        $qb = $this->dbConn->getQueryBuilder();
138
+
139
+        $qb->insert('share');
140
+        $qb->setValue('share_type', $qb->createNamedParameter($share->getShareType()));
141
+
142
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
143
+            //Set the UID of the user we share with
144
+            $qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
145
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
146
+            //Set the GID of the group we share with
147
+            $qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
148
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
149
+            //Set the token of the share
150
+            $qb->setValue('token', $qb->createNamedParameter($share->getToken()));
151
+
152
+            //If a password is set store it
153
+            if ($share->getPassword() !== null) {
154
+                $qb->setValue('password', $qb->createNamedParameter($share->getPassword()));
155
+            }
156
+
157
+            //If an expiration date is set store it
158
+            if ($share->getExpirationDate() !== null) {
159
+                $qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
160
+            }
161
+
162
+            if (method_exists($share, 'getParent')) {
163
+                $qb->setValue('parent', $qb->createNamedParameter($share->getParent()));
164
+            }
165
+        } else {
166
+            throw new \Exception('invalid share type!');
167
+        }
168
+
169
+        // Set what is shares
170
+        $qb->setValue('item_type', $qb->createParameter('itemType'));
171
+        if ($share->getNode() instanceof \OCP\Files\File) {
172
+            $qb->setParameter('itemType', 'file');
173
+        } else {
174
+            $qb->setParameter('itemType', 'folder');
175
+        }
176
+
177
+        // Set the file id
178
+        $qb->setValue('item_source', $qb->createNamedParameter($share->getNode()->getId()));
179
+        $qb->setValue('file_source', $qb->createNamedParameter($share->getNode()->getId()));
180
+
181
+        // set the permissions
182
+        $qb->setValue('permissions', $qb->createNamedParameter($share->getPermissions()));
183
+
184
+        // Set who created this share
185
+        $qb->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()));
186
+
187
+        // Set who is the owner of this file/folder (and this the owner of the share)
188
+        $qb->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()));
189
+
190
+        // Set the file target
191
+        $qb->setValue('file_target', $qb->createNamedParameter($share->getTarget()));
192
+
193
+        // Set the time this share was created
194
+        $qb->setValue('stime', $qb->createNamedParameter(time()));
195
+
196
+        // insert the data and fetch the id of the share
197
+        $this->dbConn->beginTransaction();
198
+        $qb->execute();
199
+        $id = $this->dbConn->lastInsertId('*PREFIX*share');
200
+
201
+        // Now fetch the inserted share and create a complete share object
202
+        $qb = $this->dbConn->getQueryBuilder();
203
+        $qb->select('*')
204
+            ->from('share')
205
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
206
+
207
+        $cursor = $qb->execute();
208
+        $data = $cursor->fetch();
209
+        $this->dbConn->commit();
210
+        $cursor->closeCursor();
211
+
212
+        if ($data === false) {
213
+            throw new ShareNotFound();
214
+        }
215
+
216
+        $mailSendValue = $share->getMailSend();
217
+        $data['mail_send'] = ($mailSendValue === null) ? true : $mailSendValue;
218
+
219
+        $share = $this->createShare($data);
220
+        return $share;
221
+    }
222
+
223
+    /**
224
+     * Update a share
225
+     *
226
+     * @param \OCP\Share\IShare $share
227
+     * @return \OCP\Share\IShare The share object
228
+     */
229
+    public function update(\OCP\Share\IShare $share) {
230
+
231
+        $originalShare = $this->getShareById($share->getId());
232
+
233
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
234
+            /*
235 235
 			 * We allow updating the recipient on user shares.
236 236
 			 */
237
-			$qb = $this->dbConn->getQueryBuilder();
238
-			$qb->update('share')
239
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
240
-				->set('share_with', $qb->createNamedParameter($share->getSharedWith()))
241
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
242
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
243
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
244
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
245
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
246
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
247
-				->set('note', $qb->createNamedParameter($share->getNote()))
248
-				->execute();
249
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
250
-			$qb = $this->dbConn->getQueryBuilder();
251
-			$qb->update('share')
252
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
253
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
254
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
255
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
256
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
257
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
258
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
259
-				->set('note', $qb->createNamedParameter($share->getNote()))
260
-				->execute();
261
-
262
-			/*
237
+            $qb = $this->dbConn->getQueryBuilder();
238
+            $qb->update('share')
239
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
240
+                ->set('share_with', $qb->createNamedParameter($share->getSharedWith()))
241
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
242
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
243
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
244
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
245
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
246
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
247
+                ->set('note', $qb->createNamedParameter($share->getNote()))
248
+                ->execute();
249
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
250
+            $qb = $this->dbConn->getQueryBuilder();
251
+            $qb->update('share')
252
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
253
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
254
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
255
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
256
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
257
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
258
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
259
+                ->set('note', $qb->createNamedParameter($share->getNote()))
260
+                ->execute();
261
+
262
+            /*
263 263
 			 * Update all user defined group shares
264 264
 			 */
265
-			$qb = $this->dbConn->getQueryBuilder();
266
-			$qb->update('share')
267
-				->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
268
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
269
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
270
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
271
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
272
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
273
-				->set('note', $qb->createNamedParameter($share->getNote()))
274
-				->execute();
275
-
276
-			/*
265
+            $qb = $this->dbConn->getQueryBuilder();
266
+            $qb->update('share')
267
+                ->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
268
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
269
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
270
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
271
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
272
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
273
+                ->set('note', $qb->createNamedParameter($share->getNote()))
274
+                ->execute();
275
+
276
+            /*
277 277
 			 * Now update the permissions for all children that have not set it to 0
278 278
 			 */
279
-			$qb = $this->dbConn->getQueryBuilder();
280
-			$qb->update('share')
281
-				->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
282
-				->andWhere($qb->expr()->neq('permissions', $qb->createNamedParameter(0)))
283
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
284
-				->execute();
285
-
286
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
287
-			$qb = $this->dbConn->getQueryBuilder();
288
-			$qb->update('share')
289
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
290
-				->set('password', $qb->createNamedParameter($share->getPassword()))
291
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
292
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
293
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
294
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
295
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
296
-				->set('token', $qb->createNamedParameter($share->getToken()))
297
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
298
-				->set('note', $qb->createNamedParameter($share->getNote()))
299
-				->set('hide_download', $qb->createNamedParameter($share->getHideDownload() ? 1 : 0), IQueryBuilder::PARAM_INT)
300
-				->execute();
301
-		}
302
-
303
-		if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
304
-			$this->propagateNote($share);
305
-		}
306
-
307
-
308
-		return $share;
309
-	}
310
-
311
-	/**
312
-	 * Get all children of this share
313
-	 * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
314
-	 *
315
-	 * @param \OCP\Share\IShare $parent
316
-	 * @return \OCP\Share\IShare[]
317
-	 */
318
-	public function getChildren(\OCP\Share\IShare $parent) {
319
-		$children = [];
320
-
321
-		$qb = $this->dbConn->getQueryBuilder();
322
-		$qb->select('*')
323
-			->from('share')
324
-			->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
325
-			->andWhere(
326
-				$qb->expr()->in(
327
-					'share_type',
328
-					$qb->createNamedParameter([
329
-						\OCP\Share::SHARE_TYPE_USER,
330
-						\OCP\Share::SHARE_TYPE_GROUP,
331
-						\OCP\Share::SHARE_TYPE_LINK,
332
-					], IQueryBuilder::PARAM_INT_ARRAY)
333
-				)
334
-			)
335
-			->andWhere($qb->expr()->orX(
336
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
337
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
338
-			))
339
-			->orderBy('id');
340
-
341
-		$cursor = $qb->execute();
342
-		while($data = $cursor->fetch()) {
343
-			$children[] = $this->createShare($data);
344
-		}
345
-		$cursor->closeCursor();
346
-
347
-		return $children;
348
-	}
349
-
350
-	/**
351
-	 * Delete a share
352
-	 *
353
-	 * @param \OCP\Share\IShare $share
354
-	 */
355
-	public function delete(\OCP\Share\IShare $share) {
356
-		$qb = $this->dbConn->getQueryBuilder();
357
-		$qb->delete('share')
358
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())));
359
-
360
-		/*
279
+            $qb = $this->dbConn->getQueryBuilder();
280
+            $qb->update('share')
281
+                ->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
282
+                ->andWhere($qb->expr()->neq('permissions', $qb->createNamedParameter(0)))
283
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
284
+                ->execute();
285
+
286
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
287
+            $qb = $this->dbConn->getQueryBuilder();
288
+            $qb->update('share')
289
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
290
+                ->set('password', $qb->createNamedParameter($share->getPassword()))
291
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
292
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
293
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
294
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
295
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
296
+                ->set('token', $qb->createNamedParameter($share->getToken()))
297
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
298
+                ->set('note', $qb->createNamedParameter($share->getNote()))
299
+                ->set('hide_download', $qb->createNamedParameter($share->getHideDownload() ? 1 : 0), IQueryBuilder::PARAM_INT)
300
+                ->execute();
301
+        }
302
+
303
+        if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
304
+            $this->propagateNote($share);
305
+        }
306
+
307
+
308
+        return $share;
309
+    }
310
+
311
+    /**
312
+     * Get all children of this share
313
+     * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
314
+     *
315
+     * @param \OCP\Share\IShare $parent
316
+     * @return \OCP\Share\IShare[]
317
+     */
318
+    public function getChildren(\OCP\Share\IShare $parent) {
319
+        $children = [];
320
+
321
+        $qb = $this->dbConn->getQueryBuilder();
322
+        $qb->select('*')
323
+            ->from('share')
324
+            ->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
325
+            ->andWhere(
326
+                $qb->expr()->in(
327
+                    'share_type',
328
+                    $qb->createNamedParameter([
329
+                        \OCP\Share::SHARE_TYPE_USER,
330
+                        \OCP\Share::SHARE_TYPE_GROUP,
331
+                        \OCP\Share::SHARE_TYPE_LINK,
332
+                    ], IQueryBuilder::PARAM_INT_ARRAY)
333
+                )
334
+            )
335
+            ->andWhere($qb->expr()->orX(
336
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
337
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
338
+            ))
339
+            ->orderBy('id');
340
+
341
+        $cursor = $qb->execute();
342
+        while($data = $cursor->fetch()) {
343
+            $children[] = $this->createShare($data);
344
+        }
345
+        $cursor->closeCursor();
346
+
347
+        return $children;
348
+    }
349
+
350
+    /**
351
+     * Delete a share
352
+     *
353
+     * @param \OCP\Share\IShare $share
354
+     */
355
+    public function delete(\OCP\Share\IShare $share) {
356
+        $qb = $this->dbConn->getQueryBuilder();
357
+        $qb->delete('share')
358
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())));
359
+
360
+        /*
361 361
 		 * If the share is a group share delete all possible
362 362
 		 * user defined groups shares.
363 363
 		 */
364
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
365
-			$qb->orWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())));
366
-		}
367
-
368
-		$qb->execute();
369
-	}
370
-
371
-	/**
372
-	 * Unshare a share from the recipient. If this is a group share
373
-	 * this means we need a special entry in the share db.
374
-	 *
375
-	 * @param \OCP\Share\IShare $share
376
-	 * @param string $recipient UserId of recipient
377
-	 * @throws BackendError
378
-	 * @throws ProviderException
379
-	 */
380
-	public function deleteFromSelf(\OCP\Share\IShare $share, $recipient) {
381
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
382
-
383
-			$group = $this->groupManager->get($share->getSharedWith());
384
-			$user = $this->userManager->get($recipient);
385
-
386
-			if (is_null($group)) {
387
-				throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
388
-			}
389
-
390
-			if (!$group->inGroup($user)) {
391
-				throw new ProviderException('Recipient not in receiving group');
392
-			}
393
-
394
-			// Try to fetch user specific share
395
-			$qb = $this->dbConn->getQueryBuilder();
396
-			$stmt = $qb->select('*')
397
-				->from('share')
398
-				->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
399
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
400
-				->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
401
-				->andWhere($qb->expr()->orX(
402
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
403
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
404
-				))
405
-				->execute();
406
-
407
-			$data = $stmt->fetch();
408
-
409
-			/*
364
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
365
+            $qb->orWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())));
366
+        }
367
+
368
+        $qb->execute();
369
+    }
370
+
371
+    /**
372
+     * Unshare a share from the recipient. If this is a group share
373
+     * this means we need a special entry in the share db.
374
+     *
375
+     * @param \OCP\Share\IShare $share
376
+     * @param string $recipient UserId of recipient
377
+     * @throws BackendError
378
+     * @throws ProviderException
379
+     */
380
+    public function deleteFromSelf(\OCP\Share\IShare $share, $recipient) {
381
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
382
+
383
+            $group = $this->groupManager->get($share->getSharedWith());
384
+            $user = $this->userManager->get($recipient);
385
+
386
+            if (is_null($group)) {
387
+                throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
388
+            }
389
+
390
+            if (!$group->inGroup($user)) {
391
+                throw new ProviderException('Recipient not in receiving group');
392
+            }
393
+
394
+            // Try to fetch user specific share
395
+            $qb = $this->dbConn->getQueryBuilder();
396
+            $stmt = $qb->select('*')
397
+                ->from('share')
398
+                ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
399
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
400
+                ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
401
+                ->andWhere($qb->expr()->orX(
402
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
403
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
404
+                ))
405
+                ->execute();
406
+
407
+            $data = $stmt->fetch();
408
+
409
+            /*
410 410
 			 * Check if there already is a user specific group share.
411 411
 			 * If there is update it (if required).
412 412
 			 */
413
-			if ($data === false) {
414
-				$qb = $this->dbConn->getQueryBuilder();
415
-
416
-				$type = $share->getNodeType();
417
-
418
-				//Insert new share
419
-				$qb->insert('share')
420
-					->values([
421
-						'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP),
422
-						'share_with' => $qb->createNamedParameter($recipient),
423
-						'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
424
-						'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
425
-						'parent' => $qb->createNamedParameter($share->getId()),
426
-						'item_type' => $qb->createNamedParameter($type),
427
-						'item_source' => $qb->createNamedParameter($share->getNodeId()),
428
-						'file_source' => $qb->createNamedParameter($share->getNodeId()),
429
-						'file_target' => $qb->createNamedParameter($share->getTarget()),
430
-						'permissions' => $qb->createNamedParameter(0),
431
-						'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
432
-					])->execute();
433
-
434
-			} else if ($data['permissions'] !== 0) {
435
-
436
-				// Update existing usergroup share
437
-				$qb = $this->dbConn->getQueryBuilder();
438
-				$qb->update('share')
439
-					->set('permissions', $qb->createNamedParameter(0))
440
-					->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
441
-					->execute();
442
-			}
443
-
444
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
445
-
446
-			if ($share->getSharedWith() !== $recipient) {
447
-				throw new ProviderException('Recipient does not match');
448
-			}
449
-
450
-			// We can just delete user and link shares
451
-			$this->delete($share);
452
-		} else {
453
-			throw new ProviderException('Invalid shareType');
454
-		}
455
-	}
456
-
457
-	/**
458
-	 * @inheritdoc
459
-	 *
460
-	 * For now this only works for group shares
461
-	 * If this gets implemented for normal shares we have to extend it
462
-	 */
463
-	public function restore(IShare $share, string $recipient): IShare {
464
-		$qb = $this->dbConn->getQueryBuilder();
465
-		$qb->select('permissions')
466
-			->from('share')
467
-			->where(
468
-				$qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))
469
-			);
470
-		$cursor = $qb->execute();
471
-		$data = $cursor->fetch();
472
-		$cursor->closeCursor();
473
-
474
-		$originalPermission = $data['permissions'];
475
-
476
-		$qb = $this->dbConn->getQueryBuilder();
477
-		$qb->update('share')
478
-			->set('permissions', $qb->createNamedParameter($originalPermission))
479
-			->where(
480
-				$qb->expr()->eq('parent', $qb->createNamedParameter($share->getParent()))
481
-			)->andWhere(
482
-				$qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP))
483
-			)->andWhere(
484
-				$qb->expr()->eq('share_with', $qb->createNamedParameter($recipient))
485
-			);
486
-
487
-		$qb->execute();
488
-
489
-		return $this->getShareById($share->getId(), $recipient);
490
-	}
491
-
492
-	/**
493
-	 * @inheritdoc
494
-	 */
495
-	public function move(\OCP\Share\IShare $share, $recipient) {
496
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
497
-			// Just update the target
498
-			$qb = $this->dbConn->getQueryBuilder();
499
-			$qb->update('share')
500
-				->set('file_target', $qb->createNamedParameter($share->getTarget()))
501
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
502
-				->execute();
503
-
504
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
505
-
506
-			// Check if there is a usergroup share
507
-			$qb = $this->dbConn->getQueryBuilder();
508
-			$stmt = $qb->select('id')
509
-				->from('share')
510
-				->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
511
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
512
-				->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
513
-				->andWhere($qb->expr()->orX(
514
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
515
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
516
-				))
517
-				->setMaxResults(1)
518
-				->execute();
519
-
520
-			$data = $stmt->fetch();
521
-			$stmt->closeCursor();
522
-
523
-			if ($data === false) {
524
-				// No usergroup share yet. Create one.
525
-				$qb = $this->dbConn->getQueryBuilder();
526
-				$qb->insert('share')
527
-					->values([
528
-						'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP),
529
-						'share_with' => $qb->createNamedParameter($recipient),
530
-						'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
531
-						'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
532
-						'parent' => $qb->createNamedParameter($share->getId()),
533
-						'item_type' => $qb->createNamedParameter($share->getNodeType()),
534
-						'item_source' => $qb->createNamedParameter($share->getNodeId()),
535
-						'file_source' => $qb->createNamedParameter($share->getNodeId()),
536
-						'file_target' => $qb->createNamedParameter($share->getTarget()),
537
-						'permissions' => $qb->createNamedParameter($share->getPermissions()),
538
-						'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
539
-					])->execute();
540
-			} else {
541
-				// Already a usergroup share. Update it.
542
-				$qb = $this->dbConn->getQueryBuilder();
543
-				$qb->update('share')
544
-					->set('file_target', $qb->createNamedParameter($share->getTarget()))
545
-					->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
546
-					->execute();
547
-			}
548
-		}
549
-
550
-		return $share;
551
-	}
552
-
553
-	public function getSharesInFolder($userId, Folder $node, $reshares) {
554
-		$qb = $this->dbConn->getQueryBuilder();
555
-		$qb->select('*')
556
-			->from('share', 's')
557
-			->andWhere($qb->expr()->orX(
558
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
559
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
560
-			));
561
-
562
-		$qb->andWhere($qb->expr()->orX(
563
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
564
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
565
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK))
566
-		));
567
-
568
-		/**
569
-		 * Reshares for this user are shares where they are the owner.
570
-		 */
571
-		if ($reshares === false) {
572
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
573
-		} else {
574
-			$qb->andWhere(
575
-				$qb->expr()->orX(
576
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
577
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
578
-				)
579
-			);
580
-		}
581
-
582
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
583
-		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
584
-
585
-		$qb->orderBy('id');
586
-
587
-		$cursor = $qb->execute();
588
-		$shares = [];
589
-		while ($data = $cursor->fetch()) {
590
-			$shares[$data['fileid']][] = $this->createShare($data);
591
-		}
592
-		$cursor->closeCursor();
593
-
594
-		return $shares;
595
-	}
596
-
597
-	/**
598
-	 * @inheritdoc
599
-	 */
600
-	public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
601
-		$qb = $this->dbConn->getQueryBuilder();
602
-		$qb->select('*')
603
-			->from('share')
604
-			->andWhere($qb->expr()->orX(
605
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
606
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
607
-			));
608
-
609
-		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter($shareType)));
610
-
611
-		/**
612
-		 * Reshares for this user are shares where they are the owner.
613
-		 */
614
-		if ($reshares === false) {
615
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
616
-		} else {
617
-			$qb->andWhere(
618
-				$qb->expr()->orX(
619
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
620
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
621
-				)
622
-			);
623
-		}
624
-
625
-		if ($node !== null) {
626
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
627
-		}
628
-
629
-		if ($limit !== -1) {
630
-			$qb->setMaxResults($limit);
631
-		}
632
-
633
-		$qb->setFirstResult($offset);
634
-		$qb->orderBy('id');
635
-
636
-		$cursor = $qb->execute();
637
-		$shares = [];
638
-		while($data = $cursor->fetch()) {
639
-			$shares[] = $this->createShare($data);
640
-		}
641
-		$cursor->closeCursor();
642
-
643
-		return $shares;
644
-	}
645
-
646
-	/**
647
-	 * @inheritdoc
648
-	 */
649
-	public function getShareById($id, $recipientId = null) {
650
-		$qb = $this->dbConn->getQueryBuilder();
651
-
652
-		$qb->select('*')
653
-			->from('share')
654
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
655
-			->andWhere(
656
-				$qb->expr()->in(
657
-					'share_type',
658
-					$qb->createNamedParameter([
659
-						\OCP\Share::SHARE_TYPE_USER,
660
-						\OCP\Share::SHARE_TYPE_GROUP,
661
-						\OCP\Share::SHARE_TYPE_LINK,
662
-					], IQueryBuilder::PARAM_INT_ARRAY)
663
-				)
664
-			)
665
-			->andWhere($qb->expr()->orX(
666
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
667
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
668
-			));
669
-
670
-		$cursor = $qb->execute();
671
-		$data = $cursor->fetch();
672
-		$cursor->closeCursor();
673
-
674
-		if ($data === false) {
675
-			throw new ShareNotFound();
676
-		}
677
-
678
-		try {
679
-			$share = $this->createShare($data);
680
-		} catch (InvalidShare $e) {
681
-			throw new ShareNotFound();
682
-		}
683
-
684
-		// If the recipient is set for a group share resolve to that user
685
-		if ($recipientId !== null && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
686
-			$share = $this->resolveGroupShares([$share], $recipientId)[0];
687
-		}
688
-
689
-		return $share;
690
-	}
691
-
692
-	/**
693
-	 * Get shares for a given path
694
-	 *
695
-	 * @param \OCP\Files\Node $path
696
-	 * @return \OCP\Share\IShare[]
697
-	 */
698
-	public function getSharesByPath(Node $path) {
699
-		$qb = $this->dbConn->getQueryBuilder();
700
-
701
-		$cursor = $qb->select('*')
702
-			->from('share')
703
-			->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
704
-			->andWhere(
705
-				$qb->expr()->orX(
706
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
707
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP))
708
-				)
709
-			)
710
-			->andWhere($qb->expr()->orX(
711
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
712
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
713
-			))
714
-			->execute();
715
-
716
-		$shares = [];
717
-		while($data = $cursor->fetch()) {
718
-			$shares[] = $this->createShare($data);
719
-		}
720
-		$cursor->closeCursor();
721
-
722
-		return $shares;
723
-	}
724
-
725
-	/**
726
-	 * Returns whether the given database result can be interpreted as
727
-	 * a share with accessible file (not trashed, not deleted)
728
-	 */
729
-	private function isAccessibleResult($data) {
730
-		// exclude shares leading to deleted file entries
731
-		if ($data['fileid'] === null) {
732
-			return false;
733
-		}
734
-
735
-		// exclude shares leading to trashbin on home storages
736
-		$pathSections = explode('/', $data['path'], 2);
737
-		// FIXME: would not detect rare md5'd home storage case properly
738
-		if ($pathSections[0] !== 'files'
739
-		    	&& in_array(explode(':', $data['storage_string_id'], 2)[0], array('home', 'object'))) {
740
-			return false;
741
-		}
742
-		return true;
743
-	}
744
-
745
-	/**
746
-	 * @inheritdoc
747
-	 */
748
-	public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
749
-		/** @var Share[] $shares */
750
-		$shares = [];
751
-
752
-		if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
753
-			//Get shares directly with this user
754
-			$qb = $this->dbConn->getQueryBuilder();
755
-			$qb->select('s.*',
756
-				'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
757
-				'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
758
-				'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
759
-			)
760
-				->selectAlias('st.id', 'storage_string_id')
761
-				->from('share', 's')
762
-				->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
763
-				->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'));
764
-
765
-			// Order by id
766
-			$qb->orderBy('s.id');
767
-
768
-			// Set limit and offset
769
-			if ($limit !== -1) {
770
-				$qb->setMaxResults($limit);
771
-			}
772
-			$qb->setFirstResult($offset);
773
-
774
-			$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)))
775
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
776
-				->andWhere($qb->expr()->orX(
777
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
778
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
779
-				));
780
-
781
-			// Filter by node if provided
782
-			if ($node !== null) {
783
-				$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
784
-			}
785
-
786
-			$cursor = $qb->execute();
787
-
788
-			while($data = $cursor->fetch()) {
789
-				if ($this->isAccessibleResult($data)) {
790
-					$shares[] = $this->createShare($data);
791
-				}
792
-			}
793
-			$cursor->closeCursor();
794
-
795
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
796
-			$user = $this->userManager->get($userId);
797
-			$allGroups = $this->groupManager->getUserGroups($user);
798
-
799
-			/** @var Share[] $shares2 */
800
-			$shares2 = [];
801
-
802
-			$start = 0;
803
-			while(true) {
804
-				$groups = array_slice($allGroups, $start, 100);
805
-				$start += 100;
806
-
807
-				if ($groups === []) {
808
-					break;
809
-				}
810
-
811
-				$qb = $this->dbConn->getQueryBuilder();
812
-				$qb->select('s.*',
813
-					'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
814
-					'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
815
-					'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
816
-				)
817
-					->selectAlias('st.id', 'storage_string_id')
818
-					->from('share', 's')
819
-					->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
820
-					->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'))
821
-					->orderBy('s.id')
822
-					->setFirstResult(0);
823
-
824
-				if ($limit !== -1) {
825
-					$qb->setMaxResults($limit - count($shares));
826
-				}
827
-
828
-				// Filter by node if provided
829
-				if ($node !== null) {
830
-					$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
831
-				}
832
-
833
-
834
-				$groups = array_filter($groups, function($group) { return $group instanceof IGroup; });
835
-				$groups = array_map(function(IGroup $group) { return $group->getGID(); }, $groups);
836
-
837
-				$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
838
-					->andWhere($qb->expr()->in('share_with', $qb->createNamedParameter(
839
-						$groups,
840
-						IQueryBuilder::PARAM_STR_ARRAY
841
-					)))
842
-					->andWhere($qb->expr()->orX(
843
-						$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
844
-						$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
845
-					));
846
-
847
-				$cursor = $qb->execute();
848
-				while($data = $cursor->fetch()) {
849
-					if ($offset > 0) {
850
-						$offset--;
851
-						continue;
852
-					}
853
-
854
-					if ($this->isAccessibleResult($data)) {
855
-						$shares2[] = $this->createShare($data);
856
-					}
857
-				}
858
-				$cursor->closeCursor();
859
-			}
860
-
861
-			/*
413
+            if ($data === false) {
414
+                $qb = $this->dbConn->getQueryBuilder();
415
+
416
+                $type = $share->getNodeType();
417
+
418
+                //Insert new share
419
+                $qb->insert('share')
420
+                    ->values([
421
+                        'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP),
422
+                        'share_with' => $qb->createNamedParameter($recipient),
423
+                        'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
424
+                        'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
425
+                        'parent' => $qb->createNamedParameter($share->getId()),
426
+                        'item_type' => $qb->createNamedParameter($type),
427
+                        'item_source' => $qb->createNamedParameter($share->getNodeId()),
428
+                        'file_source' => $qb->createNamedParameter($share->getNodeId()),
429
+                        'file_target' => $qb->createNamedParameter($share->getTarget()),
430
+                        'permissions' => $qb->createNamedParameter(0),
431
+                        'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
432
+                    ])->execute();
433
+
434
+            } else if ($data['permissions'] !== 0) {
435
+
436
+                // Update existing usergroup share
437
+                $qb = $this->dbConn->getQueryBuilder();
438
+                $qb->update('share')
439
+                    ->set('permissions', $qb->createNamedParameter(0))
440
+                    ->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
441
+                    ->execute();
442
+            }
443
+
444
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
445
+
446
+            if ($share->getSharedWith() !== $recipient) {
447
+                throw new ProviderException('Recipient does not match');
448
+            }
449
+
450
+            // We can just delete user and link shares
451
+            $this->delete($share);
452
+        } else {
453
+            throw new ProviderException('Invalid shareType');
454
+        }
455
+    }
456
+
457
+    /**
458
+     * @inheritdoc
459
+     *
460
+     * For now this only works for group shares
461
+     * If this gets implemented for normal shares we have to extend it
462
+     */
463
+    public function restore(IShare $share, string $recipient): IShare {
464
+        $qb = $this->dbConn->getQueryBuilder();
465
+        $qb->select('permissions')
466
+            ->from('share')
467
+            ->where(
468
+                $qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))
469
+            );
470
+        $cursor = $qb->execute();
471
+        $data = $cursor->fetch();
472
+        $cursor->closeCursor();
473
+
474
+        $originalPermission = $data['permissions'];
475
+
476
+        $qb = $this->dbConn->getQueryBuilder();
477
+        $qb->update('share')
478
+            ->set('permissions', $qb->createNamedParameter($originalPermission))
479
+            ->where(
480
+                $qb->expr()->eq('parent', $qb->createNamedParameter($share->getParent()))
481
+            )->andWhere(
482
+                $qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP))
483
+            )->andWhere(
484
+                $qb->expr()->eq('share_with', $qb->createNamedParameter($recipient))
485
+            );
486
+
487
+        $qb->execute();
488
+
489
+        return $this->getShareById($share->getId(), $recipient);
490
+    }
491
+
492
+    /**
493
+     * @inheritdoc
494
+     */
495
+    public function move(\OCP\Share\IShare $share, $recipient) {
496
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
497
+            // Just update the target
498
+            $qb = $this->dbConn->getQueryBuilder();
499
+            $qb->update('share')
500
+                ->set('file_target', $qb->createNamedParameter($share->getTarget()))
501
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
502
+                ->execute();
503
+
504
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
505
+
506
+            // Check if there is a usergroup share
507
+            $qb = $this->dbConn->getQueryBuilder();
508
+            $stmt = $qb->select('id')
509
+                ->from('share')
510
+                ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
511
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
512
+                ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
513
+                ->andWhere($qb->expr()->orX(
514
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
515
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
516
+                ))
517
+                ->setMaxResults(1)
518
+                ->execute();
519
+
520
+            $data = $stmt->fetch();
521
+            $stmt->closeCursor();
522
+
523
+            if ($data === false) {
524
+                // No usergroup share yet. Create one.
525
+                $qb = $this->dbConn->getQueryBuilder();
526
+                $qb->insert('share')
527
+                    ->values([
528
+                        'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP),
529
+                        'share_with' => $qb->createNamedParameter($recipient),
530
+                        'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
531
+                        'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
532
+                        'parent' => $qb->createNamedParameter($share->getId()),
533
+                        'item_type' => $qb->createNamedParameter($share->getNodeType()),
534
+                        'item_source' => $qb->createNamedParameter($share->getNodeId()),
535
+                        'file_source' => $qb->createNamedParameter($share->getNodeId()),
536
+                        'file_target' => $qb->createNamedParameter($share->getTarget()),
537
+                        'permissions' => $qb->createNamedParameter($share->getPermissions()),
538
+                        'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
539
+                    ])->execute();
540
+            } else {
541
+                // Already a usergroup share. Update it.
542
+                $qb = $this->dbConn->getQueryBuilder();
543
+                $qb->update('share')
544
+                    ->set('file_target', $qb->createNamedParameter($share->getTarget()))
545
+                    ->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
546
+                    ->execute();
547
+            }
548
+        }
549
+
550
+        return $share;
551
+    }
552
+
553
+    public function getSharesInFolder($userId, Folder $node, $reshares) {
554
+        $qb = $this->dbConn->getQueryBuilder();
555
+        $qb->select('*')
556
+            ->from('share', 's')
557
+            ->andWhere($qb->expr()->orX(
558
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
559
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
560
+            ));
561
+
562
+        $qb->andWhere($qb->expr()->orX(
563
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
564
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
565
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK))
566
+        ));
567
+
568
+        /**
569
+         * Reshares for this user are shares where they are the owner.
570
+         */
571
+        if ($reshares === false) {
572
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
573
+        } else {
574
+            $qb->andWhere(
575
+                $qb->expr()->orX(
576
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
577
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
578
+                )
579
+            );
580
+        }
581
+
582
+        $qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
583
+        $qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
584
+
585
+        $qb->orderBy('id');
586
+
587
+        $cursor = $qb->execute();
588
+        $shares = [];
589
+        while ($data = $cursor->fetch()) {
590
+            $shares[$data['fileid']][] = $this->createShare($data);
591
+        }
592
+        $cursor->closeCursor();
593
+
594
+        return $shares;
595
+    }
596
+
597
+    /**
598
+     * @inheritdoc
599
+     */
600
+    public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
601
+        $qb = $this->dbConn->getQueryBuilder();
602
+        $qb->select('*')
603
+            ->from('share')
604
+            ->andWhere($qb->expr()->orX(
605
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
606
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
607
+            ));
608
+
609
+        $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter($shareType)));
610
+
611
+        /**
612
+         * Reshares for this user are shares where they are the owner.
613
+         */
614
+        if ($reshares === false) {
615
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
616
+        } else {
617
+            $qb->andWhere(
618
+                $qb->expr()->orX(
619
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
620
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
621
+                )
622
+            );
623
+        }
624
+
625
+        if ($node !== null) {
626
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
627
+        }
628
+
629
+        if ($limit !== -1) {
630
+            $qb->setMaxResults($limit);
631
+        }
632
+
633
+        $qb->setFirstResult($offset);
634
+        $qb->orderBy('id');
635
+
636
+        $cursor = $qb->execute();
637
+        $shares = [];
638
+        while($data = $cursor->fetch()) {
639
+            $shares[] = $this->createShare($data);
640
+        }
641
+        $cursor->closeCursor();
642
+
643
+        return $shares;
644
+    }
645
+
646
+    /**
647
+     * @inheritdoc
648
+     */
649
+    public function getShareById($id, $recipientId = null) {
650
+        $qb = $this->dbConn->getQueryBuilder();
651
+
652
+        $qb->select('*')
653
+            ->from('share')
654
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
655
+            ->andWhere(
656
+                $qb->expr()->in(
657
+                    'share_type',
658
+                    $qb->createNamedParameter([
659
+                        \OCP\Share::SHARE_TYPE_USER,
660
+                        \OCP\Share::SHARE_TYPE_GROUP,
661
+                        \OCP\Share::SHARE_TYPE_LINK,
662
+                    ], IQueryBuilder::PARAM_INT_ARRAY)
663
+                )
664
+            )
665
+            ->andWhere($qb->expr()->orX(
666
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
667
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
668
+            ));
669
+
670
+        $cursor = $qb->execute();
671
+        $data = $cursor->fetch();
672
+        $cursor->closeCursor();
673
+
674
+        if ($data === false) {
675
+            throw new ShareNotFound();
676
+        }
677
+
678
+        try {
679
+            $share = $this->createShare($data);
680
+        } catch (InvalidShare $e) {
681
+            throw new ShareNotFound();
682
+        }
683
+
684
+        // If the recipient is set for a group share resolve to that user
685
+        if ($recipientId !== null && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
686
+            $share = $this->resolveGroupShares([$share], $recipientId)[0];
687
+        }
688
+
689
+        return $share;
690
+    }
691
+
692
+    /**
693
+     * Get shares for a given path
694
+     *
695
+     * @param \OCP\Files\Node $path
696
+     * @return \OCP\Share\IShare[]
697
+     */
698
+    public function getSharesByPath(Node $path) {
699
+        $qb = $this->dbConn->getQueryBuilder();
700
+
701
+        $cursor = $qb->select('*')
702
+            ->from('share')
703
+            ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
704
+            ->andWhere(
705
+                $qb->expr()->orX(
706
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
707
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP))
708
+                )
709
+            )
710
+            ->andWhere($qb->expr()->orX(
711
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
712
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
713
+            ))
714
+            ->execute();
715
+
716
+        $shares = [];
717
+        while($data = $cursor->fetch()) {
718
+            $shares[] = $this->createShare($data);
719
+        }
720
+        $cursor->closeCursor();
721
+
722
+        return $shares;
723
+    }
724
+
725
+    /**
726
+     * Returns whether the given database result can be interpreted as
727
+     * a share with accessible file (not trashed, not deleted)
728
+     */
729
+    private function isAccessibleResult($data) {
730
+        // exclude shares leading to deleted file entries
731
+        if ($data['fileid'] === null) {
732
+            return false;
733
+        }
734
+
735
+        // exclude shares leading to trashbin on home storages
736
+        $pathSections = explode('/', $data['path'], 2);
737
+        // FIXME: would not detect rare md5'd home storage case properly
738
+        if ($pathSections[0] !== 'files'
739
+                && in_array(explode(':', $data['storage_string_id'], 2)[0], array('home', 'object'))) {
740
+            return false;
741
+        }
742
+        return true;
743
+    }
744
+
745
+    /**
746
+     * @inheritdoc
747
+     */
748
+    public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
749
+        /** @var Share[] $shares */
750
+        $shares = [];
751
+
752
+        if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
753
+            //Get shares directly with this user
754
+            $qb = $this->dbConn->getQueryBuilder();
755
+            $qb->select('s.*',
756
+                'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
757
+                'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
758
+                'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
759
+            )
760
+                ->selectAlias('st.id', 'storage_string_id')
761
+                ->from('share', 's')
762
+                ->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
763
+                ->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'));
764
+
765
+            // Order by id
766
+            $qb->orderBy('s.id');
767
+
768
+            // Set limit and offset
769
+            if ($limit !== -1) {
770
+                $qb->setMaxResults($limit);
771
+            }
772
+            $qb->setFirstResult($offset);
773
+
774
+            $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)))
775
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
776
+                ->andWhere($qb->expr()->orX(
777
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
778
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
779
+                ));
780
+
781
+            // Filter by node if provided
782
+            if ($node !== null) {
783
+                $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
784
+            }
785
+
786
+            $cursor = $qb->execute();
787
+
788
+            while($data = $cursor->fetch()) {
789
+                if ($this->isAccessibleResult($data)) {
790
+                    $shares[] = $this->createShare($data);
791
+                }
792
+            }
793
+            $cursor->closeCursor();
794
+
795
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
796
+            $user = $this->userManager->get($userId);
797
+            $allGroups = $this->groupManager->getUserGroups($user);
798
+
799
+            /** @var Share[] $shares2 */
800
+            $shares2 = [];
801
+
802
+            $start = 0;
803
+            while(true) {
804
+                $groups = array_slice($allGroups, $start, 100);
805
+                $start += 100;
806
+
807
+                if ($groups === []) {
808
+                    break;
809
+                }
810
+
811
+                $qb = $this->dbConn->getQueryBuilder();
812
+                $qb->select('s.*',
813
+                    'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
814
+                    'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
815
+                    'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
816
+                )
817
+                    ->selectAlias('st.id', 'storage_string_id')
818
+                    ->from('share', 's')
819
+                    ->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
820
+                    ->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'))
821
+                    ->orderBy('s.id')
822
+                    ->setFirstResult(0);
823
+
824
+                if ($limit !== -1) {
825
+                    $qb->setMaxResults($limit - count($shares));
826
+                }
827
+
828
+                // Filter by node if provided
829
+                if ($node !== null) {
830
+                    $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
831
+                }
832
+
833
+
834
+                $groups = array_filter($groups, function($group) { return $group instanceof IGroup; });
835
+                $groups = array_map(function(IGroup $group) { return $group->getGID(); }, $groups);
836
+
837
+                $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
838
+                    ->andWhere($qb->expr()->in('share_with', $qb->createNamedParameter(
839
+                        $groups,
840
+                        IQueryBuilder::PARAM_STR_ARRAY
841
+                    )))
842
+                    ->andWhere($qb->expr()->orX(
843
+                        $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
844
+                        $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
845
+                    ));
846
+
847
+                $cursor = $qb->execute();
848
+                while($data = $cursor->fetch()) {
849
+                    if ($offset > 0) {
850
+                        $offset--;
851
+                        continue;
852
+                    }
853
+
854
+                    if ($this->isAccessibleResult($data)) {
855
+                        $shares2[] = $this->createShare($data);
856
+                    }
857
+                }
858
+                $cursor->closeCursor();
859
+            }
860
+
861
+            /*
862 862
  			 * Resolve all group shares to user specific shares
863 863
  			 */
864
-			$shares = $this->resolveGroupShares($shares2, $userId);
865
-		} else {
866
-			throw new BackendError('Invalid backend');
867
-		}
868
-
869
-
870
-		return $shares;
871
-	}
872
-
873
-	/**
874
-	 * Get a share by token
875
-	 *
876
-	 * @param string $token
877
-	 * @return \OCP\Share\IShare
878
-	 * @throws ShareNotFound
879
-	 */
880
-	public function getShareByToken($token) {
881
-		$qb = $this->dbConn->getQueryBuilder();
882
-
883
-		$cursor = $qb->select('*')
884
-			->from('share')
885
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK)))
886
-			->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
887
-			->andWhere($qb->expr()->orX(
888
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
889
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
890
-			))
891
-			->execute();
892
-
893
-		$data = $cursor->fetch();
894
-
895
-		if ($data === false) {
896
-			throw new ShareNotFound();
897
-		}
898
-
899
-		try {
900
-			$share = $this->createShare($data);
901
-		} catch (InvalidShare $e) {
902
-			throw new ShareNotFound();
903
-		}
904
-
905
-		return $share;
906
-	}
907
-
908
-	/**
909
-	 * Create a share object from an database row
910
-	 *
911
-	 * @param mixed[] $data
912
-	 * @return \OCP\Share\IShare
913
-	 * @throws InvalidShare
914
-	 */
915
-	private function createShare($data) {
916
-		$share = new Share($this->rootFolder, $this->userManager);
917
-		$share->setId((int)$data['id'])
918
-			->setShareType((int)$data['share_type'])
919
-			->setPermissions((int)$data['permissions'])
920
-			->setTarget($data['file_target'])
921
-			->setNote($data['note'])
922
-			->setMailSend((bool)$data['mail_send']);
923
-
924
-		$shareTime = new \DateTime();
925
-		$shareTime->setTimestamp((int)$data['stime']);
926
-		$share->setShareTime($shareTime);
927
-
928
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
929
-			$share->setSharedWith($data['share_with']);
930
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
931
-			$share->setSharedWith($data['share_with']);
932
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
933
-			$share->setPassword($data['password']);
934
-			$share->setToken($data['token']);
935
-		}
936
-
937
-		$share->setSharedBy($data['uid_initiator']);
938
-		$share->setShareOwner($data['uid_owner']);
939
-
940
-		$share->setNodeId((int)$data['file_source']);
941
-		$share->setNodeType($data['item_type']);
942
-
943
-		if ($data['expiration'] !== null) {
944
-			$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
945
-			$share->setExpirationDate($expiration);
946
-		}
947
-
948
-		if (isset($data['f_permissions'])) {
949
-			$entryData = $data;
950
-			$entryData['permissions'] = $entryData['f_permissions'];
951
-			$entryData['parent'] = $entryData['f_parent'];
952
-			$share->setNodeCacheEntry(Cache::cacheEntryFromData($entryData,
953
-				\OC::$server->getMimeTypeLoader()));
954
-		}
955
-
956
-		$share->setProviderId($this->identifier());
957
-		$share->setHideDownload((int)$data['hide_download'] === 1);
958
-
959
-		return $share;
960
-	}
961
-
962
-	/**
963
-	 * @param Share[] $shares
964
-	 * @param $userId
965
-	 * @return Share[] The updates shares if no update is found for a share return the original
966
-	 */
967
-	private function resolveGroupShares($shares, $userId) {
968
-		$result = [];
969
-
970
-		$start = 0;
971
-		while(true) {
972
-			/** @var Share[] $shareSlice */
973
-			$shareSlice = array_slice($shares, $start, 100);
974
-			$start += 100;
975
-
976
-			if ($shareSlice === []) {
977
-				break;
978
-			}
979
-
980
-			/** @var int[] $ids */
981
-			$ids = [];
982
-			/** @var Share[] $shareMap */
983
-			$shareMap = [];
984
-
985
-			foreach ($shareSlice as $share) {
986
-				$ids[] = (int)$share->getId();
987
-				$shareMap[$share->getId()] = $share;
988
-			}
989
-
990
-			$qb = $this->dbConn->getQueryBuilder();
991
-
992
-			$query = $qb->select('*')
993
-				->from('share')
994
-				->where($qb->expr()->in('parent', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
995
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
996
-				->andWhere($qb->expr()->orX(
997
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
998
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
999
-				));
1000
-
1001
-			$stmt = $query->execute();
1002
-
1003
-			while($data = $stmt->fetch()) {
1004
-				$shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
1005
-				$shareMap[$data['parent']]->setTarget($data['file_target']);
1006
-				$shareMap[$data['parent']]->setParent($data['parent']);
1007
-			}
1008
-
1009
-			$stmt->closeCursor();
1010
-
1011
-			foreach ($shareMap as $share) {
1012
-				$result[] = $share;
1013
-			}
1014
-		}
1015
-
1016
-		return $result;
1017
-	}
1018
-
1019
-	/**
1020
-	 * A user is deleted from the system
1021
-	 * So clean up the relevant shares.
1022
-	 *
1023
-	 * @param string $uid
1024
-	 * @param int $shareType
1025
-	 */
1026
-	public function userDeleted($uid, $shareType) {
1027
-		$qb = $this->dbConn->getQueryBuilder();
1028
-
1029
-		$qb->delete('share');
1030
-
1031
-		if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
1032
-			/*
864
+            $shares = $this->resolveGroupShares($shares2, $userId);
865
+        } else {
866
+            throw new BackendError('Invalid backend');
867
+        }
868
+
869
+
870
+        return $shares;
871
+    }
872
+
873
+    /**
874
+     * Get a share by token
875
+     *
876
+     * @param string $token
877
+     * @return \OCP\Share\IShare
878
+     * @throws ShareNotFound
879
+     */
880
+    public function getShareByToken($token) {
881
+        $qb = $this->dbConn->getQueryBuilder();
882
+
883
+        $cursor = $qb->select('*')
884
+            ->from('share')
885
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK)))
886
+            ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
887
+            ->andWhere($qb->expr()->orX(
888
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
889
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
890
+            ))
891
+            ->execute();
892
+
893
+        $data = $cursor->fetch();
894
+
895
+        if ($data === false) {
896
+            throw new ShareNotFound();
897
+        }
898
+
899
+        try {
900
+            $share = $this->createShare($data);
901
+        } catch (InvalidShare $e) {
902
+            throw new ShareNotFound();
903
+        }
904
+
905
+        return $share;
906
+    }
907
+
908
+    /**
909
+     * Create a share object from an database row
910
+     *
911
+     * @param mixed[] $data
912
+     * @return \OCP\Share\IShare
913
+     * @throws InvalidShare
914
+     */
915
+    private function createShare($data) {
916
+        $share = new Share($this->rootFolder, $this->userManager);
917
+        $share->setId((int)$data['id'])
918
+            ->setShareType((int)$data['share_type'])
919
+            ->setPermissions((int)$data['permissions'])
920
+            ->setTarget($data['file_target'])
921
+            ->setNote($data['note'])
922
+            ->setMailSend((bool)$data['mail_send']);
923
+
924
+        $shareTime = new \DateTime();
925
+        $shareTime->setTimestamp((int)$data['stime']);
926
+        $share->setShareTime($shareTime);
927
+
928
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
929
+            $share->setSharedWith($data['share_with']);
930
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
931
+            $share->setSharedWith($data['share_with']);
932
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
933
+            $share->setPassword($data['password']);
934
+            $share->setToken($data['token']);
935
+        }
936
+
937
+        $share->setSharedBy($data['uid_initiator']);
938
+        $share->setShareOwner($data['uid_owner']);
939
+
940
+        $share->setNodeId((int)$data['file_source']);
941
+        $share->setNodeType($data['item_type']);
942
+
943
+        if ($data['expiration'] !== null) {
944
+            $expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
945
+            $share->setExpirationDate($expiration);
946
+        }
947
+
948
+        if (isset($data['f_permissions'])) {
949
+            $entryData = $data;
950
+            $entryData['permissions'] = $entryData['f_permissions'];
951
+            $entryData['parent'] = $entryData['f_parent'];
952
+            $share->setNodeCacheEntry(Cache::cacheEntryFromData($entryData,
953
+                \OC::$server->getMimeTypeLoader()));
954
+        }
955
+
956
+        $share->setProviderId($this->identifier());
957
+        $share->setHideDownload((int)$data['hide_download'] === 1);
958
+
959
+        return $share;
960
+    }
961
+
962
+    /**
963
+     * @param Share[] $shares
964
+     * @param $userId
965
+     * @return Share[] The updates shares if no update is found for a share return the original
966
+     */
967
+    private function resolveGroupShares($shares, $userId) {
968
+        $result = [];
969
+
970
+        $start = 0;
971
+        while(true) {
972
+            /** @var Share[] $shareSlice */
973
+            $shareSlice = array_slice($shares, $start, 100);
974
+            $start += 100;
975
+
976
+            if ($shareSlice === []) {
977
+                break;
978
+            }
979
+
980
+            /** @var int[] $ids */
981
+            $ids = [];
982
+            /** @var Share[] $shareMap */
983
+            $shareMap = [];
984
+
985
+            foreach ($shareSlice as $share) {
986
+                $ids[] = (int)$share->getId();
987
+                $shareMap[$share->getId()] = $share;
988
+            }
989
+
990
+            $qb = $this->dbConn->getQueryBuilder();
991
+
992
+            $query = $qb->select('*')
993
+                ->from('share')
994
+                ->where($qb->expr()->in('parent', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
995
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
996
+                ->andWhere($qb->expr()->orX(
997
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
998
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
999
+                ));
1000
+
1001
+            $stmt = $query->execute();
1002
+
1003
+            while($data = $stmt->fetch()) {
1004
+                $shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
1005
+                $shareMap[$data['parent']]->setTarget($data['file_target']);
1006
+                $shareMap[$data['parent']]->setParent($data['parent']);
1007
+            }
1008
+
1009
+            $stmt->closeCursor();
1010
+
1011
+            foreach ($shareMap as $share) {
1012
+                $result[] = $share;
1013
+            }
1014
+        }
1015
+
1016
+        return $result;
1017
+    }
1018
+
1019
+    /**
1020
+     * A user is deleted from the system
1021
+     * So clean up the relevant shares.
1022
+     *
1023
+     * @param string $uid
1024
+     * @param int $shareType
1025
+     */
1026
+    public function userDeleted($uid, $shareType) {
1027
+        $qb = $this->dbConn->getQueryBuilder();
1028
+
1029
+        $qb->delete('share');
1030
+
1031
+        if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
1032
+            /*
1033 1033
 			 * Delete all user shares that are owned by this user
1034 1034
 			 * or that are received by this user
1035 1035
 			 */
1036 1036
 
1037
-			$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)));
1037
+            $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)));
1038 1038
 
1039
-			$qb->andWhere(
1040
-				$qb->expr()->orX(
1041
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
1042
-					$qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
1043
-				)
1044
-			);
1045
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
1046
-			/*
1039
+            $qb->andWhere(
1040
+                $qb->expr()->orX(
1041
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
1042
+                    $qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
1043
+                )
1044
+            );
1045
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
1046
+            /*
1047 1047
 			 * Delete all group shares that are owned by this user
1048 1048
 			 * Or special user group shares that are received by this user
1049 1049
 			 */
1050
-			$qb->where(
1051
-				$qb->expr()->andX(
1052
-					$qb->expr()->orX(
1053
-						$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
1054
-						$qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP))
1055
-					),
1056
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid))
1057
-				)
1058
-			);
1059
-
1060
-			$qb->orWhere(
1061
-				$qb->expr()->andX(
1062
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)),
1063
-					$qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
1064
-				)
1065
-			);
1066
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
1067
-			/*
1050
+            $qb->where(
1051
+                $qb->expr()->andX(
1052
+                    $qb->expr()->orX(
1053
+                        $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
1054
+                        $qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP))
1055
+                    ),
1056
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid))
1057
+                )
1058
+            );
1059
+
1060
+            $qb->orWhere(
1061
+                $qb->expr()->andX(
1062
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)),
1063
+                    $qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
1064
+                )
1065
+            );
1066
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
1067
+            /*
1068 1068
 			 * Delete all link shares owned by this user.
1069 1069
 			 * And all link shares initiated by this user (until #22327 is in)
1070 1070
 			 */
1071
-			$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK)));
1072
-
1073
-			$qb->andWhere(
1074
-				$qb->expr()->orX(
1075
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
1076
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($uid))
1077
-				)
1078
-			);
1079
-		}
1080
-
1081
-		$qb->execute();
1082
-	}
1083
-
1084
-	/**
1085
-	 * Delete all shares received by this group. As well as any custom group
1086
-	 * shares for group members.
1087
-	 *
1088
-	 * @param string $gid
1089
-	 */
1090
-	public function groupDeleted($gid) {
1091
-		/*
1071
+            $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK)));
1072
+
1073
+            $qb->andWhere(
1074
+                $qb->expr()->orX(
1075
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
1076
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($uid))
1077
+                )
1078
+            );
1079
+        }
1080
+
1081
+        $qb->execute();
1082
+    }
1083
+
1084
+    /**
1085
+     * Delete all shares received by this group. As well as any custom group
1086
+     * shares for group members.
1087
+     *
1088
+     * @param string $gid
1089
+     */
1090
+    public function groupDeleted($gid) {
1091
+        /*
1092 1092
 		 * First delete all custom group shares for group members
1093 1093
 		 */
1094
-		$qb = $this->dbConn->getQueryBuilder();
1095
-		$qb->select('id')
1096
-			->from('share')
1097
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1098
-			->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1099
-
1100
-		$cursor = $qb->execute();
1101
-		$ids = [];
1102
-		while($row = $cursor->fetch()) {
1103
-			$ids[] = (int)$row['id'];
1104
-		}
1105
-		$cursor->closeCursor();
1106
-
1107
-		if (!empty($ids)) {
1108
-			$chunks = array_chunk($ids, 100);
1109
-			foreach ($chunks as $chunk) {
1110
-				$qb->delete('share')
1111
-					->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
1112
-					->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1113
-				$qb->execute();
1114
-			}
1115
-		}
1116
-
1117
-		/*
1094
+        $qb = $this->dbConn->getQueryBuilder();
1095
+        $qb->select('id')
1096
+            ->from('share')
1097
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1098
+            ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1099
+
1100
+        $cursor = $qb->execute();
1101
+        $ids = [];
1102
+        while($row = $cursor->fetch()) {
1103
+            $ids[] = (int)$row['id'];
1104
+        }
1105
+        $cursor->closeCursor();
1106
+
1107
+        if (!empty($ids)) {
1108
+            $chunks = array_chunk($ids, 100);
1109
+            foreach ($chunks as $chunk) {
1110
+                $qb->delete('share')
1111
+                    ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
1112
+                    ->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1113
+                $qb->execute();
1114
+            }
1115
+        }
1116
+
1117
+        /*
1118 1118
 		 * Now delete all the group shares
1119 1119
 		 */
1120
-		$qb = $this->dbConn->getQueryBuilder();
1121
-		$qb->delete('share')
1122
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1123
-			->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1124
-		$qb->execute();
1125
-	}
1126
-
1127
-	/**
1128
-	 * Delete custom group shares to this group for this user
1129
-	 *
1130
-	 * @param string $uid
1131
-	 * @param string $gid
1132
-	 */
1133
-	public function userDeletedFromGroup($uid, $gid) {
1134
-		/*
1120
+        $qb = $this->dbConn->getQueryBuilder();
1121
+        $qb->delete('share')
1122
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1123
+            ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1124
+        $qb->execute();
1125
+    }
1126
+
1127
+    /**
1128
+     * Delete custom group shares to this group for this user
1129
+     *
1130
+     * @param string $uid
1131
+     * @param string $gid
1132
+     */
1133
+    public function userDeletedFromGroup($uid, $gid) {
1134
+        /*
1135 1135
 		 * Get all group shares
1136 1136
 		 */
1137
-		$qb = $this->dbConn->getQueryBuilder();
1138
-		$qb->select('id')
1139
-			->from('share')
1140
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1141
-			->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1142
-
1143
-		$cursor = $qb->execute();
1144
-		$ids = [];
1145
-		while($row = $cursor->fetch()) {
1146
-			$ids[] = (int)$row['id'];
1147
-		}
1148
-		$cursor->closeCursor();
1149
-
1150
-		if (!empty($ids)) {
1151
-			$chunks = array_chunk($ids, 100);
1152
-			foreach ($chunks as $chunk) {
1153
-				/*
1137
+        $qb = $this->dbConn->getQueryBuilder();
1138
+        $qb->select('id')
1139
+            ->from('share')
1140
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1141
+            ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1142
+
1143
+        $cursor = $qb->execute();
1144
+        $ids = [];
1145
+        while($row = $cursor->fetch()) {
1146
+            $ids[] = (int)$row['id'];
1147
+        }
1148
+        $cursor->closeCursor();
1149
+
1150
+        if (!empty($ids)) {
1151
+            $chunks = array_chunk($ids, 100);
1152
+            foreach ($chunks as $chunk) {
1153
+                /*
1154 1154
 				 * Delete all special shares wit this users for the found group shares
1155 1155
 				 */
1156
-				$qb->delete('share')
1157
-					->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
1158
-					->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($uid)))
1159
-					->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1160
-				$qb->execute();
1161
-			}
1162
-		}
1163
-	}
1164
-
1165
-	/**
1166
-	 * @inheritdoc
1167
-	 */
1168
-	public function getAccessList($nodes, $currentAccess) {
1169
-		$ids = [];
1170
-		foreach ($nodes as $node) {
1171
-			$ids[] = $node->getId();
1172
-		}
1173
-
1174
-		$qb = $this->dbConn->getQueryBuilder();
1175
-
1176
-		$or = $qb->expr()->orX(
1177
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
1178
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
1179
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK))
1180
-		);
1181
-
1182
-		if ($currentAccess) {
1183
-			$or->add($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)));
1184
-		}
1185
-
1186
-		$qb->select('id', 'parent', 'share_type', 'share_with', 'file_source', 'file_target', 'permissions')
1187
-			->from('share')
1188
-			->where(
1189
-				$or
1190
-			)
1191
-			->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1192
-			->andWhere($qb->expr()->orX(
1193
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1194
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1195
-			));
1196
-		$cursor = $qb->execute();
1197
-
1198
-		$users = [];
1199
-		$link = false;
1200
-		while($row = $cursor->fetch()) {
1201
-			$type = (int)$row['share_type'];
1202
-			if ($type === \OCP\Share::SHARE_TYPE_USER) {
1203
-				$uid = $row['share_with'];
1204
-				$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1205
-				$users[$uid][$row['id']] = $row;
1206
-			} else if ($type === \OCP\Share::SHARE_TYPE_GROUP) {
1207
-				$gid = $row['share_with'];
1208
-				$group = $this->groupManager->get($gid);
1209
-
1210
-				if ($group === null) {
1211
-					continue;
1212
-				}
1213
-
1214
-				$userList = $group->getUsers();
1215
-				foreach ($userList as $user) {
1216
-					$uid = $user->getUID();
1217
-					$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1218
-					$users[$uid][$row['id']] = $row;
1219
-				}
1220
-			} else if ($type === \OCP\Share::SHARE_TYPE_LINK) {
1221
-				$link = true;
1222
-			} else if ($type === self::SHARE_TYPE_USERGROUP && $currentAccess === true) {
1223
-				$uid = $row['share_with'];
1224
-				$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1225
-				$users[$uid][$row['id']] = $row;
1226
-			}
1227
-		}
1228
-		$cursor->closeCursor();
1229
-
1230
-		if ($currentAccess === true) {
1231
-			$users = array_map([$this, 'filterSharesOfUser'], $users);
1232
-			$users = array_filter($users);
1233
-		} else {
1234
-			$users = array_keys($users);
1235
-		}
1236
-
1237
-		return ['users' => $users, 'public' => $link];
1238
-	}
1239
-
1240
-	/**
1241
-	 * For each user the path with the fewest slashes is returned
1242
-	 * @param array $shares
1243
-	 * @return array
1244
-	 */
1245
-	protected function filterSharesOfUser(array $shares) {
1246
-		// Group shares when the user has a share exception
1247
-		foreach ($shares as $id => $share) {
1248
-			$type = (int) $share['share_type'];
1249
-			$permissions = (int) $share['permissions'];
1250
-
1251
-			if ($type === self::SHARE_TYPE_USERGROUP) {
1252
-				unset($shares[$share['parent']]);
1253
-
1254
-				if ($permissions === 0) {
1255
-					unset($shares[$id]);
1256
-				}
1257
-			}
1258
-		}
1259
-
1260
-		$best = [];
1261
-		$bestDepth = 0;
1262
-		foreach ($shares as $id => $share) {
1263
-			$depth = substr_count($share['file_target'], '/');
1264
-			if (empty($best) || $depth < $bestDepth) {
1265
-				$bestDepth = $depth;
1266
-				$best = [
1267
-					'node_id' => $share['file_source'],
1268
-					'node_path' => $share['file_target'],
1269
-				];
1270
-			}
1271
-		}
1272
-
1273
-		return $best;
1274
-	}
1275
-
1276
-	/**
1277
-	 * propagate notes to the recipients
1278
-	 *
1279
-	 * @param IShare $share
1280
-	 * @throws \OCP\Files\NotFoundException
1281
-	 */
1282
-	private function propagateNote(IShare $share) {
1283
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
1284
-			$user = $this->userManager->get($share->getSharedWith());
1285
-			$this->sendNote([$user], $share);
1286
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
1287
-			$group = $this->groupManager->get($share->getSharedWith());
1288
-			$groupMembers = $group->getUsers();
1289
-			$this->sendNote($groupMembers, $share);
1290
-		}
1291
-	}
1292
-
1293
-	/**
1294
-	 * send note by mail
1295
-	 *
1296
-	 * @param array $recipients
1297
-	 * @param IShare $share
1298
-	 * @throws \OCP\Files\NotFoundException
1299
-	 */
1300
-	private function sendNote(array $recipients, IShare $share) {
1301
-
1302
-		$toList = [];
1303
-
1304
-		foreach ($recipients as $recipient) {
1305
-			/** @var IUser $recipient */
1306
-			$email = $recipient->getEMailAddress();
1307
-			if ($email) {
1308
-				$toList[$email] = $recipient->getDisplayName();
1309
-			}
1310
-		}
1311
-
1312
-		if (!empty($toList)) {
1313
-
1314
-			$filename = $share->getNode()->getName();
1315
-			$initiator = $share->getSharedBy();
1316
-			$note = $share->getNote();
1317
-
1318
-			$initiatorUser = $this->userManager->get($initiator);
1319
-			$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
1320
-			$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
1321
-			$plainHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]);
1322
-			$htmlHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]);
1323
-			$message = $this->mailer->createMessage();
1324
-
1325
-			$emailTemplate = $this->mailer->createEMailTemplate('defaultShareProvider.sendNote');
1326
-
1327
-			$emailTemplate->setSubject($this->l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName]));
1328
-			$emailTemplate->addHeader();
1329
-			$emailTemplate->addHeading($htmlHeading, $plainHeading);
1330
-			$emailTemplate->addBodyText(htmlspecialchars($note), $note);
1331
-
1332
-			$link = $this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $share->getNode()->getId()]);
1333
-			$emailTemplate->addBodyButton(
1334
-				$this->l->t('Open »%s«', [$filename]),
1335
-				$link
1336
-			);
1337
-
1338
-
1339
-			// The "From" contains the sharers name
1340
-			$instanceName = $this->defaults->getName();
1341
-			$senderName = $this->l->t(
1342
-				'%1$s via %2$s',
1343
-				[
1344
-					$initiatorDisplayName,
1345
-					$instanceName
1346
-				]
1347
-			);
1348
-			$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
1349
-			if ($initiatorEmailAddress !== null) {
1350
-				$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
1351
-				$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
1352
-			} else {
1353
-				$emailTemplate->addFooter();
1354
-			}
1355
-
1356
-			if (count($toList) === 1) {
1357
-				$message->setTo($toList);
1358
-			} else {
1359
-				$message->setTo([]);
1360
-				$message->setBcc($toList);
1361
-			}
1362
-			$message->useTemplate($emailTemplate);
1363
-			$this->mailer->send($message);
1364
-		}
1365
-
1366
-	}
1156
+                $qb->delete('share')
1157
+                    ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
1158
+                    ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($uid)))
1159
+                    ->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1160
+                $qb->execute();
1161
+            }
1162
+        }
1163
+    }
1164
+
1165
+    /**
1166
+     * @inheritdoc
1167
+     */
1168
+    public function getAccessList($nodes, $currentAccess) {
1169
+        $ids = [];
1170
+        foreach ($nodes as $node) {
1171
+            $ids[] = $node->getId();
1172
+        }
1173
+
1174
+        $qb = $this->dbConn->getQueryBuilder();
1175
+
1176
+        $or = $qb->expr()->orX(
1177
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
1178
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
1179
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK))
1180
+        );
1181
+
1182
+        if ($currentAccess) {
1183
+            $or->add($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)));
1184
+        }
1185
+
1186
+        $qb->select('id', 'parent', 'share_type', 'share_with', 'file_source', 'file_target', 'permissions')
1187
+            ->from('share')
1188
+            ->where(
1189
+                $or
1190
+            )
1191
+            ->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1192
+            ->andWhere($qb->expr()->orX(
1193
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1194
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1195
+            ));
1196
+        $cursor = $qb->execute();
1197
+
1198
+        $users = [];
1199
+        $link = false;
1200
+        while($row = $cursor->fetch()) {
1201
+            $type = (int)$row['share_type'];
1202
+            if ($type === \OCP\Share::SHARE_TYPE_USER) {
1203
+                $uid = $row['share_with'];
1204
+                $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1205
+                $users[$uid][$row['id']] = $row;
1206
+            } else if ($type === \OCP\Share::SHARE_TYPE_GROUP) {
1207
+                $gid = $row['share_with'];
1208
+                $group = $this->groupManager->get($gid);
1209
+
1210
+                if ($group === null) {
1211
+                    continue;
1212
+                }
1213
+
1214
+                $userList = $group->getUsers();
1215
+                foreach ($userList as $user) {
1216
+                    $uid = $user->getUID();
1217
+                    $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1218
+                    $users[$uid][$row['id']] = $row;
1219
+                }
1220
+            } else if ($type === \OCP\Share::SHARE_TYPE_LINK) {
1221
+                $link = true;
1222
+            } else if ($type === self::SHARE_TYPE_USERGROUP && $currentAccess === true) {
1223
+                $uid = $row['share_with'];
1224
+                $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1225
+                $users[$uid][$row['id']] = $row;
1226
+            }
1227
+        }
1228
+        $cursor->closeCursor();
1229
+
1230
+        if ($currentAccess === true) {
1231
+            $users = array_map([$this, 'filterSharesOfUser'], $users);
1232
+            $users = array_filter($users);
1233
+        } else {
1234
+            $users = array_keys($users);
1235
+        }
1236
+
1237
+        return ['users' => $users, 'public' => $link];
1238
+    }
1239
+
1240
+    /**
1241
+     * For each user the path with the fewest slashes is returned
1242
+     * @param array $shares
1243
+     * @return array
1244
+     */
1245
+    protected function filterSharesOfUser(array $shares) {
1246
+        // Group shares when the user has a share exception
1247
+        foreach ($shares as $id => $share) {
1248
+            $type = (int) $share['share_type'];
1249
+            $permissions = (int) $share['permissions'];
1250
+
1251
+            if ($type === self::SHARE_TYPE_USERGROUP) {
1252
+                unset($shares[$share['parent']]);
1253
+
1254
+                if ($permissions === 0) {
1255
+                    unset($shares[$id]);
1256
+                }
1257
+            }
1258
+        }
1259
+
1260
+        $best = [];
1261
+        $bestDepth = 0;
1262
+        foreach ($shares as $id => $share) {
1263
+            $depth = substr_count($share['file_target'], '/');
1264
+            if (empty($best) || $depth < $bestDepth) {
1265
+                $bestDepth = $depth;
1266
+                $best = [
1267
+                    'node_id' => $share['file_source'],
1268
+                    'node_path' => $share['file_target'],
1269
+                ];
1270
+            }
1271
+        }
1272
+
1273
+        return $best;
1274
+    }
1275
+
1276
+    /**
1277
+     * propagate notes to the recipients
1278
+     *
1279
+     * @param IShare $share
1280
+     * @throws \OCP\Files\NotFoundException
1281
+     */
1282
+    private function propagateNote(IShare $share) {
1283
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
1284
+            $user = $this->userManager->get($share->getSharedWith());
1285
+            $this->sendNote([$user], $share);
1286
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
1287
+            $group = $this->groupManager->get($share->getSharedWith());
1288
+            $groupMembers = $group->getUsers();
1289
+            $this->sendNote($groupMembers, $share);
1290
+        }
1291
+    }
1292
+
1293
+    /**
1294
+     * send note by mail
1295
+     *
1296
+     * @param array $recipients
1297
+     * @param IShare $share
1298
+     * @throws \OCP\Files\NotFoundException
1299
+     */
1300
+    private function sendNote(array $recipients, IShare $share) {
1301
+
1302
+        $toList = [];
1303
+
1304
+        foreach ($recipients as $recipient) {
1305
+            /** @var IUser $recipient */
1306
+            $email = $recipient->getEMailAddress();
1307
+            if ($email) {
1308
+                $toList[$email] = $recipient->getDisplayName();
1309
+            }
1310
+        }
1311
+
1312
+        if (!empty($toList)) {
1313
+
1314
+            $filename = $share->getNode()->getName();
1315
+            $initiator = $share->getSharedBy();
1316
+            $note = $share->getNote();
1317
+
1318
+            $initiatorUser = $this->userManager->get($initiator);
1319
+            $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
1320
+            $initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
1321
+            $plainHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]);
1322
+            $htmlHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]);
1323
+            $message = $this->mailer->createMessage();
1324
+
1325
+            $emailTemplate = $this->mailer->createEMailTemplate('defaultShareProvider.sendNote');
1326
+
1327
+            $emailTemplate->setSubject($this->l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName]));
1328
+            $emailTemplate->addHeader();
1329
+            $emailTemplate->addHeading($htmlHeading, $plainHeading);
1330
+            $emailTemplate->addBodyText(htmlspecialchars($note), $note);
1331
+
1332
+            $link = $this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $share->getNode()->getId()]);
1333
+            $emailTemplate->addBodyButton(
1334
+                $this->l->t('Open »%s«', [$filename]),
1335
+                $link
1336
+            );
1337
+
1338
+
1339
+            // The "From" contains the sharers name
1340
+            $instanceName = $this->defaults->getName();
1341
+            $senderName = $this->l->t(
1342
+                '%1$s via %2$s',
1343
+                [
1344
+                    $initiatorDisplayName,
1345
+                    $instanceName
1346
+                ]
1347
+            );
1348
+            $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
1349
+            if ($initiatorEmailAddress !== null) {
1350
+                $message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
1351
+                $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
1352
+            } else {
1353
+                $emailTemplate->addFooter();
1354
+            }
1355
+
1356
+            if (count($toList) === 1) {
1357
+                $message->setTo($toList);
1358
+            } else {
1359
+                $message->setTo([]);
1360
+                $message->setBcc($toList);
1361
+            }
1362
+            $message->useTemplate($emailTemplate);
1363
+            $this->mailer->send($message);
1364
+        }
1365
+
1366
+    }
1367 1367
 }
Please login to merge, or discard this patch.
Spacing   +26 added lines, -26 removed lines patch added patch discarded remove patch
@@ -339,7 +339,7 @@  discard block
 block discarded – undo
339 339
 			->orderBy('id');
340 340
 
341 341
 		$cursor = $qb->execute();
342
-		while($data = $cursor->fetch()) {
342
+		while ($data = $cursor->fetch()) {
343 343
 			$children[] = $this->createShare($data);
344 344
 		}
345 345
 		$cursor->closeCursor();
@@ -384,7 +384,7 @@  discard block
 block discarded – undo
384 384
 			$user = $this->userManager->get($recipient);
385 385
 
386 386
 			if (is_null($group)) {
387
-				throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
387
+				throw new ProviderException('Group "'.$share->getSharedWith().'" does not exist');
388 388
 			}
389 389
 
390 390
 			if (!$group->inGroup($user)) {
@@ -579,7 +579,7 @@  discard block
 block discarded – undo
579 579
 			);
580 580
 		}
581 581
 
582
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
582
+		$qb->innerJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
583 583
 		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
584 584
 
585 585
 		$qb->orderBy('id');
@@ -635,7 +635,7 @@  discard block
 block discarded – undo
635 635
 
636 636
 		$cursor = $qb->execute();
637 637
 		$shares = [];
638
-		while($data = $cursor->fetch()) {
638
+		while ($data = $cursor->fetch()) {
639 639
 			$shares[] = $this->createShare($data);
640 640
 		}
641 641
 		$cursor->closeCursor();
@@ -714,7 +714,7 @@  discard block
 block discarded – undo
714 714
 			->execute();
715 715
 
716 716
 		$shares = [];
717
-		while($data = $cursor->fetch()) {
717
+		while ($data = $cursor->fetch()) {
718 718
 			$shares[] = $this->createShare($data);
719 719
 		}
720 720
 		$cursor->closeCursor();
@@ -785,7 +785,7 @@  discard block
 block discarded – undo
785 785
 
786 786
 			$cursor = $qb->execute();
787 787
 
788
-			while($data = $cursor->fetch()) {
788
+			while ($data = $cursor->fetch()) {
789 789
 				if ($this->isAccessibleResult($data)) {
790 790
 					$shares[] = $this->createShare($data);
791 791
 				}
@@ -800,7 +800,7 @@  discard block
 block discarded – undo
800 800
 			$shares2 = [];
801 801
 
802 802
 			$start = 0;
803
-			while(true) {
803
+			while (true) {
804 804
 				$groups = array_slice($allGroups, $start, 100);
805 805
 				$start += 100;
806 806
 
@@ -845,7 +845,7 @@  discard block
 block discarded – undo
845 845
 					));
846 846
 
847 847
 				$cursor = $qb->execute();
848
-				while($data = $cursor->fetch()) {
848
+				while ($data = $cursor->fetch()) {
849 849
 					if ($offset > 0) {
850 850
 						$offset--;
851 851
 						continue;
@@ -914,15 +914,15 @@  discard block
 block discarded – undo
914 914
 	 */
915 915
 	private function createShare($data) {
916 916
 		$share = new Share($this->rootFolder, $this->userManager);
917
-		$share->setId((int)$data['id'])
918
-			->setShareType((int)$data['share_type'])
919
-			->setPermissions((int)$data['permissions'])
917
+		$share->setId((int) $data['id'])
918
+			->setShareType((int) $data['share_type'])
919
+			->setPermissions((int) $data['permissions'])
920 920
 			->setTarget($data['file_target'])
921 921
 			->setNote($data['note'])
922
-			->setMailSend((bool)$data['mail_send']);
922
+			->setMailSend((bool) $data['mail_send']);
923 923
 
924 924
 		$shareTime = new \DateTime();
925
-		$shareTime->setTimestamp((int)$data['stime']);
925
+		$shareTime->setTimestamp((int) $data['stime']);
926 926
 		$share->setShareTime($shareTime);
927 927
 
928 928
 		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
@@ -937,7 +937,7 @@  discard block
 block discarded – undo
937 937
 		$share->setSharedBy($data['uid_initiator']);
938 938
 		$share->setShareOwner($data['uid_owner']);
939 939
 
940
-		$share->setNodeId((int)$data['file_source']);
940
+		$share->setNodeId((int) $data['file_source']);
941 941
 		$share->setNodeType($data['item_type']);
942 942
 
943 943
 		if ($data['expiration'] !== null) {
@@ -954,7 +954,7 @@  discard block
 block discarded – undo
954 954
 		}
955 955
 
956 956
 		$share->setProviderId($this->identifier());
957
-		$share->setHideDownload((int)$data['hide_download'] === 1);
957
+		$share->setHideDownload((int) $data['hide_download'] === 1);
958 958
 
959 959
 		return $share;
960 960
 	}
@@ -968,7 +968,7 @@  discard block
 block discarded – undo
968 968
 		$result = [];
969 969
 
970 970
 		$start = 0;
971
-		while(true) {
971
+		while (true) {
972 972
 			/** @var Share[] $shareSlice */
973 973
 			$shareSlice = array_slice($shares, $start, 100);
974 974
 			$start += 100;
@@ -983,7 +983,7 @@  discard block
 block discarded – undo
983 983
 			$shareMap = [];
984 984
 
985 985
 			foreach ($shareSlice as $share) {
986
-				$ids[] = (int)$share->getId();
986
+				$ids[] = (int) $share->getId();
987 987
 				$shareMap[$share->getId()] = $share;
988 988
 			}
989 989
 
@@ -1000,8 +1000,8 @@  discard block
 block discarded – undo
1000 1000
 
1001 1001
 			$stmt = $query->execute();
1002 1002
 
1003
-			while($data = $stmt->fetch()) {
1004
-				$shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
1003
+			while ($data = $stmt->fetch()) {
1004
+				$shareMap[$data['parent']]->setPermissions((int) $data['permissions']);
1005 1005
 				$shareMap[$data['parent']]->setTarget($data['file_target']);
1006 1006
 				$shareMap[$data['parent']]->setParent($data['parent']);
1007 1007
 			}
@@ -1099,8 +1099,8 @@  discard block
 block discarded – undo
1099 1099
 
1100 1100
 		$cursor = $qb->execute();
1101 1101
 		$ids = [];
1102
-		while($row = $cursor->fetch()) {
1103
-			$ids[] = (int)$row['id'];
1102
+		while ($row = $cursor->fetch()) {
1103
+			$ids[] = (int) $row['id'];
1104 1104
 		}
1105 1105
 		$cursor->closeCursor();
1106 1106
 
@@ -1142,8 +1142,8 @@  discard block
 block discarded – undo
1142 1142
 
1143 1143
 		$cursor = $qb->execute();
1144 1144
 		$ids = [];
1145
-		while($row = $cursor->fetch()) {
1146
-			$ids[] = (int)$row['id'];
1145
+		while ($row = $cursor->fetch()) {
1146
+			$ids[] = (int) $row['id'];
1147 1147
 		}
1148 1148
 		$cursor->closeCursor();
1149 1149
 
@@ -1197,8 +1197,8 @@  discard block
 block discarded – undo
1197 1197
 
1198 1198
 		$users = [];
1199 1199
 		$link = false;
1200
-		while($row = $cursor->fetch()) {
1201
-			$type = (int)$row['share_type'];
1200
+		while ($row = $cursor->fetch()) {
1201
+			$type = (int) $row['share_type'];
1202 1202
 			if ($type === \OCP\Share::SHARE_TYPE_USER) {
1203 1203
 				$uid = $row['share_with'];
1204 1204
 				$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
@@ -1348,7 +1348,7 @@  discard block
 block discarded – undo
1348 1348
 			$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
1349 1349
 			if ($initiatorEmailAddress !== null) {
1350 1350
 				$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
1351
-				$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
1351
+				$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
1352 1352
 			} else {
1353 1353
 				$emailTemplate->addFooter();
1354 1354
 			}
Please login to merge, or discard this patch.
lib/public/Share/IShare.php 1 patch
Indentation   +400 added lines, -400 removed lines patch added patch discarded remove patch
@@ -39,404 +39,404 @@
 block discarded – undo
39 39
  */
40 40
 interface IShare {
41 41
 
42
-	/**
43
-	 * Set the internal id of the share
44
-	 * It is only allowed to set the internal id of a share once.
45
-	 * Attempts to override the internal id will result in an IllegalIDChangeException
46
-	 *
47
-	 * @param string $id
48
-	 * @return \OCP\Share\IShare
49
-	 * @throws IllegalIDChangeException
50
-	 * @throws \InvalidArgumentException
51
-	 * @since 9.1.0
52
-	 */
53
-	public function setId($id);
54
-
55
-	/**
56
-	 * Get the internal id of the share.
57
-	 *
58
-	 * @return string
59
-	 * @since 9.0.0
60
-	 */
61
-	public function getId();
62
-
63
-	/**
64
-	 * Get the full share id. This is the <providerid>:<internalid>.
65
-	 * The full id is unique in the system.
66
-	 *
67
-	 * @return string
68
-	 * @since 9.0.0
69
-	 * @throws \UnexpectedValueException If the fullId could not be constructed
70
-	 */
71
-	public function getFullId();
72
-
73
-	/**
74
-	 * Set the provider id of the share
75
-	 * It is only allowed to set the provider id of a share once.
76
-	 * Attempts to override the provider id will result in an IllegalIDChangeException
77
-	 *
78
-	 * @param string $id
79
-	 * @return \OCP\Share\IShare
80
-	 * @throws IllegalIDChangeException
81
-	 * @throws \InvalidArgumentException
82
-	 * @since 9.1.0
83
-	 */
84
-	public function setProviderId($id);
85
-
86
-	/**
87
-	 * Set the node of the file/folder that is shared
88
-	 *
89
-	 * @param Node $node
90
-	 * @return \OCP\Share\IShare The modified object
91
-	 * @since 9.0.0
92
-	 */
93
-	public function setNode(Node $node);
94
-
95
-	/**
96
-	 * Get the node of the file/folder that is shared
97
-	 *
98
-	 * @return File|Folder
99
-	 * @since 9.0.0
100
-	 * @throws NotFoundException
101
-	 */
102
-	public function getNode();
103
-
104
-	/**
105
-	 * Set file id for lazy evaluation of the node
106
-	 * @param int $fileId
107
-	 * @return \OCP\Share\IShare The modified object
108
-	 * @since 9.0.0
109
-	 */
110
-	public function setNodeId($fileId);
111
-
112
-	/**
113
-	 * Get the fileid of the node of this share
114
-	 * @return int
115
-	 * @since 9.0.0
116
-	 * @throws NotFoundException
117
-	 */
118
-	public function getNodeId();
119
-
120
-	/**
121
-	 * Set the type of node (file/folder)
122
-	 *
123
-	 * @param string $type
124
-	 * @return \OCP\Share\IShare The modified object
125
-	 * @since 9.0.0
126
-	 */
127
-	public function setNodeType($type);
128
-
129
-	/**
130
-	 * Get the type of node (file/folder)
131
-	 *
132
-	 * @return string
133
-	 * @since 9.0.0
134
-	 * @throws NotFoundException
135
-	 */
136
-	public function getNodeType();
137
-
138
-	/**
139
-	 * Set the shareType
140
-	 *
141
-	 * @param int $shareType
142
-	 * @return \OCP\Share\IShare The modified object
143
-	 * @since 9.0.0
144
-	 */
145
-	public function setShareType($shareType);
146
-
147
-	/**
148
-	 * Get the shareType
149
-	 *
150
-	 * @return int
151
-	 * @since 9.0.0
152
-	 */
153
-	public function getShareType();
154
-
155
-	/**
156
-	 * Set the receiver of this share.
157
-	 *
158
-	 * @param string $sharedWith
159
-	 * @return \OCP\Share\IShare The modified object
160
-	 * @since 9.0.0
161
-	 */
162
-	public function setSharedWith($sharedWith);
163
-
164
-	/**
165
-	 * Get the receiver of this share.
166
-	 *
167
-	 * @return string
168
-	 * @since 9.0.0
169
-	 */
170
-	public function getSharedWith();
171
-
172
-	/**
173
-	 * Set the display name of the receiver of this share.
174
-	 *
175
-	 * @param string $displayName
176
-	 * @return \OCP\Share\IShare The modified object
177
-	 * @since 14.0.0
178
-	 */
179
-	public function setSharedWithDisplayName($displayName);
180
-
181
-	/**
182
-	 * Get the display name of the receiver of this share.
183
-	 *
184
-	 * @return string
185
-	 * @since 14.0.0
186
-	 */
187
-	public function getSharedWithDisplayName();
188
-
189
-	/**
190
-	 * Set the avatar of the receiver of this share.
191
-	 *
192
-	 * @param string $src
193
-	 * @return \OCP\Share\IShare The modified object
194
-	 * @since 14.0.0
195
-	 */
196
-	public function setSharedWithAvatar($src);
197
-
198
-	/**
199
-	 * Get the avatar of the receiver of this share.
200
-	 *
201
-	 * @return string
202
-	 * @since 14.0.0
203
-	 */
204
-	public function getSharedWithAvatar();
205
-
206
-	/**
207
-	 * Set the permissions.
208
-	 * See \OCP\Constants::PERMISSION_*
209
-	 *
210
-	 * @param int $permissions
211
-	 * @return \OCP\Share\IShare The modified object
212
-	 * @since 9.0.0
213
-	 */
214
-	public function setPermissions($permissions);
215
-
216
-	/**
217
-	 * Get the share permissions
218
-	 * See \OCP\Constants::PERMISSION_*
219
-	 *
220
-	 * @return int
221
-	 * @since 9.0.0
222
-	 */
223
-	public function getPermissions();
224
-
225
-	/**
226
-	 * Attach a note to a share
227
-	 *
228
-	 * @param string $note
229
-	 * @return \OCP\Share\IShare The modified object
230
-	 * @since 14.0.0
231
-	 */
232
-	public function setNote($note);
233
-
234
-	/**
235
-	 * Get note attached to a share
236
-	 *
237
-	 * @return string
238
-	 * @since 14.0.0
239
-	 */
240
-	public function getNote();
241
-
242
-
243
-	/**
244
-	 * Set the expiration date
245
-	 *
246
-	 * @param null|\DateTime $expireDate
247
-	 * @return \OCP\Share\IShare The modified object
248
-	 * @since 9.0.0
249
-	 */
250
-	public function setExpirationDate($expireDate);
251
-
252
-	/**
253
-	 * Get the expiration date
254
-	 *
255
-	 * @return \DateTime
256
-	 * @since 9.0.0
257
-	 */
258
-	public function getExpirationDate();
259
-
260
-	/**
261
-	 * Set the sharer of the path.
262
-	 *
263
-	 * @param string $sharedBy
264
-	 * @return \OCP\Share\IShare The modified object
265
-	 * @since 9.0.0
266
-	 */
267
-	public function setSharedBy($sharedBy);
268
-
269
-	/**
270
-	 * Get share sharer
271
-	 *
272
-	 * @return string
273
-	 * @since 9.0.0
274
-	 */
275
-	public function getSharedBy();
276
-
277
-	/**
278
-	 * Set the original share owner (who owns the path that is shared)
279
-	 *
280
-	 * @param string $shareOwner
281
-	 * @return \OCP\Share\IShare The modified object
282
-	 * @since 9.0.0
283
-	 */
284
-	public function setShareOwner($shareOwner);
285
-
286
-	/**
287
-	 * Get the original share owner (who owns the path that is shared)
288
-	 *
289
-	 * @return string
290
-	 * @since 9.0.0
291
-	 */
292
-	public function getShareOwner();
293
-
294
-	/**
295
-	 * Set the password for this share.
296
-	 * When the share is passed to the share manager to be created
297
-	 * or updated the password will be hashed.
298
-	 *
299
-	 * @param string $password
300
-	 * @return \OCP\Share\IShare The modified object
301
-	 * @since 9.0.0
302
-	 */
303
-	public function setPassword($password);
304
-
305
-	/**
306
-	 * Get the password of this share.
307
-	 * If this share is obtained via a shareprovider the password is
308
-	 * hashed.
309
-	 *
310
-	 * @return string
311
-	 * @since 9.0.0
312
-	 */
313
-	public function getPassword();
314
-
315
-
316
-	/**
317
-	 * Set if the recipient can start a conversation with the owner to get the
318
-	 * password using Nextcloud Talk.
319
-	 *
320
-	 * @param bool $sendPasswordByTalk
321
-	 * @return \OCP\Share\IShare The modified object
322
-	 * @since 14.0.0
323
-	 */
324
-	public function setSendPasswordByTalk(bool $sendPasswordByTalk);
325
-
326
-	/**
327
-	 * Get if the recipient can start a conversation with the owner to get the
328
-	 * password using Nextcloud Talk.
329
-	 * The returned value does not take into account other factors, like Talk
330
-	 * being enabled for the owner of the share or not; it just cover whether
331
-	 * the option is enabled for the share itself or not.
332
-	 *
333
-	 * @return bool
334
-	 * @since 14.0.0
335
-	 */
336
-	public function getSendPasswordByTalk(): bool;
337
-
338
-	/**
339
-	 * Set the public link token.
340
-	 *
341
-	 * @param string $token
342
-	 * @return \OCP\Share\IShare The modified object
343
-	 * @since 9.0.0
344
-	 */
345
-	public function setToken($token);
346
-
347
-	/**
348
-	 * Get the public link token.
349
-	 *
350
-	 * @return string
351
-	 * @since 9.0.0
352
-	 */
353
-	public function getToken();
354
-
355
-	/**
356
-	 * Set the target path of this share relative to the recipients user folder.
357
-	 *
358
-	 * @param string $target
359
-	 * @return \OCP\Share\IShare The modified object
360
-	 * @since 9.0.0
361
-	 */
362
-	public function setTarget($target);
363
-
364
-	/**
365
-	 * Get the target path of this share relative to the recipients user folder.
366
-	 *
367
-	 * @return string
368
-	 * @since 9.0.0
369
-	 */
370
-	public function getTarget();
371
-
372
-	/**
373
-	 * Set the time this share was created
374
-	 *
375
-	 * @param \DateTime $shareTime
376
-	 * @return \OCP\Share\IShare The modified object
377
-	 * @since 9.0.0
378
-	 */
379
-	public function setShareTime(\DateTime $shareTime);
380
-
381
-	/**
382
-	 * Get the timestamp this share was created
383
-	 *
384
-	 * @return \DateTime
385
-	 * @since 9.0.0
386
-	 */
387
-	public function getShareTime();
388
-
389
-	/**
390
-	 * Set if the recipient is informed by mail about the share.
391
-	 *
392
-	 * @param bool $mailSend
393
-	 * @return \OCP\Share\IShare The modified object
394
-	 * @since 9.0.0
395
-	 */
396
-	public function setMailSend($mailSend);
397
-
398
-	/**
399
-	 * Get if the recipient informed by mail about the share.
400
-	 *
401
-	 * @return bool
402
-	 * @since 9.0.0
403
-	 */
404
-	public function getMailSend();
405
-
406
-	/**
407
-	 * Set the cache entry for the shared node
408
-	 *
409
-	 * @param ICacheEntry $entry
410
-	 * @since 11.0.0
411
-	 */
412
-	public function setNodeCacheEntry(ICacheEntry $entry);
413
-
414
-	/**
415
-	 * Get the cache entry for the shared node
416
-	 *
417
-	 * @return null|ICacheEntry
418
-	 * @since 11.0.0
419
-	 */
420
-	public function getNodeCacheEntry();
421
-
422
-	/**
423
-	 * Sets a shares hide download state
424
-	 * This is mainly for public shares. It will signal that the share page should
425
-	 * hide download buttons etc.
426
-	 *
427
-	 * @param bool $ro
428
-	 * @return IShare
429
-	 * @since 15.0.0
430
-	 */
431
-	public function setHideDownload(bool $hide): IShare;
432
-
433
-	/**
434
-	 * Gets a shares hide download state
435
-	 * This is mainly for public shares. It will signal that the share page should
436
-	 * hide download buttons etc.
437
-	 *
438
-	 * @return bool
439
-	 * @since 15.0.0
440
-	 */
441
-	public function getHideDownload(): bool;
42
+    /**
43
+     * Set the internal id of the share
44
+     * It is only allowed to set the internal id of a share once.
45
+     * Attempts to override the internal id will result in an IllegalIDChangeException
46
+     *
47
+     * @param string $id
48
+     * @return \OCP\Share\IShare
49
+     * @throws IllegalIDChangeException
50
+     * @throws \InvalidArgumentException
51
+     * @since 9.1.0
52
+     */
53
+    public function setId($id);
54
+
55
+    /**
56
+     * Get the internal id of the share.
57
+     *
58
+     * @return string
59
+     * @since 9.0.0
60
+     */
61
+    public function getId();
62
+
63
+    /**
64
+     * Get the full share id. This is the <providerid>:<internalid>.
65
+     * The full id is unique in the system.
66
+     *
67
+     * @return string
68
+     * @since 9.0.0
69
+     * @throws \UnexpectedValueException If the fullId could not be constructed
70
+     */
71
+    public function getFullId();
72
+
73
+    /**
74
+     * Set the provider id of the share
75
+     * It is only allowed to set the provider id of a share once.
76
+     * Attempts to override the provider id will result in an IllegalIDChangeException
77
+     *
78
+     * @param string $id
79
+     * @return \OCP\Share\IShare
80
+     * @throws IllegalIDChangeException
81
+     * @throws \InvalidArgumentException
82
+     * @since 9.1.0
83
+     */
84
+    public function setProviderId($id);
85
+
86
+    /**
87
+     * Set the node of the file/folder that is shared
88
+     *
89
+     * @param Node $node
90
+     * @return \OCP\Share\IShare The modified object
91
+     * @since 9.0.0
92
+     */
93
+    public function setNode(Node $node);
94
+
95
+    /**
96
+     * Get the node of the file/folder that is shared
97
+     *
98
+     * @return File|Folder
99
+     * @since 9.0.0
100
+     * @throws NotFoundException
101
+     */
102
+    public function getNode();
103
+
104
+    /**
105
+     * Set file id for lazy evaluation of the node
106
+     * @param int $fileId
107
+     * @return \OCP\Share\IShare The modified object
108
+     * @since 9.0.0
109
+     */
110
+    public function setNodeId($fileId);
111
+
112
+    /**
113
+     * Get the fileid of the node of this share
114
+     * @return int
115
+     * @since 9.0.0
116
+     * @throws NotFoundException
117
+     */
118
+    public function getNodeId();
119
+
120
+    /**
121
+     * Set the type of node (file/folder)
122
+     *
123
+     * @param string $type
124
+     * @return \OCP\Share\IShare The modified object
125
+     * @since 9.0.0
126
+     */
127
+    public function setNodeType($type);
128
+
129
+    /**
130
+     * Get the type of node (file/folder)
131
+     *
132
+     * @return string
133
+     * @since 9.0.0
134
+     * @throws NotFoundException
135
+     */
136
+    public function getNodeType();
137
+
138
+    /**
139
+     * Set the shareType
140
+     *
141
+     * @param int $shareType
142
+     * @return \OCP\Share\IShare The modified object
143
+     * @since 9.0.0
144
+     */
145
+    public function setShareType($shareType);
146
+
147
+    /**
148
+     * Get the shareType
149
+     *
150
+     * @return int
151
+     * @since 9.0.0
152
+     */
153
+    public function getShareType();
154
+
155
+    /**
156
+     * Set the receiver of this share.
157
+     *
158
+     * @param string $sharedWith
159
+     * @return \OCP\Share\IShare The modified object
160
+     * @since 9.0.0
161
+     */
162
+    public function setSharedWith($sharedWith);
163
+
164
+    /**
165
+     * Get the receiver of this share.
166
+     *
167
+     * @return string
168
+     * @since 9.0.0
169
+     */
170
+    public function getSharedWith();
171
+
172
+    /**
173
+     * Set the display name of the receiver of this share.
174
+     *
175
+     * @param string $displayName
176
+     * @return \OCP\Share\IShare The modified object
177
+     * @since 14.0.0
178
+     */
179
+    public function setSharedWithDisplayName($displayName);
180
+
181
+    /**
182
+     * Get the display name of the receiver of this share.
183
+     *
184
+     * @return string
185
+     * @since 14.0.0
186
+     */
187
+    public function getSharedWithDisplayName();
188
+
189
+    /**
190
+     * Set the avatar of the receiver of this share.
191
+     *
192
+     * @param string $src
193
+     * @return \OCP\Share\IShare The modified object
194
+     * @since 14.0.0
195
+     */
196
+    public function setSharedWithAvatar($src);
197
+
198
+    /**
199
+     * Get the avatar of the receiver of this share.
200
+     *
201
+     * @return string
202
+     * @since 14.0.0
203
+     */
204
+    public function getSharedWithAvatar();
205
+
206
+    /**
207
+     * Set the permissions.
208
+     * See \OCP\Constants::PERMISSION_*
209
+     *
210
+     * @param int $permissions
211
+     * @return \OCP\Share\IShare The modified object
212
+     * @since 9.0.0
213
+     */
214
+    public function setPermissions($permissions);
215
+
216
+    /**
217
+     * Get the share permissions
218
+     * See \OCP\Constants::PERMISSION_*
219
+     *
220
+     * @return int
221
+     * @since 9.0.0
222
+     */
223
+    public function getPermissions();
224
+
225
+    /**
226
+     * Attach a note to a share
227
+     *
228
+     * @param string $note
229
+     * @return \OCP\Share\IShare The modified object
230
+     * @since 14.0.0
231
+     */
232
+    public function setNote($note);
233
+
234
+    /**
235
+     * Get note attached to a share
236
+     *
237
+     * @return string
238
+     * @since 14.0.0
239
+     */
240
+    public function getNote();
241
+
242
+
243
+    /**
244
+     * Set the expiration date
245
+     *
246
+     * @param null|\DateTime $expireDate
247
+     * @return \OCP\Share\IShare The modified object
248
+     * @since 9.0.0
249
+     */
250
+    public function setExpirationDate($expireDate);
251
+
252
+    /**
253
+     * Get the expiration date
254
+     *
255
+     * @return \DateTime
256
+     * @since 9.0.0
257
+     */
258
+    public function getExpirationDate();
259
+
260
+    /**
261
+     * Set the sharer of the path.
262
+     *
263
+     * @param string $sharedBy
264
+     * @return \OCP\Share\IShare The modified object
265
+     * @since 9.0.0
266
+     */
267
+    public function setSharedBy($sharedBy);
268
+
269
+    /**
270
+     * Get share sharer
271
+     *
272
+     * @return string
273
+     * @since 9.0.0
274
+     */
275
+    public function getSharedBy();
276
+
277
+    /**
278
+     * Set the original share owner (who owns the path that is shared)
279
+     *
280
+     * @param string $shareOwner
281
+     * @return \OCP\Share\IShare The modified object
282
+     * @since 9.0.0
283
+     */
284
+    public function setShareOwner($shareOwner);
285
+
286
+    /**
287
+     * Get the original share owner (who owns the path that is shared)
288
+     *
289
+     * @return string
290
+     * @since 9.0.0
291
+     */
292
+    public function getShareOwner();
293
+
294
+    /**
295
+     * Set the password for this share.
296
+     * When the share is passed to the share manager to be created
297
+     * or updated the password will be hashed.
298
+     *
299
+     * @param string $password
300
+     * @return \OCP\Share\IShare The modified object
301
+     * @since 9.0.0
302
+     */
303
+    public function setPassword($password);
304
+
305
+    /**
306
+     * Get the password of this share.
307
+     * If this share is obtained via a shareprovider the password is
308
+     * hashed.
309
+     *
310
+     * @return string
311
+     * @since 9.0.0
312
+     */
313
+    public function getPassword();
314
+
315
+
316
+    /**
317
+     * Set if the recipient can start a conversation with the owner to get the
318
+     * password using Nextcloud Talk.
319
+     *
320
+     * @param bool $sendPasswordByTalk
321
+     * @return \OCP\Share\IShare The modified object
322
+     * @since 14.0.0
323
+     */
324
+    public function setSendPasswordByTalk(bool $sendPasswordByTalk);
325
+
326
+    /**
327
+     * Get if the recipient can start a conversation with the owner to get the
328
+     * password using Nextcloud Talk.
329
+     * The returned value does not take into account other factors, like Talk
330
+     * being enabled for the owner of the share or not; it just cover whether
331
+     * the option is enabled for the share itself or not.
332
+     *
333
+     * @return bool
334
+     * @since 14.0.0
335
+     */
336
+    public function getSendPasswordByTalk(): bool;
337
+
338
+    /**
339
+     * Set the public link token.
340
+     *
341
+     * @param string $token
342
+     * @return \OCP\Share\IShare The modified object
343
+     * @since 9.0.0
344
+     */
345
+    public function setToken($token);
346
+
347
+    /**
348
+     * Get the public link token.
349
+     *
350
+     * @return string
351
+     * @since 9.0.0
352
+     */
353
+    public function getToken();
354
+
355
+    /**
356
+     * Set the target path of this share relative to the recipients user folder.
357
+     *
358
+     * @param string $target
359
+     * @return \OCP\Share\IShare The modified object
360
+     * @since 9.0.0
361
+     */
362
+    public function setTarget($target);
363
+
364
+    /**
365
+     * Get the target path of this share relative to the recipients user folder.
366
+     *
367
+     * @return string
368
+     * @since 9.0.0
369
+     */
370
+    public function getTarget();
371
+
372
+    /**
373
+     * Set the time this share was created
374
+     *
375
+     * @param \DateTime $shareTime
376
+     * @return \OCP\Share\IShare The modified object
377
+     * @since 9.0.0
378
+     */
379
+    public function setShareTime(\DateTime $shareTime);
380
+
381
+    /**
382
+     * Get the timestamp this share was created
383
+     *
384
+     * @return \DateTime
385
+     * @since 9.0.0
386
+     */
387
+    public function getShareTime();
388
+
389
+    /**
390
+     * Set if the recipient is informed by mail about the share.
391
+     *
392
+     * @param bool $mailSend
393
+     * @return \OCP\Share\IShare The modified object
394
+     * @since 9.0.0
395
+     */
396
+    public function setMailSend($mailSend);
397
+
398
+    /**
399
+     * Get if the recipient informed by mail about the share.
400
+     *
401
+     * @return bool
402
+     * @since 9.0.0
403
+     */
404
+    public function getMailSend();
405
+
406
+    /**
407
+     * Set the cache entry for the shared node
408
+     *
409
+     * @param ICacheEntry $entry
410
+     * @since 11.0.0
411
+     */
412
+    public function setNodeCacheEntry(ICacheEntry $entry);
413
+
414
+    /**
415
+     * Get the cache entry for the shared node
416
+     *
417
+     * @return null|ICacheEntry
418
+     * @since 11.0.0
419
+     */
420
+    public function getNodeCacheEntry();
421
+
422
+    /**
423
+     * Sets a shares hide download state
424
+     * This is mainly for public shares. It will signal that the share page should
425
+     * hide download buttons etc.
426
+     *
427
+     * @param bool $ro
428
+     * @return IShare
429
+     * @since 15.0.0
430
+     */
431
+    public function setHideDownload(bool $hide): IShare;
432
+
433
+    /**
434
+     * Gets a shares hide download state
435
+     * This is mainly for public shares. It will signal that the share page should
436
+     * hide download buttons etc.
437
+     *
438
+     * @return bool
439
+     * @since 15.0.0
440
+     */
441
+    public function getHideDownload(): bool;
442 442
 }
Please login to merge, or discard this patch.