Passed
Push — master ( 337cd2...30a123 )
by Roeland
39:31 queued 24:50
created
lib/private/Share20/DefaultShareProvider.php 2 patches
Indentation   +1284 added lines, -1284 removed lines patch added patch discarded remove patch
@@ -58,1321 +58,1321 @@
 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 label for public link
150
-			$qb->setValue('label', $qb->createNamedParameter($share->getLabel()));
151
-			//Set the token of the share
152
-			$qb->setValue('token', $qb->createNamedParameter($share->getToken()));
153
-
154
-			//If a password is set store it
155
-			if ($share->getPassword() !== null) {
156
-				$qb->setValue('password', $qb->createNamedParameter($share->getPassword()));
157
-			}
158
-
159
-			$qb->setValue('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL));
160
-
161
-			//If an expiration date is set store it
162
-			if ($share->getExpirationDate() !== null) {
163
-				$qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
164
-			}
165
-
166
-			if (method_exists($share, 'getParent')) {
167
-				$qb->setValue('parent', $qb->createNamedParameter($share->getParent()));
168
-			}
169
-		} else {
170
-			throw new \Exception('invalid share type!');
171
-		}
172
-
173
-		// Set what is shares
174
-		$qb->setValue('item_type', $qb->createParameter('itemType'));
175
-		if ($share->getNode() instanceof \OCP\Files\File) {
176
-			$qb->setParameter('itemType', 'file');
177
-		} else {
178
-			$qb->setParameter('itemType', 'folder');
179
-		}
180
-
181
-		// Set the file id
182
-		$qb->setValue('item_source', $qb->createNamedParameter($share->getNode()->getId()));
183
-		$qb->setValue('file_source', $qb->createNamedParameter($share->getNode()->getId()));
184
-
185
-		// set the permissions
186
-		$qb->setValue('permissions', $qb->createNamedParameter($share->getPermissions()));
187
-
188
-		// Set who created this share
189
-		$qb->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()));
190
-
191
-		// Set who is the owner of this file/folder (and this the owner of the share)
192
-		$qb->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()));
193
-
194
-		// Set the file target
195
-		$qb->setValue('file_target', $qb->createNamedParameter($share->getTarget()));
196
-
197
-		// Set the time this share was created
198
-		$qb->setValue('stime', $qb->createNamedParameter(time()));
199
-
200
-		// insert the data and fetch the id of the share
201
-		$this->dbConn->beginTransaction();
202
-		$qb->execute();
203
-		$id = $this->dbConn->lastInsertId('*PREFIX*share');
204
-
205
-		// Now fetch the inserted share and create a complete share object
206
-		$qb = $this->dbConn->getQueryBuilder();
207
-		$qb->select('*')
208
-			->from('share')
209
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
210
-
211
-		$cursor = $qb->execute();
212
-		$data = $cursor->fetch();
213
-		$this->dbConn->commit();
214
-		$cursor->closeCursor();
215
-
216
-		if ($data === false) {
217
-			throw new ShareNotFound();
218
-		}
219
-
220
-		$mailSendValue = $share->getMailSend();
221
-		$data['mail_send'] = ($mailSendValue === null) ? true : $mailSendValue;
222
-
223
-		$share = $this->createShare($data);
224
-		return $share;
225
-	}
226
-
227
-	/**
228
-	 * Update a share
229
-	 *
230
-	 * @param \OCP\Share\IShare $share
231
-	 * @return \OCP\Share\IShare The share object
232
-	 * @throws ShareNotFound
233
-	 * @throws \OCP\Files\InvalidPathException
234
-	 * @throws \OCP\Files\NotFoundException
235
-	 */
236
-	public function update(\OCP\Share\IShare $share) {
237
-
238
-		$originalShare = $this->getShareById($share->getId());
239
-
240
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
241
-			/*
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 label for public link
150
+            $qb->setValue('label', $qb->createNamedParameter($share->getLabel()));
151
+            //Set the token of the share
152
+            $qb->setValue('token', $qb->createNamedParameter($share->getToken()));
153
+
154
+            //If a password is set store it
155
+            if ($share->getPassword() !== null) {
156
+                $qb->setValue('password', $qb->createNamedParameter($share->getPassword()));
157
+            }
158
+
159
+            $qb->setValue('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL));
160
+
161
+            //If an expiration date is set store it
162
+            if ($share->getExpirationDate() !== null) {
163
+                $qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
164
+            }
165
+
166
+            if (method_exists($share, 'getParent')) {
167
+                $qb->setValue('parent', $qb->createNamedParameter($share->getParent()));
168
+            }
169
+        } else {
170
+            throw new \Exception('invalid share type!');
171
+        }
172
+
173
+        // Set what is shares
174
+        $qb->setValue('item_type', $qb->createParameter('itemType'));
175
+        if ($share->getNode() instanceof \OCP\Files\File) {
176
+            $qb->setParameter('itemType', 'file');
177
+        } else {
178
+            $qb->setParameter('itemType', 'folder');
179
+        }
180
+
181
+        // Set the file id
182
+        $qb->setValue('item_source', $qb->createNamedParameter($share->getNode()->getId()));
183
+        $qb->setValue('file_source', $qb->createNamedParameter($share->getNode()->getId()));
184
+
185
+        // set the permissions
186
+        $qb->setValue('permissions', $qb->createNamedParameter($share->getPermissions()));
187
+
188
+        // Set who created this share
189
+        $qb->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()));
190
+
191
+        // Set who is the owner of this file/folder (and this the owner of the share)
192
+        $qb->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()));
193
+
194
+        // Set the file target
195
+        $qb->setValue('file_target', $qb->createNamedParameter($share->getTarget()));
196
+
197
+        // Set the time this share was created
198
+        $qb->setValue('stime', $qb->createNamedParameter(time()));
199
+
200
+        // insert the data and fetch the id of the share
201
+        $this->dbConn->beginTransaction();
202
+        $qb->execute();
203
+        $id = $this->dbConn->lastInsertId('*PREFIX*share');
204
+
205
+        // Now fetch the inserted share and create a complete share object
206
+        $qb = $this->dbConn->getQueryBuilder();
207
+        $qb->select('*')
208
+            ->from('share')
209
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
210
+
211
+        $cursor = $qb->execute();
212
+        $data = $cursor->fetch();
213
+        $this->dbConn->commit();
214
+        $cursor->closeCursor();
215
+
216
+        if ($data === false) {
217
+            throw new ShareNotFound();
218
+        }
219
+
220
+        $mailSendValue = $share->getMailSend();
221
+        $data['mail_send'] = ($mailSendValue === null) ? true : $mailSendValue;
222
+
223
+        $share = $this->createShare($data);
224
+        return $share;
225
+    }
226
+
227
+    /**
228
+     * Update a share
229
+     *
230
+     * @param \OCP\Share\IShare $share
231
+     * @return \OCP\Share\IShare The share object
232
+     * @throws ShareNotFound
233
+     * @throws \OCP\Files\InvalidPathException
234
+     * @throws \OCP\Files\NotFoundException
235
+     */
236
+    public function update(\OCP\Share\IShare $share) {
237
+
238
+        $originalShare = $this->getShareById($share->getId());
239
+
240
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
241
+            /*
242 242
 			 * We allow updating the recipient on user shares.
243 243
 			 */
244
-			$qb = $this->dbConn->getQueryBuilder();
245
-			$qb->update('share')
246
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
247
-				->set('share_with', $qb->createNamedParameter($share->getSharedWith()))
248
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
249
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
250
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
251
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
252
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
253
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
254
-				->set('note', $qb->createNamedParameter($share->getNote()))
255
-				->execute();
256
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
257
-			$qb = $this->dbConn->getQueryBuilder();
258
-			$qb->update('share')
259
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
260
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
261
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
262
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
263
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
264
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
265
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
266
-				->set('note', $qb->createNamedParameter($share->getNote()))
267
-				->execute();
268
-
269
-			/*
244
+            $qb = $this->dbConn->getQueryBuilder();
245
+            $qb->update('share')
246
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
247
+                ->set('share_with', $qb->createNamedParameter($share->getSharedWith()))
248
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
249
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
250
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
251
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
252
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
253
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
254
+                ->set('note', $qb->createNamedParameter($share->getNote()))
255
+                ->execute();
256
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
257
+            $qb = $this->dbConn->getQueryBuilder();
258
+            $qb->update('share')
259
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
260
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
261
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
262
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
263
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
264
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
265
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
266
+                ->set('note', $qb->createNamedParameter($share->getNote()))
267
+                ->execute();
268
+
269
+            /*
270 270
 			 * Update all user defined group shares
271 271
 			 */
272
-			$qb = $this->dbConn->getQueryBuilder();
273
-			$qb->update('share')
274
-				->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
275
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
276
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
277
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
278
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
279
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
280
-				->set('note', $qb->createNamedParameter($share->getNote()))
281
-				->execute();
282
-
283
-			/*
272
+            $qb = $this->dbConn->getQueryBuilder();
273
+            $qb->update('share')
274
+                ->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
275
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
276
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
277
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
278
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
279
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
280
+                ->set('note', $qb->createNamedParameter($share->getNote()))
281
+                ->execute();
282
+
283
+            /*
284 284
 			 * Now update the permissions for all children that have not set it to 0
285 285
 			 */
286
-			$qb = $this->dbConn->getQueryBuilder();
287
-			$qb->update('share')
288
-				->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
289
-				->andWhere($qb->expr()->neq('permissions', $qb->createNamedParameter(0)))
290
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
291
-				->execute();
292
-
293
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
294
-			$qb = $this->dbConn->getQueryBuilder();
295
-			$qb->update('share')
296
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
297
-				->set('password', $qb->createNamedParameter($share->getPassword()))
298
-				->set('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL))
299
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
300
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
301
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
302
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
303
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
304
-				->set('token', $qb->createNamedParameter($share->getToken()))
305
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
306
-				->set('note', $qb->createNamedParameter($share->getNote()))
307
-				->set('label', $qb->createNamedParameter($share->getLabel()))
308
-				->set('hide_download', $qb->createNamedParameter($share->getHideDownload() ? 1 : 0), IQueryBuilder::PARAM_INT)
309
-				->execute();
310
-		}
311
-
312
-		if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
313
-			$this->propagateNote($share);
314
-		}
315
-
316
-
317
-		return $share;
318
-	}
319
-
320
-	/**
321
-	 * Get all children of this share
322
-	 * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
323
-	 *
324
-	 * @param \OCP\Share\IShare $parent
325
-	 * @return \OCP\Share\IShare[]
326
-	 */
327
-	public function getChildren(\OCP\Share\IShare $parent) {
328
-		$children = [];
329
-
330
-		$qb = $this->dbConn->getQueryBuilder();
331
-		$qb->select('*')
332
-			->from('share')
333
-			->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
334
-			->andWhere(
335
-				$qb->expr()->in(
336
-					'share_type',
337
-					$qb->createNamedParameter([
338
-						\OCP\Share::SHARE_TYPE_USER,
339
-						\OCP\Share::SHARE_TYPE_GROUP,
340
-						\OCP\Share::SHARE_TYPE_LINK,
341
-					], IQueryBuilder::PARAM_INT_ARRAY)
342
-				)
343
-			)
344
-			->andWhere($qb->expr()->orX(
345
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
346
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
347
-			))
348
-			->orderBy('id');
349
-
350
-		$cursor = $qb->execute();
351
-		while($data = $cursor->fetch()) {
352
-			$children[] = $this->createShare($data);
353
-		}
354
-		$cursor->closeCursor();
355
-
356
-		return $children;
357
-	}
358
-
359
-	/**
360
-	 * Delete a share
361
-	 *
362
-	 * @param \OCP\Share\IShare $share
363
-	 */
364
-	public function delete(\OCP\Share\IShare $share) {
365
-		$qb = $this->dbConn->getQueryBuilder();
366
-		$qb->delete('share')
367
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())));
368
-
369
-		/*
286
+            $qb = $this->dbConn->getQueryBuilder();
287
+            $qb->update('share')
288
+                ->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
289
+                ->andWhere($qb->expr()->neq('permissions', $qb->createNamedParameter(0)))
290
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
291
+                ->execute();
292
+
293
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
294
+            $qb = $this->dbConn->getQueryBuilder();
295
+            $qb->update('share')
296
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
297
+                ->set('password', $qb->createNamedParameter($share->getPassword()))
298
+                ->set('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL))
299
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
300
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
301
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
302
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
303
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
304
+                ->set('token', $qb->createNamedParameter($share->getToken()))
305
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
306
+                ->set('note', $qb->createNamedParameter($share->getNote()))
307
+                ->set('label', $qb->createNamedParameter($share->getLabel()))
308
+                ->set('hide_download', $qb->createNamedParameter($share->getHideDownload() ? 1 : 0), IQueryBuilder::PARAM_INT)
309
+                ->execute();
310
+        }
311
+
312
+        if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
313
+            $this->propagateNote($share);
314
+        }
315
+
316
+
317
+        return $share;
318
+    }
319
+
320
+    /**
321
+     * Get all children of this share
322
+     * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
323
+     *
324
+     * @param \OCP\Share\IShare $parent
325
+     * @return \OCP\Share\IShare[]
326
+     */
327
+    public function getChildren(\OCP\Share\IShare $parent) {
328
+        $children = [];
329
+
330
+        $qb = $this->dbConn->getQueryBuilder();
331
+        $qb->select('*')
332
+            ->from('share')
333
+            ->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
334
+            ->andWhere(
335
+                $qb->expr()->in(
336
+                    'share_type',
337
+                    $qb->createNamedParameter([
338
+                        \OCP\Share::SHARE_TYPE_USER,
339
+                        \OCP\Share::SHARE_TYPE_GROUP,
340
+                        \OCP\Share::SHARE_TYPE_LINK,
341
+                    ], IQueryBuilder::PARAM_INT_ARRAY)
342
+                )
343
+            )
344
+            ->andWhere($qb->expr()->orX(
345
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
346
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
347
+            ))
348
+            ->orderBy('id');
349
+
350
+        $cursor = $qb->execute();
351
+        while($data = $cursor->fetch()) {
352
+            $children[] = $this->createShare($data);
353
+        }
354
+        $cursor->closeCursor();
355
+
356
+        return $children;
357
+    }
358
+
359
+    /**
360
+     * Delete a share
361
+     *
362
+     * @param \OCP\Share\IShare $share
363
+     */
364
+    public function delete(\OCP\Share\IShare $share) {
365
+        $qb = $this->dbConn->getQueryBuilder();
366
+        $qb->delete('share')
367
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())));
368
+
369
+        /*
370 370
 		 * If the share is a group share delete all possible
371 371
 		 * user defined groups shares.
372 372
 		 */
