Completed
Push — stable13 ( 0d6027...cebd51 )
by Morris
10:43
created
lib/private/Share20/DefaultShareProvider.php 1 patch
Indentation   +1107 added lines, -1107 removed lines patch added patch discarded remove patch
@@ -52,1144 +52,1144 @@
 block discarded – undo
52 52
  */
53 53
 class DefaultShareProvider implements IShareProvider {
54 54
 
55
-	// Special share type for user modified group shares
56
-	const SHARE_TYPE_USERGROUP = 2;
57
-
58
-	/** @var IDBConnection */
59
-	private $dbConn;
60
-
61
-	/** @var IUserManager */
62
-	private $userManager;
63
-
64
-	/** @var IGroupManager */
65
-	private $groupManager;
66
-
67
-	/** @var IRootFolder */
68
-	private $rootFolder;
69
-
70
-	/**
71
-	 * DefaultShareProvider constructor.
72
-	 *
73
-	 * @param IDBConnection $connection
74
-	 * @param IUserManager $userManager
75
-	 * @param IGroupManager $groupManager
76
-	 * @param IRootFolder $rootFolder
77
-	 */
78
-	public function __construct(
79
-			IDBConnection $connection,
80
-			IUserManager $userManager,
81
-			IGroupManager $groupManager,
82
-			IRootFolder $rootFolder) {
83
-		$this->dbConn = $connection;
84
-		$this->userManager = $userManager;
85
-		$this->groupManager = $groupManager;
86
-		$this->rootFolder = $rootFolder;
87
-	}
88
-
89
-	/**
90
-	 * Return the identifier of this provider.
91
-	 *
92
-	 * @return string Containing only [a-zA-Z0-9]
93
-	 */
94
-	public function identifier() {
95
-		return 'ocinternal';
96
-	}
97
-
98
-	/**
99
-	 * Share a path
100
-	 *
101
-	 * @param \OCP\Share\IShare $share
102
-	 * @return \OCP\Share\IShare The share object
103
-	 * @throws ShareNotFound
104
-	 * @throws \Exception
105
-	 */
106
-	public function create(\OCP\Share\IShare $share) {
107
-		$qb = $this->dbConn->getQueryBuilder();
108
-
109
-		$qb->insert('share');
110
-		$qb->setValue('share_type', $qb->createNamedParameter($share->getShareType()));
111
-
112
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
113
-			//Set the UID of the user we share with
114
-			$qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
115
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
116
-			//Set the GID of the group we share with
117
-			$qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
118
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
119
-			//Set the token of the share
120
-			$qb->setValue('token', $qb->createNamedParameter($share->getToken()));
121
-
122
-			//If a password is set store it
123
-			if ($share->getPassword() !== null) {
124
-				$qb->setValue('password', $qb->createNamedParameter($share->getPassword()));
125
-			}
126
-
127
-			//If an expiration date is set store it
128
-			if ($share->getExpirationDate() !== null) {
129
-				$qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
130
-			}
131
-
132
-			if (method_exists($share, 'getParent')) {
133
-				$qb->setValue('parent', $qb->createNamedParameter($share->getParent()));
134
-			}
135
-		} else {
136
-			throw new \Exception('invalid share type!');
137
-		}
138
-
139
-		// Set what is shares
140
-		$qb->setValue('item_type', $qb->createParameter('itemType'));
141
-		if ($share->getNode() instanceof \OCP\Files\File) {
142
-			$qb->setParameter('itemType', 'file');
143
-		} else {
144
-			$qb->setParameter('itemType', 'folder');
145
-		}
146
-
147
-		// Set the file id
148
-		$qb->setValue('item_source', $qb->createNamedParameter($share->getNode()->getId()));
149
-		$qb->setValue('file_source', $qb->createNamedParameter($share->getNode()->getId()));
150
-
151
-		// set the permissions
152
-		$qb->setValue('permissions', $qb->createNamedParameter($share->getPermissions()));
153
-
154
-		// Set who created this share
155
-		$qb->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()));
156
-
157
-		// Set who is the owner of this file/folder (and this the owner of the share)
158
-		$qb->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()));
159
-
160
-		// Set the file target
161
-		$qb->setValue('file_target', $qb->createNamedParameter($share->getTarget()));
162
-
163
-		// Set the time this share was created
164
-		$qb->setValue('stime', $qb->createNamedParameter(time()));
165
-
166
-		// insert the data and fetch the id of the share
167
-		$this->dbConn->beginTransaction();
168
-		$qb->execute();
169
-		$id = $this->dbConn->lastInsertId('*PREFIX*share');
170
-
171
-		// Now fetch the inserted share and create a complete share object
172
-		$qb = $this->dbConn->getQueryBuilder();
173
-		$qb->select('*')
174
-			->from('share')
175
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
176
-
177
-		$cursor = $qb->execute();
178
-		$data = $cursor->fetch();
179
-		$this->dbConn->commit();
180
-		$cursor->closeCursor();
181
-
182
-		if ($data === false) {
183
-			throw new ShareNotFound();
184
-		}
185
-
186
-		$mailSendValue = $share->getMailSend();
187
-		$data['mail_send'] = ($mailSendValue === null) ? true : $mailSendValue;
188
-
189
-		$share = $this->createShare($data);
190
-		return $share;
191
-	}
192
-
193
-	/**
194
-	 * Update a share
195
-	 *
196
-	 * @param \OCP\Share\IShare $share
197
-	 * @return \OCP\Share\IShare The share object
198
-	 */
199
-	public function update(\OCP\Share\IShare $share) {
200
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
201
-			/*
55
+    // Special share type for user modified group shares
56
+    const SHARE_TYPE_USERGROUP = 2;
57
+
58
+    /** @var IDBConnection */
59
+    private $dbConn;
60
+
61
+    /** @var IUserManager */
62
+    private $userManager;
63
+
64
+    /** @var IGroupManager */
65
+    private $groupManager;
66
+
67
+    /** @var IRootFolder */
68
+    private $rootFolder;
69
+
70
+    /**
71
+     * DefaultShareProvider constructor.
72
+     *
73
+     * @param IDBConnection $connection
74
+     * @param IUserManager $userManager
75
+     * @param IGroupManager $groupManager
76
+     * @param IRootFolder $rootFolder
77
+     */
78
+    public function __construct(
79
+            IDBConnection $connection,
80
+            IUserManager $userManager,
81
+            IGroupManager $groupManager,
82
+            IRootFolder $rootFolder) {
83
+        $this->dbConn = $connection;
84
+        $this->userManager = $userManager;
85
+        $this->groupManager = $groupManager;
86
+        $this->rootFolder = $rootFolder;
87
+    }
88
+
89
+    /**
90
+     * Return the identifier of this provider.
91
+     *
92
+     * @return string Containing only [a-zA-Z0-9]
93
+     */
94
+    public function identifier() {
95
+        return 'ocinternal';
96
+    }
97
+
98
+    /**
99
+     * Share a path
100
+     *
101
+     * @param \OCP\Share\IShare $share
102
+     * @return \OCP\Share\IShare The share object
103
+     * @throws ShareNotFound
104
+     * @throws \Exception
105
+     */
106
+    public function create(\OCP\Share\IShare $share) {
107
+        $qb = $this->dbConn->getQueryBuilder();
108
+
109
+        $qb->insert('share');
110
+        $qb->setValue('share_type', $qb->createNamedParameter($share->getShareType()));
111
+
112
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
113
+            //Set the UID of the user we share with
114
+            $qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
115
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
116
+            //Set the GID of the group we share with
117
+            $qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
118
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
119
+            //Set the token of the share
120
+            $qb->setValue('token', $qb->createNamedParameter($share->getToken()));
121
+
122
+            //If a password is set store it
123
+            if ($share->getPassword() !== null) {
124
+                $qb->setValue('password', $qb->createNamedParameter($share->getPassword()));
125
+            }
126
+
127
+            //If an expiration date is set store it
128
+            if ($share->getExpirationDate() !== null) {
129
+                $qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
130
+            }
131
+
132
+            if (method_exists($share, 'getParent')) {
133
+                $qb->setValue('parent', $qb->createNamedParameter($share->getParent()));
134
+            }
135
+        } else {
136
+            throw new \Exception('invalid share type!');
137
+        }
138
+
139
+        // Set what is shares
140
+        $qb->setValue('item_type', $qb->createParameter('itemType'));
141
+        if ($share->getNode() instanceof \OCP\Files\File) {
142
+            $qb->setParameter('itemType', 'file');
143
+        } else {
144
+            $qb->setParameter('itemType', 'folder');
145
+        }
146
+
147
+        // Set the file id
148
+        $qb->setValue('item_source', $qb->createNamedParameter($share->getNode()->getId()));
149
+        $qb->setValue('file_source', $qb->createNamedParameter($share->getNode()->getId()));
150
+
151
+        // set the permissions
152
+        $qb->setValue('permissions', $qb->createNamedParameter($share->getPermissions()));
153
+
154
+        // Set who created this share
155
+        $qb->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()));
156
+
157
+        // Set who is the owner of this file/folder (and this the owner of the share)
158
+        $qb->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()));
159
+
160
+        // Set the file target
161
+        $qb->setValue('file_target', $qb->createNamedParameter($share->getTarget()));
162
+
163
+        // Set the time this share was created
164
+        $qb->setValue('stime', $qb->createNamedParameter(time()));
165
+
166
+        // insert the data and fetch the id of the share
167
+        $this->dbConn->beginTransaction();
168
+        $qb->execute();
169
+        $id = $this->dbConn->lastInsertId('*PREFIX*share');
170
+
171
+        // Now fetch the inserted share and create a complete share object
172
+        $qb = $this->dbConn->getQueryBuilder();
173
+        $qb->select('*')
174
+            ->from('share')
175
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
176
+
177
+        $cursor = $qb->execute();
178
+        $data = $cursor->fetch();
179
+        $this->dbConn->commit();
180
+        $cursor->closeCursor();
181
+
182
+        if ($data === false) {
183
+            throw new ShareNotFound();
184
+        }
185
+
186
+        $mailSendValue = $share->getMailSend();
187
+        $data['mail_send'] = ($mailSendValue === null) ? true : $mailSendValue;
188
+
189
+        $share = $this->createShare($data);
190
+        return $share;
191
+    }
192
+
193
+    /**
194
+     * Update a share
195
+     *
196
+     * @param \OCP\Share\IShare $share
197
+     * @return \OCP\Share\IShare The share object
198
+     */
199
+    public function update(\OCP\Share\IShare $share) {
200
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
201
+            /*
202 202
 			 * We allow updating the recipient on user shares.
203 203
 			 */
204
-			$qb = $this->dbConn->getQueryBuilder();
205
-			$qb->update('share')
206
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
207
-				->set('share_with', $qb->createNamedParameter($share->getSharedWith()))
208
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
209
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
210
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
211
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
212
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
213
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
214
-				->execute();
215
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
216
-			$qb = $this->dbConn->getQueryBuilder();
217
-			$qb->update('share')
218
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
219
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
220
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
221
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
222
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
223
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
224
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
225
-				->execute();
226
-
227
-			/*
204
+            $qb = $this->dbConn->getQueryBuilder();
205
+            $qb->update('share')
206
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
207
+                ->set('share_with', $qb->createNamedParameter($share->getSharedWith()))
208
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
209
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
210
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
211
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
212
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
213
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
214
+                ->execute();
215
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
216
+            $qb = $this->dbConn->getQueryBuilder();
217
+            $qb->update('share')
218
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
219
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
220
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
221
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
222
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
223
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
224
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
225
+                ->execute();
226
+
227
+            /*
228 228
 			 * Update all user defined group shares
229 229
 			 */
230
-			$qb = $this->dbConn->getQueryBuilder();
231
-			$qb->update('share')
232
-				->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
233
-				->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
234
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
235
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
236
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
237
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
238
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
239
-				->execute();
240
-
241
-			/*
230
+            $qb = $this->dbConn->getQueryBuilder();
231
+            $qb->update('share')
232
+                ->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
233
+                ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
234
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
235
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
236
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
237
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
238
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
239
+                ->execute();
240
+
241
+            /*
242 242
 			 * Now update the permissions for all children that have not set it to 0
243 243
 			 */
244
-			$qb = $this->dbConn->getQueryBuilder();
245
-			$qb->update('share')
246
-				->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
247
-				->andWhere($qb->expr()->neq('permissions', $qb->createNamedParameter(0)))
248
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
249
-				->execute();
250
-
251
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
252
-			$qb = $this->dbConn->getQueryBuilder();
253
-			$qb->update('share')
254
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
255
-				->set('password', $qb->createNamedParameter($share->getPassword()))
256
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
257
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
258
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
259
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
260
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
261
-				->set('token', $qb->createNamedParameter($share->getToken()))
262
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
263
-				->execute();
264
-		}
265
-
266
-		return $share;
267
-	}
268
-
269
-	/**
270
-	 * Get all children of this share
271
-	 * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
272
-	 *
273
-	 * @param \OCP\Share\IShare $parent
274
-	 * @return \OCP\Share\IShare[]
275
-	 */
276
-	public function getChildren(\OCP\Share\IShare $parent) {
277
-		$children = [];
278
-
279
-		$qb = $this->dbConn->getQueryBuilder();
280
-		$qb->select('*')
281
-			->from('share')
282
-			->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
283
-			->andWhere(
284
-				$qb->expr()->in(
285
-					'share_type',
286
-					$qb->createNamedParameter([
287
-						\OCP\Share::SHARE_TYPE_USER,
288
-						\OCP\Share::SHARE_TYPE_GROUP,
289
-						\OCP\Share::SHARE_TYPE_LINK,
290
-					], IQueryBuilder::PARAM_INT_ARRAY)
291
-				)
292
-			)
293
-			->andWhere($qb->expr()->orX(
294
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
295
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
296
-			))
297
-			->orderBy('id');
298
-
299
-		$cursor = $qb->execute();
300
-		while($data = $cursor->fetch()) {
301
-			$children[] = $this->createShare($data);
302
-		}
303
-		$cursor->closeCursor();
304
-
305
-		return $children;
306
-	}
307
-
308
-	/**
309
-	 * Delete a share
310
-	 *
311
-	 * @param \OCP\Share\IShare $share
312
-	 */
313
-	public function delete(\OCP\Share\IShare $share) {
314
-		$qb = $this->dbConn->getQueryBuilder();
315
-		$qb->delete('share')
316
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())));
317
-
318
-		/*
244
+            $qb = $this->dbConn->getQueryBuilder();
245
+            $qb->update('share')
246
+                ->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
247
+                ->andWhere($qb->expr()->neq('permissions', $qb->createNamedParameter(0)))
248
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
249
+                ->execute();
250
+
251
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
252
+            $qb = $this->dbConn->getQueryBuilder();
253
+            $qb->update('share')
254
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
255
+                ->set('password', $qb->createNamedParameter($share->getPassword()))
256
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
257
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
258
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
259
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
260
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
261
+                ->set('token', $qb->createNamedParameter($share->getToken()))
262
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
263
+                ->execute();
264
+        }
265
+
266
+        return $share;
267
+    }
268
+
269
+    /**
270
+     * Get all children of this share
271
+     * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
272
+     *
273
+     * @param \OCP\Share\IShare $parent
274
+     * @return \OCP\Share\IShare[]
275
+     */
276
+    public function getChildren(\OCP\Share\IShare $parent) {
277
+        $children = [];
278
+
279
+        $qb = $this->dbConn->getQueryBuilder();
280
+        $qb->select('*')
281
+            ->from('share')
282
+            ->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
283
+            ->andWhere(
284
+                $qb->expr()->in(
285
+                    'share_type',
286
+                    $qb->createNamedParameter([
287
+                        \OCP\Share::SHARE_TYPE_USER,
288
+                        \OCP\Share::SHARE_TYPE_GROUP,
289
+                        \OCP\Share::SHARE_TYPE_LINK,
290
+                    ], IQueryBuilder::PARAM_INT_ARRAY)
291
+                )
292
+            )
293
+            ->andWhere($qb->expr()->orX(
294
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
295
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
296
+            ))
297
+            ->orderBy('id');
298
+
299
+        $cursor = $qb->execute();
300
+        while($data = $cursor->fetch()) {
301
+            $children[] = $this->createShare($data);
302
+        }
303
+        $cursor->closeCursor();
304
+
305
+        return $children;
306
+    }
307
+
308
+    /**
309
+     * Delete a share
310
+     *
311
+     * @param \OCP\Share\IShare $share
312
+     */
313
+    public function delete(\OCP\Share\IShare $share) {
314
+        $qb = $this->dbConn->getQueryBuilder();
315
+        $qb->delete('share')
316
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())));
317
+
318
+        /*
319 319
 		 * If the share is a group share delete all possible
320 320
 		 * user defined groups shares.
321 321
 		 */