373
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
374
-			$qb->orWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())));
375
-		}
376
-
377
-		$qb->execute();
378
-	}
379
-
380
-	/**
381
-	 * Unshare a share from the recipient. If this is a group share
382
-	 * this means we need a special entry in the share db.
383
-	 *
384
-	 * @param \OCP\Share\IShare $share
385
-	 * @param string $recipient UserId of recipient
386
-	 * @throws BackendError
387
-	 * @throws ProviderException
388
-	 */
389
-	public function deleteFromSelf(\OCP\Share\IShare $share, $recipient) {
390
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
391
-
392
-			$group = $this->groupManager->get($share->getSharedWith());
393
-			$user = $this->userManager->get($recipient);
394
-
395
-			if (is_null($group)) {
396
-				throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
397
-			}
398
-
399
-			if (!$group->inGroup($user)) {
400
-				throw new ProviderException('Recipient not in receiving group');
401
-			}
402
-
403
-			// Try to fetch user specific share
404
-			$qb = $this->dbConn->getQueryBuilder();
405
-			$stmt = $qb->select('*')
406
-				->from('share')
407
-				->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
408
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
409
-				->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
410
-				->andWhere($qb->expr()->orX(
411
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
412
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
413
-				))
414
-				->execute();
415
-
416
-			$data = $stmt->fetch();
417
-
418
-			/*
373
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
374
+            $qb->orWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())));
375
+        }
376
+
377
+        $qb->execute();
378
+    }
379
+
380
+    /**
381
+     * Unshare a share from the recipient. If this is a group share
382
+     * this means we need a special entry in the share db.
383
+     *
384
+     * @param \OCP\Share\IShare $share
385
+     * @param string $recipient UserId of recipient
386
+     * @throws BackendError
387
+     * @throws ProviderException
388
+     */
389
+    public function deleteFromSelf(\OCP\Share\IShare $share, $recipient) {
390
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
391
+
392
+            $group = $this->groupManager->get($share->getSharedWith());
393
+            $user = $this->userManager->get($recipient);
394
+
395
+            if (is_null($group)) {
396
+                throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
397
+            }
398
+
399
+            if (!$group->inGroup($user)) {
400
+                throw new ProviderException('Recipient not in receiving group');
401
+            }
402
+
403
+            // Try to fetch user specific share
404
+            $qb = $this->dbConn->getQueryBuilder();
405
+            $stmt = $qb->select('*')
406
+                ->from('share')
407
+                ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
408
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
409
+                ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
410
+                ->andWhere($qb->expr()->orX(
411
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
412
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
413
+                ))
414
+                ->execute();
415
+
416
+            $data = $stmt->fetch();
417
+
418
+            /*
419 419
 			 * Check if there already is a user specific group share.
420 420
 			 * If there is update it (if required).
421 421
 			 */
422
-			if ($data === false) {
423
-				$qb = $this->dbConn->getQueryBuilder();
424
-
425
-				$type = $share->getNodeType();
426
-
427
-				//Insert new share
428
-				$qb->insert('share')
429
-					->values([
430
-						'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP),
431
-						'share_with' => $qb->createNamedParameter($recipient),
432
-						'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
433
-						'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
434
-						'parent' => $qb->createNamedParameter($share->getId()),
435
-						'item_type' => $qb->createNamedParameter($type),
436
-						'item_source' => $qb->createNamedParameter($share->getNodeId()),
437
-						'file_source' => $qb->createNamedParameter($share->getNodeId()),
438
-						'file_target' => $qb->createNamedParameter($share->getTarget()),
439
-						'permissions' => $qb->createNamedParameter(0),
440
-						'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
441
-					])->execute();
442
-
443
-			} else if ($data['permissions'] !== 0) {
444
-
445
-				// Update existing usergroup share
446
-				$qb = $this->dbConn->getQueryBuilder();
447
-				$qb->update('share')
448
-					->set('permissions', $qb->createNamedParameter(0))
449
-					->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
450
-					->execute();
451
-			}
452
-
453
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
454
-
455
-			if ($share->getSharedWith() !== $recipient) {
456
-				throw new ProviderException('Recipient does not match');
457
-			}
458
-
459
-			// We can just delete user and link shares
460
-			$this->delete($share);
461
-		} else {
462
-			throw new ProviderException('Invalid shareType');
463
-		}
464
-	}
465
-
466
-	/**
467
-	 * @inheritdoc
468
-	 *
469
-	 * For now this only works for group shares
470
-	 * If this gets implemented for normal shares we have to extend it
471
-	 */
472
-	public function restore(IShare $share, string $recipient): IShare {
473
-		$qb = $this->dbConn->getQueryBuilder();
474
-		$qb->select('permissions')
475
-			->from('share')
476
-			->where(
477
-				$qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))
478
-			);
479
-		$cursor = $qb->execute();
480
-		$data = $cursor->fetch();
481
-		$cursor->closeCursor();
482
-
483
-		$originalPermission = $data['permissions'];
484
-
485
-		$qb = $this->dbConn->getQueryBuilder();
486
-		$qb->update('share')
487
-			->set('permissions', $qb->createNamedParameter($originalPermission))
488
-			->where(
489
-				$qb->expr()->eq('parent', $qb->createNamedParameter($share->getParent()))
490
-			)->andWhere(
491
-				$qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP))
492
-			)->andWhere(
493
-				$qb->expr()->eq('share_with', $qb->createNamedParameter($recipient))
494
-			);
495
-
496
-		$qb->execute();
497
-
498
-		return $this->getShareById($share->getId(), $recipient);
499
-	}
500
-
501
-	/**
502
-	 * @inheritdoc
503
-	 */
504
-	public function move(\OCP\Share\IShare $share, $recipient) {
505
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
506
-			// Just update the target
507
-			$qb = $this->dbConn->getQueryBuilder();
508
-			$qb->update('share')
509
-				->set('file_target', $qb->createNamedParameter($share->getTarget()))
510
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
511
-				->execute();
512
-
513
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
514
-
515
-			// Check if there is a usergroup share
516
-			$qb = $this->dbConn->getQueryBuilder();
517
-			$stmt = $qb->select('id')
518
-				->from('share')
519
-				->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
520
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
521
-				->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
522
-				->andWhere($qb->expr()->orX(
523
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
524
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
525
-				))
526
-				->setMaxResults(1)
527
-				->execute();
528
-
529
-			$data = $stmt->fetch();
530
-			$stmt->closeCursor();
531
-
532
-			if ($data === false) {
533
-				// No usergroup share yet. Create one.
534
-				$qb = $this->dbConn->getQueryBuilder();
535
-				$qb->insert('share')
536
-					->values([
537
-						'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP),
538
-						'share_with' => $qb->createNamedParameter($recipient),
539
-						'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
540
-						'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
541
-						'parent' => $qb->createNamedParameter($share->getId()),
542
-						'item_type' => $qb->createNamedParameter($share->getNodeType()),
543
-						'item_source' => $qb->createNamedParameter($share->getNodeId()),
544
-						'file_source' => $qb->createNamedParameter($share->getNodeId()),
545
-						'file_target' => $qb->createNamedParameter($share->getTarget()),
546
-						'permissions' => $qb->createNamedParameter($share->getPermissions()),
547
-						'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
548
-					])->execute();
549
-			} else {
550
-				// Already a usergroup share. Update it.
551
-				$qb = $this->dbConn->getQueryBuilder();
552
-				$qb->update('share')
553
-					->set('file_target', $qb->createNamedParameter($share->getTarget()))
554
-					->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
555
-					->execute();
556
-			}
557
-		}
558
-
559
-		return $share;
560
-	}
561
-
562
-	public function getSharesInFolder($userId, Folder $node, $reshares) {
563
-		$qb = $this->dbConn->getQueryBuilder();
564
-		$qb->select('*')
565
-			->from('share', 's')
566
-			->andWhere($qb->expr()->orX(
567
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
568
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
569
-			));
570
-
571
-		$qb->andWhere($qb->expr()->orX(
572
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
573
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
574
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK))
575
-		));
576
-
577
-		/**
578
-		 * Reshares for this user are shares where they are the owner.
579
-		 */
580
-		if ($reshares === false) {
581
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
582
-		} else {
583
-			$qb->andWhere(
584
-				$qb->expr()->orX(
585
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
586
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
587
-				)
588
-			);
589
-		}
590
-
591
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
592
-		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
593
-
594
-		$qb->orderBy('id');
595
-
596
-		$cursor = $qb->execute();
597
-		$shares = [];
598
-		while ($data = $cursor->fetch()) {
599
-			$shares[$data['fileid']][] = $this->createShare($data);
600
-		}
601
-		$cursor->closeCursor();
602
-
603
-		return $shares;
604
-	}
605
-
606
-	/**
607
-	 * @inheritdoc
608
-	 */
609
-	public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
610
-		$qb = $this->dbConn->getQueryBuilder();
611
-		$qb->select('*')
612
-			->from('share')
613
-			->andWhere($qb->expr()->orX(
614
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
615
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
616
-			));
617
-
618
-		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter($shareType)));
619
-
620
-		/**
621
-		 * Reshares for this user are shares where they are the owner.
622
-		 */
623
-		if ($reshares === false) {
624
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
625
-		} else {
626
-			$qb->andWhere(
627
-				$qb->expr()->orX(
628
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
629
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
630
-				)
631
-			);
632
-		}
633
-
634
-		if ($node !== null) {
635
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
636
-		}
637
-
638
-		if ($limit !== -1) {
639
-			$qb->setMaxResults($limit);
640
-		}
641
-
642
-		$qb->setFirstResult($offset);
643
-		$qb->orderBy('id');
644
-
645
-		$cursor = $qb->execute();
646
-		$shares = [];
647
-		while($data = $cursor->fetch()) {
648
-			$shares[] = $this->createShare($data);
649
-		}
650
-		$cursor->closeCursor();
651
-
652
-		return $shares;
653
-	}
654
-
655
-	/**
656
-	 * @inheritdoc
657
-	 */
658
-	public function getShareById($id, $recipientId = null) {
659
-		$qb = $this->dbConn->getQueryBuilder();
660
-
661
-		$qb->select('*')
662
-			->from('share')
663
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
664
-			->andWhere(
665
-				$qb->expr()->in(
666
-					'share_type',
667
-					$qb->createNamedParameter([
668
-						\OCP\Share::SHARE_TYPE_USER,
669
-						\OCP\Share::SHARE_TYPE_GROUP,
670
-						\OCP\Share::SHARE_TYPE_LINK,
671
-					], IQueryBuilder::PARAM_INT_ARRAY)
672
-				)
673
-			)
674
-			->andWhere($qb->expr()->orX(
675
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
676
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
677
-			));
678
-
679
-		$cursor = $qb->execute();
680
-		$data = $cursor->fetch();
681
-		$cursor->closeCursor();
682
-
683
-		if ($data === false) {
684
-			throw new ShareNotFound();
685
-		}
686
-
687
-		try {
688
-			$share = $this->createShare($data);
689
-		} catch (InvalidShare $e) {
690
-			throw new ShareNotFound();
691
-		}
692
-
693
-		// If the recipient is set for a group share resolve to that user
694
-		if ($recipientId !== null && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
695
-			$share = $this->resolveGroupShares([$share], $recipientId)[0];
696
-		}
697
-
698
-		return $share;
699
-	}
700
-
701
-	/**
702
-	 * Get shares for a given path
703
-	 *
704
-	 * @param \OCP\Files\Node $path
705
-	 * @return \OCP\Share\IShare[]
706
-	 */
707
-	public function getSharesByPath(Node $path) {
708
-		$qb = $this->dbConn->getQueryBuilder();
709
-
710
-		$cursor = $qb->select('*')
711
-			->from('share')
712
-			->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
713
-			->andWhere(
714
-				$qb->expr()->orX(
715
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
716
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP))
717
-				)
718
-			)
719
-			->andWhere($qb->expr()->orX(
720
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
721
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
722
-			))
723
-			->execute();
724
-
725
-		$shares = [];
726
-		while($data = $cursor->fetch()) {
727
-			$shares[] = $this->createShare($data);
728
-		}
729
-		$cursor->closeCursor();
730
-
731
-		return $shares;
732
-	}
733
-
734
-	/**
735
-	 * Returns whether the given database result can be interpreted as
736
-	 * a share with accessible file (not trashed, not deleted)
737
-	 */
738
-	private function isAccessibleResult($data) {
739
-		// exclude shares leading to deleted file entries
740
-		if ($data['fileid'] === null) {
741
-			return false;
742
-		}
743
-
744
-		// exclude shares leading to trashbin on home storages
745
-		$pathSections = explode('/', $data['path'], 2);
746
-		// FIXME: would not detect rare md5'd home storage case properly
747
-		if ($pathSections[0] !== 'files'
748
-		    	&& in_array(explode(':', $data['storage_string_id'], 2)[0], array('home', 'object'))) {
749
-			return false;
750
-		}
751
-		return true;
752
-	}
753
-
754
-	/**
755
-	 * @inheritdoc
756
-	 */
757
-	public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
758
-		/** @var Share[] $shares */
759
-		$shares = [];
760
-
761
-		if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
762
-			//Get shares directly with this user
763
-			$qb = $this->dbConn->getQueryBuilder();
764
-			$qb->select('s.*',
765
-				'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
766
-				'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
767
-				'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
768
-			)
769
-				->selectAlias('st.id', 'storage_string_id')
770
-				->from('share', 's')
771
-				->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
772
-				->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'));
773
-
774
-			// Order by id
775
-			$qb->orderBy('s.id');
776
-
777
-			// Set limit and offset
778
-			if ($limit !== -1) {
779
-				$qb->setMaxResults($limit);
780
-			}
781
-			$qb->setFirstResult($offset);
782
-
783
-			$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)))
784
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
785
-				->andWhere($qb->expr()->orX(
786
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
787
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
788
-				));
789
-
790
-			// Filter by node if provided
791
-			if ($node !== null) {
792
-				$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
793
-			}
794
-
795
-			$cursor = $qb->execute();
796
-
797
-			while($data = $cursor->fetch()) {
798
-				if ($this->isAccessibleResult($data)) {
799
-					$shares[] = $this->createShare($data);
800
-				}
801
-			}
802
-			$cursor->closeCursor();
803
-
804
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
805
-			$user = $this->userManager->get($userId);
806
-			$allGroups = $this->groupManager->getUserGroups($user);
807
-
808
-			/** @var Share[] $shares2 */
809
-			$shares2 = [];
810
-
811
-			$start = 0;
812
-			while(true) {
813
-				$groups = array_slice($allGroups, $start, 100);
814
-				$start += 100;
815
-
816
-				if ($groups === []) {
817
-					break;
818
-				}
819
-
820
-				$qb = $this->dbConn->getQueryBuilder();
821
-				$qb->select('s.*',
822
-					'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
823
-					'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
824
-					'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
825
-				)
826
-					->selectAlias('st.id', 'storage_string_id')
827
-					->from('share', 's')
828
-					->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
829
-					->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'))
830
-					->orderBy('s.id')
831
-					->setFirstResult(0);
832
-
833
-				if ($limit !== -1) {
834
-					$qb->setMaxResults($limit - count($shares));
835
-				}
836
-
837
-				// Filter by node if provided
838
-				if ($node !== null) {
839
-					$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
840
-				}
841
-
842
-
843
-				$groups = array_filter($groups, function($group) { return $group instanceof IGroup; });
844
-				$groups = array_map(function(IGroup $group) { return $group->getGID(); }, $groups);
845
-
846
-				$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
847
-					->andWhere($qb->expr()->in('share_with', $qb->createNamedParameter(
848
-						$groups,
849
-						IQueryBuilder::PARAM_STR_ARRAY
850
-					)))
851
-					->andWhere($qb->expr()->orX(
852
-						$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
853
-						$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
854
-					));
855
-
856
-				$cursor = $qb->execute();
857
-				while($data = $cursor->fetch()) {
858
-					if ($offset > 0) {
859
-						$offset--;
860
-						continue;
861
-					}
862
-
863
-					if ($this->isAccessibleResult($data)) {
864
-						$shares2[] = $this->createShare($data);
865
-					}
866
-				}
867
-				$cursor->closeCursor();
868
-			}
869
-
870
-			/*
422
+            if ($data === false) {
423
+                $qb = $this->dbConn->getQueryBuilder();
424
+
425
+                $type = $share->getNodeType();
426
+
427
+                //Insert new share
428
+                $qb->insert('share')
429
+                    ->values([
430
+                        'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP),
431
+                        'share_with' => $qb->createNamedParameter($recipient),
432
+                        'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
433
+                        'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
434
+                        'parent' => $qb->createNamedParameter($share->getId()),
435
+                        'item_type' => $qb->createNamedParameter($type),
436
+                        'item_source' => $qb->createNamedParameter($share->getNodeId()),
437
+                        'file_source' => $qb->createNamedParameter($share->getNodeId()),
438
+                        'file_target' => $qb->createNamedParameter($share->getTarget()),
439
+                        'permissions' => $qb->createNamedParameter(0),
440
+                        'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
441
+                    ])->execute();
442
+
443
+            } else if ($data['permissions'] !== 0) {
444
+
445
+                // Update existing usergroup share
446
+                $qb = $this->dbConn->getQueryBuilder();
447
+                $qb->update('share')
448
+                    ->set('permissions', $qb->createNamedParameter(0))
449
+                    ->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
450
+                    ->execute();
451
+            }
452
+
453
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
454
+
455
+            if ($share->getSharedWith() !== $recipient) {
456
+                throw new ProviderException('Recipient does not match');
457
+            }
458
+
459
+            // We can just delete user and link shares
460
+            $this->delete($share);
461
+        } else {
462
+            throw new ProviderException('Invalid shareType');
463
+        }
464
+    }
465
+
466
+    /**
467
+     * @inheritdoc
468
+     *
469
+     * For now this only works for group shares
470
+     * If this gets implemented for normal shares we have to extend it
471
+     */
472
+    public function restore(IShare $share, string $recipient): IShare {
473
+        $qb = $this->dbConn->getQueryBuilder();
474
+        $qb->select('permissions')
475
+            ->from('share')
476
+            ->where(
477
+                $qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))
478
+            );
479
+        $cursor = $qb->execute();
480
+        $data = $cursor->fetch();
481
+        $cursor->closeCursor();
482
+
483
+        $originalPermission = $data['permissions'];
484
+
485
+        $qb = $this->dbConn->getQueryBuilder();
486
+        $qb->update('share')
487
+            ->set('permissions', $qb->createNamedParameter($originalPermission))
488
+            ->where(
489
+                $qb->expr()->eq('parent', $qb->createNamedParameter($share->getParent()))
490
+            )->andWhere(
491
+                $qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP))
492
+            )->andWhere(
493
+                $qb->expr()->eq('share_with', $qb->createNamedParameter($recipient))
494
+            );
495
+
496
+        $qb->execute();
497
+
498
+        return $this->getShareById($share->getId(), $recipient);
499
+    }
500
+
501
+    /**
502
+     * @inheritdoc
503
+     */
504
+    public function move(\OCP\Share\IShare $share, $recipient) {
505
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
506
+            // Just update the target
507
+            $qb = $this->dbConn->getQueryBuilder();
508
+            $qb->update('share')
509
+                ->set('file_target', $qb->createNamedParameter($share->getTarget()))
510
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
511
+                ->execute();
512
+
513
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
514
+
515
+            // Check if there is a usergroup share
516
+            $qb = $this->dbConn->getQueryBuilder();
517
+            $stmt = $qb->select('id')
518
+                ->from('share')
519
+                ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
520
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
521
+                ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
522
+                ->andWhere($qb->expr()->orX(
523
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
524
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
525
+                ))
526
+                ->setMaxResults(1)
527
+                ->execute();
528
+
529
+            $data = $stmt->fetch();
530
+            $stmt->closeCursor();
531
+
532
+            if ($data === false) {
533
+                // No usergroup share yet. Create one.
534
+                $qb = $this->dbConn->getQueryBuilder();
535
+                $qb->insert('share')
536
+                    ->values([
537
+                        'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP),
538
+                        'share_with' => $qb->createNamedParameter($recipient),
539
+                        'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
540
+                        'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
541
+                        'parent' => $qb->createNamedParameter($share->getId()),
542
+                        'item_type' => $qb->createNamedParameter($share->getNodeType()),
543
+                        'item_source' => $qb->createNamedParameter($share->getNodeId()),
544
+                        'file_source' => $qb->createNamedParameter($share->getNodeId()),
545
+                        'file_target' => $qb->createNamedParameter($share->getTarget()),
546
+                        'permissions' => $qb->createNamedParameter($share->getPermissions()),
547
+                        'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
548
+                    ])->execute();
549
+            } else {
550
+                // Already a usergroup share. Update it.
551
+                $qb = $this->dbConn->getQueryBuilder();
552
+                $qb->update('share')
553
+                    ->set('file_target', $qb->createNamedParameter($share->getTarget()))
554
+                    ->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
555
+                    ->execute();
556
+            }
557
+        }
558
+
559
+        return $share;
560
+    }
561
+
562
+    public function getSharesInFolder($userId, Folder $node, $reshares) {
563
+        $qb = $this->dbConn->getQueryBuilder();
564
+        $qb->select('*')
565
+            ->from('share', 's')
566
+            ->andWhere($qb->expr()->orX(
567
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
568
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
569
+            ));
570
+
571
+        $qb->andWhere($qb->expr()->orX(
572
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
573
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
574
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK))
575
+        ));
576
+
577
+        /**
578
+         * Reshares for this user are shares where they are the owner.
579
+         */
580
+        if ($reshares === false) {
581
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
582
+        } else {
583
+            $qb->andWhere(
584
+                $qb->expr()->orX(
585
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
586
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
587
+                )
588
+            );
589
+        }
590
+
591
+        $qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
592
+        $qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
593
+
594
+        $qb->orderBy('id');
595
+
596
+        $cursor = $qb->execute();
597
+        $shares = [];
598
+        while ($data = $cursor->fetch()) {
599
+            $shares[$data['fileid']][] = $this->createShare($data);
600
+        }
601
+        $cursor->closeCursor();
602
+
603
+        return $shares;
604
+    }
605
+
606
+    /**
607
+     * @inheritdoc
608
+     */
609
+    public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
610
+        $qb = $this->dbConn->getQueryBuilder();
611
+        $qb->select('*')
612
+            ->from('share')
613
+            ->andWhere($qb->expr()->orX(
614
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
615
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
616
+            ));
617
+
618
+        $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter($shareType)));
619
+
620
+        /**
621
+         * Reshares for this user are shares where they are the owner.
622
+         */
623
+        if ($reshares === false) {
624
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
625
+        } else {
626
+            $qb->andWhere(
627
+                $qb->expr()->orX(
628
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
629
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
630
+                )
631
+            );
632
+        }
633
+
634
+        if ($node !== null) {
635
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
636
+        }
637
+
638
+        if ($limit !== -1) {
639
+            $qb->setMaxResults($limit);
640
+        }
641
+
642
+        $qb->setFirstResult($offset);
643
+        $qb->orderBy('id');
644
+
645
+        $cursor = $qb->execute();
646
+        $shares = [];
647
+        while($data = $cursor->fetch()) {
648
+            $shares[] = $this->createShare($data);
649
+        }
650
+        $cursor->closeCursor();
651
+
652
+        return $shares;
653
+    }
654
+
655
+    /**
656
+     * @inheritdoc
657
+     */
658
+    public function getShareById($id, $recipientId = null) {
659
+        $qb = $this->dbConn->getQueryBuilder();
660
+
661
+        $qb->select('*')
662
+            ->from('share')
663
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
664
+            ->andWhere(
665
+                $qb->expr()->in(
666
+                    'share_type',
667
+                    $qb->createNamedParameter([
668
+                        \OCP\Share::SHARE_TYPE_USER,
669
+                        \OCP\Share::SHARE_TYPE_GROUP,
670
+                        \OCP\Share::SHARE_TYPE_LINK,
671
+                    ], IQueryBuilder::PARAM_INT_ARRAY)
672
+                )
673
+            )
674
+            ->andWhere($qb->expr()->orX(
675
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
676
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
677
+            ));
678
+
679
+        $cursor = $qb->execute();
680
+        $data = $cursor->fetch();
681
+        $cursor->closeCursor();
682
+
683
+        if ($data === false) {
684
+            throw new ShareNotFound();
685
+        }
686
+
687
+        try {
688
+            $share = $this->createShare($data);
689
+        } catch (InvalidShare $e) {
690
+            throw new ShareNotFound();
691
+        }
692
+
693
+        // If the recipient is set for a group share resolve to that user
694
+        if ($recipientId !== null && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
695
+            $share = $this->resolveGroupShares([$share], $recipientId)[0];
696
+        }
697
+
698
+        return $share;
699
+    }
700
+
701
+    /**
702
+     * Get shares for a given path
703
+     *
704
+     * @param \OCP\Files\Node $path
705
+     * @return \OCP\Share\IShare[]
706
+     */
707
+    public function getSharesByPath(Node $path) {
708
+        $qb = $this->dbConn->getQueryBuilder();
709
+
710
+        $cursor = $qb->select('*')
711
+            ->from('share')
712
+            ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
713
+            ->andWhere(
714
+                $qb->expr()->orX(
715
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
716
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP))
717
+                )
718
+            )
719
+            ->andWhere($qb->expr()->orX(
720
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
721
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
722
+            ))
723
+            ->execute();
724
+
725
+        $shares = [];
726
+        while($data = $cursor->fetch()) {
727
+            $shares[] = $this->createShare($data);
728
+        }
729
+        $cursor->closeCursor();
730
+
731
+        return $shares;
732
+    }
733
+
734
+    /**
735
+     * Returns whether the given database result can be interpreted as
736
+     * a share with accessible file (not trashed, not deleted)
737
+     */
738
+    private function isAccessibleResult($data) {
739
+        // exclude shares leading to deleted file entries
740
+        if ($data['fileid'] === null) {
741
+            return false;
742
+        }
743
+
744
+        // exclude shares leading to trashbin on home storages
745
+        $pathSections = explode('/', $data['path'], 2);
746
+        // FIXME: would not detect rare md5'd home storage case properly
747
+        if ($pathSections[0] !== 'files'
748
+                && in_array(explode(':', $data['storage_string_id'], 2)[0], array('home', 'object'))) {
749
+            return false;
750
+        }
751
+        return true;
752
+    }
753
+
754
+    /**
755
+     * @inheritdoc
756
+     */
757
+    public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
758
+        /** @var Share[] $shares */
759
+        $shares = [];
760
+
761
+        if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
762
+            //Get shares directly with this user
763
+            $qb = $this->dbConn->getQueryBuilder();
764
+            $qb->select('s.*',
765
+                'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
766
+                'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
767
+                'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
768
+            )
769
+                ->selectAlias('st.id', 'storage_string_id')
770
+                ->from('share', 's')
771
+                ->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
772
+                ->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'));
773
+
774
+            // Order by id
775
+            $qb->orderBy('s.id');
776
+
777
+            // Set limit and offset
778
+            if ($limit !== -1) {
779
+                $qb->setMaxResults($limit);
780
+            }
781
+            $qb->setFirstResult($offset);
782
+
783
+            $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)))
784
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
785
+                ->andWhere($qb->expr()->orX(
786
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
787
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
788
+                ));
789
+
790
+            // Filter by node if provided
791
+            if ($node !== null) {
792
+                $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
793
+            }
794
+
795
+            $cursor = $qb->execute();
796
+
797
+            while($data = $cursor->fetch()) {
798
+                if ($this->isAccessibleResult($data)) {
799
+                    $shares[] = $this->createShare($data);
800
+                }
801
+            }
802
+            $cursor->closeCursor();
803
+
804
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
805
+            $user = $this->userManager->get($userId);
806
+            $allGroups = $this->groupManager->getUserGroups($user);
807
+
808
+            /** @var Share[] $shares2 */
809
+            $shares2 = [];
810
+
811
+            $start = 0;
812
+            while(true) {
813
+                $groups = array_slice($allGroups, $start, 100);
814
+                $start += 100;
815
+
816
+                if ($groups === []) {
817
+                    break;
818
+                }
819
+
820
+                $qb = $this->dbConn->getQueryBuilder();
821
+                $qb->select('s.*',
822
+                    'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
823
+                    'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
824
+                    'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
825
+                )
826
+                    ->selectAlias('st.id', 'storage_string_id')
827
+                    ->from('share', 's')
828
+                    ->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
829
+                    ->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'))
830
+                    ->orderBy('s.id')
831
+                    ->setFirstResult(0);
832
+
833
+                if ($limit !== -1) {
834
+                    $qb->setMaxResults($limit - count($shares));
835
+                }
836
+
837
+                // Filter by node if provided
838
+                if ($node !== null) {
839
+                    $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
840
+                }
841
+
842
+
843
+                $groups = array_filter($groups, function($group) { return $group instanceof IGroup; });
844
+                $groups = array_map(function(IGroup $group) { return $group->getGID(); }, $groups);
845
+
846
+                $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
847
+                    ->andWhere($qb->expr()->in('share_with', $qb->createNamedParameter(
848
+                        $groups,
849
+                        IQueryBuilder::PARAM_STR_ARRAY
850
+                    )))
851
+                    ->andWhere($qb->expr()->orX(
852
+                        $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
853
+                        $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
854
+                    ));
855
+
856
+                $cursor = $qb->execute();
857
+                while($data = $cursor->fetch()) {
858
+                    if ($offset > 0) {
859
+                        $offset--;
860
+                        continue;
861
+                    }
862
+
863
+                    if ($this->isAccessibleResult($data)) {
864
+                        $shares2[] = $this->createShare($data);
865
+                    }
866
+                }
867
+                $cursor->closeCursor();
868
+            }
869
+
870
+            /*
871 871
  			 * Resolve all group shares to user specific shares
872 872
  			 */