322
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
323
-			$qb->orWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())));
324
-		}
325
-
326
-		$qb->execute();
327
-	}
328
-
329
-	/**
330
-	 * Unshare a share from the recipient. If this is a group share
331
-	 * this means we need a special entry in the share db.
332
-	 *
333
-	 * @param \OCP\Share\IShare $share
334
-	 * @param string $recipient UserId of recipient
335
-	 * @throws BackendError
336
-	 * @throws ProviderException
337
-	 */
338
-	public function deleteFromSelf(\OCP\Share\IShare $share, $recipient) {
339
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
340
-
341
-			$group = $this->groupManager->get($share->getSharedWith());
342
-			$user = $this->userManager->get($recipient);
343
-
344
-			if (is_null($group)) {
345
-				throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
346
-			}
347
-
348
-			if (!$group->inGroup($user)) {
349
-				throw new ProviderException('Recipient not in receiving group');
350
-			}
351
-
352
-			// Try to fetch user specific share
353
-			$qb = $this->dbConn->getQueryBuilder();
354
-			$stmt = $qb->select('*')
355
-				->from('share')
356
-				->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
357
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
358
-				->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
359
-				->andWhere($qb->expr()->orX(
360
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
361
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
362
-				))
363
-				->execute();
364
-
365
-			$data = $stmt->fetch();
366
-
367
-			/*
322
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
323
+            $qb->orWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())));
324
+        }
325
+
326
+        $qb->execute();
327
+    }
328
+
329
+    /**
330
+     * Unshare a share from the recipient. If this is a group share
331
+     * this means we need a special entry in the share db.
332
+     *
333
+     * @param \OCP\Share\IShare $share
334
+     * @param string $recipient UserId of recipient
335
+     * @throws BackendError
336
+     * @throws ProviderException
337
+     */
338
+    public function deleteFromSelf(\OCP\Share\IShare $share, $recipient) {
339
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
340
+
341
+            $group = $this->groupManager->get($share->getSharedWith());
342
+            $user = $this->userManager->get($recipient);
343
+
344
+            if (is_null($group)) {
345
+                throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
346
+            }
347
+
348
+            if (!$group->inGroup($user)) {
349
+                throw new ProviderException('Recipient not in receiving group');
350
+            }
351
+
352
+            // Try to fetch user specific share
353
+            $qb = $this->dbConn->getQueryBuilder();
354
+            $stmt = $qb->select('*')
355
+                ->from('share')
356
+                ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
357
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
358
+                ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
359
+                ->andWhere($qb->expr()->orX(
360
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
361
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
362
+                ))
363
+                ->execute();
364
+
365
+            $data = $stmt->fetch();
366
+
367
+            /*
368 368
 			 * Check if there already is a user specific group share.
369 369
 			 * If there is update it (if required).
370 370
 			 */
371
-			if ($data === false) {
372
-				$qb = $this->dbConn->getQueryBuilder();
373
-
374
-				$type = $share->getNodeType();
375
-
376
-				//Insert new share
377
-				$qb->insert('share')
378
-					->values([
379
-						'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP),
380
-						'share_with' => $qb->createNamedParameter($recipient),
381
-						'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
382
-						'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
383
-						'parent' => $qb->createNamedParameter($share->getId()),
384
-						'item_type' => $qb->createNamedParameter($type),
385
-						'item_source' => $qb->createNamedParameter($share->getNodeId()),
386
-						'file_source' => $qb->createNamedParameter($share->getNodeId()),
387
-						'file_target' => $qb->createNamedParameter($share->getTarget()),
388
-						'permissions' => $qb->createNamedParameter(0),
389
-						'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
390
-					])->execute();
391
-
392
-			} else if ($data['permissions'] !== 0) {
393
-
394
-				// Update existing usergroup share
395
-				$qb = $this->dbConn->getQueryBuilder();
396
-				$qb->update('share')
397
-					->set('permissions', $qb->createNamedParameter(0))
398
-					->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
399
-					->execute();
400
-			}
401
-
402
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
403
-
404
-			if ($share->getSharedWith() !== $recipient) {
405
-				throw new ProviderException('Recipient does not match');
406
-			}
407
-
408
-			// We can just delete user and link shares
409
-			$this->delete($share);
410
-		} else {
411
-			throw new ProviderException('Invalid shareType');
412
-		}
413
-	}
414
-
415
-	/**
416
-	 * @inheritdoc
417
-	 */
418
-	public function move(\OCP\Share\IShare $share, $recipient) {
419
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
420
-			// Just update the target
421
-			$qb = $this->dbConn->getQueryBuilder();
422
-			$qb->update('share')
423
-				->set('file_target', $qb->createNamedParameter($share->getTarget()))
424
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
425
-				->execute();
426
-
427
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
428
-
429
-			// Check if there is a usergroup share
430
-			$qb = $this->dbConn->getQueryBuilder();
431
-			$stmt = $qb->select('id')
432
-				->from('share')
433
-				->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
434
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
435
-				->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
436
-				->andWhere($qb->expr()->orX(
437
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
438
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
439
-				))
440
-				->setMaxResults(1)
441
-				->execute();
442
-
443
-			$data = $stmt->fetch();
444
-			$stmt->closeCursor();
445
-
446
-			if ($data === false) {
447
-				// No usergroup share yet. Create one.
448
-				$qb = $this->dbConn->getQueryBuilder();
449
-				$qb->insert('share')
450
-					->values([
451
-						'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP),
452
-						'share_with' => $qb->createNamedParameter($recipient),
453
-						'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
454
-						'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
455
-						'parent' => $qb->createNamedParameter($share->getId()),
456
-						'item_type' => $qb->createNamedParameter($share->getNodeType()),
457
-						'item_source' => $qb->createNamedParameter($share->getNodeId()),
458
-						'file_source' => $qb->createNamedParameter($share->getNodeId()),
459
-						'file_target' => $qb->createNamedParameter($share->getTarget()),
460
-						'permissions' => $qb->createNamedParameter($share->getPermissions()),
461
-						'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
462
-					])->execute();
463
-			} else {
464
-				// Already a usergroup share. Update it.
465
-				$qb = $this->dbConn->getQueryBuilder();
466
-				$qb->update('share')
467
-					->set('file_target', $qb->createNamedParameter($share->getTarget()))
468
-					->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
469
-					->execute();
470
-			}
471
-		}
472
-
473
-		return $share;
474
-	}
475
-
476
-	public function getSharesInFolder($userId, Folder $node, $reshares) {
477
-		$qb = $this->dbConn->getQueryBuilder();
478
-		$qb->select('*')
479
-			->from('share', 's')
480
-			->andWhere($qb->expr()->orX(
481
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
482
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
483
-			));
484
-
485
-		$qb->andWhere($qb->expr()->orX(
486
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
487
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
488
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK))
489
-		));
490
-
491
-		/**
492
-		 * Reshares for this user are shares where they are the owner.
493
-		 */
494
-		if ($reshares === false) {
495
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
496
-		} else {
497
-			$qb->andWhere(
498
-				$qb->expr()->orX(
499
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
500
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
501
-				)
502
-			);
503
-		}
504
-
505
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
506
-		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
507
-
508
-		$qb->orderBy('id');
509
-
510
-		$cursor = $qb->execute();
511
-		$shares = [];
512
-		while ($data = $cursor->fetch()) {
513
-			$shares[$data['fileid']][] = $this->createShare($data);
514
-		}
515
-		$cursor->closeCursor();
516
-
517
-		return $shares;
518
-	}
519
-
520
-	/**
521
-	 * @inheritdoc
522
-	 */
523
-	public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
524
-		$qb = $this->dbConn->getQueryBuilder();
525
-		$qb->select('*')
526
-			->from('share')
527
-			->andWhere($qb->expr()->orX(
528
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
529
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
530
-			));
531
-
532
-		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter($shareType)));
533
-
534
-		/**
535
-		 * Reshares for this user are shares where they are the owner.
536
-		 */
537
-		if ($reshares === false) {
538
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
539
-		} else {
540
-			$qb->andWhere(
541
-				$qb->expr()->orX(
542
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
543
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
544
-				)
545
-			);
546
-		}
547
-
548
-		if ($node !== null) {
549
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
550
-		}
551
-
552
-		if ($limit !== -1) {
553
-			$qb->setMaxResults($limit);
554
-		}
555
-
556
-		$qb->setFirstResult($offset);
557
-		$qb->orderBy('id');
558
-
559
-		$cursor = $qb->execute();
560
-		$shares = [];
561
-		while($data = $cursor->fetch()) {
562
-			$shares[] = $this->createShare($data);
563
-		}
564
-		$cursor->closeCursor();
565
-
566
-		return $shares;
567
-	}
568
-
569
-	/**
570
-	 * @inheritdoc
571
-	 */
572
-	public function getShareById($id, $recipientId = null) {
573
-		$qb = $this->dbConn->getQueryBuilder();
574
-
575
-		$qb->select('*')
576
-			->from('share')
577
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
578
-			->andWhere(
579
-				$qb->expr()->in(
580
-					'share_type',
581
-					$qb->createNamedParameter([
582
-						\OCP\Share::SHARE_TYPE_USER,
583
-						\OCP\Share::SHARE_TYPE_GROUP,
584
-						\OCP\Share::SHARE_TYPE_LINK,
585
-					], IQueryBuilder::PARAM_INT_ARRAY)
586
-				)
587
-			)
588
-			->andWhere($qb->expr()->orX(
589
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
590
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
591
-			));
592
-
593
-		$cursor = $qb->execute();
594
-		$data = $cursor->fetch();
595
-		$cursor->closeCursor();
596
-
597
-		if ($data === false) {
598
-			throw new ShareNotFound();
599
-		}
600
-
601
-		try {
602
-			$share = $this->createShare($data);
603
-		} catch (InvalidShare $e) {
604
-			throw new ShareNotFound();
605
-		}
606
-
607
-		// If the recipient is set for a group share resolve to that user
608
-		if ($recipientId !== null && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
609
-			$share = $this->resolveGroupShares([$share], $recipientId)[0];
610
-		}
611
-
612
-		return $share;
613
-	}
614
-
615
-	/**
616
-	 * Get shares for a given path
617
-	 *
618
-	 * @param \OCP\Files\Node $path
619
-	 * @return \OCP\Share\IShare[]
620
-	 */
621
-	public function getSharesByPath(Node $path) {
622
-		$qb = $this->dbConn->getQueryBuilder();
623
-
624
-		$cursor = $qb->select('*')
625
-			->from('share')
626
-			->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
627
-			->andWhere(
628
-				$qb->expr()->orX(
629
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
630
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP))
631
-				)
632
-			)
633
-			->andWhere($qb->expr()->orX(
634
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
635
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
636
-			))
637
-			->execute();
638
-
639
-		$shares = [];
640
-		while($data = $cursor->fetch()) {
641
-			$shares[] = $this->createShare($data);
642
-		}
643
-		$cursor->closeCursor();
644
-
645
-		return $shares;
646
-	}
647
-
648
-	/**
649
-	 * Returns whether the given database result can be interpreted as
650
-	 * a share with accessible file (not trashed, not deleted)
651
-	 */
652
-	private function isAccessibleResult($data) {
653
-		// exclude shares leading to deleted file entries
654
-		if ($data['fileid'] === null) {
655
-			return false;
656
-		}
657
-
658
-		// exclude shares leading to trashbin on home storages
659
-		$pathSections = explode('/', $data['path'], 2);
660
-		// FIXME: would not detect rare md5'd home storage case properly
661
-		if ($pathSections[0] !== 'files'
662
-		    	&& in_array(explode(':', $data['storage_string_id'], 2)[0], array('home', 'object'))) {
663
-			return false;
664
-		}
665
-		return true;
666
-	}
667
-
668
-	/**
669
-	 * @inheritdoc
670
-	 */
671
-	public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
672
-		/** @var Share[] $shares */
673
-		$shares = [];
674
-
675
-		if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
676
-			//Get shares directly with this user
677
-			$qb = $this->dbConn->getQueryBuilder();
678
-			$qb->select('s.*',
679
-				'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
680
-				'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
681
-				'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
682
-			)
683
-				->selectAlias('st.id', 'storage_string_id')
684
-				->from('share', 's')
685
-				->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
686
-				->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'));
687
-
688
-			// Order by id
689
-			$qb->orderBy('s.id');
690
-
691
-			// Set limit and offset
692
-			if ($limit !== -1) {
693
-				$qb->setMaxResults($limit);
694
-			}
695
-			$qb->setFirstResult($offset);
696
-
697
-			$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)))
698
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
699
-				->andWhere($qb->expr()->orX(
700
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
701
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
702
-				));
703
-
704
-			// Filter by node if provided
705
-			if ($node !== null) {
706
-				$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
707
-			}
708
-
709
-			$cursor = $qb->execute();
710
-
711
-			while($data = $cursor->fetch()) {
712
-				if ($this->isAccessibleResult($data)) {
713
-					$shares[] = $this->createShare($data);
714
-				}
715
-			}
716
-			$cursor->closeCursor();
717
-
718
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
719
-			$user = $this->userManager->get($userId);
720
-			$allGroups = $this->groupManager->getUserGroups($user);
721
-
722
-			/** @var Share[] $shares2 */
723
-			$shares2 = [];
724
-
725
-			$start = 0;
726
-			while(true) {
727
-				$groups = array_slice($allGroups, $start, 100);
728
-				$start += 100;
729
-
730
-				if ($groups === []) {
731
-					break;
732
-				}
733
-
734
-				$qb = $this->dbConn->getQueryBuilder();
735
-				$qb->select('s.*',
736
-					'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
737
-					'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
738
-					'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
739
-				)
740
-					->selectAlias('st.id', 'storage_string_id')
741
-					->from('share', 's')
742
-					->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
743
-					->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'))
744
-					->orderBy('s.id')
745
-					->setFirstResult(0);
746
-
747
-				if ($limit !== -1) {
748
-					$qb->setMaxResults($limit - count($shares));
749
-				}
750
-
751
-				// Filter by node if provided
752
-				if ($node !== null) {
753
-					$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
754
-				}
755
-
756
-
757
-				$groups = array_filter($groups, function($group) { return $group instanceof IGroup; });
758
-				$groups = array_map(function(IGroup $group) { return $group->getGID(); }, $groups);
759
-
760
-				$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
761
-					->andWhere($qb->expr()->in('share_with', $qb->createNamedParameter(
762
-						$groups,
763
-						IQueryBuilder::PARAM_STR_ARRAY
764
-					)))
765
-					->andWhere($qb->expr()->orX(
766
-						$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
767
-						$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
768
-					));
769
-
770
-				$cursor = $qb->execute();
771
-				while($data = $cursor->fetch()) {
772
-					if ($offset > 0) {
773
-						$offset--;
774
-						continue;
775
-					}
776
-
777
-					if ($this->isAccessibleResult($data)) {
778
-						$shares2[] = $this->createShare($data);
779
-					}
780
-				}
781
-				$cursor->closeCursor();
782
-			}
783
-
784
-			/*
371
+            if ($data === false) {
372
+                $qb = $this->dbConn->getQueryBuilder();
373
+
374
+                $type = $share->getNodeType();
375
+
376
+                //Insert new share
377
+                $qb->insert('share')
378
+                    ->values([
379
+                        'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP),
380
+                        'share_with' => $qb->createNamedParameter($recipient),
381
+                        'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
382
+                        'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
383
+                        'parent' => $qb->createNamedParameter($share->getId()),
384
+                        'item_type' => $qb->createNamedParameter($type),
385
+                        'item_source' => $qb->createNamedParameter($share->getNodeId()),
386
+                        'file_source' => $qb->createNamedParameter($share->getNodeId()),
387
+                        'file_target' => $qb->createNamedParameter($share->getTarget()),
388
+                        'permissions' => $qb->createNamedParameter(0),
389
+                        'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
390
+                    ])->execute();
391
+
392
+            } else if ($data['permissions'] !== 0) {
393
+
394
+                // Update existing usergroup share
395
+                $qb = $this->dbConn->getQueryBuilder();
396
+                $qb->update('share')
397
+                    ->set('permissions', $qb->createNamedParameter(0))
398
+                    ->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
399
+                    ->execute();
400
+            }
401
+
402
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
403
+
404
+            if ($share->getSharedWith() !== $recipient) {
405
+                throw new ProviderException('Recipient does not match');
406
+            }
407
+
408
+            // We can just delete user and link shares
409
+            $this->delete($share);
410
+        } else {
411
+            throw new ProviderException('Invalid shareType');
412
+        }
413
+    }
414
+
415
+    /**
416
+     * @inheritdoc
417
+     */
418
+    public function move(\OCP\Share\IShare $share, $recipient) {
419
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
420
+            // Just update the target
421
+            $qb = $this->dbConn->getQueryBuilder();
422
+            $qb->update('share')
423
+                ->set('file_target', $qb->createNamedParameter($share->getTarget()))
424
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
425
+                ->execute();
426
+
427
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
428
+
429
+            // Check if there is a usergroup share
430
+            $qb = $this->dbConn->getQueryBuilder();
431
+            $stmt = $qb->select('id')
432
+                ->from('share')
433
+                ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
434
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
435
+                ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
436
+                ->andWhere($qb->expr()->orX(
437
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
438
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
439
+                ))
440
+                ->setMaxResults(1)
441
+                ->execute();
442
+
443
+            $data = $stmt->fetch();
444
+            $stmt->closeCursor();
445
+
446
+            if ($data === false) {
447
+                // No usergroup share yet. Create one.
448
+                $qb = $this->dbConn->getQueryBuilder();
449
+                $qb->insert('share')
450
+                    ->values([
451
+                        'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP),
452
+                        'share_with' => $qb->createNamedParameter($recipient),
453
+                        'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
454
+                        'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
455
+                        'parent' => $qb->createNamedParameter($share->getId()),
456
+                        'item_type' => $qb->createNamedParameter($share->getNodeType()),
457
+                        'item_source' => $qb->createNamedParameter($share->getNodeId()),
458
+                        'file_source' => $qb->createNamedParameter($share->getNodeId()),
459
+                        'file_target' => $qb->createNamedParameter($share->getTarget()),
460
+                        'permissions' => $qb->createNamedParameter($share->getPermissions()),
461
+                        'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
462
+                    ])->execute();
463
+            } else {
464
+                // Already a usergroup share. Update it.
465
+                $qb = $this->dbConn->getQueryBuilder();
466
+                $qb->update('share')
467
+                    ->set('file_target', $qb->createNamedParameter($share->getTarget()))
468
+                    ->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
469
+                    ->execute();
470
+            }
471
+        }
472
+
473
+        return $share;
474
+    }
475
+
476
+    public function getSharesInFolder($userId, Folder $node, $reshares) {
477
+        $qb = $this->dbConn->getQueryBuilder();
478
+        $qb->select('*')
479
+            ->from('share', 's')
480
+            ->andWhere($qb->expr()->orX(
481
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
482
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
483
+            ));
484
+
485
+        $qb->andWhere($qb->expr()->orX(
486
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
487
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
488
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK))
489
+        ));
490
+
491
+        /**
492
+         * Reshares for this user are shares where they are the owner.
493
+         */
494
+        if ($reshares === false) {
495
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
496
+        } else {
497
+            $qb->andWhere(
498
+                $qb->expr()->orX(
499
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
500
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
501
+                )
502
+            );
503
+        }
504
+
505
+        $qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
506
+        $qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
507
+
508
+        $qb->orderBy('id');
509
+
510
+        $cursor = $qb->execute();
511
+        $shares = [];
512
+        while ($data = $cursor->fetch()) {
513
+            $shares[$data['fileid']][] = $this->createShare($data);
514
+        }
515
+        $cursor->closeCursor();
516
+
517
+        return $shares;
518
+    }
519
+
520
+    /**
521
+     * @inheritdoc
522
+     */
523
+    public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
524
+        $qb = $this->dbConn->getQueryBuilder();
525
+        $qb->select('*')
526
+            ->from('share')
527
+            ->andWhere($qb->expr()->orX(
528
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
529
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
530
+            ));
531
+
532
+        $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter($shareType)));
533
+
534
+        /**
535
+         * Reshares for this user are shares where they are the owner.
536
+         */
537
+        if ($reshares === false) {
538
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
539
+        } else {
540
+            $qb->andWhere(
541
+                $qb->expr()->orX(
542
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
543
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
544
+                )
545
+            );
546
+        }
547
+
548
+        if ($node !== null) {
549
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
550
+        }
551
+
552
+        if ($limit !== -1) {
553
+            $qb->setMaxResults($limit);
554
+        }
555
+
556
+        $qb->setFirstResult($offset);
557
+        $qb->orderBy('id');
558
+
559
+        $cursor = $qb->execute();
560
+        $shares = [];
561
+        while($data = $cursor->fetch()) {
562
+            $shares[] = $this->createShare($data);
563
+        }
564
+        $cursor->closeCursor();
565
+
566
+        return $shares;
567
+    }
568
+
569
+    /**
570
+     * @inheritdoc
571
+     */
572
+    public function getShareById($id, $recipientId = null) {
573
+        $qb = $this->dbConn->getQueryBuilder();
574
+
575
+        $qb->select('*')
576
+            ->from('share')
577
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
578
+            ->andWhere(
579
+                $qb->expr()->in(
580
+                    'share_type',
581
+                    $qb->createNamedParameter([
582
+                        \OCP\Share::SHARE_TYPE_USER,
583
+                        \OCP\Share::SHARE_TYPE_GROUP,
584
+                        \OCP\Share::SHARE_TYPE_LINK,
585
+                    ], IQueryBuilder::PARAM_INT_ARRAY)
586
+                )
587
+            )
588
+            ->andWhere($qb->expr()->orX(
589
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
590
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
591
+            ));
592
+
593
+        $cursor = $qb->execute();
594
+        $data = $cursor->fetch();
595
+        $cursor->closeCursor();
596
+
597
+        if ($data === false) {
598
+            throw new ShareNotFound();
599
+        }
600
+
601
+        try {
602
+            $share = $this->createShare($data);
603
+        } catch (InvalidShare $e) {
604
+            throw new ShareNotFound();
605
+        }
606
+
607
+        // If the recipient is set for a group share resolve to that user
608
+        if ($recipientId !== null && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
609
+            $share = $this->resolveGroupShares([$share], $recipientId)[0];
610
+        }
611
+
612
+        return $share;
613
+    }
614
+
615
+    /**
616
+     * Get shares for a given path
617
+     *
618
+     * @param \OCP\Files\Node $path
619
+     * @return \OCP\Share\IShare[]
620
+     */
621
+    public function getSharesByPath(Node $path) {
622
+        $qb = $this->dbConn->getQueryBuilder();
623
+
624
+        $cursor = $qb->select('*')
625
+            ->from('share')
626
+            ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
627
+            ->andWhere(
628
+                $qb->expr()->orX(
629
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
630
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP))
631
+                )
632
+            )
633
+            ->andWhere($qb->expr()->orX(
634
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
635
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
636
+            ))
637
+            ->execute();
638
+
639
+        $shares = [];
640
+        while($data = $cursor->fetch()) {
641
+            $shares[] = $this->createShare($data);
642
+        }
643
+        $cursor->closeCursor();
644
+
645
+        return $shares;
646
+    }
647
+
648
+    /**
649
+     * Returns whether the given database result can be interpreted as
650
+     * a share with accessible file (not trashed, not deleted)
651
+     */
652
+    private function isAccessibleResult($data) {
653
+        // exclude shares leading to deleted file entries
654
+        if ($data['fileid'] === null) {
655
+            return false;
656
+        }
657
+
658
+        // exclude shares leading to trashbin on home storages
659
+        $pathSections = explode('/', $data['path'], 2);
660
+        // FIXME: would not detect rare md5'd home storage case properly
661
+        if ($pathSections[0] !== 'files'
662
+                && in_array(explode(':', $data['storage_string_id'], 2)[0], array('home', 'object'))) {
663
+            return false;
664
+        }
665
+        return true;
666
+    }
667
+
668
+    /**
669
+     * @inheritdoc
670
+     */
671
+    public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
672
+        /** @var Share[] $shares */
673
+        $shares = [];
674
+
675
+        if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
676
+            //Get shares directly with this user
677
+            $qb = $this->dbConn->getQueryBuilder();
678
+            $qb->select('s.*',
679
+                'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
680
+                'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
681
+                'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
682
+            )
683
+                ->selectAlias('st.id', 'storage_string_id')
684
+                ->from('share', 's')
685
+                ->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
686
+                ->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'));
687
+
688
+            // Order by id
689
+            $qb->orderBy('s.id');
690
+
691
+            // Set limit and offset
692
+            if ($limit !== -1) {
693
+                $qb->setMaxResults($limit);
694
+            }
695
+            $qb->setFirstResult($offset);
696
+
697
+            $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)))
698
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
699
+                ->andWhere($qb->expr()->orX(
700
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
701
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
702
+                ));
703
+
704
+            // Filter by node if provided
705
+            if ($node !== null) {
706
+                $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
707
+            }
708
+
709
+            $cursor = $qb->execute();
710
+
711
+            while($data = $cursor->fetch()) {
712
+                if ($this->isAccessibleResult($data)) {
713
+                    $shares[] = $this->createShare($data);
714
+                }
715
+            }
716
+            $cursor->closeCursor();
717
+
718
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
719
+            $user = $this->userManager->get($userId);
720
+            $allGroups = $this->groupManager->getUserGroups($user);
721
+
722
+            /** @var Share[] $shares2 */
723
+            $shares2 = [];
724
+
725
+            $start = 0;
726
+            while(true) {
727
+                $groups = array_slice($allGroups, $start, 100);
728
+                $start += 100;
729
+
730
+                if ($groups === []) {
731
+                    break;
732
+                }
733
+
734
+                $qb = $this->dbConn->getQueryBuilder();
735
+                $qb->select('s.*',
736
+                    'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
737
+                    'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
738
+                    'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
739
+                )
740
+                    ->selectAlias('st.id', 'storage_string_id')
741
+                    ->from('share', 's')
742
+                    ->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
743
+                    ->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'))
744
+                    ->orderBy('s.id')
745
+                    ->setFirstResult(0);
746
+
747
+                if ($limit !== -1) {
748
+                    $qb->setMaxResults($limit - count($shares));
749
+                }
750
+
751
+                // Filter by node if provided
752
+                if ($node !== null) {
753
+                    $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
754
+                }
755
+
756
+
757
+                $groups = array_filter($groups, function($group) { return $group instanceof IGroup; });
758
+                $groups = array_map(function(IGroup $group) { return $group->getGID(); }, $groups);
759
+
760
+                $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
761
+                    ->andWhere($qb->expr()->in('share_with', $qb->createNamedParameter(
762
+                        $groups,
763
+                        IQueryBuilder::PARAM_STR_ARRAY
764
+                    )))
765
+                    ->andWhere($qb->expr()->orX(
766
+                        $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
767
+                        $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
768
+                    ));
769
+
770
+                $cursor = $qb->execute();
771
+                while($data = $cursor->fetch()) {
772
+                    if ($offset > 0) {
773
+                        $offset--;
774
+                        continue;
775
+                    }
776
+
777
+                    if ($this->isAccessibleResult($data)) {
778
+                        $shares2[] = $this->createShare($data);
779
+                    }
780
+                }
781
+                $cursor->closeCursor();
782
+            }
783
+
784
+            /*
785 785
  			 * Resolve all group shares to user specific shares
786 786
  			 */
787
-			$shares = $this->resolveGroupShares($shares2, $userId);
788
-		} else {
789
-			throw new BackendError('Invalid backend');
790
-		}
791
-
792
-
793
-		return $shares;
794
-	}
795
-
796
-	/**
797
-	 * Get a share by token
798
-	 *
799
-	 * @param string $token
800
-	 * @return \OCP\Share\IShare
801
-	 * @throws ShareNotFound
802
-	 */
803
-	public function getShareByToken($token) {
804
-		$qb = $this->dbConn->getQueryBuilder();
805
-
806
-		$cursor = $qb->select('*')
807
-			->from('share')
808
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK)))
809
-			->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
810
-			->andWhere($qb->expr()->orX(
811
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
812
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
813
-			))
814
-			->execute();
815
-
816
-		$data = $cursor->fetch();
817
-
818
-		if ($data === false) {
819
-			throw new ShareNotFound();
820
-		}
821
-
822
-		try {
823
-			$share = $this->createShare($data);
824
-		} catch (InvalidShare $e) {
825
-			throw new ShareNotFound();
826
-		}
827
-
828
-		return $share;
829
-	}
830
-
831
-	/**
832
-	 * Create a share object from an database row
833
-	 *
834
-	 * @param mixed[] $data
835
-	 * @return \OCP\Share\IShare
836
-	 * @throws InvalidShare
837
-	 */
838
-	private function createShare($data) {
839
-		$share = new Share($this->rootFolder, $this->userManager);
840
-		$share->setId((int)$data['id'])
841
-			->setShareType((int)$data['share_type'])
842
-			->setPermissions((int)$data['permissions'])
843
-			->setTarget($data['file_target'])
844
-			->setMailSend((bool)$data['mail_send']);
845
-
846
-		$shareTime = new \DateTime();
847
-		$shareTime->setTimestamp((int)$data['stime']);
848
-		$share->setShareTime($shareTime);
849
-
850
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
851
-			$share->setSharedWith($data['share_with']);
852
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
853
-			$share->setSharedWith($data['share_with']);
854
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
855
-			$share->setPassword($data['password']);
856
-			$share->setToken($data['token']);
857
-		}
858
-
859
-		$share->setSharedBy($data['uid_initiator']);
860
-		$share->setShareOwner($data['uid_owner']);
861
-
862
-		$share->setNodeId((int)$data['file_source']);
863
-		$share->setNodeType($data['item_type']);
864
-
865
-		if ($data['expiration'] !== null) {
866
-			$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
867
-			$share->setExpirationDate($expiration);
868
-		}
869
-
870
-		if (isset($data['f_permissions'])) {
871
-			$entryData = $data;
872
-			$entryData['permissions'] = $entryData['f_permissions'];
873
-			$entryData['parent'] = $entryData['f_parent'];
874
-			$share->setNodeCacheEntry(Cache::cacheEntryFromData($entryData,
875
-				\OC::$server->getMimeTypeLoader()));
876
-		}
877
-
878
-		$share->setProviderId($this->identifier());
879
-
880
-		return $share;
881
-	}
882
-
883
-	/**
884
-	 * @param Share[] $shares
885
-	 * @param $userId
886
-	 * @return Share[] The updates shares if no update is found for a share return the original
887
-	 */
888
-	private function resolveGroupShares($shares, $userId) {
889
-		$result = [];
890
-
891
-		$start = 0;
892
-		while(true) {
893
-			/** @var Share[] $shareSlice */
894
-			$shareSlice = array_slice($shares, $start, 100);
895
-			$start += 100;
896
-
897
-			if ($shareSlice === []) {
898
-				break;
899
-			}
900
-
901
-			/** @var int[] $ids */
902
-			$ids = [];
903
-			/** @var Share[] $shareMap */
904
-			$shareMap = [];
905
-
906
-			foreach ($shareSlice as $share) {
907
-				$ids[] = (int)$share->getId();
908
-				$shareMap[$share->getId()] = $share;
909
-			}
910
-
911
-			$qb = $this->dbConn->getQueryBuilder();
912
-
913
-			$query = $qb->select('*')
914
-				->from('share')
915
-				->where($qb->expr()->in('parent', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
916
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
917
-				->andWhere($qb->expr()->orX(
918
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
919
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
920
-				));
921
-
922
-			$stmt = $query->execute();
923
-
924
-			while($data = $stmt->fetch()) {
925
-				$shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
926
-				$shareMap[$data['parent']]->setTarget($data['file_target']);
927
-			}
928
-
929
-			$stmt->closeCursor();
930
-
931
-			foreach ($shareMap as $share) {
932
-				$result[] = $share;
933
-			}
934
-		}
935
-
936
-		return $result;
937
-	}
938
-
939
-	/**
940
-	 * A user is deleted from the system
941
-	 * So clean up the relevant shares.
942
-	 *
943
-	 * @param string $uid
944
-	 * @param int $shareType
945
-	 */
946
-	public function userDeleted($uid, $shareType) {
947
-		$qb = $this->dbConn->getQueryBuilder();
948
-
949
-		$qb->delete('share');
950
-
951
-		if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
952
-			/*
787
+            $shares = $this->resolveGroupShares($shares2, $userId);
788
+        } else {
789
+            throw new BackendError('Invalid backend');
790
+        }
791
+
792
+
793
+        return $shares;
794
+    }
795
+
796
+    /**
797
+     * Get a share by token
798
+     *
799
+     * @param string $token
800
+     * @return \OCP\Share\IShare
801
+     * @throws ShareNotFound
802
+     */
803
+    public function getShareByToken($token) {
804
+        $qb = $this->dbConn->getQueryBuilder();
805
+
806
+        $cursor = $qb->select('*')
807
+            ->from('share')
808
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK)))
809
+            ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
810
+            ->andWhere($qb->expr()->orX(
811
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
812
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
813
+            ))
814
+            ->execute();
815
+
816
+        $data = $cursor->fetch();
817
+
818
+        if ($data === false) {
819
+            throw new ShareNotFound();
820
+        }
821
+
822
+        try {
823
+            $share = $this->createShare($data);
824
+        } catch (InvalidShare $e) {
825
+            throw new ShareNotFound();
826
+        }
827
+
828
+        return $share;
829
+    }
830
+
831
+    /**
832
+     * Create a share object from an database row
833
+     *
834
+     * @param mixed[] $data
835
+     * @return \OCP\Share\IShare
836
+     * @throws InvalidShare
837
+     */
838
+    private function createShare($data) {
839
+        $share = new Share($this->rootFolder, $this->userManager);
840
+        $share->setId((int)$data['id'])
841
+            ->setShareType((int)$data['share_type'])
842
+            ->setPermissions((int)$data['permissions'])
843
+            ->setTarget($data['file_target'])
844
+            ->setMailSend((bool)$data['mail_send']);
845
+
846
+        $shareTime = new \DateTime();
847
+        $shareTime->setTimestamp((int)$data['stime']);
848
+        $share->setShareTime($shareTime);
849
+
850
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
851
+            $share->setSharedWith($data['share_with']);
852
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
853
+            $share->setSharedWith($data['share_with']);
854
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
855
+            $share->setPassword($data['password']);
856
+            $share->setToken($data['token']);
857
+        }
858
+
859
+        $share->setSharedBy($data['uid_initiator']);
860
+        $share->setShareOwner($data['uid_owner']);
861
+
862
+        $share->setNodeId((int)$data['file_source']);
863
+        $share->setNodeType($data['item_type']);
864
+
865
+        if ($data['expiration'] !== null) {
866
+            $expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
867
+            $share->setExpirationDate($expiration);
868
+        }
869
+
870
+        if (isset($data['f_permissions'])) {
871
+            $entryData = $data;
872
+            $entryData['permissions'] = $entryData['f_permissions'];
873
+            $entryData['parent'] = $entryData['f_parent'];
874
+            $share->setNodeCacheEntry(Cache::cacheEntryFromData($entryData,
875
+                \OC::$server->getMimeTypeLoader()));
876
+        }
877
+
878
+        $share->setProviderId($this->identifier());
879
+
880
+        return $share;
881
+    }
882
+
883
+    /**
884
+     * @param Share[] $shares
885
+     * @param $userId
886
+     * @return Share[] The updates shares if no update is found for a share return the original
887
+     */
888
+    private function resolveGroupShares($shares, $userId) {
889
+        $result = [];
890
+
891
+        $start = 0;
892
+        while(true) {
893
+            /** @var Share[] $shareSlice */
894
+            $shareSlice = array_slice($shares, $start, 100);
895
+            $start += 100;
896
+
897
+            if ($shareSlice === []) {
898
+                break;
899
+            }
900
+
901
+            /** @var int[] $ids */
902
+            $ids = [];
903
+            /** @var Share[] $shareMap */
904
+            $shareMap = [];
905
+
906
+            foreach ($shareSlice as $share) {
907
+                $ids[] = (int)$share->getId();
908
+                $shareMap[$share->getId()] = $share;
909
+            }
910
+
911
+            $qb = $this->dbConn->getQueryBuilder();
912
+
913
+            $query = $qb->select('*')
914
+                ->from('share')
915
+                ->where($qb->expr()->in('parent', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
916
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
917
+                ->andWhere($qb->expr()->orX(
918
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
919
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
920
+                ));
921
+
922
+            $stmt = $query->execute();
923
+
924
+            while($data = $stmt->fetch()) {
925
+                $shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
926
+                $shareMap[$data['parent']]->setTarget($data['file_target']);
927
+            }
928
+
929
+            $stmt->closeCursor();
930
+
931
+            foreach ($shareMap as $share) {
932
+                $result[] = $share;
933
+            }
934
+        }
935
+
936
+        return $result;
937
+    }
938
+
939
+    /**
940
+     * A user is deleted from the system
941
+     * So clean up the relevant shares.
942
+     *
943
+     * @param string $uid
944
+     * @param int $shareType
945
+     */
946
+    public function userDeleted($uid, $shareType) {
947
+        $qb = $this->dbConn->getQueryBuilder();
948
+
949
+        $qb->delete('share');
950
+
951
+        if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
952
+            /*
953 953
 			 * Delete all user shares that are owned by this user
954 954
 			 * or that are received by this user
955 955
 			 */
956 956
 
957
-			$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)));
957
+            $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)));
958 958
 