873
-			$shares = $this->resolveGroupShares($shares2, $userId);
874
-		} else {
875
-			throw new BackendError('Invalid backend');
876
-		}
877
-
878
-
879
-		return $shares;
880
-	}
881
-
882
-	/**
883
-	 * Get a share by token
884
-	 *
885
-	 * @param string $token
886
-	 * @return \OCP\Share\IShare
887
-	 * @throws ShareNotFound
888
-	 */
889
-	public function getShareByToken($token) {
890
-		$qb = $this->dbConn->getQueryBuilder();
891
-
892
-		$cursor = $qb->select('*')
893
-			->from('share')
894
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK)))
895
-			->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
896
-			->andWhere($qb->expr()->orX(
897
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
898
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
899
-			))
900
-			->execute();
901
-
902
-		$data = $cursor->fetch();
903
-
904
-		if ($data === false) {
905
-			throw new ShareNotFound();
906
-		}
907
-
908
-		try {
909
-			$share = $this->createShare($data);
910
-		} catch (InvalidShare $e) {
911
-			throw new ShareNotFound();
912
-		}
913
-
914
-		return $share;
915
-	}
916
-
917
-	/**
918
-	 * Create a share object from an database row
919
-	 *
920
-	 * @param mixed[] $data
921
-	 * @return \OCP\Share\IShare
922
-	 * @throws InvalidShare
923
-	 */
924
-	private function createShare($data) {
925
-		$share = new Share($this->rootFolder, $this->userManager);
926
-		$share->setId((int)$data['id'])
927
-			->setShareType((int)$data['share_type'])
928
-			->setPermissions((int)$data['permissions'])
929
-			->setTarget($data['file_target'])
930
-			->setNote($data['note'])
931
-			->setMailSend((bool)$data['mail_send'])
932
-			->setLabel($data['label']);
933
-
934
-		$shareTime = new \DateTime();
935
-		$shareTime->setTimestamp((int)$data['stime']);
936
-		$share->setShareTime($shareTime);
937
-
938
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
939
-			$share->setSharedWith($data['share_with']);
940
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
941
-			$share->setSharedWith($data['share_with']);
942
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
943
-			$share->setPassword($data['password']);
944
-			$share->setSendPasswordByTalk((bool)$data['password_by_talk']);
945
-			$share->setToken($data['token']);
946
-		}
947
-
948
-		$share->setSharedBy($data['uid_initiator']);
949
-		$share->setShareOwner($data['uid_owner']);
950
-
951
-		$share->setNodeId((int)$data['file_source']);
952
-		$share->setNodeType($data['item_type']);
953
-
954
-		if ($data['expiration'] !== null) {
955
-			$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
956
-			$share->setExpirationDate($expiration);
957
-		}
958
-
959
-		if (isset($data['f_permissions'])) {
960
-			$entryData = $data;
961
-			$entryData['permissions'] = $entryData['f_permissions'];
962
-			$entryData['parent'] = $entryData['f_parent'];
963
-			$share->setNodeCacheEntry(Cache::cacheEntryFromData($entryData,
964
-				\OC::$server->getMimeTypeLoader()));
965
-		}
966
-
967
-		$share->setProviderId($this->identifier());
968
-		$share->setHideDownload((int)$data['hide_download'] === 1);
969
-
970
-		return $share;
971
-	}
972
-
973
-	/**
974
-	 * @param Share[] $shares
975
-	 * @param $userId
976
-	 * @return Share[] The updates shares if no update is found for a share return the original
977
-	 */
978
-	private function resolveGroupShares($shares, $userId) {
979
-		$result = [];
980
-
981
-		$start = 0;
982
-		while(true) {
983
-			/** @var Share[] $shareSlice */
984
-			$shareSlice = array_slice($shares, $start, 100);
985
-			$start += 100;
986
-
987
-			if ($shareSlice === []) {
988
-				break;
989
-			}
990
-
991
-			/** @var int[] $ids */
992
-			$ids = [];
993
-			/** @var Share[] $shareMap */
994
-			$shareMap = [];
995
-
996
-			foreach ($shareSlice as $share) {
997
-				$ids[] = (int)$share->getId();
998
-				$shareMap[$share->getId()] = $share;
999
-			}
1000
-
1001
-			$qb = $this->dbConn->getQueryBuilder();
1002
-
1003
-			$query = $qb->select('*')
1004
-				->from('share')
1005
-				->where($qb->expr()->in('parent', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1006
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
1007
-				->andWhere($qb->expr()->orX(
1008
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1009
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1010
-				));
1011
-
1012
-			$stmt = $query->execute();
1013
-
1014
-			while($data = $stmt->fetch()) {
1015
-				$shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
1016
-				$shareMap[$data['parent']]->setTarget($data['file_target']);
1017
-				$shareMap[$data['parent']]->setParent($data['parent']);
1018
-			}
1019
-
1020
-			$stmt->closeCursor();
1021
-
1022
-			foreach ($shareMap as $share) {
1023
-				$result[] = $share;
1024
-			}
1025
-		}
1026
-
1027
-		return $result;
1028
-	}
1029
-
1030
-	/**
1031
-	 * A user is deleted from the system
1032
-	 * So clean up the relevant shares.
1033
-	 *
1034
-	 * @param string $uid
1035
-	 * @param int $shareType
1036
-	 */
1037
-	public function userDeleted($uid, $shareType) {
1038
-		$qb = $this->dbConn->getQueryBuilder();
1039
-
1040
-		$qb->delete('share');
1041
-
1042
-		if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
1043
-			/*
873
+            $shares = $this->resolveGroupShares($shares2, $userId);
874
+        } else {
875
+            throw new BackendError('Invalid backend');
876
+        }
877
+
878
+
879
+        return $shares;
880
+    }
881
+
882
+    /**
883
+     * Get a share by token
884
+     *
885
+     * @param string $token
886
+     * @return \OCP\Share\IShare
887
+     * @throws ShareNotFound
888
+     */
889
+    public function getShareByToken($token) {
890
+        $qb = $this->dbConn->getQueryBuilder();
891
+
892
+        $cursor = $qb->select('*')
893
+            ->from('share')
894
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK)))
895
+            ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
896
+            ->andWhere($qb->expr()->orX(
897
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
898
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
899
+            ))
900
+            ->execute();
901
+
902
+        $data = $cursor->fetch();
903
+
904
+        if ($data === false) {
905
+            throw new ShareNotFound();
906
+        }
907
+
908
+        try {
909
+            $share = $this->createShare($data);
910
+        } catch (InvalidShare $e) {
911
+            throw new ShareNotFound();
912
+        }
913
+
914
+        return $share;
915
+    }
916
+
917
+    /**
918
+     * Create a share object from an database row
919
+     *
920
+     * @param mixed[] $data
921
+     * @return \OCP\Share\IShare
922
+     * @throws InvalidShare
923
+     */
924
+    private function createShare($data) {
925
+        $share = new Share($this->rootFolder, $this->userManager);
926
+        $share->setId((int)$data['id'])
927
+            ->setShareType((int)$data['share_type'])
928
+            ->setPermissions((int)$data['permissions'])
929
+            ->setTarget($data['file_target'])
930
+            ->setNote($data['note'])
931
+            ->setMailSend((bool)$data['mail_send'])
932
+            ->setLabel($data['label']);
933
+
934
+        $shareTime = new \DateTime();
935
+        $shareTime->setTimestamp((int)$data['stime']);
936
+        $share->setShareTime($shareTime);
937
+
938
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
939
+            $share->setSharedWith($data['share_with']);
940
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
941
+            $share->setSharedWith($data['share_with']);
942
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
943
+            $share->setPassword($data['password']);
944
+            $share->setSendPasswordByTalk((bool)$data['password_by_talk']);
945
+            $share->setToken($data['token']);
946
+        }
947
+
948
+        $share->setSharedBy($data['uid_initiator']);
949
+        $share->setShareOwner($data['uid_owner']);
950
+
951
+        $share->setNodeId((int)$data['file_source']);
952
+        $share->setNodeType($data['item_type']);
953
+
954
+        if ($data['expiration'] !== null) {
955
+            $expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
956
+            $share->setExpirationDate($expiration);
957
+        }
958
+
959
+        if (isset($data['f_permissions'])) {
960
+            $entryData = $data;
961
+            $entryData['permissions'] = $entryData['f_permissions'];
962
+            $entryData['parent'] = $entryData['f_parent'];
963
+            $share->setNodeCacheEntry(Cache::cacheEntryFromData($entryData,
964
+                \OC::$server->getMimeTypeLoader()));
965
+        }
966
+
967
+        $share->setProviderId($this->identifier());
968
+        $share->setHideDownload((int)$data['hide_download'] === 1);
969
+
970
+        return $share;
971
+    }
972
+
973
+    /**
974
+     * @param Share[] $shares
975
+     * @param $userId
976
+     * @return Share[] The updates shares if no update is found for a share return the original
977
+     */
978
+    private function resolveGroupShares($shares, $userId) {
979
+        $result = [];
980
+
981
+        $start = 0;
982
+        while(true) {
983
+            /** @var Share[] $shareSlice */
984
+            $shareSlice = array_slice($shares, $start, 100);
985
+            $start += 100;
986
+
987
+            if ($shareSlice === []) {
988
+                break;
989
+            }
990
+
991
+            /** @var int[] $ids */
992
+            $ids = [];
993
+            /** @var Share[] $shareMap */
994
+            $shareMap = [];
995
+
996
+            foreach ($shareSlice as $share) {
997
+                $ids[] = (int)$share->getId();
998
+                $shareMap[$share->getId()] = $share;
999
+            }
1000
+
1001
+            $qb = $this->dbConn->getQueryBuilder();
1002
+
1003
+            $query = $qb->select('*')
1004
+                ->from('share')
1005
+                ->where($qb->expr()->in('parent', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1006
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
1007
+                ->andWhere($qb->expr()->orX(
1008
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1009
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1010
+                ));
1011
+
1012
+            $stmt = $query->execute();
1013
+
1014
+            while($data = $stmt->fetch()) {
1015
+                $shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
1016
+                $shareMap[$data['parent']]->setTarget($data['file_target']);
1017
+                $shareMap[$data['parent']]->setParent($data['parent']);
1018
+            }
1019
+
1020
+            $stmt->closeCursor();
1021
+
1022
+            foreach ($shareMap as $share) {
1023
+                $result[] = $share;
1024
+            }
1025
+        }
1026
+
1027
+        return $result;
1028
+    }
1029
+
1030
+    /**
1031
+     * A user is deleted from the system
1032
+     * So clean up the relevant shares.
1033
+     *
1034
+     * @param string $uid
1035
+     * @param int $shareType
1036
+     */
1037
+    public function userDeleted($uid, $shareType) {
1038
+        $qb = $this->dbConn->getQueryBuilder();
1039
+
1040
+        $qb->delete('share');
1041
+
1042
+        if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
1043
+            /*
1044 1044
 			 * Delete all user shares that are owned by this user
1045 1045
 			 * or that are received by this user
1046 1046
 			 */
1047 1047
 
1048
-			$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)));
1048
+            $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)));
1049 1049
 
1050
-			$qb->andWhere(
1051
-				$qb->expr()->orX(
1052
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
1053
-					$qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
1054
-				)
1055
-			);
1056
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
1057
-			/*
1050
+            $qb->andWhere(
1051
+                $qb->expr()->orX(
1052
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
1053
+                    $qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
1054
+                )
1055
+            );
1056
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
1057
+            /*
1058 1058
 			 * Delete all group shares that are owned by this user
1059 1059
 			 * Or special user group shares that are received by this user
1060 1060
 			 */
1061
-			$qb->where(
1062
-				$qb->expr()->andX(
1063
-					$qb->expr()->orX(
1064
-						$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
1065
-						$qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP))
1066
-					),
1067
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid))
1068
-				)
1069
-			);
1070
-
1071
-			$qb->orWhere(
1072
-				$qb->expr()->andX(
1073
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)),
1074
-					$qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
1075
-				)
1076
-			);
1077
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
1078
-			/*
1061
+            $qb->where(
1062
+                $qb->expr()->andX(
1063
+                    $qb->expr()->orX(
1064
+                        $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
1065
+                        $qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP))
1066
+                    ),
1067
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid))
1068
+                )
1069
+            );
1070
+
1071
+            $qb->orWhere(
1072
+                $qb->expr()->andX(
1073
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)),
1074
+                    $qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
1075
+                )
1076
+            );
1077
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
1078
+            /*
1079 1079
 			 * Delete all link shares owned by this user.
1080 1080
 			 * And all link shares initiated by this user (until #22327 is in)
1081 1081
 			 */