959
-			$qb->andWhere(
960
-				$qb->expr()->orX(
961
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
962
-					$qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
963
-				)
964
-			);
965
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
966
-			/*
959
+            $qb->andWhere(
960
+                $qb->expr()->orX(
961
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
962
+                    $qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
963
+                )
964
+            );
965
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
966
+            /*
967 967
 			 * Delete all group shares that are owned by this user
968 968
 			 * Or special user group shares that are received by this user
969 969
 			 */
970
-			$qb->where(
971
-				$qb->expr()->andX(
972
-					$qb->expr()->orX(
973
-						$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
974
-						$qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP))
975
-					),
976
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid))
977
-				)
978
-			);
979
-
980
-			$qb->orWhere(
981
-				$qb->expr()->andX(
982
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)),
983
-					$qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
984
-				)
985
-			);
986
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
987
-			/*
970
+            $qb->where(
971
+                $qb->expr()->andX(
972
+                    $qb->expr()->orX(
973
+                        $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
974
+                        $qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP))
975
+                    ),
976
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid))
977
+                )
978
+            );
979
+
980
+            $qb->orWhere(
981
+                $qb->expr()->andX(
982
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)),
983
+                    $qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
984
+                )
985
+            );
986
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
987
+            /*
988 988
 			 * Delete all link shares owned by this user.
989 989
 			 * And all link shares initiated by this user (until #22327 is in)
990 990
 			 */
991
-			$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK)));
992
-
993
-			$qb->andWhere(
994
-				$qb->expr()->orX(
995
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
996
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($uid))
997
-				)
998
-			);
999
-		}
1000
-
1001
-		$qb->execute();
1002
-	}
1003
-
1004
-	/**
1005
-	 * Delete all shares received by this group. As well as any custom group
1006
-	 * shares for group members.
1007
-	 *
1008
-	 * @param string $gid
1009
-	 */
1010
-	public function groupDeleted($gid) {
1011
-		/*
991
+            $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK)));
992
+
993
+            $qb->andWhere(
994
+                $qb->expr()->orX(
995
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
996
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($uid))
997
+                )
998
+            );
999
+        }
1000
+
1001
+        $qb->execute();
1002
+    }
1003
+
1004
+    /**
1005
+     * Delete all shares received by this group. As well as any custom group
1006
+     * shares for group members.
1007
+     *
1008
+     * @param string $gid
1009
+     */
1010
+    public function groupDeleted($gid) {
1011
+        /*
1012 1012
 		 * First delete all custom group shares for group members
1013 1013
 		 */
1014
-		$qb = $this->dbConn->getQueryBuilder();
1015
-		$qb->select('id')
1016
-			->from('share')
1017
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1018
-			->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1019
-
1020
-		$cursor = $qb->execute();
1021
-		$ids = [];
1022
-		while($row = $cursor->fetch()) {
1023
-			$ids[] = (int)$row['id'];
1024
-		}
1025
-		$cursor->closeCursor();
1026
-
1027
-		if (!empty($ids)) {
1028
-			$chunks = array_chunk($ids, 100);
1029
-			foreach ($chunks as $chunk) {
1030
-				$qb->delete('share')
1031
-					->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
1032
-					->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1033
-				$qb->execute();
1034
-			}
1035
-		}
1036
-
1037
-		/*
1014
+        $qb = $this->dbConn->getQueryBuilder();
1015
+        $qb->select('id')
1016
+            ->from('share')
1017
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1018
+            ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1019
+
1020
+        $cursor = $qb->execute();
1021
+        $ids = [];
1022
+        while($row = $cursor->fetch()) {
1023
+            $ids[] = (int)$row['id'];
1024
+        }
1025
+        $cursor->closeCursor();
1026
+
1027
+        if (!empty($ids)) {
1028
+            $chunks = array_chunk($ids, 100);
1029
+            foreach ($chunks as $chunk) {
1030
+                $qb->delete('share')
1031
+                    ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
1032
+                    ->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1033
+                $qb->execute();
1034
+            }
1035
+        }
1036
+
1037
+        /*
1038 1038
 		 * Now delete all the group shares
1039 1039
 		 */
1040
-		$qb = $this->dbConn->getQueryBuilder();
1041
-		$qb->delete('share')
1042
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1043
-			->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1044
-		$qb->execute();
1045
-	}
1046
-
1047
-	/**
1048
-	 * Delete custom group shares to this group for this user
1049
-	 *
1050
-	 * @param string $uid
1051
-	 * @param string $gid
1052
-	 */
1053
-	public function userDeletedFromGroup($uid, $gid) {
1054
-		/*
1040
+        $qb = $this->dbConn->getQueryBuilder();
1041
+        $qb->delete('share')
1042
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1043
+            ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1044
+        $qb->execute();
1045
+    }
1046
+
1047
+    /**
1048
+     * Delete custom group shares to this group for this user
1049
+     *
1050
+     * @param string $uid
1051
+     * @param string $gid
1052
+     */
1053
+    public function userDeletedFromGroup($uid, $gid) {
1054
+        /*
1055 1055
 		 * Get all group shares
1056 1056
 		 */
1057
-		$qb = $this->dbConn->getQueryBuilder();
1058
-		$qb->select('id')
1059
-			->from('share')
1060
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1061
-			->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1062
-
1063
-		$cursor = $qb->execute();
1064
-		$ids = [];
1065
-		while($row = $cursor->fetch()) {
1066
-			$ids[] = (int)$row['id'];
1067
-		}
1068
-		$cursor->closeCursor();
1069
-
1070
-		if (!empty($ids)) {
1071
-			$chunks = array_chunk($ids, 100);
1072
-			foreach ($chunks as $chunk) {
1073
-				/*
1057
+        $qb = $this->dbConn->getQueryBuilder();
1058
+        $qb->select('id')
1059
+            ->from('share')
1060
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)))
1061
+            ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1062
+
1063
+        $cursor = $qb->execute();
1064
+        $ids = [];
1065
+        while($row = $cursor->fetch()) {
1066
+            $ids[] = (int)$row['id'];
1067
+        }
1068
+        $cursor->closeCursor();
1069
+
1070
+        if (!empty($ids)) {
1071
+            $chunks = array_chunk($ids, 100);
1072
+            foreach ($chunks as $chunk) {
1073
+                /*
1074 1074
 				 * Delete all special shares wit this users for the found group shares
1075 1075
 				 */
1076
-				$qb->delete('share')
1077
-					->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
1078
-					->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($uid)))
1079
-					->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1080
-				$qb->execute();
1081
-			}
1082
-		}
1083
-	}
1084
-
1085
-	/**
1086
-	 * @inheritdoc
1087
-	 */
1088
-	public function getAccessList($nodes, $currentAccess) {
1089
-		$ids = [];
1090
-		foreach ($nodes as $node) {
1091
-			$ids[] = $node->getId();
1092
-		}
1093
-
1094
-		$qb = $this->dbConn->getQueryBuilder();
1095
-
1096
-		$or = $qb->expr()->orX(
1097
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
1098
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
1099
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK))
1100
-		);
1101
-
1102
-		if ($currentAccess) {
1103
-			$or->add($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)));
1104
-		}
1105
-
1106
-		$qb->select('id', 'parent', 'share_type', 'share_with', 'file_source', 'file_target', 'permissions')
1107
-			->from('share')
1108
-			->where(
1109
-				$or
1110
-			)
1111
-			->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1112
-			->andWhere($qb->expr()->orX(
1113
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1114
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1115
-			));
1116
-		$cursor = $qb->execute();
1117
-
1118
-		$users = [];
1119
-		$link = false;
1120
-		while($row = $cursor->fetch()) {
1121
-			$type = (int)$row['share_type'];
1122
-			if ($type === \OCP\Share::SHARE_TYPE_USER) {
1123
-				$uid = $row['share_with'];
1124
-				$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1125
-				$users[$uid][$row['id']] = $row;
1126
-			} else if ($type === \OCP\Share::SHARE_TYPE_GROUP) {
1127
-				$gid = $row['share_with'];
1128
-				$group = $this->groupManager->get($gid);
1129
-
1130
-				if ($group === null) {
1131
-					continue;
1132
-				}
1133
-
1134
-				$userList = $group->getUsers();
1135
-				foreach ($userList as $user) {
1136
-					$uid = $user->getUID();
1137
-					$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1138
-					$users[$uid][$row['id']] = $row;
1139
-				}
1140
-			} else if ($type === \OCP\Share::SHARE_TYPE_LINK) {
1141
-				$link = true;
1142
-			} else if ($type === self::SHARE_TYPE_USERGROUP && $currentAccess === true) {
1143
-				$uid = $row['share_with'];
1144
-				$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1145
-				$users[$uid][$row['id']] = $row;
1146
-			}
1147
-		}
1148
-		$cursor->closeCursor();
1149
-
1150
-		if ($currentAccess === true) {
1151
-			$users = array_map([$this, 'filterSharesOfUser'], $users);
1152
-			$users = array_filter($users);
1153
-		} else {
1154
-			$users = array_keys($users);
1155
-		}
1156
-
1157
-		return ['users' => $users, 'public' => $link];
1158
-	}
1159
-
1160
-	/**
1161
-	 * For each user the path with the fewest slashes is returned
1162
-	 * @param array $shares
1163
-	 * @return array
1164
-	 */
1165
-	protected function filterSharesOfUser(array $shares) {
1166
-		// Group shares when the user has a share exception
1167
-		foreach ($shares as $id => $share) {
1168
-			$type = (int) $share['share_type'];
1169
-			$permissions = (int) $share['permissions'];
1170
-
1171
-			if ($type === self::SHARE_TYPE_USERGROUP) {
1172
-				unset($shares[$share['parent']]);
1173
-
1174
-				if ($permissions === 0) {
1175
-					unset($shares[$id]);
1176
-				}
1177
-			}
1178
-		}
1179
-
1180
-		$best = [];
1181
-		$bestDepth = 0;
1182
-		foreach ($shares as $id => $share) {
1183
-			$depth = substr_count($share['file_target'], '/');
1184
-			if (empty($best) || $depth < $bestDepth) {
1185
-				$bestDepth = $depth;
1186
-				$best = [
1187
-					'node_id' => $share['file_source'],
1188
-					'node_path' => $share['file_target'],
1189
-				];
1190
-			}
1191
-		}
1192
-
1193
-		return $best;
1194
-	}
1076
+                $qb->delete('share')
1077
+                    ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)))
1078
+                    ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($uid)))
1079
+                    ->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1080
+                $qb->execute();
1081
+            }
1082
+        }
1083
+    }
1084
+
1085
+    /**
1086
+     * @inheritdoc
1087
+     */
1088
+    public function getAccessList($nodes, $currentAccess) {
1089
+        $ids = [];
1090
+        foreach ($nodes as $node) {
1091
+            $ids[] = $node->getId();
1092
+        }
1093
+
1094
+        $qb = $this->dbConn->getQueryBuilder();
1095
+
1096
+        $or = $qb->expr()->orX(
1097
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)),
1098
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)),
1099
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_LINK))
1100
+        );
1101
+
1102
+        if ($currentAccess) {
1103
+            $or->add($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP)));
1104
+        }
1105
+
1106
+        $qb->select('id', 'parent', 'share_type', 'share_with', 'file_source', 'file_target', 'permissions')
1107
+            ->from('share')
1108
+            ->where(
1109
+                $or
1110
+            )
1111
+            ->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1112
+            ->andWhere($qb->expr()->orX(
1113
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1114
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1115
+            ));
1116
+        $cursor = $qb->execute();
1117
+
1118
+        $users = [];
1119
+        $link = false;
1120
+        while($row = $cursor->fetch()) {
1121
+            $type = (int)$row['share_type'];
1122
+            if ($type === \OCP\Share::SHARE_TYPE_USER) {
1123
+                $uid = $row['share_with'];
1124
+                $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1125
+                $users[$uid][$row['id']] = $row;
1126
+            } else if ($type === \OCP\Share::SHARE_TYPE_GROUP) {
1127
+                $gid = $row['share_with'];
1128
+                $group = $this->groupManager->get($gid);
1129
+
1130
+                if ($group === null) {
1131
+                    continue;
1132
+                }
1133
+
1134
+                $userList = $group->getUsers();
1135
+                foreach ($userList as $user) {
1136
+                    $uid = $user->getUID();
1137
+                    $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1138
+                    $users[$uid][$row['id']] = $row;
1139
+                }
1140
+            } else if ($type === \OCP\Share::SHARE_TYPE_LINK) {
1141
+                $link = true;
1142
+            } else if ($type === self::SHARE_TYPE_USERGROUP && $currentAccess === true) {
1143
+                $uid = $row['share_with'];
1144
+                $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1145
+                $users[$uid][$row['id']] = $row;
1146
+            }
1147
+        }
1148
+        $cursor->closeCursor();
1149
+
1150
+        if ($currentAccess === true) {
1151
+            $users = array_map([$this, 'filterSharesOfUser'], $users);
1152
+            $users = array_filter($users);
1153
+        } else {
1154
+            $users = array_keys($users);
1155
+        }
1156
+
1157
+        return ['users' => $users, 'public' => $link];
1158
+    }
1159
+
1160
+    /**
1161
+     * For each user the path with the fewest slashes is returned
1162
+     * @param array $shares
1163
+     * @return array
1164
+     */
1165
+    protected function filterSharesOfUser(array $shares) {
1166
+        // Group shares when the user has a share exception
1167
+        foreach ($shares as $id => $share) {
1168
+            $type = (int) $share['share_type'];
1169
+            $permissions = (int) $share['permissions'];
1170
+
1171
+            if ($type === self::SHARE_TYPE_USERGROUP) {
1172
+                unset($shares[$share['parent']]);
1173
+
1174
+                if ($permissions === 0) {
1175
+                    unset($shares[$id]);
1176
+                }
1177
+            }
1178
+        }
1179
+
1180
+        $best = [];
1181
+        $bestDepth = 0;
1182
+        foreach ($shares as $id => $share) {
1183
+            $depth = substr_count($share['file_target'], '/');
1184
+            if (empty($best) || $depth < $bestDepth) {
1185
+                $bestDepth = $depth;
1186
+                $best = [
1187
+                    'node_id' => $share['file_source'],
1188
+                    'node_path' => $share['file_target'],
1189
+                ];
1190
+            }
1191
+        }
1192
+
1193
+        return $best;
1194
+    }
1195 1195
 }
Please login to merge, or discard this patch.