1082
-			$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK)));
1083
-
1084
-			$qb->andWhere(
1085
-				$qb->expr()->orX(
1086
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
1087
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($uid))
1088
-				)
1089
-			);
1090
-		}
1091
-
1092
-		$qb->execute();
1093
-	}
1094
-
1095
-	/**
1096
-	 * Delete all shares received by this group. As well as any custom group
1097
-	 * shares for group members.
1098
-	 *
1099
-	 * @param string $gid
1100
-	 */
1101
-	public function groupDeleted($gid) {
1102
-		/*
1082
+            $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK)));
1083
+
1084
+            $qb->andWhere(
1085
+                $qb->expr()->orX(
1086
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
1087
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($uid))
1088
+                )
1089
+            );
1090
+        }
1091
+
1092
+        $qb->execute();
1093
+    }
1094
+
1095
+    /**
1096
+     * Delete all shares received by this group. As well as any custom group
1097
+     * shares for group members.
1098
+     *
1099
+     * @param string $gid
1100
+     */
1101
+    public function groupDeleted($gid) {
1102
+        /*
1103 1103
 		 * First delete all custom group shares for group members
1104 1104
 		 */
1105
-		$qb = $this->dbConn->getQueryBuilder();
1106
-		$qb->select('id')
1107
-			->from('share')
1108
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1109
-			->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1110
-
1111
-		$cursor = $qb->execute();
1112
-		$ids = [];
1113
-		while($row = $cursor->fetch()) {
1114
-			$ids[] = (int)$row['id'];
1115
-		}
1116
-		$cursor->closeCursor();
1117
-
1118
-		if (!empty($ids)) {
1119
-			$chunks = array_chunk($ids, 100);
1120
-			foreach ($chunks as $chunk) {
1121
-				$qb->delete('share')
1122
-					->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
1123
-					->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1124
-				$qb->execute();
1125
-			}
1126
-		}
1127
-
1128
-		/*
1105
+        $qb = $this->dbConn->getQueryBuilder();
1106
+        $qb->select('id')
1107
+            ->from('share')
1108
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1109
+            ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1110
+
1111
+        $cursor = $qb->execute();
1112
+        $ids = [];
1113
+        while($row = $cursor->fetch()) {
1114
+            $ids[] = (int)$row['id'];
1115
+        }
1116
+        $cursor->closeCursor();
1117
+
1118
+        if (!empty($ids)) {
1119
+            $chunks = array_chunk($ids, 100);
1120
+            foreach ($chunks as $chunk) {
1121
+                $qb->delete('share')
1122
+                    ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
1123
+                    ->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1124
+                $qb->execute();
1125
+            }
1126
+        }
1127
+
1128
+        /*
1129 1129
 		 * Now delete all the group shares
1130 1130
 		 */
1131
-		$qb = $this->dbConn->getQueryBuilder();
1132
-		$qb->delete('share')
1133
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1134
-			->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1135
-		$qb->execute();
1136
-	}
1137
-
1138
-	/**
1139
-	 * Delete custom group shares to this group for this user
1140
-	 *
1141
-	 * @param string $uid
1142
-	 * @param string $gid
1143
-	 */
1144
-	public function userDeletedFromGroup($uid, $gid) {
1145
-		/*
1131
+        $qb = $this->dbConn->getQueryBuilder();
1132
+        $qb->delete('share')
1133
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1134
+            ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1135
+        $qb->execute();
1136
+    }
1137
+
1138
+    /**
1139
+     * Delete custom group shares to this group for this user
1140
+     *
1141
+     * @param string $uid
1142
+     * @param string $gid
1143
+     */
1144
+    public function userDeletedFromGroup($uid, $gid) {
1145
+        /*
1146 1146
 		 * Get all group shares
1147 1147
 		 */
1148
-		$qb = $this->dbConn->getQueryBuilder();
1149
-		$qb->select('id')
1150
-			->from('share')
1151
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1152
-			->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1153
-
1154
-		$cursor = $qb->execute();
1155
-		$ids = [];
1156
-		while($row = $cursor->fetch()) {
1157
-			$ids[] = (int)$row['id'];
1158
-		}
1159
-		$cursor->closeCursor();
1160
-
1161
-		if (!empty($ids)) {
1162
-			$chunks = array_chunk($ids, 100);
1163
-			foreach ($chunks as $chunk) {
1164
-				/*
1148
+        $qb = $this->dbConn->getQueryBuilder();
1149
+        $qb->select('id')
1150
+            ->from('share')
1151
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1152
+            ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1153
+
1154
+        $cursor = $qb->execute();
1155
+        $ids = [];
1156
+        while($row = $cursor->fetch()) {
1157
+            $ids[] = (int)$row['id'];
1158
+        }
1159
+        $cursor->closeCursor();
1160
+
1161
+        if (!empty($ids)) {
1162
+            $chunks = array_chunk($ids, 100);
1163
+            foreach ($chunks as $chunk) {
1164
+                /*
1165 1165
 				 * Delete all special shares wit this users for the found group shares
1166 1166
 				 */
1167
-				$qb->delete('share')
1168
-					->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
1169
-					->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($uid)))
1170
-					->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1171
-				$qb->execute();
1172
-			}
1173
-		}
1174
-	}
1175
-
1176
-	/**
1177
-	 * @inheritdoc
1178
-	 */
1179
-	public function getAccessList($nodes, $currentAccess) {
1180
-		$ids = [];
1181
-		foreach ($nodes as $node) {
1182
-			$ids[] = $node->getId();
1183
-		}
1184
-
1185
-		$qb = $this->dbConn->getQueryBuilder();
1186
-
1187
-		$or = $qb->expr()->orX(
1188
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
1189
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
1190
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK))
1191
-		);
1192
-
1193
-		if ($currentAccess) {
1194
-			$or->add($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)));
1195
-		}
1196
-
1197
-		$qb->select('id', 'parent', 'share_type', 'share_with', 'file_source', 'file_target', 'permissions')
1198
-			->from('share')
1199
-			->where(
1200
-				$or
1201
-			)
1202
-			->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1203
-			->andWhere($qb->expr()->orX(
1204
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1205
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1206
-			));
1207
-		$cursor = $qb->execute();
1208
-
1209
-		$users = [];
1210
-		$link = false;
1211
-		while($row = $cursor->fetch()) {
1212
-			$type = (int)$row['share_type'];
1213
-			if ($type === \OCP\Share::SHARE_TYPE_USER) {
1214
-				$uid = $row['share_with'];
1215
-				$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1216
-				$users[$uid][$row['id']] = $row;
1217
-			} else if ($type === \OCP\Share::SHARE_TYPE_GROUP) {
1218
-				$gid = $row['share_with'];
1219
-				$group = $this->groupManager->get($gid);
1220
-
1221
-				if ($group === null) {
1222
-					continue;
1223
-				}
1224
-
1225
-				$userList = $group->getUsers();
1226
-				foreach ($userList as $user) {
1227
-					$uid = $user->getUID();
1228
-					$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1229
-					$users[$uid][$row['id']] = $row;
1230
-				}
1231
-			} else if ($type === \OCP\Share::SHARE_TYPE_LINK) {
1232
-				$link = true;
1233
-			} else if ($type === self::SHARE_TYPE_USERGROUP && $currentAccess === true) {
1234
-				$uid = $row['share_with'];
1235
-				$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1236
-				$users[$uid][$row['id']] = $row;
1237
-			}
1238
-		}
1239
-		$cursor->closeCursor();
1240
-
1241
-		if ($currentAccess === true) {
1242
-			$users = array_map([$this, 'filterSharesOfUser'], $users);
1243
-			$users = array_filter($users);
1244
-		} else {
1245
-			$users = array_keys($users);
1246
-		}
1247
-
1248
-		return ['users' => $users, 'public' => $link];
1249
-	}
1250
-
1251
-	/**
1252
-	 * For each user the path with the fewest slashes is returned
1253
-	 * @param array $shares
1254
-	 * @return array
1255
-	 */
1256
-	protected function filterSharesOfUser(array $shares) {
1257
-		// Group shares when the user has a share exception
1258
-		foreach ($shares as $id => $share) {
1259
-			$type = (int) $share['share_type'];
1260
-			$permissions = (int) $share['permissions'];
1261
-
1262
-			if ($type === self::SHARE_TYPE_USERGROUP) {
1263
-				unset($shares[$share['parent']]);
1264
-
1265
-				if ($permissions === 0) {
1266
-					unset($shares[$id]);
1267
-				}
1268
-			}
1269
-		}
1270
-
1271
-		$best = [];
1272
-		$bestDepth = 0;
1273
-		foreach ($shares as $id => $share) {
1274
-			$depth = substr_count($share['file_target'], '/');
1275
-			if (empty($best) || $depth < $bestDepth) {
1276
-				$bestDepth = $depth;
1277
-				$best = [
1278
-					'node_id' => $share['file_source'],
1279
-					'node_path' => $share['file_target'],
1280
-				];
1281
-			}
1282
-		}
1283
-
1284
-		return $best;
1285
-	}
1286
-
1287
-	/**
1288
-	 * propagate notes to the recipients
1289
-	 *
1290
-	 * @param IShare $share
1291
-	 * @throws \OCP\Files\NotFoundException
1292
-	 */
1293
-	private function propagateNote(IShare $share) {
1294
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
1295
-			$user = $this->userManager->get($share->getSharedWith());
1296
-			$this->sendNote([$user], $share);
1297
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
1298
-			$group = $this->groupManager->get($share->getSharedWith());
1299
-			$groupMembers = $group->getUsers();
1300
-			$this->sendNote($groupMembers, $share);
1301
-		}
1302
-	}
1303
-
1304
-	/**
1305
-	 * send note by mail
1306
-	 *
1307
-	 * @param array $recipients
1308
-	 * @param IShare $share
1309
-	 * @throws \OCP\Files\NotFoundException
1310
-	 */
1311
-	private function sendNote(array $recipients, IShare $share) {
1312
-
1313
-		$toList = [];
1314
-
1315
-		foreach ($recipients as $recipient) {
1316
-			/** @var IUser $recipient */
1317
-			$email = $recipient->getEMailAddress();
1318
-			if ($email) {
1319
-				$toList[$email] = $recipient->getDisplayName();
1320
-			}
1321
-		}
1322
-
1323
-		if (!empty($toList)) {
1324
-
1325
-			$filename = $share->getNode()->getName();
1326
-			$initiator = $share->getSharedBy();
1327
-			$note = $share->getNote();
1328
-
1329
-			$initiatorUser = $this->userManager->get($initiator);
1330
-			$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
1331
-			$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
1332
-			$plainHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]);
1333
-			$htmlHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]);
1334
-			$message = $this->mailer->createMessage();
1335
-
1336
-			$emailTemplate = $this->mailer->createEMailTemplate('defaultShareProvider.sendNote');
1337
-
1338
-			$emailTemplate->setSubject($this->l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName]));
1339
-			$emailTemplate->addHeader();
1340
-			$emailTemplate->addHeading($htmlHeading, $plainHeading);
1341
-			$emailTemplate->addBodyText(htmlspecialchars($note), $note);
1342
-
1343
-			$link = $this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $share->getNode()->getId()]);
1344
-			$emailTemplate->addBodyButton(
1345
-				$this->l->t('Open »%s«', [$filename]),
1346
-				$link
1347
-			);
1348
-
1349
-
1350
-			// The "From" contains the sharers name
1351
-			$instanceName = $this->defaults->getName();
1352
-			$senderName = $this->l->t(
1353
-				'%1$s via %2$s',
1354
-				[
1355
-					$initiatorDisplayName,
1356
-					$instanceName
1357
-				]
1358
-			);
1359
-			$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
1360
-			if ($initiatorEmailAddress !== null) {
1361
-				$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
1362
-				$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
1363
-			} else {
1364
-				$emailTemplate->addFooter();
1365
-			}
1366
-
1367
-			if (count($toList) === 1) {
1368
-				$message->setTo($toList);
1369
-			} else {
1370
-				$message->setTo([]);
1371
-				$message->setBcc($toList);
1372
-			}
1373
-			$message->useTemplate($emailTemplate);
1374
-			$this->mailer->send($message);
1375
-		}
1376
-
1377
-	}
1167
+                $qb->delete('share')
1168
+                    ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
1169
+                    ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($uid)))
1170
+                    ->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1171
+                $qb->execute();
1172
+            }
1173
+        }
1174
+    }
1175
+
1176
+    /**
1177
+     * @inheritdoc
1178
+     */
1179
+    public function getAccessList($nodes, $currentAccess) {
1180
+        $ids = [];
1181
+        foreach ($nodes as $node) {
1182
+            $ids[] = $node->getId();
1183
+        }
1184
+
1185
+        $qb = $this->dbConn->getQueryBuilder();
1186
+
1187
+        $or = $qb->expr()->orX(
1188
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
1189
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
1190
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK))
1191
+        );
1192
+
1193
+        if ($currentAccess) {
1194
+            $or->add($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)));
1195
+        }
1196
+
1197
+        $qb->select('id', 'parent', 'share_type', 'share_with', 'file_source', 'file_target', 'permissions')
1198
+            ->from('share')
1199
+            ->where(
1200
+                $or
1201
+            )
1202
+            ->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1203
+            ->andWhere($qb->expr()->orX(
1204
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1205
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1206
+            ));
1207
+        $cursor = $qb->execute();
1208
+
1209
+        $users = [];
1210
+        $link = false;
1211
+        while($row = $cursor->fetch()) {
1212
+            $type = (int)$row['share_type'];
1213
+            if ($type === \OCP\Share::SHARE_TYPE_USER) {
1214
+                $uid = $row['share_with'];
1215
+                $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1216
+                $users[$uid][$row['id']] = $row;
1217
+            } else if ($type === \OCP\Share::SHARE_TYPE_GROUP) {
1218
+                $gid = $row['share_with'];
1219
+                $group = $this->groupManager->get($gid);
1220
+
1221
+                if ($group === null) {
1222
+                    continue;
1223
+                }
1224
+
1225
+                $userList = $group->getUsers();
1226
+                foreach ($userList as $user) {
1227
+                    $uid = $user->getUID();
1228
+                    $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1229
+                    $users[$uid][$row['id']] = $row;
1230
+                }
1231
+            } else if ($type === \OCP\Share::SHARE_TYPE_LINK) {
1232
+                $link = true;
1233
+            } else if ($type === self::SHARE_TYPE_USERGROUP && $currentAccess === true) {
1234
+                $uid = $row['share_with'];
1235
+                $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1236
+                $users[$uid][$row['id']] = $row;
1237
+            }
1238
+        }
1239
+        $cursor->closeCursor();
1240
+
1241
+        if ($currentAccess === true) {
1242
+            $users = array_map([$this, 'filterSharesOfUser'], $users);
1243
+            $users = array_filter($users);
1244
+        } else {
1245
+            $users = array_keys($users);
1246
+        }
1247
+
1248
+        return ['users' => $users, 'public' => $link];
1249
+    }
1250
+
1251
+    /**
1252
+     * For each user the path with the fewest slashes is returned
1253
+     * @param array $shares
1254
+     * @return array
1255
+     */
1256
+    protected function filterSharesOfUser(array $shares) {
1257
+        // Group shares when the user has a share exception
1258
+        foreach ($shares as $id => $share) {
1259
+            $type = (int) $share['share_type'];
1260
+            $permissions = (int) $share['permissions'];
1261
+
1262
+            if ($type === self::SHARE_TYPE_USERGROUP) {
1263
+                unset($shares[$share['parent']]);
1264
+
1265
+                if ($permissions === 0) {
1266
+                    unset($shares[$id]);
1267
+                }
1268
+            }
1269
+        }
1270
+
1271
+        $best = [];
1272
+        $bestDepth = 0;
1273
+        foreach ($shares as $id => $share) {
1274
+            $depth = substr_count($share['file_target'], '/');
1275
+            if (empty($best) || $depth < $bestDepth) {
1276
+                $bestDepth = $depth;
1277
+                $best = [
1278
+                    'node_id' => $share['file_source'],
1279
+                    'node_path' => $share['file_target'],
1280
+                ];
1281
+            }
1282
+        }
1283
+
1284
+        return $best;
1285
+    }
1286
+
1287
+    /**
1288
+     * propagate notes to the recipients
1289
+     *
1290
+     * @param IShare $share
1291
+     * @throws \OCP\Files\NotFoundException
1292
+     */
1293
+    private function propagateNote(IShare $share) {
1294
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
1295
+            $user = $this->userManager->get($share->getSharedWith());
1296
+            $this->sendNote([$user], $share);
1297
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
1298
+            $group = $this->groupManager->get($share->getSharedWith());
1299
+            $groupMembers = $group->getUsers();
1300
+            $this->sendNote($groupMembers, $share);
1301
+        }
1302
+    }
1303
+
1304
+    /**
1305
+     * send note by mail
1306
+     *
1307
+     * @param array $recipients
1308
+     * @param IShare $share
1309
+     * @throws \OCP\Files\NotFoundException
1310
+     */
1311
+    private function sendNote(array $recipients, IShare $share) {
1312
+
1313
+        $toList = [];
1314
+
1315
+        foreach ($recipients as $recipient) {
1316
+            /** @var IUser $recipient */
1317
+            $email = $recipient->getEMailAddress();
1318
+            if ($email) {
1319
+                $toList[$email] = $recipient->getDisplayName();
1320
+            }
1321
+        }
1322
+
1323
+        if (!empty($toList)) {
1324
+
1325
+            $filename = $share->getNode()->getName();
1326
+            $initiator = $share->getSharedBy();
1327
+            $note = $share->getNote();
1328
+
1329
+            $initiatorUser = $this->userManager->get($initiator);
1330
+            $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
1331
+            $initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
1332
+            $plainHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]);
1333
+            $htmlHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]);
1334
+            $message = $this->mailer->createMessage();
1335
+
1336
+            $emailTemplate = $this->mailer->createEMailTemplate('defaultShareProvider.sendNote');
1337
+
1338
+            $emailTemplate->setSubject($this->l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName]));
1339
+            $emailTemplate->addHeader();
1340
+            $emailTemplate->addHeading($htmlHeading, $plainHeading);
1341
+            $emailTemplate->addBodyText(htmlspecialchars($note), $note);
1342
+
1343
+            $link = $this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $share->getNode()->getId()]);
1344
+            $emailTemplate->addBodyButton(
1345
+                $this->l->t('Open »%s«', [$filename]),
1346
+                $link
1347
+            );
1348
+
1349
+
1350
+            // The "From" contains the sharers name
1351
+            $instanceName = $this->defaults->getName();
1352
+            $senderName = $this->l->t(
1353
+                '%1$s via %2$s',
1354
+                [
1355
+                    $initiatorDisplayName,
1356
+                    $instanceName
1357
+                ]
1358
+            );
1359
+            $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
1360
+            if ($initiatorEmailAddress !== null) {
1361
+                $message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
1362
+                $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
1363
+            } else {
1364
+                $emailTemplate->addFooter();
1365
+            }
1366
+
1367
+            if (count($toList) === 1) {
1368
+                $message->setTo($toList);
1369
+            } else {
1370
+                $message->setTo([]);
1371
+                $message->setBcc($toList);
1372
+            }
1373
+            $message->useTemplate($emailTemplate);
1374
+            $this->mailer->send($message);
1375
+        }
1376
+
1377
+    }
1378 1378
 }
Please login to merge, or discard this patch.
Spacing   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -348,7 +348,7 @@  discard block
 block discarded – undo
348 348
 			->orderBy('id');
349 349
 
350 350
 		$cursor = $qb->execute();
351
-		while($data = $cursor->fetch()) {
351
+		while ($data = $cursor->fetch()) {
352 352
 			$children[] = $this->createShare($data);
353 353
 		}
354 354
 		$cursor->closeCursor();
@@ -393,7 +393,7 @@  discard block
 block discarded – undo
393 393
 			$user = $this->userManager->get($recipient);
394 394
 
395 395
 			if (is_null($group)) {
396
-				throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
396
+				throw new ProviderException('Group "'.$share->getSharedWith().'" does not exist');
397 397
 			}
398 398
 
399 399
 			if (!$group->inGroup($user)) {
@@ -588,7 +588,7 @@  discard block
 block discarded – undo
588 588
 			);
589 589
 		}
590 590
 
591
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
591
+		$qb->innerJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
592 592
 		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
593 593
 
594 594
 		$qb->orderBy('id');
@@ -644,7 +644,7 @@  discard block
 block discarded – undo
644 644
 
645 645
 		$cursor = $qb->execute();
646 646
 		$shares = [];
647
-		while($data = $cursor->fetch()) {
647
+		while ($data = $cursor->fetch()) {
648 648
 			$shares[] = $this->createShare($data);
649 649
 		}
650 650
 		$cursor->closeCursor();
@@ -723,7 +723,7 @@  discard block
 block discarded – undo
723 723
 			->execute();
724 724
 
725 725
 		$shares = [];
726
-		while($data = $cursor->fetch()) {
726
+		while ($data = $cursor->fetch()) {
727 727
 			$shares[] = $this->createShare($data);
728 728
 		}
729 729
 		$cursor->closeCursor();
@@ -794,7 +794,7 @@  discard block
 block discarded – undo
794 794
 
795 795
 			$cursor = $qb->execute();
796 796
 
797
-			while($data = $cursor->fetch()) {
797
+			while ($data = $cursor->fetch()) {
798 798
 				if ($this->isAccessibleResult($data)) {
799 799
 					$shares[] = $this->createShare($data);
800 800
 				}
@@ -809,7 +809,7 @@  discard block
 block discarded – undo
809 809
 			$shares2 = [];
810 810
 
811 811
 			$start = 0;
812
-			while(true) {
812
+			while (true) {
813 813
 				$groups = array_slice($allGroups, $start, 100);
814 814
 				$start += 100;
815 815
 
@@ -854,7 +854,7 @@  discard block
 block discarded – undo
854 854
 					));
855 855
 
856 856
 				$cursor = $qb->execute();
857
-				while($data = $cursor->fetch()) {
857
+				while ($data = $cursor->fetch()) {
858 858
 					if ($offset > 0) {
859 859
 						$offset--;
860 860
 						continue;
@@ -923,16 +923,16 @@  discard block
 block discarded – undo
923 923
 	 */
924 924
 	private function createShare($data) {
925 925
 		$share = new Share($this->rootFolder, $this->userManager);
926
-		$share->setId((int)$data['id'])
927
-			->setShareType((int)$data['share_type'])
928
-			->setPermissions((int)$data['permissions'])
926
+		$share->setId((int) $data['id'])
927
+			->setShareType((int) $data['share_type'])
928
+			->setPermissions((int) $data['permissions'])
929 929
 			->setTarget($data['file_target'])
930 930
 			->setNote($data['note'])
931
-			->setMailSend((bool)$data['mail_send'])
931
+			->setMailSend((bool) $data['mail_send'])
932 932
 			->setLabel($data['label']);
933 933
 
934 934
 		$shareTime = new \DateTime();
935
-		$shareTime->setTimestamp((int)$data['stime']);
935
+		$shareTime->setTimestamp((int) $data['stime']);
936 936
 		$share->setShareTime($shareTime);
937 937
 
938 938
 		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
@@ -941,14 +941,14 @@  discard block
 block discarded – undo
941 941
 			$share->setSharedWith($data['share_with']);
942 942
 		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
943 943
 			$share->setPassword($data['password']);
944
-			$share->setSendPasswordByTalk((bool)$data['password_by_talk']);
944
+			$share->setSendPasswordByTalk((bool) $data['password_by_talk']);
945 945
 			$share->setToken($data['token']);
946 946
 		}
947 947
 
948 948
 		$share->setSharedBy($data['uid_initiator']);
949 949
 		$share->setShareOwner($data['uid_owner']);
950 950
 
951
-		$share->setNodeId((int)$data['file_source']);
951
+		$share->setNodeId((int) $data['file_source']);
952 952
 		$share->setNodeType($data['item_type']);
953 953
 
954 954
 		if ($data['expiration'] !== null) {
@@ -965,7 +965,7 @@  discard block
 block discarded – undo
965 965
 		}
966 966
 
967 967
 		$share->setProviderId($this->identifier());
968
-		$share->setHideDownload((int)$data['hide_download'] === 1);
968
+		$share->setHideDownload((int) $data['hide_download'] === 1);
969 969
 
970 970
 		return $share;
971 971
 	}
@@ -979,7 +979,7 @@  discard block
 block discarded – undo
979 979
 		$result = [];
980 980
 
981 981
 		$start = 0;
982
-		while(true) {
982
+		while (true) {
983 983
 			/** @var Share[] $shareSlice */
984 984
 			$shareSlice = array_slice($shares, $start, 100);
985 985
 			$start += 100;
@@ -994,7 +994,7 @@  discard block
 block discarded – undo
994 994
 			$shareMap = [];
995 995
 
996 996
 			foreach ($shareSlice as $share) {
997
-				$ids[] = (int)$share->getId();
997
+				$ids[] = (int) $share->getId();
998 998
 				$shareMap[$share->getId()] = $share;
999 999
 			}
1000 1000
 
@@ -1011,8 +1011,8 @@  discard block
 block discarded – undo
1011 1011
 
1012 1012
 			$stmt = $query->execute();
1013 1013
 
1014
-			while($data = $stmt->fetch()) {
1015
-				$shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
1014
+			while ($data = $stmt->fetch()) {
1015
+				$shareMap[$data['parent']]->setPermissions((int) $data['permissions']);
1016 1016
 				$shareMap[$data['parent']]->setTarget($data['file_target']);
1017 1017
 				$shareMap[$data['parent']]->setParent($data['parent']);
1018 1018
 			}
@@ -1110,8 +1110,8 @@  discard block
 block discarded – undo
1110 1110
 
1111 1111
 		$cursor = $qb->execute();
1112 1112
 		$ids = [];
1113
-		while($row = $cursor->fetch()) {
1114
-			$ids[] = (int)$row['id'];
1113
+		while ($row = $cursor->fetch()) {
1114
+			$ids[] = (int) $row['id'];
1115 1115
 		}
1116 1116
 		$cursor->closeCursor();
1117 1117
 
@@ -1153,8 +1153,8 @@  discard block
 block discarded – undo
1153 1153
 
1154 1154
 		$cursor = $qb->execute();
1155 1155
 		$ids = [];
1156
-		while($row = $cursor->fetch()) {
1157
-			$ids[] = (int)$row['id'];
1156
+		while ($row = $cursor->fetch()) {
1157
+			$ids[] = (int) $row['id'];
1158 1158
 		}
1159 1159
 		$cursor->closeCursor();
1160 1160
 
@@ -1208,8 +1208,8 @@  discard block
 block discarded – undo
1208 1208
 
1209 1209
 		$users = [];
1210 1210
 		$link = false;
1211
-		while($row = $cursor->fetch()) {
1212
-			$type = (int)$row['share_type'];
1211
+		while ($row = $cursor->fetch()) {
1212
+			$type = (int) $row['share_type'];
1213 1213
 			if ($type === \OCP\Share::SHARE_TYPE_USER) {
1214 1214
 				$uid = $row['share_with'];
1215 1215
 				$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
@@ -1359,7 +1359,7 @@  discard block
 block discarded – undo
1359 1359
 			$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
1360 1360
 			if ($initiatorEmailAddress !== null) {
1361 1361
 				$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
1362
-				$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
1362
+				$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
1363 1363
 			} else {
1364 1364
 				$emailTemplate->addFooter();
1365 1365
 			}
Please login to merge, or discard this patch.
apps/files_sharing/lib/Controller/ShareAPIController.php 2 patches
Indentation   +1050 added lines, -1050 removed lines patch added patch discarded remove patch
@@ -66,1060 +66,1060 @@
 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
-			'label' => $share->getLabel(),
164
-			'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
165
-		];
166
-
167
-		$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
168
-		if ($recipientNode) {
169
-			$node = $recipientNode;
170
-		} else {
171
-			$nodes = $userFolder->getById($share->getNodeId());
172
-			if (empty($nodes)) {
173
-				// fallback to guessing the path
174
-				$node = $userFolder->get($share->getTarget());
175
-				if ($node === null || $share->getTarget() === '') {
176
-					throw new NotFoundException();
177
-				}
178
-			} else {
179
-				$node = $nodes[0];
180
-			}
181
-		}
182
-
183
-		$result['path'] = $userFolder->getRelativePath($node->getPath());
184
-		if ($node instanceOf \OCP\Files\Folder) {
185
-			$result['item_type'] = 'folder';
186
-		} else {
187
-			$result['item_type'] = 'file';
188
-		}
189
-		$result['mimetype'] = $node->getMimetype();
190
-		$result['storage_id'] = $node->getStorage()->getId();
191
-		$result['storage'] = $node->getStorage()->getCache()->getNumericStorageId();
192
-		$result['item_source'] = $node->getId();
193
-		$result['file_source'] = $node->getId();
194
-		$result['file_parent'] = $node->getParent()->getId();
195
-		$result['file_target'] = $share->getTarget();
196
-
197
-		$expiration = $share->getExpirationDate();
198
-		if ($expiration !== null) {
199
-			$result['expiration'] = $expiration->format('Y-m-d 00:00:00');
200
-		}
201
-
202
-		if ($share->getShareType() === Share::SHARE_TYPE_USER) {
203
-			$sharedWith = $this->userManager->get($share->getSharedWith());
204
-			$result['share_with'] = $share->getSharedWith();
205
-			$result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith();
206
-		} else if ($share->getShareType() === Share::SHARE_TYPE_GROUP) {
207
-			$group = $this->groupManager->get($share->getSharedWith());
208
-			$result['share_with'] = $share->getSharedWith();
209
-			$result['share_with_displayname'] = $group !== null ? $group->getDisplayName() : $share->getSharedWith();
210
-		} else if ($share->getShareType() === Share::SHARE_TYPE_LINK) {
211
-
212
-			$result['share_with'] = $share->getPassword();
213
-			$result['share_with_displayname'] = $share->getPassword();
214
-
215
-			$result['send_password_by_talk'] = $share->getSendPasswordByTalk();
216
-
217
-			$result['token'] = $share->getToken();
218
-			$result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]);
219
-
220
-		} else if ($share->getShareType() === Share::SHARE_TYPE_REMOTE || $share->getShareType() === Share::SHARE_TYPE_REMOTE_GROUP) {
221
-			$result['share_with'] = $share->getSharedWith();
222
-			$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'CLOUD');
223
-			$result['token'] = $share->getToken();
224
-		} else if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) {
225
-			$result['share_with'] = $share->getSharedWith();
226
-			$result['password'] = $share->getPassword();
227
-			$result['send_password_by_talk'] = $share->getSendPasswordByTalk();
228
-			$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
229
-			$result['token'] = $share->getToken();
230
-		} else if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) {
231
-			// getSharedWith() returns either "name (type, owner)" or
232
-			// "name (type, owner) [id]", depending on the Circles app version.
233
-			$hasCircleId = (substr($share->getSharedWith(), -1) === ']');
234
-
235
-			$result['share_with_displayname'] = $share->getSharedWithDisplayName();
236
-			if (empty($result['share_with_displayname'])) {
237
-				$displayNameLength = ($hasCircleId? strrpos($share->getSharedWith(), ' '): strlen($share->getSharedWith()));
238
-				$result['share_with_displayname'] = substr($share->getSharedWith(), 0, $displayNameLength);
239
-			}
240
-
241
-			$result['share_with_avatar'] = $share->getSharedWithAvatar();
242
-
243
-			$shareWithStart = ($hasCircleId? strrpos($share->getSharedWith(), '[') + 1: 0);
244
-			$shareWithLength = ($hasCircleId? -1: strpos($share->getSharedWith(), ' '));
245
-			$result['share_with'] = substr($share->getSharedWith(), $shareWithStart, $shareWithLength);
246
-		} else if ($share->getShareType() === Share::SHARE_TYPE_ROOM) {
247
-			$result['share_with'] = $share->getSharedWith();
248
-			$result['share_with_displayname'] = '';
249
-
250
-			try {
251
-				$result = array_merge($result, $this->getRoomShareHelper()->formatShare($share));
252
-			} catch (QueryException $e) {
253
-			}
254
-		}
255
-
256
-
257
-		$result['mail_send'] = $share->getMailSend() ? 1 : 0;
258
-		$result['hide_download'] = $share->getHideDownload() ? 1 : 0;
259
-
260
-		return $result;
261
-	}
262
-
263
-	/**
264
-	 * Check if one of the users address books knows the exact property, if
265
-	 * yes we return the full name.
266
-	 *
267
-	 * @param string $query
268
-	 * @param string $property
269
-	 * @return string
270
-	 */
271
-	private function getDisplayNameFromAddressBook(string $query, string $property): string {
272
-		// FIXME: If we inject the contacts manager it gets initialized bofore any address books are registered
273
-		$result = \OC::$server->getContactsManager()->search($query, [$property]);
274
-		foreach ($result as $r) {
275
-			foreach($r[$property] as $value) {
276
-				if ($value === $query) {
277
-					return $r['FN'];
278
-				}
279
-			}
280
-		}
281
-
282
-		return $query;
283
-	}
284
-
285
-	/**
286
-	 * Get a specific share by id
287
-	 *
288
-	 * @NoAdminRequired
289
-	 *
290
-	 * @param string $id
291
-	 * @return DataResponse
292
-	 * @throws OCSNotFoundException
293
-	 */
294
-	public function getShare(string $id): DataResponse {
295
-		try {
296
-			$share = $this->getShareById($id);
297
-		} catch (ShareNotFound $e) {
298
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
299
-		}
300
-
301
-		if ($this->canAccessShare($share)) {
302
-			try {
303
-				$share = $this->formatShare($share);
304
-				return new DataResponse([$share]);
305
-			} catch (NotFoundException $e) {
306
-				//Fall trough
307
-			}
308
-		}
309
-
310
-		throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
311
-	}
312
-
313
-	/**
314
-	 * Delete a share
315
-	 *
316
-	 * @NoAdminRequired
317
-	 *
318
-	 * @param string $id
319
-	 * @return DataResponse
320
-	 * @throws OCSNotFoundException
321
-	 */
322
-	public function deleteShare(string $id): DataResponse {
323
-		try {
324
-			$share = $this->getShareById($id);
325
-		} catch (ShareNotFound $e) {
326
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
327
-		}
328
-
329
-		try {
330
-			$this->lock($share->getNode());
331
-		} catch (LockedException $e) {
332
-			throw new OCSNotFoundException($this->l->t('could not delete share'));
333
-		}
334
-
335
-		if (!$this->canAccessShare($share)) {
336
-			throw new OCSNotFoundException($this->l->t('Could not delete share'));
337
-		}
338
-
339
-		if (($share->getShareType() === Share::SHARE_TYPE_GROUP ||
340
-				$share->getShareType() === Share::SHARE_TYPE_ROOM) &&
341
-			$share->getShareOwner() !== $this->currentUser &&
342
-			$share->getSharedBy() !== $this->currentUser) {
343
-			$this->shareManager->deleteFromSelf($share, $this->currentUser);
344
-		} else {
345
-			$this->shareManager->deleteShare($share);
346
-		}
347
-
348
-		return new DataResponse();
349
-	}
350
-
351
-	/**
352
-	 * @NoAdminRequired
353
-	 *
354
-	 * @param string $path
355
-	 * @param int $permissions
356
-	 * @param int $shareType
357
-	 * @param string $shareWith
358
-	 * @param string $publicUpload
359
-	 * @param string $password
360
-	 * @param string $sendPasswordByTalk
361
-	 * @param string $expireDate
362
-	 * @param string $label
363
-	 *
364
-	 * @return DataResponse
365
-	 * @throws NotFoundException
366
-	 * @throws OCSBadRequestException
367
-	 * @throws OCSException
368
-	 * @throws OCSForbiddenException
369
-	 * @throws OCSNotFoundException
370
-	 * @throws \OCP\Files\InvalidPathException
371
-	 * @suppress PhanUndeclaredClassMethod
372
-	 */
373
-	public function createShare(
374
-		string $path = null,
375
-		int $permissions = null,
376
-		int $shareType = -1,
377
-		string $shareWith = null,
378
-		string $publicUpload = 'false',
379
-		string $password = '',
380
-		string $sendPasswordByTalk = null,
381
-		string $expireDate = '',
382
-		string $label = ''
383
-	): DataResponse {
384
-		$share = $this->shareManager->newShare();
385
-
386
-		if ($permissions === null) {
387
-			$permissions = $this->config->getAppValue('core', 'shareapi_default_permissions', Constants::PERMISSION_ALL);
388
-		}
389
-
390
-		// Verify path
391
-		if ($path === null) {
392
-			throw new OCSNotFoundException($this->l->t('Please specify a file or folder path'));
393
-		}
394
-
395
-		$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
396
-		try {
397
-			$path = $userFolder->get($path);
398
-		} catch (NotFoundException $e) {
399
-			throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
400
-		}
401
-
402
-		$share->setNode($path);
403
-
404
-		try {
405
-			$this->lock($share->getNode());
406
-		} catch (LockedException $e) {
407
-			throw new OCSNotFoundException($this->l->t('Could not create share'));
408
-		}
409
-
410
-		if ($permissions < 0 || $permissions > Constants::PERMISSION_ALL) {
411
-			throw new OCSNotFoundException($this->l->t('invalid permissions'));
412
-		}
413
-
414
-		// Shares always require read permissions
415
-		$permissions |= Constants::PERMISSION_READ;
416
-
417
-		if ($path instanceof \OCP\Files\File) {
418
-			// Single file shares should never have delete or create permissions
419
-			$permissions &= ~Constants::PERMISSION_DELETE;
420
-			$permissions &= ~Constants::PERMISSION_CREATE;
421
-		}
422
-
423
-		/*
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
+            'label' => $share->getLabel(),
164
+            'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
165
+        ];
166
+
167
+        $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
168
+        if ($recipientNode) {
169
+            $node = $recipientNode;
170
+        } else {
171
+            $nodes = $userFolder->getById($share->getNodeId());
172
+            if (empty($nodes)) {
173
+                // fallback to guessing the path
174
+                $node = $userFolder->get($share->getTarget());
175
+                if ($node === null || $share->getTarget() === '') {
176
+                    throw new NotFoundException();
177
+                }
178
+            } else {
179
+                $node = $nodes[0];
180
+            }
181
+        }
182
+
183
+        $result['path'] = $userFolder->getRelativePath($node->getPath());
184
+        if ($node instanceOf \OCP\Files\Folder) {
185
+            $result['item_type'] = 'folder';
186
+        } else {
187
+            $result['item_type'] = 'file';
188
+        }
189
+        $result['mimetype'] = $node->getMimetype();
190
+        $result['storage_id'] = $node->getStorage()->getId();
191
+        $result['storage'] = $node->getStorage()->getCache()->getNumericStorageId();
192
+        $result['item_source'] = $node->getId();
193
+        $result['file_source'] = $node->getId();
194
+        $result['file_parent'] = $node->getParent()->getId();
195
+        $result['file_target'] = $share->getTarget();
196
+
197
+        $expiration = $share->getExpirationDate();
198
+        if ($expiration !== null) {
199
+            $result['expiration'] = $expiration->format('Y-m-d 00:00:00');
200
+        }
201
+
202
+        if ($share->getShareType() === Share::SHARE_TYPE_USER) {
203
+            $sharedWith = $this->userManager->get($share->getSharedWith());
204
+            $result['share_with'] = $share->getSharedWith();
205
+            $result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith();
206
+        } else if ($share->getShareType() === Share::SHARE_TYPE_GROUP) {
207
+            $group = $this->groupManager->get($share->getSharedWith());
208
+            $result['share_with'] = $share->getSharedWith();
209
+            $result['share_with_displayname'] = $group !== null ? $group->getDisplayName() : $share->getSharedWith();
210
+        } else if ($share->getShareType() === Share::SHARE_TYPE_LINK) {
211
+
212
+            $result['share_with'] = $share->getPassword();
213
+            $result['share_with_displayname'] = $share->getPassword();
214
+
215
+            $result['send_password_by_talk'] = $share->getSendPasswordByTalk();
216
+
217
+            $result['token'] = $share->getToken();
218
+            $result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]);
219
+
220
+        } else if ($share->getShareType() === Share::SHARE_TYPE_REMOTE || $share->getShareType() === Share::SHARE_TYPE_REMOTE_GROUP) {
221
+            $result['share_with'] = $share->getSharedWith();
222
+            $result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'CLOUD');
223
+            $result['token'] = $share->getToken();
224
+        } else if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) {
225
+            $result['share_with'] = $share->getSharedWith();
226
+            $result['password'] = $share->getPassword();
227
+            $result['send_password_by_talk'] = $share->getSendPasswordByTalk();
228
+            $result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
229
+            $result['token'] = $share->getToken();
230
+        } else if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) {
231
+            // getSharedWith() returns either "name (type, owner)" or
232
+            // "name (type, owner) [id]", depending on the Circles app version.
233
+            $hasCircleId = (substr($share->getSharedWith(), -1) === ']');
234
+
235
+            $result['share_with_displayname'] = $share->getSharedWithDisplayName();
236
+            if (empty($result['share_with_displayname'])) {
237
+                $displayNameLength = ($hasCircleId? strrpos($share->getSharedWith(), ' '): strlen($share->getSharedWith()));
238
+                $result['share_with_displayname'] = substr($share->getSharedWith(), 0, $displayNameLength);
239
+            }
240
+
241
+            $result['share_with_avatar'] = $share->getSharedWithAvatar();
242
+
243
+            $shareWithStart = ($hasCircleId? strrpos($share->getSharedWith(), '[') + 1: 0);
244
+            $shareWithLength = ($hasCircleId? -1: strpos($share->getSharedWith(), ' '));
245
+            $result['share_with'] = substr($share->getSharedWith(), $shareWithStart, $shareWithLength);
246
+        } else if ($share->getShareType() === Share::SHARE_TYPE_ROOM) {
247
+            $result['share_with'] = $share->getSharedWith();
248
+            $result['share_with_displayname'] = '';
249
+
250
+            try {
251
+                $result = array_merge($result, $this->getRoomShareHelper()->formatShare($share));
252
+            } catch (QueryException $e) {
253
+            }
254
+        }
255
+
256
+
257
+        $result['mail_send'] = $share->getMailSend() ? 1 : 0;
258
+        $result['hide_download'] = $share->getHideDownload() ? 1 : 0;
259
+
260
+        return $result;
261
+    }
262
+
263
+    /**
264
+     * Check if one of the users address books knows the exact property, if
265
+     * yes we return the full name.
266
+     *
267
+     * @param string $query
268
+     * @param string $property
269
+     * @return string
270
+     */
271
+    private function getDisplayNameFromAddressBook(string $query, string $property): string {
272
+        // FIXME: If we inject the contacts manager it gets initialized bofore any address books are registered
273
+        $result = \OC::$server->getContactsManager()->search($query, [$property]);
274
+        foreach ($result as $r) {
275
+            foreach($r[$property] as $value) {
276
+                if ($value === $query) {
277
+                    return $r['FN'];
278
+                }
279
+            }
280
+        }
281
+
282
+        return $query;
283
+    }
284
+
285
+    /**
286
+     * Get a specific share by id
287
+     *
288
+     * @NoAdminRequired
289
+     *
290
+     * @param string $id
291
+     * @return DataResponse
292
+     * @throws OCSNotFoundException
293
+     */
294
+    public function getShare(string $id): DataResponse {
295
+        try {
296
+            $share = $this->getShareById($id);
297
+        } catch (ShareNotFound $e) {
298
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
299
+        }
300
+
301
+        if ($this->canAccessShare($share)) {
302
+            try {
303
+                $share = $this->formatShare($share);
304
+                return new DataResponse([$share]);
305
+            } catch (NotFoundException $e) {
306
+                //Fall trough
307
+            }
308
+        }
309
+
310
+        throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
311
+    }
312
+
313
+    /**
314
+     * Delete a share
315
+     *
316
+     * @NoAdminRequired
317
+     *
318
+     * @param string $id
319
+     * @return DataResponse
320
+     * @throws OCSNotFoundException
321
+     */
322
+    public function deleteShare(string $id): DataResponse {
323
+        try {
324
+            $share = $this->getShareById($id);
325
+        } catch (ShareNotFound $e) {
326
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
327
+        }
328
+
329
+        try {
330
+            $this->lock($share->getNode());
331
+        } catch (LockedException $e) {
332
+            throw new OCSNotFoundException($this->l->t('could not delete share'));
333
+        }
334
+
335
+        if (!$this->canAccessShare($share)) {
336
+            throw new OCSNotFoundException($this->l->t('Could not delete share'));
337
+        }
338
+
339
+        if (($share->getShareType() === Share::SHARE_TYPE_GROUP ||
340
+                $share->getShareType() === Share::SHARE_TYPE_ROOM) &&
341
+            $share->getShareOwner() !== $this->currentUser &&
342
+            $share->getSharedBy() !== $this->currentUser) {
343
+            $this->shareManager->deleteFromSelf($share, $this->currentUser);
344
+        } else {
345
+            $this->shareManager->deleteShare($share);
346
+        }
347
+
348
+        return new DataResponse();
349
+    }
350
+
351
+    /**
352
+     * @NoAdminRequired
353
+     *
354
+     * @param string $path
355
+     * @param int $permissions
356
+     * @param int $shareType
357
+     * @param string $shareWith
358
+     * @param string $publicUpload
359
+     * @param string $password
360
+     * @param string $sendPasswordByTalk
361
+     * @param string $expireDate
362
+     * @param string $label
363
+     *
364
+     * @return DataResponse
365
+     * @throws NotFoundException
366
+     * @throws OCSBadRequestException
367
+     * @throws OCSException
368
+     * @throws OCSForbiddenException
369
+     * @throws OCSNotFoundException
370
+     * @throws \OCP\Files\InvalidPathException
371
+     * @suppress PhanUndeclaredClassMethod
372
+     */
373
+    public function createShare(
374
+        string $path = null,
375
+        int $permissions = null,
376
+        int $shareType = -1,
377
+        string $shareWith = null,
378
+        string $publicUpload = 'false',
379
+        string $password = '',
380
+        string $sendPasswordByTalk = null,
381
+        string $expireDate = '',
382
+        string $label = ''
383
+    ): DataResponse {
384
+        $share = $this->shareManager->newShare();
385
+
386
+        if ($permissions === null) {
387
+            $permissions = $this->config->getAppValue('core', 'shareapi_default_permissions', Constants::PERMISSION_ALL);
388
+        }
389
+
390
+        // Verify path
391
+        if ($path === null) {
392
+            throw new OCSNotFoundException($this->l->t('Please specify a file or folder path'));
393
+        }
394
+
395
+        $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
396
+        try {
397
+            $path = $userFolder->get($path);
398
+        } catch (NotFoundException $e) {
399
+            throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
400
+        }
401
+
402
+        $share->setNode($path);
403
+
404
+        try {
405
+            $this->lock($share->getNode());
406
+        } catch (LockedException $e) {
407
+            throw new OCSNotFoundException($this->l->t('Could not create share'));
408
+        }
409
+
410
+        if ($permissions < 0 || $permissions > Constants::PERMISSION_ALL) {
411
+            throw new OCSNotFoundException($this->l->t('invalid permissions'));
412
+        }
413
+
414
+        // Shares always require read permissions
415
+        $permissions |= Constants::PERMISSION_READ;
416
+
417
+        if ($path instanceof \OCP\Files\File) {
418
+            // Single file shares should never have delete or create permissions
419
+            $permissions &= ~Constants::PERMISSION_DELETE;
420
+            $permissions &= ~Constants::PERMISSION_CREATE;
421
+        }
422
+
423
+        /*
424 424
 		 * Hack for https://github.com/owncloud/core/issues/22587
425 425
 		 * We check the permissions via webdav. But the permissions of the mount point
426 426
 		 * do not equal the share permissions. Here we fix that for federated mounts.
427 427
 		 */
428
-		if ($path->getStorage()->instanceOfStorage(Storage::class)) {
429
-			$permissions &= ~($permissions & ~$path->getPermissions());
430
-		}
431
-
432
-		if ($shareType === Share::SHARE_TYPE_USER) {
433
-			// Valid user is required to share
434
-			if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
435
-				throw new OCSNotFoundException($this->l->t('Please specify a valid user'));
436
-			}
437
-			$share->setSharedWith($shareWith);
438
-			$share->setPermissions($permissions);
439
-		} else if ($shareType === Share::SHARE_TYPE_GROUP) {
440
-			if (!$this->shareManager->allowGroupSharing()) {
441
-				throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator'));
442
-			}
443
-
444
-			// Valid group is required to share
445
-			if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
446
-				throw new OCSNotFoundException($this->l->t('Please specify a valid group'));
447
-			}
448
-			$share->setSharedWith($shareWith);
449
-			$share->setPermissions($permissions);
450
-		} else if ($shareType === Share::SHARE_TYPE_LINK) {
451
-			//Can we even share links?
452
-			if (!$this->shareManager->shareApiAllowLinks()) {
453
-				throw new OCSNotFoundException($this->l->t('Public link sharing is disabled by the administrator'));
454
-			}
455
-
456
-			if ($publicUpload === 'true') {
457
-				// Check if public upload is allowed
458
-				if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
459
-					throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
460
-				}
461
-
462
-				// Public upload can only be set for folders
463
-				if ($path instanceof \OCP\Files\File) {
464
-					throw new OCSNotFoundException($this->l->t('Public upload is only possible for publicly shared folders'));
465
-				}
466
-
467
-				$share->setPermissions(
468
-					Constants::PERMISSION_READ |
469
-					Constants::PERMISSION_CREATE |
470
-					Constants::PERMISSION_UPDATE |
471
-					Constants::PERMISSION_DELETE
472
-				);
473
-			} else {
474
-				$share->setPermissions(Constants::PERMISSION_READ);
475
-			}
476
-
477
-			// Set password
478
-			if ($password !== '') {
479
-				$share->setPassword($password);
480
-			}
481
-
482
-
483
-			if (!empty($label)) {
484
-				$share->setLabel($label);
485
-			}
486
-
487
-			if ($sendPasswordByTalk === 'true') {
488
-				if (!$this->appManager->isEnabledForUser('spreed')) {
489
-					throw new OCSForbiddenException($this->l->t('Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled', [$path->getPath()]));
490
-				}
491
-
492
-				$share->setSendPasswordByTalk(true);
493
-			}
494
-
495
-			//Expire date
496
-			if ($expireDate !== '') {
497
-				try {
498
-					$expireDate = $this->parseDate($expireDate);
499
-					$share->setExpirationDate($expireDate);
500
-				} catch (\Exception $e) {
501
-					throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
502
-				}
503
-			}
504
-
505
-		} else if ($shareType === Share::SHARE_TYPE_REMOTE) {
506
-			if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
507
-				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]));
508
-			}
509
-
510
-			$share->setSharedWith($shareWith);
511
-			$share->setPermissions($permissions);
512
-		}  else if ($shareType === Share::SHARE_TYPE_REMOTE_GROUP) {
513
-			if (!$this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
514
-				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]));
515
-			}
516
-
517
-			$share->setSharedWith($shareWith);
518
-			$share->setPermissions($permissions);
519
-		} else if ($shareType === Share::SHARE_TYPE_EMAIL) {
520
-			if ($share->getNodeType() === 'file') {
521
-				$share->setPermissions(Constants::PERMISSION_READ);
522
-			} else {
523
-				$share->setPermissions($permissions);
524
-			}
525
-			$share->setSharedWith($shareWith);
526
-
527
-			if ($sendPasswordByTalk === 'true') {
528
-				if (!$this->appManager->isEnabledForUser('spreed')) {
529
-					throw new OCSForbiddenException($this->l->t('Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled', [$path->getPath()]));
530
-				}
531
-
532
-				$share->setSendPasswordByTalk(true);
533
-			}
534
-		} else if ($shareType === Share::SHARE_TYPE_CIRCLE) {
535
-			if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) {
536
-				throw new OCSNotFoundException($this->l->t('You cannot share to a Circle if the app is not enabled'));
537
-			}
538
-
539
-			$circle = \OCA\Circles\Api\v1\Circles::detailsCircle($shareWith);
540
-
541
-			// Valid circle is required to share
542
-			if ($circle === null) {
543
-				throw new OCSNotFoundException($this->l->t('Please specify a valid circle'));
544
-			}
545
-			$share->setSharedWith($shareWith);
546
-			$share->setPermissions($permissions);
547
-		} else if ($shareType === Share::SHARE_TYPE_ROOM) {
548
-			try {
549
-				$this->getRoomShareHelper()->createShare($share, $shareWith, $permissions, $expireDate);
550
-			} catch (QueryException $e) {
551
-				throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not support room shares', [$path->getPath()]));
552
-			}
553
-		} else {
554
-			throw new OCSBadRequestException($this->l->t('Unknown share type'));
555
-		}
556
-
557
-		$share->setShareType($shareType);
558
-		$share->setSharedBy($this->currentUser);
559
-
560
-		try {
561
-			$share = $this->shareManager->createShare($share);
562
-		} catch (GenericShareException $e) {
563
-			$code = $e->getCode() === 0 ? 403 : $e->getCode();
564
-			throw new OCSException($e->getHint(), $code);
565
-		} catch (\Exception $e) {
566
-			throw new OCSForbiddenException($e->getMessage(), $e);
567
-		}
568
-
569
-		$output = $this->formatShare($share);
570
-
571
-		return new DataResponse($output);
572
-	}
573
-
574
-	/**
575
-	 * @param \OCP\Files\File|\OCP\Files\Folder $node
576
-	 * @param boolean $includeTags
577
-	 * @return DataResponse
578
-	 */
579
-	private function getSharedWithMe($node = null, bool $includeTags): DataResponse {
580
-
581
-		$userShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_USER, $node, -1, 0);
582
-		$groupShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_GROUP, $node, -1, 0);
583
-		$circleShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_CIRCLE, $node, -1, 0);
584
-		$roomShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_ROOM, $node, -1, 0);
585
-
586
-		$shares = array_merge($userShares, $groupShares, $circleShares, $roomShares);
587
-
588
-		$shares = array_filter($shares, function (IShare $share) {
589
-			return $share->getShareOwner() !== $this->currentUser;
590
-		});
591
-
592
-		$formatted = [];
593
-		foreach ($shares as $share) {
594
-			if ($this->canAccessShare($share)) {
595
-				try {
596
-					$formatted[] = $this->formatShare($share);
597
-				} catch (NotFoundException $e) {
598
-					// Ignore this share
599
-				}
600
-			}
601
-		}
602
-
603
-		if ($includeTags) {
604
-			$formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
605
-		}
606
-
607
-		return new DataResponse($formatted);
608
-	}
609
-
610
-	/**
611
-	 * @param \OCP\Files\Folder $folder
612
-	 * @return DataResponse
613
-	 * @throws OCSBadRequestException
614
-	 */
615
-	private function getSharesInDir(Node $folder): DataResponse {
616
-		if (!($folder instanceof \OCP\Files\Folder)) {
617
-			throw new OCSBadRequestException($this->l->t('Not a directory'));
618
-		}
619
-
620
-		$nodes = $folder->getDirectoryListing();
621
-		/** @var \OCP\Share\IShare[] $shares */
622
-		$shares = [];
623
-		foreach ($nodes as $node) {
624
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $node, false, -1, 0));
625
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
626
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $node, false, -1, 0));
627
-			if($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
628
-				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $node, false, -1, 0));
629
-			}
630
-			if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
631
-				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE, $node, false, -1, 0));
632
-			}
633
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_ROOM, $node, false, -1, 0));
634
-		}
635
-
636
-		$formatted = [];
637
-		foreach ($shares as $share) {
638
-			try {
639
-				$formatted[] = $this->formatShare($share);
640
-			} catch (NotFoundException $e) {
641
-				//Ignore this share
642
-			}
643
-		}
644
-
645
-		return new DataResponse($formatted);
646
-	}
647
-
648
-	/**
649
-	 * The getShares function.
650
-	 *
651
-	 * @NoAdminRequired
652
-	 *
653
-	 * @param string $shared_with_me
654
-	 * @param string $reshares
655
-	 * @param string $subfiles
656
-	 * @param string $path
657
-	 *
658
-	 * - Get shares by the current user
659
-	 * - Get shares by the current user and reshares (?reshares=true)
660
-	 * - Get shares with the current user (?shared_with_me=true)
661
-	 * - Get shares for a specific path (?path=...)
662
-	 * - Get all shares in a folder (?subfiles=true&path=..)
663
-	 *
664
-	 * @return DataResponse
665
-	 * @throws OCSNotFoundException
666
-	 */
667
-	public function getShares(
668
-		string $shared_with_me = 'false',
669
-		string $reshares = 'false',
670
-		string $subfiles = 'false',
671
-		string $path = null,
672
-		string $include_tags = 'false'
673
-	): DataResponse {
674
-
675
-		if ($path !== null) {
676
-			$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
677
-			try {
678
-				$path = $userFolder->get($path);
679
-				$this->lock($path);
680
-			} catch (\OCP\Files\NotFoundException $e) {
681
-				throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
682
-			} catch (LockedException $e) {
683
-				throw new OCSNotFoundException($this->l->t('Could not lock path'));
684
-			}
685
-		}
686
-
687
-		$include_tags = $include_tags === 'true';
688
-
689
-		if ($shared_with_me === 'true') {
690
-			$result = $this->getSharedWithMe($path, $include_tags);
691
-			return $result;
692
-		}
693
-
694
-		if ($subfiles === 'true') {
695
-			$result = $this->getSharesInDir($path);
696
-			return $result;
697
-		}
698
-
699
-		if ($reshares === 'true') {
700
-			$reshares = true;
701
-		} else {
702
-			$reshares = false;
703
-		}
704
-
705
-		// Get all shares
706
-		$userShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $path, $reshares, -1, 0);
707
-		$groupShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0);
708
-		$linkShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0);
709
-		if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
710
-			$mailShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $path, $reshares, -1, 0);
711
-		} else {
712
-			$mailShares = [];
713
-		}
714
-		if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) {
715
-			$circleShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_CIRCLE, $path, $reshares, -1, 0);
716
-		} else {
717
-			$circleShares = [];
718
-		}
719
-		$roomShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_ROOM, $path, $reshares, -1, 0);
720
-
721
-		$shares = array_merge($userShares, $groupShares, $linkShares, $mailShares, $circleShares, $roomShares);
722
-
723
-		if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
724
-			$federatedShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0);
725
-			$shares = array_merge($shares, $federatedShares);
726
-		}
727
-
728
-		if ($this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
729
-			$federatedShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE_GROUP, $path, $reshares, -1, 0);
730
-			$shares = array_merge($shares, $federatedShares);
731
-		}
732
-
733
-		$formatted = [];
734
-		foreach ($shares as $share) {
735
-			try {
736
-				$formatted[] = $this->formatShare($share, $path);
737
-			} catch (NotFoundException $e) {
738
-				//Ignore share
739
-			}
740
-		}
741
-
742
-		if ($include_tags) {
743
-			$formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
744
-		}
745
-
746
-		return new DataResponse($formatted);
747
-	}
748
-
749
-	/**
750
-	 * @NoAdminRequired
751
-	 *
752
-	 * @param string $id
753
-	 * @param int $permissions
754
-	 * @param string $password
755
-	 * @param string $sendPasswordByTalk
756
-	 * @param string $publicUpload
757
-	 * @param string $expireDate
758
-	 * @param string $note
759
-	 * @param string $label
760
-	 * @param string $hideDownload
761
-	 * @return DataResponse
762
-	 * @throws LockedException
763
-	 * @throws NotFoundException
764
-	 * @throws OCSBadRequestException
765
-	 * @throws OCSForbiddenException
766
-	 * @throws OCSNotFoundException
767
-	 */
768
-	public function updateShare(
769
-		string $id,
770
-		int $permissions = null,
771
-		string $password = null,
772
-		string $sendPasswordByTalk = null,
773
-		string $publicUpload = null,
774
-		string $expireDate = null,
775
-		string $note = null,
776
-		string $label = null,
777
-		string $hideDownload = null
778
-	): DataResponse {
779
-		try {
780
-			$share = $this->getShareById($id);
781
-		} catch (ShareNotFound $e) {
782
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
783
-		}
784
-
785
-		$this->lock($share->getNode());
786
-
787
-		if (!$this->canAccessShare($share, false)) {
788
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
789
-		}
790
-
791
-		if ($permissions === null &&
792
-			$password === null &&
793
-			$sendPasswordByTalk === null &&
794
-			$publicUpload === null &&
795
-			$expireDate === null &&
796
-			$note === null &&
797
-			$label === null &&
798
-			$hideDownload === null
799
-		) {
800
-			throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
801
-		}
802
-
803
-		if($note !== null) {
804
-			$share->setNote($note);
805
-		}
806
-
807
-		/*
428
+        if ($path->getStorage()->instanceOfStorage(Storage::class)) {
429
+            $permissions &= ~($permissions & ~$path->getPermissions());
430
+        }
431
+
432
+        if ($shareType === Share::SHARE_TYPE_USER) {
433
+            // Valid user is required to share
434
+            if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
435
+                throw new OCSNotFoundException($this->l->t('Please specify a valid user'));
436
+            }
437
+            $share->setSharedWith($shareWith);
438
+            $share->setPermissions($permissions);
439
+        } else if ($shareType === Share::SHARE_TYPE_GROUP) {
440
+            if (!$this->shareManager->allowGroupSharing()) {
441
+                throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator'));
442
+            }
443
+
444
+            // Valid group is required to share
445
+            if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
446
+                throw new OCSNotFoundException($this->l->t('Please specify a valid group'));
447
+            }
448
+            $share->setSharedWith($shareWith);
449
+            $share->setPermissions($permissions);
450
+        } else if ($shareType === Share::SHARE_TYPE_LINK) {
451
+            //Can we even share links?
452
+            if (!$this->shareManager->shareApiAllowLinks()) {
453
+                throw new OCSNotFoundException($this->l->t('Public link sharing is disabled by the administrator'));
454
+            }
455
+
456
+            if ($publicUpload === 'true') {
457
+                // Check if public upload is allowed
458
+                if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
459
+                    throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
460
+                }
461
+
462
+                // Public upload can only be set for folders
463
+                if ($path instanceof \OCP\Files\File) {
464
+                    throw new OCSNotFoundException($this->l->t('Public upload is only possible for publicly shared folders'));
465
+                }
466
+
467
+                $share->setPermissions(
468
+                    Constants::PERMISSION_READ |
469
+                    Constants::PERMISSION_CREATE |
470
+                    Constants::PERMISSION_UPDATE |
471
+                    Constants::PERMISSION_DELETE
472
+                );
473
+            } else {
474
+                $share->setPermissions(Constants::PERMISSION_READ);
475
+            }
476
+
477
+            // Set password
478
+            if ($password !== '') {
479
+                $share->setPassword($password);
480
+            }
481
+
482
+
483
+            if (!empty($label)) {
484
+                $share->setLabel($label);
485
+            }
486
+
487
+            if ($sendPasswordByTalk === 'true') {
488
+                if (!$this->appManager->isEnabledForUser('spreed')) {
489
+                    throw new OCSForbiddenException($this->l->t('Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled', [$path->getPath()]));
490
+                }
491
+
492
+                $share->setSendPasswordByTalk(true);
493
+            }
494
+
495
+            //Expire date
496
+            if ($expireDate !== '') {
497
+                try {
498
+                    $expireDate = $this->parseDate($expireDate);
499
+                    $share->setExpirationDate($expireDate);
500
+                } catch (\Exception $e) {
501
+                    throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
502
+                }
503
+            }
504
+
505
+        } else if ($shareType === Share::SHARE_TYPE_REMOTE) {
506
+            if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
507
+                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]));
508
+            }
509
+
510
+            $share->setSharedWith($shareWith);
511
+            $share->setPermissions($permissions);
512
+        }  else if ($shareType === Share::SHARE_TYPE_REMOTE_GROUP) {
513
+            if (!$this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
514
+                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]));
515
+            }
516
+
517
+            $share->setSharedWith($shareWith);
518
+            $share->setPermissions($permissions);
519
+        } else if ($shareType === Share::SHARE_TYPE_EMAIL) {
520
+            if ($share->getNodeType() === 'file') {
521
+                $share->setPermissions(Constants::PERMISSION_READ);
522
+            } else {
523
+                $share->setPermissions($permissions);
524
+            }
525
+            $share->setSharedWith($shareWith);
526
+
527
+            if ($sendPasswordByTalk === 'true') {
528
+                if (!$this->appManager->isEnabledForUser('spreed')) {
529
+                    throw new OCSForbiddenException($this->l->t('Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled', [$path->getPath()]));
530
+                }
531
+
532
+                $share->setSendPasswordByTalk(true);
533
+            }
534
+        } else if ($shareType === Share::SHARE_TYPE_CIRCLE) {
535
+            if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) {
536
+                throw new OCSNotFoundException($this->l->t('You cannot share to a Circle if the app is not enabled'));
537
+            }
538
+
539
+            $circle = \OCA\Circles\Api\v1\Circles::detailsCircle($shareWith);
540
+
541
+            // Valid circle is required to share
542
+            if ($circle === null) {
543
+                throw new OCSNotFoundException($this->l->t('Please specify a valid circle'));
544
+            }
545
+            $share->setSharedWith($shareWith);
546
+            $share->setPermissions($permissions);
547
+        } else if ($shareType === Share::SHARE_TYPE_ROOM) {
548
+            try {
549
+                $this->getRoomShareHelper()->createShare($share, $shareWith, $permissions, $expireDate);
550
+            } catch (QueryException $e) {
551
+                throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not support room shares', [$path->getPath()]));
552
+            }
553
+        } else {
554
+            throw new OCSBadRequestException($this->l->t('Unknown share type'));
555
+        }
556
+
557
+        $share->setShareType($shareType);
558
+        $share->setSharedBy($this->currentUser);
559
+
560
+        try {
561
+            $share = $this->shareManager->createShare($share);
562
+        } catch (GenericShareException $e) {
563
+            $code = $e->getCode() === 0 ? 403 : $e->getCode();
564
+            throw new OCSException($e->getHint(), $code);
565
+        } catch (\Exception $e) {
566
+            throw new OCSForbiddenException($e->getMessage(), $e);
567
+        }
568
+
569
+        $output = $this->formatShare($share);
570
+
571
+        return new DataResponse($output);
572
+    }
573
+
574
+    /**
575
+     * @param \OCP\Files\File|\OCP\Files\Folder $node
576
+     * @param boolean $includeTags
577
+     * @return DataResponse
578
+     */
579
+    private function getSharedWithMe($node = null, bool $includeTags): DataResponse {
580
+
581
+        $userShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_USER, $node, -1, 0);
582
+        $groupShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_GROUP, $node, -1, 0);
583
+        $circleShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_CIRCLE, $node, -1, 0);
584
+        $roomShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_ROOM, $node, -1, 0);
585
+
586
+        $shares = array_merge($userShares, $groupShares, $circleShares, $roomShares);
587
+
588
+        $shares = array_filter($shares, function (IShare $share) {
589
+            return $share->getShareOwner() !== $this->currentUser;
590
+        });
591
+
592
+        $formatted = [];
593
+        foreach ($shares as $share) {
594
+            if ($this->canAccessShare($share)) {
595
+                try {
596
+                    $formatted[] = $this->formatShare($share);
597
+                } catch (NotFoundException $e) {
598
+                    // Ignore this share
599
+                }
600
+            }
601
+        }
602
+
603
+        if ($includeTags) {
604
+            $formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
605
+        }
606
+
607
+        return new DataResponse($formatted);
608
+    }
609
+
610
+    /**
611
+     * @param \OCP\Files\Folder $folder
612
+     * @return DataResponse
613
+     * @throws OCSBadRequestException
614
+     */
615
+    private function getSharesInDir(Node $folder): DataResponse {
616
+        if (!($folder instanceof \OCP\Files\Folder)) {
617
+            throw new OCSBadRequestException($this->l->t('Not a directory'));
618
+        }
619
+
620
+        $nodes = $folder->getDirectoryListing();
621
+        /** @var \OCP\Share\IShare[] $shares */
622
+        $shares = [];
623
+        foreach ($nodes as $node) {
624
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $node, false, -1, 0));
625
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
626
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $node, false, -1, 0));
627
+            if($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
628
+                $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $node, false, -1, 0));
629
+            }
630
+            if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
631
+                $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE, $node, false, -1, 0));
632
+            }
633
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_ROOM, $node, false, -1, 0));
634
+        }
635
+
636
+        $formatted = [];
637
+        foreach ($shares as $share) {
638
+            try {
639
+                $formatted[] = $this->formatShare($share);
640
+            } catch (NotFoundException $e) {
641
+                //Ignore this share
642
+            }
643
+        }
644
+
645
+        return new DataResponse($formatted);
646
+    }
647
+
648
+    /**
649
+     * The getShares function.
650
+     *
651
+     * @NoAdminRequired
652
+     *
653
+     * @param string $shared_with_me
654
+     * @param string $reshares
655
+     * @param string $subfiles
656
+     * @param string $path
657
+     *
658
+     * - Get shares by the current user
659
+     * - Get shares by the current user and reshares (?reshares=true)
660
+     * - Get shares with the current user (?shared_with_me=true)
661
+     * - Get shares for a specific path (?path=...)
662
+     * - Get all shares in a folder (?subfiles=true&path=..)
663
+     *
664
+     * @return DataResponse
665
+     * @throws OCSNotFoundException
666
+     */
667
+    public function getShares(
668
+        string $shared_with_me = 'false',
669
+        string $reshares = 'false',
670
+        string $subfiles = 'false',
671
+        string $path = null,
672
+        string $include_tags = 'false'
673
+    ): DataResponse {
674
+
675
+        if ($path !== null) {
676
+            $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
677
+            try {
678
+                $path = $userFolder->get($path);
679
+                $this->lock($path);
680
+            } catch (\OCP\Files\NotFoundException $e) {
681
+                throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
682
+            } catch (LockedException $e) {
683
+                throw new OCSNotFoundException($this->l->t('Could not lock path'));
684
+            }
685
+        }
686
+
687
+        $include_tags = $include_tags === 'true';
688
+
689
+        if ($shared_with_me === 'true') {
690
+            $result = $this->getSharedWithMe($path, $include_tags);
691
+            return $result;
692
+        }
693
+
694
+        if ($subfiles === 'true') {
695
+            $result = $this->getSharesInDir($path);
696
+            return $result;
697
+        }
698
+
699
+        if ($reshares === 'true') {
700
+            $reshares = true;
701
+        } else {
702
+            $reshares = false;
703
+        }
704
+
705
+        // Get all shares
706
+        $userShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $path, $reshares, -1, 0);
707
+        $groupShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0);
708
+        $linkShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0);
709
+        if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
710
+            $mailShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $path, $reshares, -1, 0);
711
+        } else {
712
+            $mailShares = [];
713
+        }
714
+        if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) {
715
+            $circleShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_CIRCLE, $path, $reshares, -1, 0);
716
+        } else {
717
+            $circleShares = [];
718
+        }
719
+        $roomShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_ROOM, $path, $reshares, -1, 0);
720
+
721
+        $shares = array_merge($userShares, $groupShares, $linkShares, $mailShares, $circleShares, $roomShares);
722
+
723
+        if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
724
+            $federatedShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0);
725
+            $shares = array_merge($shares, $federatedShares);
726
+        }
727
+
728
+        if ($this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
729
+            $federatedShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE_GROUP, $path, $reshares, -1, 0);
730
+            $shares = array_merge($shares, $federatedShares);
731
+        }
732
+
733
+        $formatted = [];
734
+        foreach ($shares as $share) {
735
+            try {
736
+                $formatted[] = $this->formatShare($share, $path);
737
+            } catch (NotFoundException $e) {
738
+                //Ignore share
739
+            }
740
+        }
741
+
742
+        if ($include_tags) {
743
+            $formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
744
+        }
745
+
746
+        return new DataResponse($formatted);
747
+    }
748
+
749
+    /**
750
+     * @NoAdminRequired
751
+     *
752
+     * @param string $id
753
+     * @param int $permissions
754
+     * @param string $password
755
+     * @param string $sendPasswordByTalk
756
+     * @param string $publicUpload
757
+     * @param string $expireDate
758
+     * @param string $note
759
+     * @param string $label
760
+     * @param string $hideDownload
761
+     * @return DataResponse
762
+     * @throws LockedException
763
+     * @throws NotFoundException
764
+     * @throws OCSBadRequestException
765
+     * @throws OCSForbiddenException
766
+     * @throws OCSNotFoundException
767
+     */
768
+    public function updateShare(
769
+        string $id,
770
+        int $permissions = null,
771
+        string $password = null,
772
+        string $sendPasswordByTalk = null,
773
+        string $publicUpload = null,
774
+        string $expireDate = null,
775
+        string $note = null,
776
+        string $label = null,
777
+        string $hideDownload = null
778
+    ): DataResponse {
779
+        try {
780
+            $share = $this->getShareById($id);
781
+        } catch (ShareNotFound $e) {
782
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
783
+        }
784
+
785
+        $this->lock($share->getNode());
786
+
787
+        if (!$this->canAccessShare($share, false)) {
788
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
789
+        }
790
+
791
+        if ($permissions === null &&
792
+            $password === null &&
793
+            $sendPasswordByTalk === null &&
794
+            $publicUpload === null &&
795
+            $expireDate === null &&
796
+            $note === null &&
797
+            $label === null &&
798
+            $hideDownload === null
799
+        ) {
800
+            throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
801
+        }
802
+
803
+        if($note !== null) {
804
+            $share->setNote($note);
805
+        }
806
+
807
+        /*
808 808
 		 * expirationdate, password and publicUpload only make sense for link shares
809 809
 		 */
810
-		if ($share->getShareType() === Share::SHARE_TYPE_LINK) {
811
-
812
-			// Update hide download state
813
-			if ($hideDownload === 'true') {
814
-				$share->setHideDownload(true);
815
-			} else if ($hideDownload === 'false') {
816
-				$share->setHideDownload(false);
817
-			}
818
-
819
-			$newPermissions = null;
820
-			if ($publicUpload === 'true') {
821
-				$newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
822
-			} else if ($publicUpload === 'false') {
823
-				$newPermissions = Constants::PERMISSION_READ;
824
-			}
825
-
826
-			if ($permissions !== null) {
827
-				$newPermissions = (int)$permissions;
828
-				$newPermissions = $newPermissions & ~Constants::PERMISSION_SHARE;
829
-			}
830
-
831
-			if ($newPermissions !== null &&
832
-				!in_array($newPermissions, [
833
-					Constants::PERMISSION_READ,
834
-					Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE, // legacy
835
-					Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE, // correct
836
-					Constants::PERMISSION_CREATE, // hidden file list
837
-					Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE, // allow to edit single files
838
-				], true)
839
-			) {
840
-				throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links'));
841
-			}
842
-
843
-			if (
844
-				// legacy
845
-				$newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE) ||
846
-				// correct
847
-				$newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE)
848
-			) {
849
-				if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
850
-					throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
851
-				}
852
-
853
-				if (!($share->getNode() instanceof \OCP\Files\Folder)) {
854
-					throw new OCSBadRequestException($this->l->t('Public upload is only possible for publicly shared folders'));
855
-				}
856
-
857
-				// normalize to correct public upload permissions
858
-				$newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
859
-			}
860
-
861
-			if ($newPermissions !== null) {
862
-				$share->setPermissions($newPermissions);
863
-				$permissions = $newPermissions;
864
-			}
865
-
866
-			if ($expireDate === '') {
867
-				$share->setExpirationDate(null);
868
-			} else if ($expireDate !== null) {
869
-				try {
870
-					$expireDate = $this->parseDate($expireDate);
871
-				} catch (\Exception $e) {
872
-					throw new OCSBadRequestException($e->getMessage(), $e);
873
-				}
874
-				$share->setExpirationDate($expireDate);
875
-			}
876
-
877
-			if ($password === '') {
878
-				$share->setPassword(null);
879
-			} else if ($password !== null) {
880
-				$share->setPassword($password);
881
-			}
882
-
883
-			if ($label !== null) {
884
-				$share->setLabel($label);
885
-			}
886
-
887
-			if ($sendPasswordByTalk === 'true') {
888
-				if (!$this->appManager->isEnabledForUser('spreed')) {
889
-					throw new OCSForbiddenException($this->l->t('Sharing sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled'));
890
-				}
891
-
892
-				$share->setSendPasswordByTalk(true);
893
-			} else if ($sendPasswordByTalk !== null) {
894
-				$share->setSendPasswordByTalk(false);
895
-			}
896
-		} else {
897
-			if ($permissions !== null) {
898
-				$permissions = (int)$permissions;
899
-				$share->setPermissions($permissions);
900
-			}
901
-
902
-			if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) {
903
-				if ($password === '') {
904
-					$share->setPassword(null);
905
-				} else if ($password !== null) {
906
-					$share->setPassword($password);
907
-				}
908
-
909
-				if ($sendPasswordByTalk === 'true') {
910
-					if (!$this->appManager->isEnabledForUser('spreed')) {
911
-						throw new OCSForbiddenException($this->l->t('Sharing sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled'));
912
-					}
913
-
914
-					$share->setSendPasswordByTalk(true);
915
-				} else {
916
-					$share->setSendPasswordByTalk(false);
917
-				}
918
-			}
919
-
920
-			if ($expireDate === '') {
921
-				$share->setExpirationDate(null);
922
-			} else if ($expireDate !== null) {
923
-				try {
924
-					$expireDate = $this->parseDate($expireDate);
925
-				} catch (\Exception $e) {
926
-					throw new OCSBadRequestException($e->getMessage(), $e);
927
-				}
928
-				$share->setExpirationDate($expireDate);
929
-			}
930
-
931
-		}
932
-
933
-		if ($permissions !== null && $share->getShareOwner() !== $this->currentUser) {
934
-			/* Check if this is an incomming share */
935
-			$incomingShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_USER, $share->getNode(), -1, 0);
936
-			$incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0));
937
-			$incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_ROOM, $share->getNode(), -1, 0));
938
-
939
-			/** @var \OCP\Share\IShare[] $incomingShares */
940
-			if (!empty($incomingShares)) {
941
-				$maxPermissions = 0;
942
-				foreach ($incomingShares as $incomingShare) {
943
-					$maxPermissions |= $incomingShare->getPermissions();
944
-				}
945
-
946
-				if ($share->getPermissions() & ~$maxPermissions) {
947
-					throw new OCSNotFoundException($this->l->t('Cannot increase permissions'));
948
-				}
949
-			}
950
-		}
951
-
952
-
953
-		try {
954
-			$share = $this->shareManager->updateShare($share);
955
-		} catch (\Exception $e) {
956
-			throw new OCSBadRequestException($e->getMessage(), $e);
957
-		}
958
-
959
-		return new DataResponse($this->formatShare($share));
960
-	}
961
-
962
-	/**
963
-	 * @suppress PhanUndeclaredClassMethod
964
-	 */
965
-	protected function canAccessShare(\OCP\Share\IShare $share, bool $checkGroups = true): bool {
966
-		// A file with permissions 0 can't be accessed by us. So Don't show it
967
-		if ($share->getPermissions() === 0) {
968
-			return false;
969
-		}
970
-
971
-		// Owner of the file and the sharer of the file can always get share
972
-		if ($share->getShareOwner() === $this->currentUser ||
973
-			$share->getSharedBy() === $this->currentUser
974
-		) {
975
-			return true;
976
-		}
977
-
978
-		// If the share is shared with you (or a group you are a member of)
979
-		if ($share->getShareType() === Share::SHARE_TYPE_USER &&
980
-			$share->getSharedWith() === $this->currentUser
981
-		) {
982
-			return true;
983
-		}
984
-
985
-		if ($checkGroups && $share->getShareType() === Share::SHARE_TYPE_GROUP) {
986
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
987
-			$user = $this->userManager->get($this->currentUser);
988
-			if ($user !== null && $sharedWith !== null && $sharedWith->inGroup($user)) {
989
-				return true;
990
-			}
991
-		}
992
-
993
-		if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) {
994
-			// TODO: have a sanity check like above?
995
-			return true;
996
-		}
997
-
998
-		if ($share->getShareType() === Share::SHARE_TYPE_ROOM) {
999
-			try {
1000
-				return $this->getRoomShareHelper()->canAccessShare($share, $this->currentUser);
1001
-			} catch (QueryException $e) {
1002
-				return false;
1003
-			}
1004
-		}
1005
-
1006
-		return false;
1007
-	}
1008
-
1009
-	/**
1010
-	 * Make sure that the passed date is valid ISO 8601
1011
-	 * So YYYY-MM-DD
1012
-	 * If not throw an exception
1013
-	 *
1014
-	 * @param string $expireDate
1015
-	 *
1016
-	 * @throws \Exception
1017
-	 * @return \DateTime
1018
-	 */
1019
-	private function parseDate(string $expireDate): \DateTime {
1020
-		try {
1021
-			$date = new \DateTime($expireDate);
1022
-		} catch (\Exception $e) {
1023
-			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
1024
-		}
1025
-
1026
-		if ($date === false) {
1027
-			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
1028
-		}
1029
-
1030
-		$date->setTime(0, 0, 0);
1031
-
1032
-		return $date;
1033
-	}
1034
-
1035
-	/**
1036
-	 * Since we have multiple providers but the OCS Share API v1 does
1037
-	 * not support this we need to check all backends.
1038
-	 *
1039
-	 * @param string $id
1040
-	 * @return \OCP\Share\IShare
1041
-	 * @throws ShareNotFound
1042
-	 */
1043
-	private function getShareById(string $id): IShare {
1044
-		$share = null;
1045
-
1046
-		// First check if it is an internal share.
1047
-		try {
1048
-			$share = $this->shareManager->getShareById('ocinternal:' . $id, $this->currentUser);
1049
-			return $share;
1050
-		} catch (ShareNotFound $e) {
1051
-			// Do nothing, just try the other share type
1052
-		}
1053
-
1054
-
1055
-		try {
1056
-			if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) {
1057
-				$share = $this->shareManager->getShareById('ocCircleShare:' . $id, $this->currentUser);
1058
-				return $share;
1059
-			}
1060
-		} catch (ShareNotFound $e) {
1061
-			// Do nothing, just try the other share type
1062
-		}
1063
-
1064
-		try {
1065
-			if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
1066
-				$share = $this->shareManager->getShareById('ocMailShare:' . $id, $this->currentUser);
1067
-				return $share;
1068
-			}
1069
-		} catch (ShareNotFound $e) {
1070
-			// Do nothing, just try the other share type
1071
-		}
1072
-
1073
-		try {
1074
-			$share = $this->shareManager->getShareById('ocRoomShare:' . $id, $this->currentUser);
1075
-			return $share;
1076
-		} catch (ShareNotFound $e) {
1077
-			// Do nothing, just try the other share type
1078
-		}
1079
-
1080
-		if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
1081
-			throw new ShareNotFound();
1082
-		}
1083
-		$share = $this->shareManager->getShareById('ocFederatedSharing:' . $id, $this->currentUser);
1084
-
1085
-		return $share;
1086
-	}
1087
-
1088
-	/**
1089
-	 * Lock a Node
1090
-	 *
1091
-	 * @param \OCP\Files\Node $node
1092
-	 * @throws LockedException
1093
-	 */
1094
-	private function lock(\OCP\Files\Node $node) {
1095
-		$node->lock(ILockingProvider::LOCK_SHARED);
1096
-		$this->lockedNode = $node;
1097
-	}
1098
-
1099
-	/**
1100
-	 * Cleanup the remaining locks
1101
-	 * @throws @LockedException
1102
-	 */
1103
-	public function cleanup() {
1104
-		if ($this->lockedNode !== null) {
1105
-			$this->lockedNode->unlock(ILockingProvider::LOCK_SHARED);
1106
-		}
1107
-	}
1108
-
1109
-	/**
1110
-	 * Returns the helper of ShareAPIController for room shares.
1111
-	 *
1112
-	 * If the Talk application is not enabled or the helper is not available
1113
-	 * a QueryException is thrown instead.
1114
-	 *
1115
-	 * @return \OCA\Spreed\Share\Helper\ShareAPIController
1116
-	 * @throws QueryException
1117
-	 */
1118
-	private function getRoomShareHelper() {
1119
-		if (!$this->appManager->isEnabledForUser('spreed')) {
1120
-			throw new QueryException();
1121
-		}
1122
-
1123
-		return $this->serverContainer->query('\OCA\Spreed\Share\Helper\ShareAPIController');
1124
-	}
810
+        if ($share->getShareType() === Share::SHARE_TYPE_LINK) {
811
+
812
+            // Update hide download state
813
+            if ($hideDownload === 'true') {
814
+                $share->setHideDownload(true);
815
+            } else if ($hideDownload === 'false') {
816
+                $share->setHideDownload(false);
817
+            }
818
+
819
+            $newPermissions = null;
820
+            if ($publicUpload === 'true') {
821
+                $newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
822
+            } else if ($publicUpload === 'false') {
823
+                $newPermissions = Constants::PERMISSION_READ;
824
+            }
825
+
826
+            if ($permissions !== null) {
827
+                $newPermissions = (int)$permissions;
828
+                $newPermissions = $newPermissions & ~Constants::PERMISSION_SHARE;
829
+            }
830
+
831
+            if ($newPermissions !== null &&
832
+                !in_array($newPermissions, [
833
+                    Constants::PERMISSION_READ,
834
+                    Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE, // legacy
835
+                    Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE, // correct
836
+                    Constants::PERMISSION_CREATE, // hidden file list
837
+                    Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE, // allow to edit single files
838
+                ], true)
839
+            ) {
840
+                throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links'));
841
+            }
842
+
843
+            if (
844
+                // legacy
845
+                $newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE) ||
846
+                // correct
847
+                $newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE)
848
+            ) {
849
+                if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
850
+                    throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
851
+                }
852
+
853
+                if (!($share->getNode() instanceof \OCP\Files\Folder)) {
854
+                    throw new OCSBadRequestException($this->l->t('Public upload is only possible for publicly shared folders'));
855
+                }
856
+
857
+                // normalize to correct public upload permissions
858
+                $newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
859
+            }
860
+
861
+            if ($newPermissions !== null) {
862
+                $share->setPermissions($newPermissions);
863
+                $permissions = $newPermissions;
864
+            }
865
+
866
+            if ($expireDate === '') {
867
+                $share->setExpirationDate(null);
868
+            } else if ($expireDate !== null) {
869
+                try {
870
+                    $expireDate = $this->parseDate($expireDate);
871
+                } catch (\Exception $e) {
872
+                    throw new OCSBadRequestException($e->getMessage(), $e);
873
+                }
874
+                $share->setExpirationDate($expireDate);
875
+            }
876
+
877
+            if ($password === '') {
878
+                $share->setPassword(null);
879
+            } else if ($password !== null) {
880
+                $share->setPassword($password);
881
+            }
882
+
883
+            if ($label !== null) {
884
+                $share->setLabel($label);
885
+            }
886
+
887
+            if ($sendPasswordByTalk === 'true') {
888
+                if (!$this->appManager->isEnabledForUser('spreed')) {
889
+                    throw new OCSForbiddenException($this->l->t('Sharing sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled'));
890
+                }
891
+
892
+                $share->setSendPasswordByTalk(true);
893
+            } else if ($sendPasswordByTalk !== null) {
894
+                $share->setSendPasswordByTalk(false);
895
+            }
896
+        } else {
897
+            if ($permissions !== null) {
898
+                $permissions = (int)$permissions;
899
+                $share->setPermissions($permissions);
900
+            }
901
+
902
+            if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) {
903
+                if ($password === '') {
904
+                    $share->setPassword(null);
905
+                } else if ($password !== null) {
906
+                    $share->setPassword($password);
907
+                }
908
+
909
+                if ($sendPasswordByTalk === 'true') {
910
+                    if (!$this->appManager->isEnabledForUser('spreed')) {
911
+                        throw new OCSForbiddenException($this->l->t('Sharing sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled'));
912
+                    }
913
+
914
+                    $share->setSendPasswordByTalk(true);
915
+                } else {
916
+                    $share->setSendPasswordByTalk(false);
917
+                }
918
+            }
919
+
920
+            if ($expireDate === '') {
921
+                $share->setExpirationDate(null);
922
+            } else if ($expireDate !== null) {
923
+                try {
924
+                    $expireDate = $this->parseDate($expireDate);
925
+                } catch (\Exception $e) {
926
+                    throw new OCSBadRequestException($e->getMessage(), $e);
927
+                }
928
+                $share->setExpirationDate($expireDate);
929
+            }
930
+
931
+        }
932
+
933
+        if ($permissions !== null && $share->getShareOwner() !== $this->currentUser) {
934
+            /* Check if this is an incomming share */
935
+            $incomingShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_USER, $share->getNode(), -1, 0);
936
+            $incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0));
937
+            $incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_ROOM, $share->getNode(), -1, 0));
938
+
939
+            /** @var \OCP\Share\IShare[] $incomingShares */
940
+            if (!empty($incomingShares)) {
941
+                $maxPermissions = 0;
942
+                foreach ($incomingShares as $incomingShare) {
943
+                    $maxPermissions |= $incomingShare->getPermissions();
944
+                }
945
+
946
+                if ($share->getPermissions() & ~$maxPermissions) {
947
+                    throw new OCSNotFoundException($this->l->t('Cannot increase permissions'));
948
+                }
949
+            }
950
+        }
951
+
952
+
953
+        try {
954
+            $share = $this->shareManager->updateShare($share);
955
+        } catch (\Exception $e) {
956
+            throw new OCSBadRequestException($e->getMessage(), $e);
957
+        }
958
+
959
+        return new DataResponse($this->formatShare($share));
960
+    }
961
+
962
+    /**
963
+     * @suppress PhanUndeclaredClassMethod
964
+     */
965
+    protected function canAccessShare(\OCP\Share\IShare $share, bool $checkGroups = true): bool {
966
+        // A file with permissions 0 can't be accessed by us. So Don't show it
967
+        if ($share->getPermissions() === 0) {
968
+            return false;
969
+        }
970
+
971
+        // Owner of the file and the sharer of the file can always get share
972
+        if ($share->getShareOwner() === $this->currentUser ||
973
+            $share->getSharedBy() === $this->currentUser
974
+        ) {
975
+            return true;
976
+        }
977
+
978
+        // If the share is shared with you (or a group you are a member of)
979
+        if ($share->getShareType() === Share::SHARE_TYPE_USER &&
980
+            $share->getSharedWith() === $this->currentUser
981
+        ) {
982
+            return true;
983
+        }
984
+
985
+        if ($checkGroups && $share->getShareType() === Share::SHARE_TYPE_GROUP) {
986
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
987
+            $user = $this->userManager->get($this->currentUser);
988
+            if ($user !== null && $sharedWith !== null && $sharedWith->inGroup($user)) {
989
+                return true;
990
+            }
991
+        }
992
+
993
+        if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) {
994
+            // TODO: have a sanity check like above?
995
+            return true;
996
+        }
997
+
998
+        if ($share->getShareType() === Share::SHARE_TYPE_ROOM) {
999
+            try {
1000
+                return $this->getRoomShareHelper()->canAccessShare($share, $this->currentUser);
1001
+            } catch (QueryException $e) {
1002
+                return false;
1003
+            }
1004
+        }
1005
+
1006
+        return false;
1007
+    }
1008
+
1009
+    /**
1010
+     * Make sure that the passed date is valid ISO 8601
1011
+     * So YYYY-MM-DD
1012
+     * If not throw an exception
1013
+     *
1014
+     * @param string $expireDate
1015
+     *
1016
+     * @throws \Exception
1017
+     * @return \DateTime
1018
+     */
1019
+    private function parseDate(string $expireDate): \DateTime {
1020
+        try {
1021
+            $date = new \DateTime($expireDate);
1022
+        } catch (\Exception $e) {
1023
+            throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
1024
+        }
1025
+
1026
+        if ($date === false) {
1027
+            throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
1028
+        }
1029
+
1030
+        $date->setTime(0, 0, 0);
1031
+
1032
+        return $date;
1033
+    }
1034
+
1035
+    /**
1036
+     * Since we have multiple providers but the OCS Share API v1 does
1037
+     * not support this we need to check all backends.
1038
+     *
1039
+     * @param string $id
1040
+     * @return \OCP\Share\IShare
1041
+     * @throws ShareNotFound
1042
+     */
1043
+    private function getShareById(string $id): IShare {
1044
+        $share = null;
1045
+
1046
+        // First check if it is an internal share.
1047
+        try {
1048
+            $share = $this->shareManager->getShareById('ocinternal:' . $id, $this->currentUser);
1049
+            return $share;
1050
+        } catch (ShareNotFound $e) {
1051
+            // Do nothing, just try the other share type
1052
+        }
1053
+
1054
+
1055
+        try {
1056
+            if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) {
1057
+                $share = $this->shareManager->getShareById('ocCircleShare:' . $id, $this->currentUser);
1058
+                return $share;
1059
+            }
1060
+        } catch (ShareNotFound $e) {
1061
+            // Do nothing, just try the other share type
1062
+        }
1063
+
1064
+        try {
1065
+            if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
1066
+                $share = $this->shareManager->getShareById('ocMailShare:' . $id, $this->currentUser);
1067
+                return $share;
1068
+            }
1069
+        } catch (ShareNotFound $e) {
1070
+            // Do nothing, just try the other share type
1071
+        }
1072
+
1073
+        try {
1074
+            $share = $this->shareManager->getShareById('ocRoomShare:' . $id, $this->currentUser);
1075
+            return $share;
1076
+        } catch (ShareNotFound $e) {
1077
+            // Do nothing, just try the other share type
1078
+        }
1079
+
1080
+        if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
1081
+            throw new ShareNotFound();
1082
+        }
1083
+        $share = $this->shareManager->getShareById('ocFederatedSharing:' . $id, $this->currentUser);
1084
+
1085
+        return $share;
1086
+    }
1087
+
1088
+    /**
1089
+     * Lock a Node
1090
+     *
1091
+     * @param \OCP\Files\Node $node
1092
+     * @throws LockedException
1093
+     */
1094
+    private function lock(\OCP\Files\Node $node) {
1095
+        $node->lock(ILockingProvider::LOCK_SHARED);
1096
+        $this->lockedNode = $node;
1097
+    }
1098
+
1099
+    /**
1100
+     * Cleanup the remaining locks
1101
+     * @throws @LockedException
1102
+     */
1103
+    public function cleanup() {
1104
+        if ($this->lockedNode !== null) {
1105
+            $this->lockedNode->unlock(ILockingProvider::LOCK_SHARED);
1106
+        }
1107
+    }
1108
+
1109
+    /**
1110
+     * Returns the helper of ShareAPIController for room shares.
1111
+     *
1112
+     * If the Talk application is not enabled or the helper is not available
1113
+     * a QueryException is thrown instead.
1114
+     *
1115
+     * @return \OCA\Spreed\Share\Helper\ShareAPIController
1116
+     * @throws QueryException
1117
+     */
1118
+    private function getRoomShareHelper() {
1119
+        if (!$this->appManager->isEnabledForUser('spreed')) {
1120
+            throw new QueryException();
1121
+        }
1122
+
1123
+        return $this->serverContainer->query('\OCA\Spreed\Share\Helper\ShareAPIController');
1124
+    }
1125 1125
 }
Please login to merge, or discard this patch.
Spacing   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -234,14 +234,14 @@  discard block
 block discarded – undo
234 234
 
235 235
 			$result['share_with_displayname'] = $share->getSharedWithDisplayName();
236 236
 			if (empty($result['share_with_displayname'])) {
237
-				$displayNameLength = ($hasCircleId? strrpos($share->getSharedWith(), ' '): strlen($share->getSharedWith()));
237
+				$displayNameLength = ($hasCircleId ? strrpos($share->getSharedWith(), ' ') : strlen($share->getSharedWith()));
238 238
 				$result['share_with_displayname'] = substr($share->getSharedWith(), 0, $displayNameLength);
239 239
 			}
240 240
 
241 241
 			$result['share_with_avatar'] = $share->getSharedWithAvatar();
242 242
 
243
-			$shareWithStart = ($hasCircleId? strrpos($share->getSharedWith(), '[') + 1: 0);
244
-			$shareWithLength = ($hasCircleId? -1: strpos($share->getSharedWith(), ' '));
243
+			$shareWithStart = ($hasCircleId ? strrpos($share->getSharedWith(), '[') + 1 : 0);
244
+			$shareWithLength = ($hasCircleId ? -1 : strpos($share->getSharedWith(), ' '));
245 245
 			$result['share_with'] = substr($share->getSharedWith(), $shareWithStart, $shareWithLength);
246 246
 		} else if ($share->getShareType() === Share::SHARE_TYPE_ROOM) {
247 247
 			$result['share_with'] = $share->getSharedWith();
@@ -272,7 +272,7 @@  discard block
 block discarded – undo
272 272
 		// FIXME: If we inject the contacts manager it gets initialized bofore any address books are registered
273 273
 		$result = \OC::$server->getContactsManager()->search($query, [$property]);
274 274
 		foreach ($result as $r) {
275
-			foreach($r[$property] as $value) {
275
+			foreach ($r[$property] as $value) {
276 276
 				if ($value === $query) {
277 277
 					return $r['FN'];
278 278
 				}
@@ -509,7 +509,7 @@  discard block
 block discarded – undo
509 509
 
510 510
 			$share->setSharedWith($shareWith);
511 511
 			$share->setPermissions($permissions);
512
-		}  else if ($shareType === Share::SHARE_TYPE_REMOTE_GROUP) {
512
+		} else if ($shareType === Share::SHARE_TYPE_REMOTE_GROUP) {
513 513
 			if (!$this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
514 514
 				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]));
515 515
 			}
@@ -585,7 +585,7 @@  discard block
 block discarded – undo
585 585
 
586 586
 		$shares = array_merge($userShares, $groupShares, $circleShares, $roomShares);
587 587
 
588
-		$shares = array_filter($shares, function (IShare $share) {
588
+		$shares = array_filter($shares, function(IShare $share) {
589 589
 			return $share->getShareOwner() !== $this->currentUser;
590 590
 		});
591 591
 
@@ -624,7 +624,7 @@  discard block
 block discarded – undo
624 624
 			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $node, false, -1, 0));
625 625
 			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
626 626
 			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $node, false, -1, 0));
627
-			if($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
627
+			if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
628 628
 				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $node, false, -1, 0));
629 629
 			}
630 630
 			if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
@@ -800,7 +800,7 @@  discard block
 block discarded – undo
800 800
 			throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
801 801
 		}
802 802
 
803
-		if($note !== null) {
803
+		if ($note !== null) {
804 804
 			$share->setNote($note);
805 805
 		}
806 806
 
@@ -824,7 +824,7 @@  discard block
 block discarded – undo
824 824
 			}
825 825
 
826 826
 			if ($permissions !== null) {
827
-				$newPermissions = (int)$permissions;
827
+				$newPermissions = (int) $permissions;
828 828
 				$newPermissions = $newPermissions & ~Constants::PERMISSION_SHARE;
829 829
 			}
830 830
 
@@ -895,7 +895,7 @@  discard block
 block discarded – undo
895 895
 			}
896 896
 		} else {
897 897
 			if ($permissions !== null) {
898
-				$permissions = (int)$permissions;
898
+				$permissions = (int) $permissions;
899 899
 				$share->setPermissions($permissions);
900 900
 			}
901 901
 
@@ -1045,7 +1045,7 @@  discard block
 block discarded – undo
1045 1045
 
1046 1046
 		// First check if it is an internal share.
1047 1047
 		try {
1048
-			$share = $this->shareManager->getShareById('ocinternal:' . $id, $this->currentUser);
1048
+			$share = $this->shareManager->getShareById('ocinternal:'.$id, $this->currentUser);
1049 1049
 			return $share;
1050 1050
 		} catch (ShareNotFound $e) {
1051 1051
 			// Do nothing, just try the other share type
@@ -1054,7 +1054,7 @@  discard block
 block discarded – undo
1054 1054
 
1055 1055
 		try {
1056 1056
 			if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) {
1057
-				$share = $this->shareManager->getShareById('ocCircleShare:' . $id, $this->currentUser);
1057
+				$share = $this->shareManager->getShareById('ocCircleShare:'.$id, $this->currentUser);
1058 1058
 				return $share;
1059 1059
 			}
1060 1060
 		} catch (ShareNotFound $e) {
@@ -1063,7 +1063,7 @@  discard block
 block discarded – undo
1063 1063
 
1064 1064
 		try {
1065 1065
 			if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
1066
-				$share = $this->shareManager->getShareById('ocMailShare:' . $id, $this->currentUser);
1066
+				$share = $this->shareManager->getShareById('ocMailShare:'.$id, $this->currentUser);
1067 1067
 				return $share;
1068 1068
 			}
1069 1069
 		} catch (ShareNotFound $e) {
@@ -1071,7 +1071,7 @@  discard block
 block discarded – undo
1071 1071
 		}
1072 1072
 
1073 1073
 		try {
1074
-			$share = $this->shareManager->getShareById('ocRoomShare:' . $id, $this->currentUser);
1074
+			$share = $this->shareManager->getShareById('ocRoomShare:'.$id, $this->currentUser);
1075 1075
 			return $share;
1076 1076
 		} catch (ShareNotFound $e) {
1077 1077
 			// Do nothing, just try the other share type
@@ -1080,7 +1080,7 @@  discard block
 block discarded – undo
1080 1080
 		if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
1081 1081
 			throw new ShareNotFound();
1082 1082
 		}
1083
-		$share = $this->shareManager->getShareById('ocFederatedSharing:' . $id, $this->currentUser);
1083
+		$share = $this->shareManager->getShareById('ocFederatedSharing:'.$id, $this->currentUser);
1084 1084
 
1085 1085
 		return $share;
1086 1086
 	}
Please login to merge, or discard this patch.