Passed
Push — master ( 30e999...85099f )
by Joas
12:49 queued 11s
created
lib/private/Share/Helper.php 1 patch
Indentation   +232 added lines, -232 removed lines patch added patch discarded remove patch
@@ -35,260 +35,260 @@
 block discarded – undo
35 35
 
36 36
 class Helper extends \OC\Share\Constants {
37 37
 
38
-	/**
39
-	 * Generate a unique target for the item
40
-	 * @param string $itemType
41
-	 * @param string $itemSource
42
-	 * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
43
-	 * @param string $shareWith User or group the item is being shared with
44
-	 * @param string $uidOwner User that is the owner of shared item
45
-	 * @param string $suggestedTarget The suggested target originating from a reshare (optional)
46
-	 * @param int $groupParent The id of the parent group share (optional)
47
-	 * @throws \Exception
48
-	 * @return string Item target
49
-	 */
50
-	public static function generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $suggestedTarget = null, $groupParent = null) {
51
-		// FIXME: $uidOwner and $groupParent seems to be unused
52
-		$backend = \OC\Share\Share::getBackend($itemType);
53
-		if ($shareType === IShare::TYPE_LINK || $shareType === IShare::TYPE_REMOTE) {
54
-			if (isset($suggestedTarget)) {
55
-				return $suggestedTarget;
56
-			}
57
-			return $backend->generateTarget($itemSource, false);
58
-		} else {
59
-			if ($shareType == IShare::TYPE_USER) {
60
-				// Share with is a user, so set share type to user and groups
61
-				$shareType = self::$shareTypeUserAndGroups;
62
-			}
38
+    /**
39
+     * Generate a unique target for the item
40
+     * @param string $itemType
41
+     * @param string $itemSource
42
+     * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
43
+     * @param string $shareWith User or group the item is being shared with
44
+     * @param string $uidOwner User that is the owner of shared item
45
+     * @param string $suggestedTarget The suggested target originating from a reshare (optional)
46
+     * @param int $groupParent The id of the parent group share (optional)
47
+     * @throws \Exception
48
+     * @return string Item target
49
+     */
50
+    public static function generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $suggestedTarget = null, $groupParent = null) {
51
+        // FIXME: $uidOwner and $groupParent seems to be unused
52
+        $backend = \OC\Share\Share::getBackend($itemType);
53
+        if ($shareType === IShare::TYPE_LINK || $shareType === IShare::TYPE_REMOTE) {
54
+            if (isset($suggestedTarget)) {
55
+                return $suggestedTarget;
56
+            }
57
+            return $backend->generateTarget($itemSource, false);
58
+        } else {
59
+            if ($shareType == IShare::TYPE_USER) {
60
+                // Share with is a user, so set share type to user and groups
61
+                $shareType = self::$shareTypeUserAndGroups;
62
+            }
63 63
 
64
-			// Check if suggested target exists first
65
-			if (!isset($suggestedTarget)) {
66
-				$suggestedTarget = $itemSource;
67
-			}
68
-			if ($shareType == IShare::TYPE_GROUP) {
69
-				$target = $backend->generateTarget($suggestedTarget, false);
70
-			} else {
71
-				$target = $backend->generateTarget($suggestedTarget, $shareWith);
72
-			}
64
+            // Check if suggested target exists first
65
+            if (!isset($suggestedTarget)) {
66
+                $suggestedTarget = $itemSource;
67
+            }
68
+            if ($shareType == IShare::TYPE_GROUP) {
69
+                $target = $backend->generateTarget($suggestedTarget, false);
70
+            } else {
71
+                $target = $backend->generateTarget($suggestedTarget, $shareWith);
72
+            }
73 73
 
74
-			return $target;
75
-		}
76
-	}
74
+            return $target;
75
+        }
76
+    }
77 77
 
78
-	/**
79
-	 * Delete all reshares and group share children of an item
80
-	 * @param int $parent Id of item to delete
81
-	 * @param bool $excludeParent If true, exclude the parent from the delete (optional)
82
-	 * @param string $uidOwner The user that the parent was shared with (optional)
83
-	 * @param int $newParent new parent for the childrens
84
-	 * @param bool $excludeGroupChildren exclude group children elements
85
-	 */
86
-	public static function delete($parent, $excludeParent = false, $uidOwner = null, $newParent = null, $excludeGroupChildren = false) {
87
-		$ids = [$parent];
88
-		$deletedItems = [];
89
-		$changeParent = [];
90
-		$parents = [$parent];
91
-		while (!empty($parents)) {
92
-			$parents = "'".implode("','", $parents)."'";
93
-			// Check the owner on the first search of reshares, useful for
94
-			// finding and deleting the reshares by a single user of a group share
95
-			$params = [];
96
-			if (count($ids) == 1 && isset($uidOwner)) {
97
-				// FIXME: don't concat $parents, use Docrine's PARAM_INT_ARRAY approach
98
-				$queryString = 'SELECT `id`, `share_with`, `item_type`, `share_type`, ' .
99
-					'`item_target`, `file_target`, `parent` ' .
100
-					'FROM `*PREFIX*share` ' .
101
-					'WHERE `parent` IN ('.$parents.') AND `uid_owner` = ? ';
102
-				$params[] = $uidOwner;
103
-			} else {
104
-				$queryString = 'SELECT `id`, `share_with`, `item_type`, `share_type`, ' .
105
-					'`item_target`, `file_target`, `parent`, `uid_owner` ' .
106
-					'FROM `*PREFIX*share` WHERE `parent` IN ('.$parents.') ';
107
-			}
108
-			if ($excludeGroupChildren) {
109
-				$queryString .= ' AND `share_type` != ?';
110
-				$params[] = self::$shareTypeGroupUserUnique;
111
-			}
112
-			$query = \OC_DB::prepare($queryString);
113
-			$result = $query->execute($params);
114
-			// Reset parents array, only go through loop again if items are found
115
-			$parents = [];
116
-			while ($item = $result->fetchRow()) {
117
-				$tmpItem = [
118
-					'id' => $item['id'],
119
-					'shareWith' => $item['share_with'],
120
-					'itemTarget' => $item['item_target'],
121
-					'itemType' => $item['item_type'],
122
-					'shareType' => (int)$item['share_type'],
123
-				];
124
-				if (isset($item['file_target'])) {
125
-					$tmpItem['fileTarget'] = $item['file_target'];
126
-				}
127
-				// if we have a new parent for the child we remember the child
128
-				// to update the parent, if not we add it to the list of items
129
-				// which should be deleted
130
-				if ($newParent !== null) {
131
-					$changeParent[] = $item['id'];
132
-				} else {
133
-					$deletedItems[] = $tmpItem;
134
-					$ids[] = $item['id'];
135
-					$parents[] = $item['id'];
136
-				}
137
-			}
138
-		}
139
-		if ($excludeParent) {
140
-			unset($ids[0]);
141
-		}
78
+    /**
79
+     * Delete all reshares and group share children of an item
80
+     * @param int $parent Id of item to delete
81
+     * @param bool $excludeParent If true, exclude the parent from the delete (optional)
82
+     * @param string $uidOwner The user that the parent was shared with (optional)
83
+     * @param int $newParent new parent for the childrens
84
+     * @param bool $excludeGroupChildren exclude group children elements
85
+     */
86
+    public static function delete($parent, $excludeParent = false, $uidOwner = null, $newParent = null, $excludeGroupChildren = false) {
87
+        $ids = [$parent];
88
+        $deletedItems = [];
89
+        $changeParent = [];
90
+        $parents = [$parent];
91
+        while (!empty($parents)) {
92
+            $parents = "'".implode("','", $parents)."'";
93
+            // Check the owner on the first search of reshares, useful for
94
+            // finding and deleting the reshares by a single user of a group share
95
+            $params = [];
96
+            if (count($ids) == 1 && isset($uidOwner)) {
97
+                // FIXME: don't concat $parents, use Docrine's PARAM_INT_ARRAY approach
98
+                $queryString = 'SELECT `id`, `share_with`, `item_type`, `share_type`, ' .
99
+                    '`item_target`, `file_target`, `parent` ' .
100
+                    'FROM `*PREFIX*share` ' .
101
+                    'WHERE `parent` IN ('.$parents.') AND `uid_owner` = ? ';
102
+                $params[] = $uidOwner;
103
+            } else {
104
+                $queryString = 'SELECT `id`, `share_with`, `item_type`, `share_type`, ' .
105
+                    '`item_target`, `file_target`, `parent`, `uid_owner` ' .
106
+                    'FROM `*PREFIX*share` WHERE `parent` IN ('.$parents.') ';
107
+            }
108
+            if ($excludeGroupChildren) {
109
+                $queryString .= ' AND `share_type` != ?';
110
+                $params[] = self::$shareTypeGroupUserUnique;
111
+            }
112
+            $query = \OC_DB::prepare($queryString);
113
+            $result = $query->execute($params);
114
+            // Reset parents array, only go through loop again if items are found
115
+            $parents = [];
116
+            while ($item = $result->fetchRow()) {
117
+                $tmpItem = [
118
+                    'id' => $item['id'],
119
+                    'shareWith' => $item['share_with'],
120
+                    'itemTarget' => $item['item_target'],
121
+                    'itemType' => $item['item_type'],
122
+                    'shareType' => (int)$item['share_type'],
123
+                ];
124
+                if (isset($item['file_target'])) {
125
+                    $tmpItem['fileTarget'] = $item['file_target'];
126
+                }
127
+                // if we have a new parent for the child we remember the child
128
+                // to update the parent, if not we add it to the list of items
129
+                // which should be deleted
130
+                if ($newParent !== null) {
131
+                    $changeParent[] = $item['id'];
132
+                } else {
133
+                    $deletedItems[] = $tmpItem;
134
+                    $ids[] = $item['id'];
135
+                    $parents[] = $item['id'];
136
+                }
137
+            }
138
+        }
139
+        if ($excludeParent) {
140
+            unset($ids[0]);
141
+        }
142 142
 
143
-		if (!empty($changeParent)) {
144
-			$idList = "'".implode("','", $changeParent)."'";
145
-			$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `parent` = ? WHERE `id` IN ('.$idList.')');
146
-			$query->execute([$newParent]);
147
-		}
143
+        if (!empty($changeParent)) {
144
+            $idList = "'".implode("','", $changeParent)."'";
145
+            $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `parent` = ? WHERE `id` IN ('.$idList.')');
146
+            $query->execute([$newParent]);
147
+        }
148 148
 
149
-		if (!empty($ids)) {
150
-			$idList = "'".implode("','", $ids)."'";
151
-			$query = \OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `id` IN ('.$idList.')');
152
-			$query->execute();
153
-		}
149
+        if (!empty($ids)) {
150
+            $idList = "'".implode("','", $ids)."'";
151
+            $query = \OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `id` IN ('.$idList.')');
152
+            $query->execute();
153
+        }
154 154
 
155
-		return $deletedItems;
156
-	}
155
+        return $deletedItems;
156
+    }
157 157
 
158
-	/**
159
-	 * get default expire settings defined by the admin
160
-	 * @return array contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays'
161
-	 */
162
-	public static function getDefaultExpireSetting() {
163
-		$config = \OC::$server->getConfig();
158
+    /**
159
+     * get default expire settings defined by the admin
160
+     * @return array contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays'
161
+     */
162
+    public static function getDefaultExpireSetting() {
163
+        $config = \OC::$server->getConfig();
164 164
 
165
-		$defaultExpireSettings = ['defaultExpireDateSet' => false];
165
+        $defaultExpireSettings = ['defaultExpireDateSet' => false];
166 166
 
167
-		// get default expire settings
168
-		$defaultExpireDate = $config->getAppValue('core', 'shareapi_default_expire_date', 'no');
169
-		if ($defaultExpireDate === 'yes') {
170
-			$enforceExpireDate = $config->getAppValue('core', 'shareapi_enforce_expire_date', 'no');
171
-			$defaultExpireSettings['defaultExpireDateSet'] = true;
172
-			$defaultExpireSettings['expireAfterDays'] = (int)$config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
173
-			$defaultExpireSettings['enforceExpireDate'] = $enforceExpireDate === 'yes';
174
-		}
167
+        // get default expire settings
168
+        $defaultExpireDate = $config->getAppValue('core', 'shareapi_default_expire_date', 'no');
169
+        if ($defaultExpireDate === 'yes') {
170
+            $enforceExpireDate = $config->getAppValue('core', 'shareapi_enforce_expire_date', 'no');
171
+            $defaultExpireSettings['defaultExpireDateSet'] = true;
172
+            $defaultExpireSettings['expireAfterDays'] = (int)$config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
173
+            $defaultExpireSettings['enforceExpireDate'] = $enforceExpireDate === 'yes';
174
+        }
175 175
 
176
-		return $defaultExpireSettings;
177
-	}
176
+        return $defaultExpireSettings;
177
+    }
178 178
 
179
-	public static function calcExpireDate() {
180
-		$expireAfter = \OC\Share\Share::getExpireInterval() * 24 * 60 * 60;
181
-		$expireAt = time() + $expireAfter;
182
-		$date = new \DateTime();
183
-		$date->setTimestamp($expireAt);
184
-		$date->setTime(0, 0, 0);
185
-		//$dateString = $date->format('Y-m-d') . ' 00:00:00';
179
+    public static function calcExpireDate() {
180
+        $expireAfter = \OC\Share\Share::getExpireInterval() * 24 * 60 * 60;
181
+        $expireAt = time() + $expireAfter;
182
+        $date = new \DateTime();
183
+        $date->setTimestamp($expireAt);
184
+        $date->setTime(0, 0, 0);
185
+        //$dateString = $date->format('Y-m-d') . ' 00:00:00';
186 186
 
187
-		return $date;
188
-	}
187
+        return $date;
188
+    }
189 189
 
190
-	/**
191
-	 * calculate expire date
192
-	 * @param array $defaultExpireSettings contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays'
193
-	 * @param int $creationTime timestamp when the share was created
194
-	 * @param int $userExpireDate expire timestamp set by the user
195
-	 * @return mixed integer timestamp or False
196
-	 */
197
-	public static function calculateExpireDate($defaultExpireSettings, $creationTime, $userExpireDate = null) {
198
-		$expires = false;
199
-		$defaultExpires = null;
190
+    /**
191
+     * calculate expire date
192
+     * @param array $defaultExpireSettings contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays'
193
+     * @param int $creationTime timestamp when the share was created
194
+     * @param int $userExpireDate expire timestamp set by the user
195
+     * @return mixed integer timestamp or False
196
+     */
197
+    public static function calculateExpireDate($defaultExpireSettings, $creationTime, $userExpireDate = null) {
198
+        $expires = false;
199
+        $defaultExpires = null;
200 200
 
201
-		if (!empty($defaultExpireSettings['defaultExpireDateSet'])) {
202
-			$defaultExpires = $creationTime + $defaultExpireSettings['expireAfterDays'] * 86400;
203
-		}
201
+        if (!empty($defaultExpireSettings['defaultExpireDateSet'])) {
202
+            $defaultExpires = $creationTime + $defaultExpireSettings['expireAfterDays'] * 86400;
203
+        }
204 204
 
205 205
 
206
-		if (isset($userExpireDate)) {
207
-			// if the admin decided to enforce the default expire date then we only take
208
-			// the user defined expire date of it is before the default expire date
209
-			if ($defaultExpires && !empty($defaultExpireSettings['enforceExpireDate'])) {
210
-				$expires = min($userExpireDate, $defaultExpires);
211
-			} else {
212
-				$expires = $userExpireDate;
213
-			}
214
-		} elseif ($defaultExpires && !empty($defaultExpireSettings['enforceExpireDate'])) {
215
-			$expires = $defaultExpires;
216
-		}
206
+        if (isset($userExpireDate)) {
207
+            // if the admin decided to enforce the default expire date then we only take
208
+            // the user defined expire date of it is before the default expire date
209
+            if ($defaultExpires && !empty($defaultExpireSettings['enforceExpireDate'])) {
210
+                $expires = min($userExpireDate, $defaultExpires);
211
+            } else {
212
+                $expires = $userExpireDate;
213
+            }
214
+        } elseif ($defaultExpires && !empty($defaultExpireSettings['enforceExpireDate'])) {
215
+            $expires = $defaultExpires;
216
+        }
217 217
 
218
-		return $expires;
219
-	}
218
+        return $expires;
219
+    }
220 220
 
221
-	/**
222
-	 * Strips away a potential file names and trailing slashes:
223
-	 * - http://localhost
224
-	 * - http://localhost/
225
-	 * - http://localhost/index.php
226
-	 * - http://localhost/index.php/s/{shareToken}
227
-	 *
228
-	 * all return: http://localhost
229
-	 *
230
-	 * @param string $remote
231
-	 * @return string
232
-	 */
233
-	protected static function fixRemoteURL($remote) {
234
-		$remote = str_replace('\\', '/', $remote);
235
-		if ($fileNamePosition = strpos($remote, '/index.php')) {
236
-			$remote = substr($remote, 0, $fileNamePosition);
237
-		}
238
-		$remote = rtrim($remote, '/');
221
+    /**
222
+     * Strips away a potential file names and trailing slashes:
223
+     * - http://localhost
224
+     * - http://localhost/
225
+     * - http://localhost/index.php
226
+     * - http://localhost/index.php/s/{shareToken}
227
+     *
228
+     * all return: http://localhost
229
+     *
230
+     * @param string $remote
231
+     * @return string
232
+     */
233
+    protected static function fixRemoteURL($remote) {
234
+        $remote = str_replace('\\', '/', $remote);
235
+        if ($fileNamePosition = strpos($remote, '/index.php')) {
236
+            $remote = substr($remote, 0, $fileNamePosition);
237
+        }
238
+        $remote = rtrim($remote, '/');
239 239
 
240
-		return $remote;
241
-	}
240
+        return $remote;
241
+    }
242 242
 
243
-	/**
244
-	 * split user and remote from federated cloud id
245
-	 *
246
-	 * @param string $id
247
-	 * @return string[]
248
-	 * @throws HintException
249
-	 */
250
-	public static function splitUserRemote($id) {
251
-		try {
252
-			$cloudId = \OC::$server->getCloudIdManager()->resolveCloudId($id);
253
-			return [$cloudId->getUser(), $cloudId->getRemote()];
254
-		} catch (\InvalidArgumentException $e) {
255
-			$l = \OC::$server->getL10N('core');
256
-			$hint = $l->t('Invalid Federated Cloud ID');
257
-			throw new HintException('Invalid Federated Cloud ID', $hint, 0, $e);
258
-		}
259
-	}
243
+    /**
244
+     * split user and remote from federated cloud id
245
+     *
246
+     * @param string $id
247
+     * @return string[]
248
+     * @throws HintException
249
+     */
250
+    public static function splitUserRemote($id) {
251
+        try {
252
+            $cloudId = \OC::$server->getCloudIdManager()->resolveCloudId($id);
253
+            return [$cloudId->getUser(), $cloudId->getRemote()];
254
+        } catch (\InvalidArgumentException $e) {
255
+            $l = \OC::$server->getL10N('core');
256
+            $hint = $l->t('Invalid Federated Cloud ID');
257
+            throw new HintException('Invalid Federated Cloud ID', $hint, 0, $e);
258
+        }
259
+    }
260 260
 
261
-	/**
262
-	 * check if two federated cloud IDs refer to the same user
263
-	 *
264
-	 * @param string $user1
265
-	 * @param string $server1
266
-	 * @param string $user2
267
-	 * @param string $server2
268
-	 * @return bool true if both users and servers are the same
269
-	 */
270
-	public static function isSameUserOnSameServer($user1, $server1, $user2, $server2) {
271
-		$normalizedServer1 = strtolower(\OC\Share\Share::removeProtocolFromUrl($server1));
272
-		$normalizedServer2 = strtolower(\OC\Share\Share::removeProtocolFromUrl($server2));
261
+    /**
262
+     * check if two federated cloud IDs refer to the same user
263
+     *
264
+     * @param string $user1
265
+     * @param string $server1
266
+     * @param string $user2
267
+     * @param string $server2
268
+     * @return bool true if both users and servers are the same
269
+     */
270
+    public static function isSameUserOnSameServer($user1, $server1, $user2, $server2) {
271
+        $normalizedServer1 = strtolower(\OC\Share\Share::removeProtocolFromUrl($server1));
272
+        $normalizedServer2 = strtolower(\OC\Share\Share::removeProtocolFromUrl($server2));
273 273
 
274
-		if (rtrim($normalizedServer1, '/') === rtrim($normalizedServer2, '/')) {
275
-			// FIXME this should be a method in the user management instead
276
-			\OCP\Util::emitHook(
277
-					'\OCA\Files_Sharing\API\Server2Server',
278
-					'preLoginNameUsedAsUserName',
279
-					['uid' => &$user1]
280
-			);
281
-			\OCP\Util::emitHook(
282
-					'\OCA\Files_Sharing\API\Server2Server',
283
-					'preLoginNameUsedAsUserName',
284
-					['uid' => &$user2]
285
-			);
274
+        if (rtrim($normalizedServer1, '/') === rtrim($normalizedServer2, '/')) {
275
+            // FIXME this should be a method in the user management instead
276
+            \OCP\Util::emitHook(
277
+                    '\OCA\Files_Sharing\API\Server2Server',
278
+                    'preLoginNameUsedAsUserName',
279
+                    ['uid' => &$user1]
280
+            );
281
+            \OCP\Util::emitHook(
282
+                    '\OCA\Files_Sharing\API\Server2Server',
283
+                    'preLoginNameUsedAsUserName',
284
+                    ['uid' => &$user2]
285
+            );
286 286
 
287
-			if ($user1 === $user2) {
288
-				return true;
289
-			}
290
-		}
287
+            if ($user1 === $user2) {
288
+                return true;
289
+            }
290
+        }
291 291
 
292
-		return false;
293
-	}
292
+        return false;
293
+    }
294 294
 }
Please login to merge, or discard this patch.
lib/private/Share/Share.php 2 patches
Indentation   +1482 added lines, -1482 removed lines patch added patch discarded remove patch
@@ -50,1486 +50,1486 @@
 block discarded – undo
50 50
  */
51 51
 class Share extends Constants {
52 52
 
53
-	/** CRUDS permissions (Create, Read, Update, Delete, Share) using a bitmask
54
-	 * Construct permissions for share() and setPermissions with Or (|) e.g.
55
-	 * Give user read and update permissions: PERMISSION_READ | PERMISSION_UPDATE
56
-	 *
57
-	 * Check if permission is granted with And (&) e.g. Check if delete is
58
-	 * granted: if ($permissions & PERMISSION_DELETE)
59
-	 *
60
-	 * Remove permissions with And (&) and Not (~) e.g. Remove the update
61
-	 * permission: $permissions &= ~PERMISSION_UPDATE
62
-	 *
63
-	 * Apps are required to handle permissions on their own, this class only
64
-	 * stores and manages the permissions of shares
65
-	 * @see lib/public/constants.php
66
-	 */
67
-
68
-	/**
69
-	 * Register a sharing backend class that implements OCP\Share_Backend for an item type
70
-	 * @param string $itemType Item type
71
-	 * @param string $class Backend class
72
-	 * @param string $collectionOf (optional) Depends on item type
73
-	 * @param array $supportedFileExtensions (optional) List of supported file extensions if this item type depends on files
74
-	 * @return boolean true if backend is registered or false if error
75
-	 */
76
-	public static function registerBackend($itemType, $class, $collectionOf = null, $supportedFileExtensions = null) {
77
-		if (\OC::$server->getConfig()->getAppValue('core', 'shareapi_enabled', 'yes') == 'yes') {
78
-			if (!isset(self::$backendTypes[$itemType])) {
79
-				self::$backendTypes[$itemType] = [
80
-					'class' => $class,
81
-					'collectionOf' => $collectionOf,
82
-					'supportedFileExtensions' => $supportedFileExtensions
83
-				];
84
-				return true;
85
-			}
86
-			\OCP\Util::writeLog('OCP\Share',
87
-				'Sharing backend '.$class.' not registered, '.self::$backendTypes[$itemType]['class']
88
-				.' is already registered for '.$itemType,
89
-				ILogger::WARN);
90
-		}
91
-		return false;
92
-	}
93
-
94
-	/**
95
-	 * Get the items of item type shared with the current user
96
-	 * @param string $itemType
97
-	 * @param int $format (optional) Format type must be defined by the backend
98
-	 * @param mixed $parameters (optional)
99
-	 * @param int $limit Number of items to return (optional) Returns all by default
100
-	 * @param boolean $includeCollections (optional)
101
-	 * @return mixed Return depends on format
102
-	 * @deprecated TESTS ONLY - this methods is only used by tests
103
-	 * called like this:
104
-	 * \OC\Share\Share::getItemsSharedWith('folder'); (apps/files_sharing/tests/UpdaterTest.php)
105
-	 */
106
-	public static function getItemsSharedWith() {
107
-		return self::getItems('folder', null, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, self::FORMAT_NONE,
108
-			null, -1, false);
109
-	}
110
-
111
-	/**
112
-	 * Get the items of item type shared with a user
113
-	 * @param string $itemType
114
-	 * @param string $user id for which user we want the shares
115
-	 * @param int $format (optional) Format type must be defined by the backend
116
-	 * @param mixed $parameters (optional)
117
-	 * @param int $limit Number of items to return (optional) Returns all by default
118
-	 * @param boolean $includeCollections (optional)
119
-	 * @return mixed Return depends on format
120
-	 */
121
-	public static function getItemsSharedWithUser($itemType, $user, $format = self::FORMAT_NONE,
122
-												  $parameters = null, $limit = -1, $includeCollections = false) {
123
-		return self::getItems($itemType, null, self::$shareTypeUserAndGroups, $user, null, $format,
124
-			$parameters, $limit, $includeCollections);
125
-	}
126
-
127
-	/**
128
-	 * Get the item of item type shared with a given user by source
129
-	 * @param string $itemType
130
-	 * @param string $itemSource
131
-	 * @param string $user User to whom the item was shared
132
-	 * @param string $owner Owner of the share
133
-	 * @param int $shareType only look for a specific share type
134
-	 * @return array Return list of items with file_target, permissions and expiration
135
-	 */
136
-	public static function getItemSharedWithUser($itemType, $itemSource, $user, $owner = null, $shareType = null) {
137
-		$shares = [];
138
-		$fileDependent = false;
139
-
140
-		$where = 'WHERE';
141
-		$fileDependentWhere = '';
142
-		if ($itemType === 'file' || $itemType === 'folder') {
143
-			$fileDependent = true;
144
-			$column = 'file_source';
145
-			$fileDependentWhere = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` ';
146
-			$fileDependentWhere .= 'INNER JOIN `*PREFIX*storages` ON `numeric_id` = `*PREFIX*filecache`.`storage` ';
147
-		} else {
148
-			$column = 'item_source';
149
-		}
150
-
151
-		$select = self::createSelectStatement(self::FORMAT_NONE, $fileDependent);
152
-
153
-		$where .= ' `' . $column . '` = ? AND `item_type` = ? ';
154
-		$arguments = [$itemSource, $itemType];
155
-		// for link shares $user === null
156
-		if ($user !== null) {
157
-			$where .= ' AND `share_with` = ? ';
158
-			$arguments[] = $user;
159
-		}
160
-
161
-		if ($shareType !== null) {
162
-			$where .= ' AND `share_type` = ? ';
163
-			$arguments[] = $shareType;
164
-		}
165
-
166
-		if ($owner !== null) {
167
-			$where .= ' AND `uid_owner` = ? ';
168
-			$arguments[] = $owner;
169
-		}
170
-
171
-		$query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` '. $fileDependentWhere . $where);
172
-
173
-		$result = \OC_DB::executeAudited($query, $arguments);
174
-
175
-		while ($row = $result->fetchRow()) {
176
-			if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) {
177
-				continue;
178
-			}
179
-			if ($fileDependent && (int)$row['file_parent'] === -1) {
180
-				// if it is a mount point we need to get the path from the mount manager
181
-				$mountManager = \OC\Files\Filesystem::getMountManager();
182
-				$mountPoint = $mountManager->findByStorageId($row['storage_id']);
183
-				if (!empty($mountPoint)) {
184
-					$path = $mountPoint[0]->getMountPoint();
185
-					$path = trim($path, '/');
186
-					$path = substr($path, strlen($owner) + 1); //normalize path to 'files/foo.txt`
187
-					$row['path'] = $path;
188
-				} else {
189
-					\OC::$server->getLogger()->warning(
190
-						'Could not resolve mount point for ' . $row['storage_id'],
191
-						['app' => 'OCP\Share']
192
-					);
193
-				}
194
-			}
195
-			$shares[] = $row;
196
-		}
197
-
198
-		//if didn't found a result than let's look for a group share.
199
-		if (empty($shares) && $user !== null) {
200
-			$userObject = \OC::$server->getUserManager()->get($user);
201
-			$groups = [];
202
-			if ($userObject) {
203
-				$groups = \OC::$server->getGroupManager()->getUserGroupIds($userObject);
204
-			}
205
-
206
-			if (!empty($groups)) {
207
-				$where = $fileDependentWhere . ' WHERE `' . $column . '` = ? AND `item_type` = ? AND `share_with` in (?)';
208
-				$arguments = [$itemSource, $itemType, $groups];
209
-				$types = [null, null, IQueryBuilder::PARAM_STR_ARRAY];
210
-
211
-				if ($owner !== null) {
212
-					$where .= ' AND `uid_owner` = ?';
213
-					$arguments[] = $owner;
214
-					$types[] = null;
215
-				}
216
-
217
-				// TODO: inject connection, hopefully one day in the future when this
218
-				// class isn't static anymore...
219
-				$conn = \OC::$server->getDatabaseConnection();
220
-				$result = $conn->executeQuery(
221
-					'SELECT ' . $select . ' FROM `*PREFIX*share` ' . $where,
222
-					$arguments,
223
-					$types
224
-				);
225
-
226
-				while ($row = $result->fetch()) {
227
-					$shares[] = $row;
228
-				}
229
-			}
230
-		}
231
-
232
-		return $shares;
233
-	}
234
-
235
-	/**
236
-	 * Get the item of item type shared with the current user by source
237
-	 * @param string $itemType
238
-	 * @param string $itemSource
239
-	 * @param int $format (optional) Format type must be defined by the backend
240
-	 * @param mixed $parameters
241
-	 * @param boolean $includeCollections
242
-	 * @param string $shareWith (optional) define against which user should be checked, default: current user
243
-	 * @return array
244
-	 */
245
-	public static function getItemSharedWithBySource($itemType, $itemSource, $format = self::FORMAT_NONE,
246
-													 $parameters = null, $includeCollections = false, $shareWith = null) {
247
-		$shareWith = ($shareWith === null) ? \OC_User::getUser() : $shareWith;
248
-		return self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups, $shareWith, null, $format,
249
-			$parameters, 1, $includeCollections, true);
250
-	}
251
-
252
-	/**
253
-	 * Get the shared item of item type owned by the current user
254
-	 * @param string $itemType
255
-	 * @param string $itemSource
256
-	 * @param int $format (optional) Format type must be defined by the backend
257
-	 * @param mixed $parameters
258
-	 * @param boolean $includeCollections
259
-	 * @return mixed Return depends on format
260
-	 */
261
-	public static function getItemShared($itemType, $itemSource, $format = self::FORMAT_NONE,
262
-										 $parameters = null, $includeCollections = false) {
263
-		return self::getItems($itemType, $itemSource, null, null, \OC_User::getUser(), $format,
264
-			$parameters, -1, $includeCollections);
265
-	}
266
-
267
-	/**
268
-	 * Share an item with a user, group, or via private link
269
-	 * @param string $itemType
270
-	 * @param string $itemSource
271
-	 * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
272
-	 * @param string $shareWith User or group the item is being shared with
273
-	 * @param int $permissions CRUDS
274
-	 * @param string $itemSourceName
275
-	 * @param \DateTime|null $expirationDate
276
-	 * @return boolean|string Returns true on success or false on failure, Returns token on success for links
277
-	 * @throws \OC\HintException when the share type is remote and the shareWith is invalid
278
-	 * @throws \Exception
279
-	 * @since 5.0.0 - parameter $itemSourceName was added in 6.0.0, parameter $expirationDate was added in 7.0.0, parameter $passwordChanged added in 9.0.0
280
-	 * @deprecated 14.0.0 TESTS ONLY - this methods is as of 2018-06 only used by tests
281
-	 * called like this:
282
-	 * \OC\Share\Share::shareItem('test', 1, IShare::TYPE_USER, $otherUserId, \OCP\Constants::PERMISSION_READ);
283
-	 */
284
-	public static function shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions) {
285
-		$backend = self::getBackend($itemType);
286
-
287
-		if ($backend->isShareTypeAllowed($shareType) === false) {
288
-			$message = 'Sharing failed, because the backend does not allow shares from type %i';
289
-			throw new \Exception(sprintf($message, $shareType));
290
-		}
291
-
292
-		$uidOwner = \OC_User::getUser();
293
-
294
-		// Verify share type and sharing conditions are met
295
-		if ($shareType === IShare::TYPE_USER) {
296
-			if ($shareWith == $uidOwner) {
297
-				$message = 'Sharing failed, because you can not share with yourself';
298
-				throw new \Exception($message);
299
-			}
300
-			if (!\OC::$server->getUserManager()->userExists($shareWith)) {
301
-				$message = 'Sharing failed, because the user %s does not exist';
302
-				throw new \Exception(sprintf($message, $shareWith));
303
-			}
304
-			// Check if the item source is already shared with the user, either from the same owner or a different user
305
-			if ($checkExists = self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups,
306
-				$shareWith, null, self::FORMAT_NONE, null, 1, true, true)) {
307
-				// Only allow the same share to occur again if it is the same
308
-				// owner and is not a user share, this use case is for increasing
309
-				// permissions for a specific user
310
-				if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) {
311
-					$message = 'Sharing failed, because this item is already shared with %s';
312
-					throw new \Exception(sprintf($message, $shareWith));
313
-				}
314
-			}
315
-			if ($checkExists = self::getItems($itemType, $itemSource, IShare::TYPE_USER,
316
-				$shareWith, null, self::FORMAT_NONE, null, 1, true, true)) {
317
-				// Only allow the same share to occur again if it is the same
318
-				// owner and is not a user share, this use case is for increasing
319
-				// permissions for a specific user
320
-				if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) {
321
-					$message = 'Sharing failed, because this item is already shared with user %s';
322
-					throw new \Exception(sprintf($message, $shareWith));
323
-				}
324
-			}
325
-		}
326
-
327
-		// Put the item into the database
328
-		$result = self::put('test', $itemSource, IShare::TYPE_USER, $shareWith, $uidOwner, $permissions);
329
-
330
-		return $result ? true : false;
331
-	}
332
-
333
-	/**
334
-	 * Unshare an item from a user, group, or delete a private link
335
-	 * @param string $itemType
336
-	 * @param string $itemSource
337
-	 * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
338
-	 * @param string $shareWith User or group the item is being shared with
339
-	 * @param string $owner owner of the share, if null the current user is used
340
-	 * @return boolean true on success or false on failure
341
-	 */
342
-	public static function unshare($itemType, $itemSource, $shareType, $shareWith, $owner = null) {
343
-
344
-		// check if it is a valid itemType
345
-		self::getBackend($itemType);
346
-
347
-		$items = self::getItemSharedWithUser($itemType, $itemSource, $shareWith, $owner, $shareType);
348
-
349
-		$toDelete = [];
350
-		$newParent = null;
351
-		$currentUser = $owner ? $owner : \OC_User::getUser();
352
-		foreach ($items as $item) {
353
-			// delete the item with the expected share_type and owner
354
-			if ((int)$item['share_type'] === (int)$shareType && $item['uid_owner'] === $currentUser) {
355
-				$toDelete = $item;
356
-			// if there is more then one result we don't have to delete the children
357
-				// but update their parent. For group shares the new parent should always be
358
-				// the original group share and not the db entry with the unique name
359
-			} elseif ((int)$item['share_type'] === self::$shareTypeGroupUserUnique) {
360
-				$newParent = $item['parent'];
361
-			} else {
362
-				$newParent = $item['id'];
363
-			}
364
-		}
365
-
366
-		if (!empty($toDelete)) {
367
-			self::unshareItem($toDelete, $newParent);
368
-			return true;
369
-		}
370
-		return false;
371
-	}
372
-
373
-	/**
374
-	 * Checks whether a share has expired, calls unshareItem() if yes.
375
-	 * @param array $item Share data (usually database row)
376
-	 * @return boolean True if item was expired, false otherwise.
377
-	 */
378
-	protected static function expireItem(array $item) {
379
-		$result = false;
380
-
381
-		// only use default expiration date for link shares
382
-		if ((int) $item['share_type'] === IShare::TYPE_LINK) {
383
-
384
-			// calculate expiration date
385
-			if (!empty($item['expiration'])) {
386
-				$userDefinedExpire = new \DateTime($item['expiration']);
387
-				$expires = $userDefinedExpire->getTimestamp();
388
-			} else {
389
-				$expires = null;
390
-			}
391
-
392
-
393
-			// get default expiration settings
394
-			$defaultSettings = Helper::getDefaultExpireSetting();
395
-			$expires = Helper::calculateExpireDate($defaultSettings, $item['stime'], $expires);
396
-
397
-
398
-			if (is_int($expires)) {
399
-				$now = time();
400
-				if ($now > $expires) {
401
-					self::unshareItem($item);
402
-					$result = true;
403
-				}
404
-			}
405
-		}
406
-		return $result;
407
-	}
408
-
409
-	/**
410
-	 * Unshares a share given a share data array
411
-	 * @param array $item Share data (usually database row)
412
-	 * @param int $newParent parent ID
413
-	 * @return null
414
-	 */
415
-	protected static function unshareItem(array $item, $newParent = null) {
416
-		$shareType = (int)$item['share_type'];
417
-		$shareWith = null;
418
-		if ($shareType !== IShare::TYPE_LINK) {
419
-			$shareWith = $item['share_with'];
420
-		}
421
-
422
-		// Pass all the vars we have for now, they may be useful
423
-		$hookParams = [
424
-			'id'            => $item['id'],
425
-			'itemType'      => $item['item_type'],
426
-			'itemSource'    => $item['item_source'],
427
-			'shareType'     => $shareType,
428
-			'shareWith'     => $shareWith,
429
-			'itemParent'    => $item['parent'],
430
-			'uidOwner'      => $item['uid_owner'],
431
-		];
432
-		if ($item['item_type'] === 'file' || $item['item_type'] === 'folder') {
433
-			$hookParams['fileSource'] = $item['file_source'];
434
-			$hookParams['fileTarget'] = $item['file_target'];
435
-		}
436
-
437
-		\OC_Hook::emit(\OCP\Share::class, 'pre_unshare', $hookParams);
438
-		$deletedShares = Helper::delete($item['id'], false, null, $newParent);
439
-		$deletedShares[] = $hookParams;
440
-		$hookParams['deletedShares'] = $deletedShares;
441
-		\OC_Hook::emit(\OCP\Share::class, 'post_unshare', $hookParams);
442
-		if ((int)$item['share_type'] === IShare::TYPE_REMOTE && \OC::$server->getUserSession()->getUser()) {
443
-			list(, $remote) = Helper::splitUserRemote($item['share_with']);
444
-			self::sendRemoteUnshare($remote, $item['id'], $item['token']);
445
-		}
446
-	}
447
-
448
-	/**
449
-	 * Get the backend class for the specified item type
450
-	 * @param string $itemType
451
-	 * @throws \Exception
452
-	 * @return \OCP\Share_Backend
453
-	 */
454
-	public static function getBackend($itemType) {
455
-		$l = \OC::$server->getL10N('lib');
456
-		if (isset(self::$backends[$itemType])) {
457
-			return self::$backends[$itemType];
458
-		} elseif (isset(self::$backendTypes[$itemType]['class'])) {
459
-			$class = self::$backendTypes[$itemType]['class'];
460
-			if (class_exists($class)) {
461
-				self::$backends[$itemType] = new $class;
462
-				if (!(self::$backends[$itemType] instanceof \OCP\Share_Backend)) {
463
-					$message = 'Sharing backend %s must implement the interface OCP\Share_Backend';
464
-					$message_t = $l->t('Sharing backend %s must implement the interface OCP\Share_Backend', [$class]);
465
-					\OCP\Util::writeLog('OCP\Share', sprintf($message, $class), ILogger::ERROR);
466
-					throw new \Exception($message_t);
467
-				}
468
-				return self::$backends[$itemType];
469
-			} else {
470
-				$message = 'Sharing backend %s not found';
471
-				$message_t = $l->t('Sharing backend %s not found', [$class]);
472
-				\OCP\Util::writeLog('OCP\Share', sprintf($message, $class), ILogger::ERROR);
473
-				throw new \Exception($message_t);
474
-			}
475
-		}
476
-		$message = 'Sharing backend for %s not found';
477
-		$message_t = $l->t('Sharing backend for %s not found', [$itemType]);
478
-		\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemType), ILogger::ERROR);
479
-		throw new \Exception($message_t);
480
-	}
481
-
482
-	/**
483
-	 * Check if resharing is allowed
484
-	 * @return boolean true if allowed or false
485
-	 *
486
-	 * Resharing is allowed by default if not configured
487
-	 */
488
-	public static function isResharingAllowed() {
489
-		if (!isset(self::$isResharingAllowed)) {
490
-			if (\OC::$server->getConfig()->getAppValue('core', 'shareapi_allow_resharing', 'yes') == 'yes') {
491
-				self::$isResharingAllowed = true;
492
-			} else {
493
-				self::$isResharingAllowed = false;
494
-			}
495
-		}
496
-		return self::$isResharingAllowed;
497
-	}
498
-
499
-	/**
500
-	 * Get a list of collection item types for the specified item type
501
-	 * @param string $itemType
502
-	 * @return array
503
-	 */
504
-	private static function getCollectionItemTypes($itemType) {
505
-		$collectionTypes = [$itemType];
506
-		foreach (self::$backendTypes as $type => $backend) {
507
-			if (in_array($backend['collectionOf'], $collectionTypes)) {
508
-				$collectionTypes[] = $type;
509
-			}
510
-		}
511
-		// TODO Add option for collections to be collection of themselves, only 'folder' does it now...
512
-		if (isset(self::$backendTypes[$itemType]) && (!self::getBackend($itemType) instanceof \OCP\Share_Backend_Collection || $itemType != 'folder')) {
513
-			unset($collectionTypes[0]);
514
-		}
515
-		// Return array if collections were found or the item type is a
516
-		// collection itself - collections can be inside collections
517
-		if (count($collectionTypes) > 0) {
518
-			return $collectionTypes;
519
-		}
520
-		return false;
521
-	}
522
-
523
-	/**
524
-	 * Get the owners of items shared with a user.
525
-	 *
526
-	 * @param string $user The user the items are shared with.
527
-	 * @param string $type The type of the items shared with the user.
528
-	 * @param boolean $includeCollections Include collection item types (optional)
529
-	 * @param boolean $includeOwner include owner in the list of users the item is shared with (optional)
530
-	 * @return array
531
-	 * @deprecated TESTS ONLY - this methods is only used by tests
532
-	 * called like this:
533
-	 * \OC\Share\Share::getSharedItemsOwners($this->user, $this->type, true)
534
-	 */
535
-	public static function getSharedItemsOwners($user, $type, $includeCollections = false, $includeOwner = false) {
536
-		// First, we find out if $type is part of a collection (and if that collection is part of
537
-		// another one and so on).
538
-		$collectionTypes = [];
539
-		if (!$includeCollections || !$collectionTypes = self::getCollectionItemTypes($type)) {
540
-			$collectionTypes[] = $type;
541
-		}
542
-
543
-		// Of these collection types, along with our original $type, we make a
544
-		// list of the ones for which a sharing backend has been registered.
545
-		// FIXME: Ideally, we wouldn't need to nest getItemsSharedWith in this loop but just call it
546
-		// with its $includeCollections parameter set to true. Unfortunately, this fails currently.
547
-		$allMaybeSharedItems = [];
548
-		foreach ($collectionTypes as $collectionType) {
549
-			if (isset(self::$backends[$collectionType])) {
550
-				$allMaybeSharedItems[$collectionType] = self::getItemsSharedWithUser(
551
-					$collectionType,
552
-					$user,
553
-					self::FORMAT_NONE
554
-				);
555
-			}
556
-		}
557
-
558
-		$owners = [];
559
-		if ($includeOwner) {
560
-			$owners[] = $user;
561
-		}
562
-
563
-		// We take a look at all shared items of the given $type (or of the collections it is part of)
564
-		// and find out their owners. Then, we gather the tags for the original $type from all owners,
565
-		// and return them as elements of a list that look like "Tag (owner)".
566
-		foreach ($allMaybeSharedItems as $collectionType => $maybeSharedItems) {
567
-			foreach ($maybeSharedItems as $sharedItem) {
568
-				if (isset($sharedItem['id'])) { //workaround for https://github.com/owncloud/core/issues/2814
569
-					$owners[] = $sharedItem['uid_owner'];
570
-				}
571
-			}
572
-		}
573
-
574
-		return $owners;
575
-	}
576
-
577
-	/**
578
-	 * Get shared items from the database
579
-	 * @param string $itemType
580
-	 * @param string $item Item source or target (optional)
581
-	 * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, SHARE_TYPE_LINK, $shareTypeUserAndGroups, or $shareTypeGroupUserUnique
582
-	 * @param string $shareWith User or group the item is being shared with
583
-	 * @param string $uidOwner User that is the owner of shared items (optional)
584
-	 * @param int $format Format to convert items to with formatItems() (optional)
585
-	 * @param mixed $parameters to pass to formatItems() (optional)
586
-	 * @param int $limit Number of items to return, -1 to return all matches (optional)
587
-	 * @param boolean $includeCollections Include collection item types (optional)
588
-	 * @param boolean $itemShareWithBySource (optional)
589
-	 * @param boolean $checkExpireDate
590
-	 * @return array
591
-	 *
592
-	 * See public functions getItem(s)... for parameter usage
593
-	 *
594
-	 */
595
-	public static function getItems($itemType, $item = null, $shareType = null, $shareWith = null,
596
-									$uidOwner = null, $format = self::FORMAT_NONE, $parameters = null, $limit = -1,
597
-									$includeCollections = false, $itemShareWithBySource = false, $checkExpireDate  = true) {
598
-		if (\OC::$server->getConfig()->getAppValue('core', 'shareapi_enabled', 'yes') != 'yes') {
599
-			return [];
600
-		}
601
-		$backend = self::getBackend($itemType);
602
-		$collectionTypes = false;
603
-		// Get filesystem root to add it to the file target and remove from the
604
-		// file source, match file_source with the file cache
605
-		if ($itemType == 'file' || $itemType == 'folder') {
606
-			if (!is_null($uidOwner)) {
607
-				$root = \OC\Files\Filesystem::getRoot();
608
-			} else {
609
-				$root = '';
610
-			}
611
-			$where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` ';
612
-			if (!isset($item)) {
613
-				$where .= ' AND `file_target` IS NOT NULL ';
614
-			}
615
-			$where .= 'INNER JOIN `*PREFIX*storages` ON `numeric_id` = `*PREFIX*filecache`.`storage` ';
616
-			$fileDependent = true;
617
-			$queryArgs = [];
618
-		} else {
619
-			$fileDependent = false;
620
-			$root = '';
621
-			$collectionTypes = self::getCollectionItemTypes($itemType);
622
-			if ($includeCollections && !isset($item) && $collectionTypes) {
623
-				// If includeCollections is true, find collections of this item type, e.g. a music album contains songs
624
-				if (!in_array($itemType, $collectionTypes)) {
625
-					$itemTypes = array_merge([$itemType], $collectionTypes);
626
-				} else {
627
-					$itemTypes = $collectionTypes;
628
-				}
629
-				$placeholders = implode(',', array_fill(0, count($itemTypes), '?'));
630
-				$where = ' WHERE `item_type` IN ('.$placeholders.'))';
631
-				$queryArgs = $itemTypes;
632
-			} else {
633
-				$where = ' WHERE `item_type` = ?';
634
-				$queryArgs = [$itemType];
635
-			}
636
-		}
637
-		if (\OC::$server->getConfig()->getAppValue('core', 'shareapi_allow_links', 'yes') !== 'yes') {
638
-			$where .= ' AND `share_type` != ?';
639
-			$queryArgs[] = IShare::TYPE_LINK;
640
-		}
641
-		if (isset($shareType)) {
642
-			// Include all user and group items
643
-			if ($shareType == self::$shareTypeUserAndGroups && isset($shareWith)) {
644
-				$where .= ' AND ((`share_type` in (?, ?) AND `share_with` = ?) ';
645
-				$queryArgs[] = IShare::TYPE_USER;
646
-				$queryArgs[] = self::$shareTypeGroupUserUnique;
647
-				$queryArgs[] = $shareWith;
648
-
649
-				$user = \OC::$server->getUserManager()->get($shareWith);
650
-				$groups = [];
651
-				if ($user) {
652
-					$groups = \OC::$server->getGroupManager()->getUserGroupIds($user);
653
-				}
654
-				if (!empty($groups)) {
655
-					$placeholders = implode(',', array_fill(0, count($groups), '?'));
656
-					$where .= ' OR (`share_type` = ? AND `share_with` IN ('.$placeholders.')) ';
657
-					$queryArgs[] = IShare::TYPE_GROUP;
658
-					$queryArgs = array_merge($queryArgs, $groups);
659
-				}
660
-				$where .= ')';
661
-				// Don't include own group shares
662
-				$where .= ' AND `uid_owner` != ?';
663
-				$queryArgs[] = $shareWith;
664
-			} else {
665
-				$where .= ' AND `share_type` = ?';
666
-				$queryArgs[] = $shareType;
667
-				if (isset($shareWith)) {
668
-					$where .= ' AND `share_with` = ?';
669
-					$queryArgs[] = $shareWith;
670
-				}
671
-			}
672
-		}
673
-		if (isset($uidOwner)) {
674
-			$where .= ' AND `uid_owner` = ?';
675
-			$queryArgs[] = $uidOwner;
676
-			if (!isset($shareType)) {
677
-				// Prevent unique user targets for group shares from being selected
678
-				$where .= ' AND `share_type` != ?';
679
-				$queryArgs[] = self::$shareTypeGroupUserUnique;
680
-			}
681
-			if ($fileDependent) {
682
-				$column = 'file_source';
683
-			} else {
684
-				$column = 'item_source';
685
-			}
686
-		} else {
687
-			if ($fileDependent) {
688
-				$column = 'file_target';
689
-			} else {
690
-				$column = 'item_target';
691
-			}
692
-		}
693
-		if (isset($item)) {
694
-			$collectionTypes = self::getCollectionItemTypes($itemType);
695
-			if ($includeCollections && $collectionTypes && !in_array('folder', $collectionTypes)) {
696
-				$where .= ' AND (';
697
-			} else {
698
-				$where .= ' AND';
699
-			}
700
-			// If looking for own shared items, check item_source else check item_target
701
-			if (isset($uidOwner) || $itemShareWithBySource) {
702
-				// If item type is a file, file source needs to be checked in case the item was converted
703
-				if ($fileDependent) {
704
-					$where .= ' `file_source` = ?';
705
-					$column = 'file_source';
706
-				} else {
707
-					$where .= ' `item_source` = ?';
708
-					$column = 'item_source';
709
-				}
710
-			} else {
711
-				if ($fileDependent) {
712
-					$where .= ' `file_target` = ?';
713
-					$item = \OC\Files\Filesystem::normalizePath($item);
714
-				} else {
715
-					$where .= ' `item_target` = ?';
716
-				}
717
-			}
718
-			$queryArgs[] = $item;
719
-			if ($includeCollections && $collectionTypes && !in_array('folder', $collectionTypes)) {
720
-				$placeholders = implode(',', array_fill(0, count($collectionTypes), '?'));
721
-				$where .= ' OR `item_type` IN ('.$placeholders.'))';
722
-				$queryArgs = array_merge($queryArgs, $collectionTypes);
723
-			}
724
-		}
725
-
726
-		if ($shareType == self::$shareTypeUserAndGroups && $limit === 1) {
727
-			// Make sure the unique user target is returned if it exists,
728
-			// unique targets should follow the group share in the database
729
-			// If the limit is not 1, the filtering can be done later
730
-			$where .= ' ORDER BY `*PREFIX*share`.`id` DESC';
731
-		} else {
732
-			$where .= ' ORDER BY `*PREFIX*share`.`id` ASC';
733
-		}
734
-
735
-		if ($limit != -1 && !$includeCollections) {
736
-			// The limit must be at least 3, because filtering needs to be done
737
-			if ($limit < 3) {
738
-				$queryLimit = 3;
739
-			} else {
740
-				$queryLimit = $limit;
741
-			}
742
-		} else {
743
-			$queryLimit = null;
744
-		}
745
-		$select = self::createSelectStatement($format, $fileDependent, $uidOwner);
746
-		$root = strlen($root);
747
-		$query = \OC_DB::prepare('SELECT '.$select.' FROM `*PREFIX*share` '.$where, $queryLimit);
748
-		$result = $query->execute($queryArgs);
749
-		if ($result === false) {
750
-			\OCP\Util::writeLog('OCP\Share',
751
-				\OC_DB::getErrorMessage() . ', select=' . $select . ' where=',
752
-				ILogger::ERROR);
753
-		}
754
-		$items = [];
755
-		$targets = [];
756
-		$switchedItems = [];
757
-		$mounts = [];
758
-		while ($row = $result->fetchRow()) {
759
-			self::transformDBResults($row);
760
-			// Filter out duplicate group shares for users with unique targets
761
-			if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) {
762
-				continue;
763
-			}
764
-			if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) {
765
-				$row['share_type'] = IShare::TYPE_GROUP;
766
-				$row['unique_name'] = true; // remember that we use a unique name for this user
767
-				$row['share_with'] = $items[$row['parent']]['share_with'];
768
-				// if the group share was unshared from the user we keep the permission, otherwise
769
-				// we take the permission from the parent because this is always the up-to-date
770
-				// permission for the group share
771
-				if ($row['permissions'] > 0) {
772
-					$row['permissions'] = $items[$row['parent']]['permissions'];
773
-				}
774
-				// Remove the parent group share
775
-				unset($items[$row['parent']]);
776
-				if ($row['permissions'] == 0) {
777
-					continue;
778
-				}
779
-			} elseif (!isset($uidOwner)) {
780
-				// Check if the same target already exists
781
-				if (isset($targets[$row['id']])) {
782
-					// Check if the same owner shared with the user twice
783
-					// through a group and user share - this is allowed
784
-					$id = $targets[$row['id']];
785
-					if (isset($items[$id]) && $items[$id]['uid_owner'] == $row['uid_owner']) {
786
-						// Switch to group share type to ensure resharing conditions aren't bypassed
787
-						if ($items[$id]['share_type'] != IShare::TYPE_GROUP) {
788
-							$items[$id]['share_type'] = IShare::TYPE_GROUP;
789
-							$items[$id]['share_with'] = $row['share_with'];
790
-						}
791
-						// Switch ids if sharing permission is granted on only
792
-						// one share to ensure correct parent is used if resharing
793
-						if (~(int)$items[$id]['permissions'] & \OCP\Constants::PERMISSION_SHARE
794
-							&& (int)$row['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
795
-							$items[$row['id']] = $items[$id];
796
-							$switchedItems[$id] = $row['id'];
797
-							unset($items[$id]);
798
-							$id = $row['id'];
799
-						}
800
-						$items[$id]['permissions'] |= (int)$row['permissions'];
801
-					}
802
-					continue;
803
-				} elseif (!empty($row['parent'])) {
804
-					$targets[$row['parent']] = $row['id'];
805
-				}
806
-			}
807
-			// Remove root from file source paths if retrieving own shared items
808
-			if (isset($uidOwner) && isset($row['path'])) {
809
-				if (isset($row['parent'])) {
810
-					$query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?');
811
-					$parentResult = $query->execute([$row['parent']]);
812
-					if ($result === false) {
813
-						\OCP\Util::writeLog('OCP\Share', 'Can\'t select parent: ' .
814
-							\OC_DB::getErrorMessage() . ', select=' . $select . ' where=' . $where,
815
-							ILogger::ERROR);
816
-					} else {
817
-						$parentRow = $parentResult->fetchRow();
818
-						$tmpPath = $parentRow['file_target'];
819
-						// find the right position where the row path continues from the target path
820
-						$pos = strrpos($row['path'], $parentRow['file_target']);
821
-						$subPath = substr($row['path'], $pos);
822
-						$splitPath = explode('/', $subPath);
823
-						foreach (array_slice($splitPath, 2) as $pathPart) {
824
-							$tmpPath = $tmpPath . '/' . $pathPart;
825
-						}
826
-						$row['path'] = $tmpPath;
827
-					}
828
-				} else {
829
-					if (!isset($mounts[$row['storage']])) {
830
-						$mountPoints = \OC\Files\Filesystem::getMountByNumericId($row['storage']);
831
-						if (is_array($mountPoints) && !empty($mountPoints)) {
832
-							$mounts[$row['storage']] = current($mountPoints);
833
-						}
834
-					}
835
-					if (!empty($mounts[$row['storage']])) {
836
-						$path = $mounts[$row['storage']]->getMountPoint().$row['path'];
837
-						$relPath = substr($path, $root); // path relative to data/user
838
-						$row['path'] = rtrim($relPath, '/');
839
-					}
840
-				}
841
-			}
842
-
843
-			if ($checkExpireDate) {
844
-				if (self::expireItem($row)) {
845
-					continue;
846
-				}
847
-			}
848
-			// Check if resharing is allowed, if not remove share permission
849
-			if (isset($row['permissions']) && (!self::isResharingAllowed() | \OCP\Util::isSharingDisabledForUser())) {
850
-				$row['permissions'] &= ~\OCP\Constants::PERMISSION_SHARE;
851
-			}
852
-			// Add display names to result
853
-			$row['share_with_displayname'] = $row['share_with'];
854
-			if (isset($row['share_with']) && $row['share_with'] != '' &&
855
-				$row['share_type'] === IShare::TYPE_USER) {
856
-				$shareWithUser = \OC::$server->getUserManager()->get($row['share_with']);
857
-				$row['share_with_displayname'] = $shareWithUser === null ? $row['share_with'] : $shareWithUser->getDisplayName();
858
-			} elseif (isset($row['share_with']) && $row['share_with'] != '' &&
859
-				$row['share_type'] === IShare::TYPE_REMOTE) {
860
-				$addressBookEntries = \OC::$server->getContactsManager()->search($row['share_with'], ['CLOUD']);
861
-				foreach ($addressBookEntries as $entry) {
862
-					foreach ($entry['CLOUD'] as $cloudID) {
863
-						if ($cloudID === $row['share_with']) {
864
-							$row['share_with_displayname'] = $entry['FN'];
865
-						}
866
-					}
867
-				}
868
-			}
869
-			if (isset($row['uid_owner']) && $row['uid_owner'] != '') {
870
-				$ownerUser = \OC::$server->getUserManager()->get($row['uid_owner']);
871
-				$row['displayname_owner'] = $ownerUser === null ? $row['uid_owner'] : $ownerUser->getDisplayName();
872
-			}
873
-
874
-			if ($row['permissions'] > 0) {
875
-				$items[$row['id']] = $row;
876
-			}
877
-		}
878
-
879
-		// group items if we are looking for items shared with the current user
880
-		if (isset($shareWith) && $shareWith === \OCP\User::getUser()) {
881
-			$items = self::groupItems($items, $itemType);
882
-		}
883
-
884
-		if (!empty($items)) {
885
-			$collectionItems = [];
886
-			foreach ($items as &$row) {
887
-				// Return only the item instead of a 2-dimensional array
888
-				if ($limit == 1 && $row[$column] == $item && ($row['item_type'] == $itemType || $itemType == 'file')) {
889
-					if ($format == self::FORMAT_NONE) {
890
-						return $row;
891
-					} else {
892
-						break;
893
-					}
894
-				}
895
-				// Check if this is a collection of the requested item type
896
-				if ($includeCollections && $collectionTypes && $row['item_type'] !== 'folder' && in_array($row['item_type'], $collectionTypes)) {
897
-					if (($collectionBackend = self::getBackend($row['item_type']))
898
-						&& $collectionBackend instanceof \OCP\Share_Backend_Collection) {
899
-						// Collections can be inside collections, check if the item is a collection
900
-						if (isset($item) && $row['item_type'] == $itemType && $row[$column] == $item) {
901
-							$collectionItems[] = $row;
902
-						} else {
903
-							$collection = [];
904
-							$collection['item_type'] = $row['item_type'];
905
-							if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') {
906
-								$collection['path'] = basename($row['path']);
907
-							}
908
-							$row['collection'] = $collection;
909
-							// Fetch all of the children sources
910
-							$children = $collectionBackend->getChildren($row[$column]);
911
-							foreach ($children as $child) {
912
-								$childItem = $row;
913
-								$childItem['item_type'] = $itemType;
914
-								if ($row['item_type'] != 'file' && $row['item_type'] != 'folder') {
915
-									$childItem['item_source'] = $child['source'];
916
-									$childItem['item_target'] = $child['target'];
917
-								}
918
-								if ($backend instanceof \OCP\Share_Backend_File_Dependent) {
919
-									if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') {
920
-										$childItem['file_source'] = $child['source'];
921
-									} else { // TODO is this really needed if we already know that we use the file backend?
922
-										$meta = \OC\Files\Filesystem::getFileInfo($child['file_path']);
923
-										$childItem['file_source'] = $meta['fileid'];
924
-									}
925
-									$childItem['file_target'] =
926
-										\OC\Files\Filesystem::normalizePath($child['file_path']);
927
-								}
928
-								if (isset($item)) {
929
-									if ($childItem[$column] == $item) {
930
-										// Return only the item instead of a 2-dimensional array
931
-										if ($limit == 1) {
932
-											if ($format == self::FORMAT_NONE) {
933
-												return $childItem;
934
-											} else {
935
-												// Unset the items array and break out of both loops
936
-												$items = [];
937
-												$items[] = $childItem;
938
-												break 2;
939
-											}
940
-										} else {
941
-											$collectionItems[] = $childItem;
942
-										}
943
-									}
944
-								} else {
945
-									$collectionItems[] = $childItem;
946
-								}
947
-							}
948
-						}
949
-					}
950
-					// Remove collection item
951
-					$toRemove = $row['id'];
952
-					if (array_key_exists($toRemove, $switchedItems)) {
953
-						$toRemove = $switchedItems[$toRemove];
954
-					}
955
-					unset($items[$toRemove]);
956
-				} elseif ($includeCollections && $collectionTypes && in_array($row['item_type'], $collectionTypes)) {
957
-					// FIXME: Thats a dirty hack to improve file sharing performance,
958
-					// see github issue #10588 for more details
959
-					// Need to find a solution which works for all back-ends
960
-					$collectionBackend = self::getBackend($row['item_type']);
961
-					$sharedParents = $collectionBackend->getParents($row['item_source']);
962
-					foreach ($sharedParents as $parent) {
963
-						$collectionItems[] = $parent;
964
-					}
965
-				}
966
-			}
967
-			if (!empty($collectionItems)) {
968
-				$collectionItems = array_unique($collectionItems, SORT_REGULAR);
969
-				$items = array_merge($items, $collectionItems);
970
-			}
971
-
972
-			// filter out invalid items, these can appear when subshare entries exist
973
-			// for a group in which the requested user isn't a member any more
974
-			$items = array_filter($items, function ($item) {
975
-				return $item['share_type'] !== self::$shareTypeGroupUserUnique;
976
-			});
977
-
978
-			return self::formatResult($items, $column, $backend, $format, $parameters);
979
-		} elseif ($includeCollections && $collectionTypes && in_array('folder', $collectionTypes)) {
980
-			// FIXME: Thats a dirty hack to improve file sharing performance,
981
-			// see github issue #10588 for more details
982
-			// Need to find a solution which works for all back-ends
983
-			$collectionItems = [];
984
-			$collectionBackend = self::getBackend('folder');
985
-			$sharedParents = $collectionBackend->getParents($item, $shareWith, $uidOwner);
986
-			foreach ($sharedParents as $parent) {
987
-				$collectionItems[] = $parent;
988
-			}
989
-			if ($limit === 1) {
990
-				return reset($collectionItems);
991
-			}
992
-			return self::formatResult($collectionItems, $column, $backend, $format, $parameters);
993
-		}
994
-
995
-		return [];
996
-	}
997
-
998
-	/**
999
-	 * group items with link to the same source
1000
-	 *
1001
-	 * @param array $items
1002
-	 * @param string $itemType
1003
-	 * @return array of grouped items
1004
-	 */
1005
-	protected static function groupItems($items, $itemType) {
1006
-		$fileSharing = $itemType === 'file' || $itemType === 'folder';
1007
-
1008
-		$result = [];
1009
-
1010
-		foreach ($items as $item) {
1011
-			$grouped = false;
1012
-			foreach ($result as $key => $r) {
1013
-				// for file/folder shares we need to compare file_source, otherwise we compare item_source
1014
-				// only group shares if they already point to the same target, otherwise the file where shared
1015
-				// before grouping of shares was added. In this case we don't group them toi avoid confusions
1016
-				if (($fileSharing && $item['file_source'] === $r['file_source'] && $item['file_target'] === $r['file_target']) ||
1017
-					(!$fileSharing && $item['item_source'] === $r['item_source'] && $item['item_target'] === $r['item_target'])) {
1018
-					// add the first item to the list of grouped shares
1019
-					if (!isset($result[$key]['grouped'])) {
1020
-						$result[$key]['grouped'][] = $result[$key];
1021
-					}
1022
-					$result[$key]['permissions'] = (int) $item['permissions'] | (int) $r['permissions'];
1023
-					$result[$key]['grouped'][] = $item;
1024
-					$grouped = true;
1025
-					break;
1026
-				}
1027
-			}
1028
-
1029
-			if (!$grouped) {
1030
-				$result[] = $item;
1031
-			}
1032
-		}
1033
-
1034
-		return $result;
1035
-	}
1036
-
1037
-	/**
1038
-	 * Put shared item into the database
1039
-	 * @param string $itemType Item type
1040
-	 * @param string $itemSource Item source
1041
-	 * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
1042
-	 * @param string $shareWith User or group the item is being shared with
1043
-	 * @param string $uidOwner User that is the owner of shared item
1044
-	 * @param int $permissions CRUDS permissions
1045
-	 * @throws \Exception
1046
-	 * @return mixed id of the new share or false
1047
-	 * @deprecated TESTS ONLY - this methods is only used by tests
1048
-	 * called like this:
1049
-	 * self::put('test', $itemSource, IShare::TYPE_USER, $shareWith, $uidOwner, $permissions);
1050
-	 */
1051
-	private static function put($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
1052
-								$permissions) {
1053
-		$queriesToExecute = [];
1054
-		$suggestedItemTarget = null;
1055
-		$groupFileTarget = $fileTarget = $suggestedFileTarget = $filePath = '';
1056
-		$groupItemTarget = $itemTarget = $fileSource = $parent = 0;
1057
-
1058
-		$result = self::checkReshare('test', $itemSource, IShare::TYPE_USER, $shareWith, $uidOwner, $permissions, null, null);
1059
-		if (!empty($result)) {
1060
-			$parent = $result['parent'];
1061
-			$itemSource = $result['itemSource'];
1062
-			$fileSource = $result['fileSource'];
1063
-			$suggestedItemTarget = $result['suggestedItemTarget'];
1064
-			$suggestedFileTarget = $result['suggestedFileTarget'];
1065
-			$filePath = $result['filePath'];
1066
-		}
1067
-
1068
-		$isGroupShare = false;
1069
-		$users = [$shareWith];
1070
-		$itemTarget = Helper::generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
1071
-				$suggestedItemTarget);
1072
-
1073
-		$run = true;
1074
-		$error = '';
1075
-		$preHookData = [
1076
-			'itemType' => $itemType,
1077
-			'itemSource' => $itemSource,
1078
-			'shareType' => $shareType,
1079
-			'uidOwner' => $uidOwner,
1080
-			'permissions' => $permissions,
1081
-			'fileSource' => $fileSource,
1082
-			'expiration' => null,
1083
-			'token' => null,
1084
-			'run' => &$run,
1085
-			'error' => &$error
1086
-		];
1087
-
1088
-		$preHookData['itemTarget'] = $itemTarget;
1089
-		$preHookData['shareWith'] = $shareWith;
1090
-
1091
-		\OC_Hook::emit(\OCP\Share::class, 'pre_shared', $preHookData);
1092
-
1093
-		if ($run === false) {
1094
-			throw new \Exception($error);
1095
-		}
1096
-
1097
-		foreach ($users as $user) {
1098
-			$sourceId = ($itemType === 'file' || $itemType === 'folder') ? $fileSource : $itemSource;
1099
-			$sourceExists = self::getItemSharedWithBySource($itemType, $sourceId, self::FORMAT_NONE, null, true, $user);
1100
-
1101
-			$userShareType = $shareType;
1102
-
1103
-			if ($sourceExists && $sourceExists['item_source'] === $itemSource) {
1104
-				$fileTarget = $sourceExists['file_target'];
1105
-				$itemTarget = $sourceExists['item_target'];
1106
-			} elseif (!$sourceExists) {
1107
-				$itemTarget = Helper::generateTarget($itemType, $itemSource, $userShareType, $user,
1108
-					$uidOwner, $suggestedItemTarget, $parent);
1109
-				if (isset($fileSource)) {
1110
-					$fileTarget = Helper::generateTarget('file', $filePath, $userShareType,
1111
-							$user, $uidOwner, $suggestedFileTarget, $parent);
1112
-				} else {
1113
-					$fileTarget = null;
1114
-				}
1115
-			} else {
1116
-
1117
-				// group share which doesn't exists until now, check if we need a unique target for this user
1118
-
1119
-				$itemTarget = Helper::generateTarget($itemType, $itemSource, IShare::TYPE_USER, $user,
1120
-					$uidOwner, $suggestedItemTarget, $parent);
1121
-
1122
-				// do we also need a file target
1123
-				if (isset($fileSource)) {
1124
-					$fileTarget = Helper::generateTarget('file', $filePath, IShare::TYPE_USER, $user,
1125
-						$uidOwner, $suggestedFileTarget, $parent);
1126
-				} else {
1127
-					$fileTarget = null;
1128
-				}
1129
-
1130
-				if (($itemTarget === $groupItemTarget) &&
1131
-					(!isset($fileSource) || $fileTarget === $groupFileTarget)) {
1132
-					continue;
1133
-				}
1134
-			}
1135
-
1136
-			$queriesToExecute[] = [
1137
-				'itemType'			=> $itemType,
1138
-				'itemSource'		=> $itemSource,
1139
-				'itemTarget'		=> $itemTarget,
1140
-				'shareType'			=> $userShareType,
1141
-				'shareWith'			=> $user,
1142
-				'uidOwner'			=> $uidOwner,
1143
-				'permissions'		=> $permissions,
1144
-				'shareTime'			=> time(),
1145
-				'fileSource'		=> $fileSource,
1146
-				'fileTarget'		=> $fileTarget,
1147
-				'token'				=> null,
1148
-				'parent'			=> $parent,
1149
-				'expiration'		=> null,
1150
-			];
1151
-		}
1152
-
1153
-		$id = false;
1154
-
1155
-		foreach ($queriesToExecute as $shareQuery) {
1156
-			$shareQuery['parent'] = $parent;
1157
-			$id = self::insertShare($shareQuery);
1158
-		}
1159
-
1160
-		$postHookData = [
1161
-			'itemType' => $itemType,
1162
-			'itemSource' => $itemSource,
1163
-			'parent' => $parent,
1164
-			'shareType' => $shareType,
1165
-			'uidOwner' => $uidOwner,
1166
-			'permissions' => $permissions,
1167
-			'fileSource' => $fileSource,
1168
-			'id' => $parent,
1169
-			'token' => null,
1170
-			'expirationDate' => null,
1171
-		];
1172
-
1173
-		$postHookData['shareWith'] = $isGroupShare ? $shareWith['group'] : $shareWith;
1174
-		$postHookData['itemTarget'] = $isGroupShare ? $groupItemTarget : $itemTarget;
1175
-		$postHookData['fileTarget'] = $isGroupShare ? $groupFileTarget : $fileTarget;
1176
-
1177
-		\OC_Hook::emit(\OCP\Share::class, 'post_shared', $postHookData);
1178
-
1179
-
1180
-		return $id ? $id : false;
1181
-	}
1182
-
1183
-	/**
1184
-	 * @param string $itemType
1185
-	 * @param string $itemSource
1186
-	 * @param int $shareType
1187
-	 * @param string $shareWith
1188
-	 * @param string $uidOwner
1189
-	 * @param int $permissions
1190
-	 * @param string|null $itemSourceName
1191
-	 * @param null|\DateTime $expirationDate
1192
-	 * @deprecated TESTS ONLY - this methods is only used by tests
1193
-	 * called like this:
1194
-	 * self::checkReshare('test', $itemSource, IShare::TYPE_USER, $shareWith, $uidOwner, $permissions, null, null);
1195
-	 */
1196
-	private static function checkReshare($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $itemSourceName, $expirationDate) {
1197
-		$backend = self::getBackend($itemType);
1198
-
1199
-		$result = [];
1200
-
1201
-		$column = ($itemType === 'file' || $itemType === 'folder') ? 'file_source' : 'item_source';
1202
-
1203
-		$checkReshare = self::getItemSharedWithBySource($itemType, $itemSource, self::FORMAT_NONE, null, true);
1204
-		if ($checkReshare) {
1205
-			// Check if attempting to share back to owner
1206
-			if ($checkReshare['uid_owner'] == $shareWith) {
1207
-				$message = 'Sharing %1$s failed, because the user %2$s is the original sharer';
1208
-				throw new \Exception(sprintf($message, $itemSourceName, $shareWith));
1209
-			}
1210
-		}
1211
-
1212
-		if ($checkReshare && $checkReshare['uid_owner'] !== \OC_User::getUser()) {
1213
-			// Check if share permissions is granted
1214
-			if (self::isResharingAllowed() && (int)$checkReshare['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
1215
-				if (~(int)$checkReshare['permissions'] & $permissions) {
1216
-					$message = 'Sharing %1$s failed, because the permissions exceed permissions granted to %2$s';
1217
-					throw new \Exception(sprintf($message, $itemSourceName, $uidOwner));
1218
-				} else {
1219
-					// TODO Don't check if inside folder
1220
-					$result['parent'] = $checkReshare['id'];
1221
-
1222
-					$result['expirationDate'] = $expirationDate;
1223
-					// $checkReshare['expiration'] could be null and then is always less than any value
1224
-					if (isset($checkReshare['expiration']) && $checkReshare['expiration'] < $expirationDate) {
1225
-						$result['expirationDate'] = $checkReshare['expiration'];
1226
-					}
1227
-
1228
-					// only suggest the same name as new target if it is a reshare of the
1229
-					// same file/folder and not the reshare of a child
1230
-					if ($checkReshare[$column] === $itemSource) {
1231
-						$result['filePath'] = $checkReshare['file_target'];
1232
-						$result['itemSource'] = $checkReshare['item_source'];
1233
-						$result['fileSource'] = $checkReshare['file_source'];
1234
-						$result['suggestedItemTarget'] = $checkReshare['item_target'];
1235
-						$result['suggestedFileTarget'] = $checkReshare['file_target'];
1236
-					} else {
1237
-						$result['filePath'] = ($backend instanceof \OCP\Share_Backend_File_Dependent) ? $backend->getFilePath($itemSource, $uidOwner) : null;
1238
-						$result['suggestedItemTarget'] = null;
1239
-						$result['suggestedFileTarget'] = null;
1240
-						$result['itemSource'] = $itemSource;
1241
-						$result['fileSource'] = ($backend instanceof \OCP\Share_Backend_File_Dependent) ? $itemSource : null;
1242
-					}
1243
-				}
1244
-			} else {
1245
-				$message = 'Sharing %s failed, because resharing is not allowed';
1246
-				throw new \Exception(sprintf($message, $itemSourceName));
1247
-			}
1248
-		} else {
1249
-			$result['parent'] = null;
1250
-			$result['suggestedItemTarget'] = null;
1251
-			$result['suggestedFileTarget'] = null;
1252
-			$result['itemSource'] = $itemSource;
1253
-			$result['expirationDate'] = $expirationDate;
1254
-			if (!$backend->isValidSource($itemSource, $uidOwner)) {
1255
-				$message = 'Sharing %1$s failed, because the sharing backend for '
1256
-					.'%2$s could not find its source';
1257
-				throw new \Exception(sprintf($message, $itemSource, $itemType));
1258
-			}
1259
-			if ($backend instanceof \OCP\Share_Backend_File_Dependent) {
1260
-				$result['filePath'] = $backend->getFilePath($itemSource, $uidOwner);
1261
-				$meta = \OC\Files\Filesystem::getFileInfo($result['filePath']);
1262
-				$result['fileSource'] = $meta['fileid'];
1263
-				if ($result['fileSource'] == -1) {
1264
-					$message = 'Sharing %s failed, because the file could not be found in the file cache';
1265
-					throw new \Exception(sprintf($message, $itemSource));
1266
-				}
1267
-			} else {
1268
-				$result['filePath'] = null;
1269
-				$result['fileSource'] = null;
1270
-			}
1271
-		}
1272
-
1273
-		return $result;
1274
-	}
1275
-
1276
-	/**
1277
-	 *
1278
-	 * @param array $shareData
1279
-	 * @return mixed false in case of a failure or the id of the new share
1280
-	 */
1281
-	private static function insertShare(array $shareData) {
1282
-		$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` ('
1283
-			.' `item_type`, `item_source`, `item_target`, `share_type`,'
1284
-			.' `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,'
1285
-			.' `file_target`, `token`, `parent`, `expiration`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)');
1286
-		$query->bindValue(1, $shareData['itemType']);
1287
-		$query->bindValue(2, $shareData['itemSource']);
1288
-		$query->bindValue(3, $shareData['itemTarget']);
1289
-		$query->bindValue(4, $shareData['shareType']);
1290
-		$query->bindValue(5, $shareData['shareWith']);
1291
-		$query->bindValue(6, $shareData['uidOwner']);
1292
-		$query->bindValue(7, $shareData['permissions']);
1293
-		$query->bindValue(8, $shareData['shareTime']);
1294
-		$query->bindValue(9, $shareData['fileSource']);
1295
-		$query->bindValue(10, $shareData['fileTarget']);
1296
-		$query->bindValue(11, $shareData['token']);
1297
-		$query->bindValue(12, $shareData['parent']);
1298
-		$query->bindValue(13, $shareData['expiration'], 'datetime');
1299
-		$result = $query->execute();
1300
-
1301
-		$id = false;
1302
-		if ($result) {
1303
-			$id =  \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share');
1304
-		}
1305
-
1306
-		return $id;
1307
-	}
1308
-
1309
-	/**
1310
-	 * construct select statement
1311
-	 * @param int $format
1312
-	 * @param boolean $fileDependent ist it a file/folder share or a generla share
1313
-	 * @param string $uidOwner
1314
-	 * @return string select statement
1315
-	 */
1316
-	private static function createSelectStatement($format, $fileDependent, $uidOwner = null) {
1317
-		$select = '*';
1318
-		if ($format == self::FORMAT_STATUSES) {
1319
-			if ($fileDependent) {
1320
-				$select = '`*PREFIX*share`.`id`, `*PREFIX*share`.`parent`, `share_type`, `path`, `storage`, '
1321
-					. '`share_with`, `uid_owner` , `file_source`, `stime`, `*PREFIX*share`.`permissions`, '
1322
-					. '`*PREFIX*storages`.`id` AS `storage_id`, `*PREFIX*filecache`.`parent` as `file_parent`, '
1323
-					. '`uid_initiator`';
1324
-			} else {
1325
-				$select = '`id`, `parent`, `share_type`, `share_with`, `uid_owner`, `item_source`, `stime`, `*PREFIX*share`.`permissions`';
1326
-			}
1327
-		} else {
1328
-			if (isset($uidOwner)) {
1329
-				if ($fileDependent) {
1330
-					$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`,'
1331
-						. ' `share_type`, `share_with`, `file_source`, `file_target`, `path`, `*PREFIX*share`.`permissions`, `stime`,'
1332
-						. ' `expiration`, `token`, `storage`, `mail_send`, `uid_owner`, '
1333
-						. '`*PREFIX*storages`.`id` AS `storage_id`, `*PREFIX*filecache`.`parent` as `file_parent`';
1334
-				} else {
1335
-					$select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `*PREFIX*share`.`permissions`,'
1336
-						. ' `stime`, `file_source`, `expiration`, `token`, `mail_send`, `uid_owner`';
1337
-				}
1338
-			} else {
1339
-				if ($fileDependent) {
1340
-					if ($format == \OCA\Files_Sharing\ShareBackend\File::FORMAT_GET_FOLDER_CONTENTS || $format == \OCA\Files_Sharing\ShareBackend\File::FORMAT_FILE_APP_ROOT) {
1341
-						$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`, `uid_owner`, '
1342
-							. '`share_type`, `share_with`, `file_source`, `path`, `file_target`, `stime`, '
1343
-							. '`*PREFIX*share`.`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, '
1344
-							. '`name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`, `etag`, `mail_send`';
1345
-					} else {
1346
-						$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`,'
1347
-							. '`*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`,'
1348
-							. '`file_source`, `path`, `file_target`, `*PREFIX*share`.`permissions`,'
1349
-							. '`stime`, `expiration`, `token`, `storage`, `mail_send`,'
1350
-							. '`*PREFIX*storages`.`id` AS `storage_id`, `*PREFIX*filecache`.`parent` as `file_parent`';
1351
-					}
1352
-				}
1353
-			}
1354
-		}
1355
-		return $select;
1356
-	}
1357
-
1358
-
1359
-	/**
1360
-	 * transform db results
1361
-	 * @param array $row result
1362
-	 */
1363
-	private static function transformDBResults(&$row) {
1364
-		if (isset($row['id'])) {
1365
-			$row['id'] = (int) $row['id'];
1366
-		}
1367
-		if (isset($row['share_type'])) {
1368
-			$row['share_type'] = (int) $row['share_type'];
1369
-		}
1370
-		if (isset($row['parent'])) {
1371
-			$row['parent'] = (int) $row['parent'];
1372
-		}
1373
-		if (isset($row['file_parent'])) {
1374
-			$row['file_parent'] = (int) $row['file_parent'];
1375
-		}
1376
-		if (isset($row['file_source'])) {
1377
-			$row['file_source'] = (int) $row['file_source'];
1378
-		}
1379
-		if (isset($row['permissions'])) {
1380
-			$row['permissions'] = (int) $row['permissions'];
1381
-		}
1382
-		if (isset($row['storage'])) {
1383
-			$row['storage'] = (int) $row['storage'];
1384
-		}
1385
-		if (isset($row['stime'])) {
1386
-			$row['stime'] = (int) $row['stime'];
1387
-		}
1388
-		if (isset($row['expiration']) && $row['share_type'] !== IShare::TYPE_LINK) {
1389
-			// discard expiration date for non-link shares, which might have been
1390
-			// set by ancient bugs
1391
-			$row['expiration'] = null;
1392
-		}
1393
-	}
1394
-
1395
-	/**
1396
-	 * format result
1397
-	 * @param array $items result
1398
-	 * @param string $column is it a file share or a general share ('file_target' or 'item_target')
1399
-	 * @param \OCP\Share_Backend $backend sharing backend
1400
-	 * @param int $format
1401
-	 * @param array $parameters additional format parameters
1402
-	 * @return array format result
1403
-	 */
1404
-	private static function formatResult($items, $column, $backend, $format = self::FORMAT_NONE , $parameters = null) {
1405
-		if ($format === self::FORMAT_NONE) {
1406
-			return $items;
1407
-		} elseif ($format === self::FORMAT_STATUSES) {
1408
-			$statuses = [];
1409
-			foreach ($items as $item) {
1410
-				if ($item['share_type'] === IShare::TYPE_LINK) {
1411
-					if ($item['uid_initiator'] !== \OC::$server->getUserSession()->getUser()->getUID()) {
1412
-						continue;
1413
-					}
1414
-					$statuses[$item[$column]]['link'] = true;
1415
-				} elseif (!isset($statuses[$item[$column]])) {
1416
-					$statuses[$item[$column]]['link'] = false;
1417
-				}
1418
-				if (!empty($item['file_target'])) {
1419
-					$statuses[$item[$column]]['path'] = $item['path'];
1420
-				}
1421
-			}
1422
-			return $statuses;
1423
-		} else {
1424
-			return $backend->formatItems($items, $format, $parameters);
1425
-		}
1426
-	}
1427
-
1428
-	/**
1429
-	 * remove protocol from URL
1430
-	 *
1431
-	 * @param string $url
1432
-	 * @return string
1433
-	 */
1434
-	public static function removeProtocolFromUrl($url) {
1435
-		if (strpos($url, 'https://') === 0) {
1436
-			return substr($url, strlen('https://'));
1437
-		} elseif (strpos($url, 'http://') === 0) {
1438
-			return substr($url, strlen('http://'));
1439
-		}
1440
-
1441
-		return $url;
1442
-	}
1443
-
1444
-	/**
1445
-	 * try http post first with https and then with http as a fallback
1446
-	 *
1447
-	 * @param string $remoteDomain
1448
-	 * @param string $urlSuffix
1449
-	 * @param array $fields post parameters
1450
-	 * @return array
1451
-	 */
1452
-	private static function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields) {
1453
-		$protocol = 'https://';
1454
-		$result = [
1455
-			'success' => false,
1456
-			'result' => '',
1457
-		];
1458
-		$try = 0;
1459
-		$discoveryService = \OC::$server->query(\OCP\OCS\IDiscoveryService::class);
1460
-		while ($result['success'] === false && $try < 2) {
1461
-			$federationEndpoints = $discoveryService->discover($protocol . $remoteDomain, 'FEDERATED_SHARING');
1462
-			$endpoint = isset($federationEndpoints['share']) ? $federationEndpoints['share'] : '/ocs/v2.php/cloud/shares';
1463
-			$client = \OC::$server->getHTTPClientService()->newClient();
1464
-
1465
-			try {
1466
-				$response = $client->post(
1467
-					$protocol . $remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT,
1468
-					[
1469
-						'body' => $fields,
1470
-						'connect_timeout' => 10,
1471
-					]
1472
-				);
1473
-
1474
-				$result = ['success' => true, 'result' => $response->getBody()];
1475
-			} catch (\Exception $e) {
1476
-				$result = ['success' => false, 'result' => $e->getMessage()];
1477
-			}
1478
-
1479
-			$try++;
1480
-			$protocol = 'http://';
1481
-		}
1482
-
1483
-		return $result;
1484
-	}
1485
-
1486
-	/**
1487
-	 * send server-to-server unshare to remote server
1488
-	 *
1489
-	 * @param string $remote url
1490
-	 * @param int $id share id
1491
-	 * @param string $token
1492
-	 * @return bool
1493
-	 */
1494
-	private static function sendRemoteUnshare($remote, $id, $token) {
1495
-		$url = rtrim($remote, '/');
1496
-		$fields = ['token' => $token, 'format' => 'json'];
1497
-		$url = self::removeProtocolFromUrl($url);
1498
-		$result = self::tryHttpPostToShareEndpoint($url, '/'.$id.'/unshare', $fields);
1499
-		$status = json_decode($result['result'], true);
1500
-
1501
-		return ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200));
1502
-	}
1503
-
1504
-	/**
1505
-	 * @return int
1506
-	 */
1507
-	public static function getExpireInterval() {
1508
-		return (int)\OC::$server->getConfig()->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1509
-	}
1510
-
1511
-	/**
1512
-	 * Checks whether the given path is reachable for the given owner
1513
-	 *
1514
-	 * @param string $path path relative to files
1515
-	 * @param string $ownerStorageId storage id of the owner
1516
-	 *
1517
-	 * @return boolean true if file is reachable, false otherwise
1518
-	 */
1519
-	private static function isFileReachable($path, $ownerStorageId) {
1520
-		// if outside the home storage, file is always considered reachable
1521
-		if (!(substr($ownerStorageId, 0, 6) === 'home::' ||
1522
-			substr($ownerStorageId, 0, 13) === 'object::user:'
1523
-		)) {
1524
-			return true;
1525
-		}
1526
-
1527
-		// if inside the home storage, the file has to be under "/files/"
1528
-		$path = ltrim($path, '/');
1529
-		if (substr($path, 0, 6) === 'files/') {
1530
-			return true;
1531
-		}
1532
-
1533
-		return false;
1534
-	}
53
+    /** CRUDS permissions (Create, Read, Update, Delete, Share) using a bitmask
54
+     * Construct permissions for share() and setPermissions with Or (|) e.g.
55
+     * Give user read and update permissions: PERMISSION_READ | PERMISSION_UPDATE
56
+     *
57
+     * Check if permission is granted with And (&) e.g. Check if delete is
58
+     * granted: if ($permissions & PERMISSION_DELETE)
59
+     *
60
+     * Remove permissions with And (&) and Not (~) e.g. Remove the update
61
+     * permission: $permissions &= ~PERMISSION_UPDATE
62
+     *
63
+     * Apps are required to handle permissions on their own, this class only
64
+     * stores and manages the permissions of shares
65
+     * @see lib/public/constants.php
66
+     */
67
+
68
+    /**
69
+     * Register a sharing backend class that implements OCP\Share_Backend for an item type
70
+     * @param string $itemType Item type
71
+     * @param string $class Backend class
72
+     * @param string $collectionOf (optional) Depends on item type
73
+     * @param array $supportedFileExtensions (optional) List of supported file extensions if this item type depends on files
74
+     * @return boolean true if backend is registered or false if error
75
+     */
76
+    public static function registerBackend($itemType, $class, $collectionOf = null, $supportedFileExtensions = null) {
77
+        if (\OC::$server->getConfig()->getAppValue('core', 'shareapi_enabled', 'yes') == 'yes') {
78
+            if (!isset(self::$backendTypes[$itemType])) {
79
+                self::$backendTypes[$itemType] = [
80
+                    'class' => $class,
81
+                    'collectionOf' => $collectionOf,
82
+                    'supportedFileExtensions' => $supportedFileExtensions
83
+                ];
84
+                return true;
85
+            }
86
+            \OCP\Util::writeLog('OCP\Share',
87
+                'Sharing backend '.$class.' not registered, '.self::$backendTypes[$itemType]['class']
88
+                .' is already registered for '.$itemType,
89
+                ILogger::WARN);
90
+        }
91
+        return false;
92
+    }
93
+
94
+    /**
95
+     * Get the items of item type shared with the current user
96
+     * @param string $itemType
97
+     * @param int $format (optional) Format type must be defined by the backend
98
+     * @param mixed $parameters (optional)
99
+     * @param int $limit Number of items to return (optional) Returns all by default
100
+     * @param boolean $includeCollections (optional)
101
+     * @return mixed Return depends on format
102
+     * @deprecated TESTS ONLY - this methods is only used by tests
103
+     * called like this:
104
+     * \OC\Share\Share::getItemsSharedWith('folder'); (apps/files_sharing/tests/UpdaterTest.php)
105
+     */
106
+    public static function getItemsSharedWith() {
107
+        return self::getItems('folder', null, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, self::FORMAT_NONE,
108
+            null, -1, false);
109
+    }
110
+
111
+    /**
112
+     * Get the items of item type shared with a user
113
+     * @param string $itemType
114
+     * @param string $user id for which user we want the shares
115
+     * @param int $format (optional) Format type must be defined by the backend
116
+     * @param mixed $parameters (optional)
117
+     * @param int $limit Number of items to return (optional) Returns all by default
118
+     * @param boolean $includeCollections (optional)
119
+     * @return mixed Return depends on format
120
+     */
121
+    public static function getItemsSharedWithUser($itemType, $user, $format = self::FORMAT_NONE,
122
+                                                    $parameters = null, $limit = -1, $includeCollections = false) {
123
+        return self::getItems($itemType, null, self::$shareTypeUserAndGroups, $user, null, $format,
124
+            $parameters, $limit, $includeCollections);
125
+    }
126
+
127
+    /**
128
+     * Get the item of item type shared with a given user by source
129
+     * @param string $itemType
130
+     * @param string $itemSource
131
+     * @param string $user User to whom the item was shared
132
+     * @param string $owner Owner of the share
133
+     * @param int $shareType only look for a specific share type
134
+     * @return array Return list of items with file_target, permissions and expiration
135
+     */
136
+    public static function getItemSharedWithUser($itemType, $itemSource, $user, $owner = null, $shareType = null) {
137
+        $shares = [];
138
+        $fileDependent = false;
139
+
140
+        $where = 'WHERE';
141
+        $fileDependentWhere = '';
142
+        if ($itemType === 'file' || $itemType === 'folder') {
143
+            $fileDependent = true;
144
+            $column = 'file_source';
145
+            $fileDependentWhere = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` ';
146
+            $fileDependentWhere .= 'INNER JOIN `*PREFIX*storages` ON `numeric_id` = `*PREFIX*filecache`.`storage` ';
147
+        } else {
148
+            $column = 'item_source';
149
+        }
150
+
151
+        $select = self::createSelectStatement(self::FORMAT_NONE, $fileDependent);
152
+
153
+        $where .= ' `' . $column . '` = ? AND `item_type` = ? ';
154
+        $arguments = [$itemSource, $itemType];
155
+        // for link shares $user === null
156
+        if ($user !== null) {
157
+            $where .= ' AND `share_with` = ? ';
158
+            $arguments[] = $user;
159
+        }
160
+
161
+        if ($shareType !== null) {
162
+            $where .= ' AND `share_type` = ? ';
163
+            $arguments[] = $shareType;
164
+        }
165
+
166
+        if ($owner !== null) {
167
+            $where .= ' AND `uid_owner` = ? ';
168
+            $arguments[] = $owner;
169
+        }
170
+
171
+        $query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` '. $fileDependentWhere . $where);
172
+
173
+        $result = \OC_DB::executeAudited($query, $arguments);
174
+
175
+        while ($row = $result->fetchRow()) {
176
+            if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) {
177
+                continue;
178
+            }
179
+            if ($fileDependent && (int)$row['file_parent'] === -1) {
180
+                // if it is a mount point we need to get the path from the mount manager
181
+                $mountManager = \OC\Files\Filesystem::getMountManager();
182
+                $mountPoint = $mountManager->findByStorageId($row['storage_id']);
183
+                if (!empty($mountPoint)) {
184
+                    $path = $mountPoint[0]->getMountPoint();
185
+                    $path = trim($path, '/');
186
+                    $path = substr($path, strlen($owner) + 1); //normalize path to 'files/foo.txt`
187
+                    $row['path'] = $path;
188
+                } else {
189
+                    \OC::$server->getLogger()->warning(
190
+                        'Could not resolve mount point for ' . $row['storage_id'],
191
+                        ['app' => 'OCP\Share']
192
+                    );
193
+                }
194
+            }
195
+            $shares[] = $row;
196
+        }
197
+
198
+        //if didn't found a result than let's look for a group share.
199
+        if (empty($shares) && $user !== null) {
200
+            $userObject = \OC::$server->getUserManager()->get($user);
201
+            $groups = [];
202
+            if ($userObject) {
203
+                $groups = \OC::$server->getGroupManager()->getUserGroupIds($userObject);
204
+            }
205
+
206
+            if (!empty($groups)) {
207
+                $where = $fileDependentWhere . ' WHERE `' . $column . '` = ? AND `item_type` = ? AND `share_with` in (?)';
208
+                $arguments = [$itemSource, $itemType, $groups];
209
+                $types = [null, null, IQueryBuilder::PARAM_STR_ARRAY];
210
+
211
+                if ($owner !== null) {
212
+                    $where .= ' AND `uid_owner` = ?';
213
+                    $arguments[] = $owner;
214
+                    $types[] = null;
215
+                }
216
+
217
+                // TODO: inject connection, hopefully one day in the future when this
218
+                // class isn't static anymore...
219
+                $conn = \OC::$server->getDatabaseConnection();
220
+                $result = $conn->executeQuery(
221
+                    'SELECT ' . $select . ' FROM `*PREFIX*share` ' . $where,
222
+                    $arguments,
223
+                    $types
224
+                );
225
+
226
+                while ($row = $result->fetch()) {
227
+                    $shares[] = $row;
228
+                }
229
+            }
230
+        }
231
+
232
+        return $shares;
233
+    }
234
+
235
+    /**
236
+     * Get the item of item type shared with the current user by source
237
+     * @param string $itemType
238
+     * @param string $itemSource
239
+     * @param int $format (optional) Format type must be defined by the backend
240
+     * @param mixed $parameters
241
+     * @param boolean $includeCollections
242
+     * @param string $shareWith (optional) define against which user should be checked, default: current user
243
+     * @return array
244
+     */
245
+    public static function getItemSharedWithBySource($itemType, $itemSource, $format = self::FORMAT_NONE,
246
+                                                        $parameters = null, $includeCollections = false, $shareWith = null) {
247
+        $shareWith = ($shareWith === null) ? \OC_User::getUser() : $shareWith;
248
+        return self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups, $shareWith, null, $format,
249
+            $parameters, 1, $includeCollections, true);
250
+    }
251
+
252
+    /**
253
+     * Get the shared item of item type owned by the current user
254
+     * @param string $itemType
255
+     * @param string $itemSource
256
+     * @param int $format (optional) Format type must be defined by the backend
257
+     * @param mixed $parameters
258
+     * @param boolean $includeCollections
259
+     * @return mixed Return depends on format
260
+     */
261
+    public static function getItemShared($itemType, $itemSource, $format = self::FORMAT_NONE,
262
+                                            $parameters = null, $includeCollections = false) {
263
+        return self::getItems($itemType, $itemSource, null, null, \OC_User::getUser(), $format,
264
+            $parameters, -1, $includeCollections);
265
+    }
266
+
267
+    /**
268
+     * Share an item with a user, group, or via private link
269
+     * @param string $itemType
270
+     * @param string $itemSource
271
+     * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
272
+     * @param string $shareWith User or group the item is being shared with
273
+     * @param int $permissions CRUDS
274
+     * @param string $itemSourceName
275
+     * @param \DateTime|null $expirationDate
276
+     * @return boolean|string Returns true on success or false on failure, Returns token on success for links
277
+     * @throws \OC\HintException when the share type is remote and the shareWith is invalid
278
+     * @throws \Exception
279
+     * @since 5.0.0 - parameter $itemSourceName was added in 6.0.0, parameter $expirationDate was added in 7.0.0, parameter $passwordChanged added in 9.0.0
280
+     * @deprecated 14.0.0 TESTS ONLY - this methods is as of 2018-06 only used by tests
281
+     * called like this:
282
+     * \OC\Share\Share::shareItem('test', 1, IShare::TYPE_USER, $otherUserId, \OCP\Constants::PERMISSION_READ);
283
+     */
284
+    public static function shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions) {
285
+        $backend = self::getBackend($itemType);
286
+
287
+        if ($backend->isShareTypeAllowed($shareType) === false) {
288
+            $message = 'Sharing failed, because the backend does not allow shares from type %i';
289
+            throw new \Exception(sprintf($message, $shareType));
290
+        }
291
+
292
+        $uidOwner = \OC_User::getUser();
293
+
294
+        // Verify share type and sharing conditions are met
295
+        if ($shareType === IShare::TYPE_USER) {
296
+            if ($shareWith == $uidOwner) {
297
+                $message = 'Sharing failed, because you can not share with yourself';
298
+                throw new \Exception($message);
299
+            }
300
+            if (!\OC::$server->getUserManager()->userExists($shareWith)) {
301
+                $message = 'Sharing failed, because the user %s does not exist';
302
+                throw new \Exception(sprintf($message, $shareWith));
303
+            }
304
+            // Check if the item source is already shared with the user, either from the same owner or a different user
305
+            if ($checkExists = self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups,
306
+                $shareWith, null, self::FORMAT_NONE, null, 1, true, true)) {
307
+                // Only allow the same share to occur again if it is the same
308
+                // owner and is not a user share, this use case is for increasing
309
+                // permissions for a specific user
310
+                if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) {
311
+                    $message = 'Sharing failed, because this item is already shared with %s';
312
+                    throw new \Exception(sprintf($message, $shareWith));
313
+                }
314
+            }
315
+            if ($checkExists = self::getItems($itemType, $itemSource, IShare::TYPE_USER,
316
+                $shareWith, null, self::FORMAT_NONE, null, 1, true, true)) {
317
+                // Only allow the same share to occur again if it is the same
318
+                // owner and is not a user share, this use case is for increasing
319
+                // permissions for a specific user
320
+                if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) {
321
+                    $message = 'Sharing failed, because this item is already shared with user %s';
322
+                    throw new \Exception(sprintf($message, $shareWith));
323
+                }
324
+            }
325
+        }
326
+
327
+        // Put the item into the database
328
+        $result = self::put('test', $itemSource, IShare::TYPE_USER, $shareWith, $uidOwner, $permissions);
329
+
330
+        return $result ? true : false;
331
+    }
332
+
333
+    /**
334
+     * Unshare an item from a user, group, or delete a private link
335
+     * @param string $itemType
336
+     * @param string $itemSource
337
+     * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
338
+     * @param string $shareWith User or group the item is being shared with
339
+     * @param string $owner owner of the share, if null the current user is used
340
+     * @return boolean true on success or false on failure
341
+     */
342
+    public static function unshare($itemType, $itemSource, $shareType, $shareWith, $owner = null) {
343
+
344
+        // check if it is a valid itemType
345
+        self::getBackend($itemType);
346
+
347
+        $items = self::getItemSharedWithUser($itemType, $itemSource, $shareWith, $owner, $shareType);
348
+
349
+        $toDelete = [];
350
+        $newParent = null;
351
+        $currentUser = $owner ? $owner : \OC_User::getUser();
352
+        foreach ($items as $item) {
353
+            // delete the item with the expected share_type and owner
354
+            if ((int)$item['share_type'] === (int)$shareType && $item['uid_owner'] === $currentUser) {
355
+                $toDelete = $item;
356
+            // if there is more then one result we don't have to delete the children
357
+                // but update their parent. For group shares the new parent should always be
358
+                // the original group share and not the db entry with the unique name
359
+            } elseif ((int)$item['share_type'] === self::$shareTypeGroupUserUnique) {
360
+                $newParent = $item['parent'];
361
+            } else {
362
+                $newParent = $item['id'];
363
+            }
364
+        }
365
+
366
+        if (!empty($toDelete)) {
367
+            self::unshareItem($toDelete, $newParent);
368
+            return true;
369
+        }
370
+        return false;
371
+    }
372
+
373
+    /**
374
+     * Checks whether a share has expired, calls unshareItem() if yes.
375
+     * @param array $item Share data (usually database row)
376
+     * @return boolean True if item was expired, false otherwise.
377
+     */
378
+    protected static function expireItem(array $item) {
379
+        $result = false;
380
+
381
+        // only use default expiration date for link shares
382
+        if ((int) $item['share_type'] === IShare::TYPE_LINK) {
383
+
384
+            // calculate expiration date
385
+            if (!empty($item['expiration'])) {
386
+                $userDefinedExpire = new \DateTime($item['expiration']);
387
+                $expires = $userDefinedExpire->getTimestamp();
388
+            } else {
389
+                $expires = null;
390
+            }
391
+
392
+
393
+            // get default expiration settings
394
+            $defaultSettings = Helper::getDefaultExpireSetting();
395
+            $expires = Helper::calculateExpireDate($defaultSettings, $item['stime'], $expires);
396
+
397
+
398
+            if (is_int($expires)) {
399
+                $now = time();
400
+                if ($now > $expires) {
401
+                    self::unshareItem($item);
402
+                    $result = true;
403
+                }
404
+            }
405
+        }
406
+        return $result;
407
+    }
408
+
409
+    /**
410
+     * Unshares a share given a share data array
411
+     * @param array $item Share data (usually database row)
412
+     * @param int $newParent parent ID
413
+     * @return null
414
+     */
415
+    protected static function unshareItem(array $item, $newParent = null) {
416
+        $shareType = (int)$item['share_type'];
417
+        $shareWith = null;
418
+        if ($shareType !== IShare::TYPE_LINK) {
419
+            $shareWith = $item['share_with'];
420
+        }
421
+
422
+        // Pass all the vars we have for now, they may be useful
423
+        $hookParams = [
424
+            'id'            => $item['id'],
425
+            'itemType'      => $item['item_type'],
426
+            'itemSource'    => $item['item_source'],
427
+            'shareType'     => $shareType,
428
+            'shareWith'     => $shareWith,
429
+            'itemParent'    => $item['parent'],
430
+            'uidOwner'      => $item['uid_owner'],
431
+        ];
432
+        if ($item['item_type'] === 'file' || $item['item_type'] === 'folder') {
433
+            $hookParams['fileSource'] = $item['file_source'];
434
+            $hookParams['fileTarget'] = $item['file_target'];
435
+        }
436
+
437
+        \OC_Hook::emit(\OCP\Share::class, 'pre_unshare', $hookParams);
438
+        $deletedShares = Helper::delete($item['id'], false, null, $newParent);
439
+        $deletedShares[] = $hookParams;
440
+        $hookParams['deletedShares'] = $deletedShares;
441
+        \OC_Hook::emit(\OCP\Share::class, 'post_unshare', $hookParams);
442
+        if ((int)$item['share_type'] === IShare::TYPE_REMOTE && \OC::$server->getUserSession()->getUser()) {
443
+            list(, $remote) = Helper::splitUserRemote($item['share_with']);
444
+            self::sendRemoteUnshare($remote, $item['id'], $item['token']);
445
+        }
446
+    }
447
+
448
+    /**
449
+     * Get the backend class for the specified item type
450
+     * @param string $itemType
451
+     * @throws \Exception
452
+     * @return \OCP\Share_Backend
453
+     */
454
+    public static function getBackend($itemType) {
455
+        $l = \OC::$server->getL10N('lib');
456
+        if (isset(self::$backends[$itemType])) {
457
+            return self::$backends[$itemType];
458
+        } elseif (isset(self::$backendTypes[$itemType]['class'])) {
459
+            $class = self::$backendTypes[$itemType]['class'];
460
+            if (class_exists($class)) {
461
+                self::$backends[$itemType] = new $class;
462
+                if (!(self::$backends[$itemType] instanceof \OCP\Share_Backend)) {
463
+                    $message = 'Sharing backend %s must implement the interface OCP\Share_Backend';
464
+                    $message_t = $l->t('Sharing backend %s must implement the interface OCP\Share_Backend', [$class]);
465
+                    \OCP\Util::writeLog('OCP\Share', sprintf($message, $class), ILogger::ERROR);
466
+                    throw new \Exception($message_t);
467
+                }
468
+                return self::$backends[$itemType];
469
+            } else {
470
+                $message = 'Sharing backend %s not found';
471
+                $message_t = $l->t('Sharing backend %s not found', [$class]);
472
+                \OCP\Util::writeLog('OCP\Share', sprintf($message, $class), ILogger::ERROR);
473
+                throw new \Exception($message_t);
474
+            }
475
+        }
476
+        $message = 'Sharing backend for %s not found';
477
+        $message_t = $l->t('Sharing backend for %s not found', [$itemType]);
478
+        \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemType), ILogger::ERROR);
479
+        throw new \Exception($message_t);
480
+    }
481
+
482
+    /**
483
+     * Check if resharing is allowed
484
+     * @return boolean true if allowed or false
485
+     *
486
+     * Resharing is allowed by default if not configured
487
+     */
488
+    public static function isResharingAllowed() {
489
+        if (!isset(self::$isResharingAllowed)) {
490
+            if (\OC::$server->getConfig()->getAppValue('core', 'shareapi_allow_resharing', 'yes') == 'yes') {
491
+                self::$isResharingAllowed = true;
492
+            } else {
493
+                self::$isResharingAllowed = false;
494
+            }
495
+        }
496
+        return self::$isResharingAllowed;
497
+    }
498
+
499
+    /**
500
+     * Get a list of collection item types for the specified item type
501
+     * @param string $itemType
502
+     * @return array
503
+     */
504
+    private static function getCollectionItemTypes($itemType) {
505
+        $collectionTypes = [$itemType];
506
+        foreach (self::$backendTypes as $type => $backend) {
507
+            if (in_array($backend['collectionOf'], $collectionTypes)) {
508
+                $collectionTypes[] = $type;
509
+            }
510
+        }
511
+        // TODO Add option for collections to be collection of themselves, only 'folder' does it now...
512
+        if (isset(self::$backendTypes[$itemType]) && (!self::getBackend($itemType) instanceof \OCP\Share_Backend_Collection || $itemType != 'folder')) {
513
+            unset($collectionTypes[0]);
514
+        }
515
+        // Return array if collections were found or the item type is a
516
+        // collection itself - collections can be inside collections
517
+        if (count($collectionTypes) > 0) {
518
+            return $collectionTypes;
519
+        }
520
+        return false;
521
+    }
522
+
523
+    /**
524
+     * Get the owners of items shared with a user.
525
+     *
526
+     * @param string $user The user the items are shared with.
527
+     * @param string $type The type of the items shared with the user.
528
+     * @param boolean $includeCollections Include collection item types (optional)
529
+     * @param boolean $includeOwner include owner in the list of users the item is shared with (optional)
530
+     * @return array
531
+     * @deprecated TESTS ONLY - this methods is only used by tests
532
+     * called like this:
533
+     * \OC\Share\Share::getSharedItemsOwners($this->user, $this->type, true)
534
+     */
535
+    public static function getSharedItemsOwners($user, $type, $includeCollections = false, $includeOwner = false) {
536
+        // First, we find out if $type is part of a collection (and if that collection is part of
537
+        // another one and so on).
538
+        $collectionTypes = [];
539
+        if (!$includeCollections || !$collectionTypes = self::getCollectionItemTypes($type)) {
540
+            $collectionTypes[] = $type;
541
+        }
542
+
543
+        // Of these collection types, along with our original $type, we make a
544
+        // list of the ones for which a sharing backend has been registered.
545
+        // FIXME: Ideally, we wouldn't need to nest getItemsSharedWith in this loop but just call it
546
+        // with its $includeCollections parameter set to true. Unfortunately, this fails currently.
547
+        $allMaybeSharedItems = [];
548
+        foreach ($collectionTypes as $collectionType) {
549
+            if (isset(self::$backends[$collectionType])) {
550
+                $allMaybeSharedItems[$collectionType] = self::getItemsSharedWithUser(
551
+                    $collectionType,
552
+                    $user,
553
+                    self::FORMAT_NONE
554
+                );
555
+            }
556
+        }
557
+
558
+        $owners = [];
559
+        if ($includeOwner) {
560
+            $owners[] = $user;
561
+        }
562
+
563
+        // We take a look at all shared items of the given $type (or of the collections it is part of)
564
+        // and find out their owners. Then, we gather the tags for the original $type from all owners,
565
+        // and return them as elements of a list that look like "Tag (owner)".
566
+        foreach ($allMaybeSharedItems as $collectionType => $maybeSharedItems) {
567
+            foreach ($maybeSharedItems as $sharedItem) {
568
+                if (isset($sharedItem['id'])) { //workaround for https://github.com/owncloud/core/issues/2814
569
+                    $owners[] = $sharedItem['uid_owner'];
570
+                }
571
+            }
572
+        }
573
+
574
+        return $owners;
575
+    }
576
+
577
+    /**
578
+     * Get shared items from the database
579
+     * @param string $itemType
580
+     * @param string $item Item source or target (optional)
581
+     * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, SHARE_TYPE_LINK, $shareTypeUserAndGroups, or $shareTypeGroupUserUnique
582
+     * @param string $shareWith User or group the item is being shared with
583
+     * @param string $uidOwner User that is the owner of shared items (optional)
584
+     * @param int $format Format to convert items to with formatItems() (optional)
585
+     * @param mixed $parameters to pass to formatItems() (optional)
586
+     * @param int $limit Number of items to return, -1 to return all matches (optional)
587
+     * @param boolean $includeCollections Include collection item types (optional)
588
+     * @param boolean $itemShareWithBySource (optional)
589
+     * @param boolean $checkExpireDate
590
+     * @return array
591
+     *
592
+     * See public functions getItem(s)... for parameter usage
593
+     *
594
+     */
595
+    public static function getItems($itemType, $item = null, $shareType = null, $shareWith = null,
596
+                                    $uidOwner = null, $format = self::FORMAT_NONE, $parameters = null, $limit = -1,
597
+                                    $includeCollections = false, $itemShareWithBySource = false, $checkExpireDate  = true) {
598
+        if (\OC::$server->getConfig()->getAppValue('core', 'shareapi_enabled', 'yes') != 'yes') {
599
+            return [];
600
+        }
601
+        $backend = self::getBackend($itemType);
602
+        $collectionTypes = false;
603
+        // Get filesystem root to add it to the file target and remove from the
604
+        // file source, match file_source with the file cache
605
+        if ($itemType == 'file' || $itemType == 'folder') {
606
+            if (!is_null($uidOwner)) {
607
+                $root = \OC\Files\Filesystem::getRoot();
608
+            } else {
609
+                $root = '';
610
+            }
611
+            $where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` ';
612
+            if (!isset($item)) {
613
+                $where .= ' AND `file_target` IS NOT NULL ';
614
+            }
615
+            $where .= 'INNER JOIN `*PREFIX*storages` ON `numeric_id` = `*PREFIX*filecache`.`storage` ';
616
+            $fileDependent = true;
617
+            $queryArgs = [];
618
+        } else {
619
+            $fileDependent = false;
620
+            $root = '';
621
+            $collectionTypes = self::getCollectionItemTypes($itemType);
622
+            if ($includeCollections && !isset($item) && $collectionTypes) {
623
+                // If includeCollections is true, find collections of this item type, e.g. a music album contains songs
624
+                if (!in_array($itemType, $collectionTypes)) {
625
+                    $itemTypes = array_merge([$itemType], $collectionTypes);
626
+                } else {
627
+                    $itemTypes = $collectionTypes;
628
+                }
629
+                $placeholders = implode(',', array_fill(0, count($itemTypes), '?'));
630
+                $where = ' WHERE `item_type` IN ('.$placeholders.'))';
631
+                $queryArgs = $itemTypes;
632
+            } else {
633
+                $where = ' WHERE `item_type` = ?';
634
+                $queryArgs = [$itemType];
635
+            }
636
+        }
637
+        if (\OC::$server->getConfig()->getAppValue('core', 'shareapi_allow_links', 'yes') !== 'yes') {
638
+            $where .= ' AND `share_type` != ?';
639
+            $queryArgs[] = IShare::TYPE_LINK;
640
+        }
641
+        if (isset($shareType)) {
642
+            // Include all user and group items
643
+            if ($shareType == self::$shareTypeUserAndGroups && isset($shareWith)) {
644
+                $where .= ' AND ((`share_type` in (?, ?) AND `share_with` = ?) ';
645
+                $queryArgs[] = IShare::TYPE_USER;
646
+                $queryArgs[] = self::$shareTypeGroupUserUnique;
647
+                $queryArgs[] = $shareWith;
648
+
649
+                $user = \OC::$server->getUserManager()->get($shareWith);
650
+                $groups = [];
651
+                if ($user) {
652
+                    $groups = \OC::$server->getGroupManager()->getUserGroupIds($user);
653
+                }
654
+                if (!empty($groups)) {
655
+                    $placeholders = implode(',', array_fill(0, count($groups), '?'));
656
+                    $where .= ' OR (`share_type` = ? AND `share_with` IN ('.$placeholders.')) ';
657
+                    $queryArgs[] = IShare::TYPE_GROUP;
658
+                    $queryArgs = array_merge($queryArgs, $groups);
659
+                }
660
+                $where .= ')';
661
+                // Don't include own group shares
662
+                $where .= ' AND `uid_owner` != ?';
663
+                $queryArgs[] = $shareWith;
664
+            } else {
665
+                $where .= ' AND `share_type` = ?';
666
+                $queryArgs[] = $shareType;
667
+                if (isset($shareWith)) {
668
+                    $where .= ' AND `share_with` = ?';
669
+                    $queryArgs[] = $shareWith;
670
+                }
671
+            }
672
+        }
673
+        if (isset($uidOwner)) {
674
+            $where .= ' AND `uid_owner` = ?';
675
+            $queryArgs[] = $uidOwner;
676
+            if (!isset($shareType)) {
677
+                // Prevent unique user targets for group shares from being selected
678
+                $where .= ' AND `share_type` != ?';
679
+                $queryArgs[] = self::$shareTypeGroupUserUnique;
680
+            }
681
+            if ($fileDependent) {
682
+                $column = 'file_source';
683
+            } else {
684
+                $column = 'item_source';
685
+            }
686
+        } else {
687
+            if ($fileDependent) {
688
+                $column = 'file_target';
689
+            } else {
690
+                $column = 'item_target';
691
+            }
692
+        }
693
+        if (isset($item)) {
694
+            $collectionTypes = self::getCollectionItemTypes($itemType);
695
+            if ($includeCollections && $collectionTypes && !in_array('folder', $collectionTypes)) {
696
+                $where .= ' AND (';
697
+            } else {
698
+                $where .= ' AND';
699
+            }
700
+            // If looking for own shared items, check item_source else check item_target
701
+            if (isset($uidOwner) || $itemShareWithBySource) {
702
+                // If item type is a file, file source needs to be checked in case the item was converted
703
+                if ($fileDependent) {
704
+                    $where .= ' `file_source` = ?';
705
+                    $column = 'file_source';
706
+                } else {
707
+                    $where .= ' `item_source` = ?';
708
+                    $column = 'item_source';
709
+                }
710
+            } else {
711
+                if ($fileDependent) {
712
+                    $where .= ' `file_target` = ?';
713
+                    $item = \OC\Files\Filesystem::normalizePath($item);
714
+                } else {
715
+                    $where .= ' `item_target` = ?';
716
+                }
717
+            }
718
+            $queryArgs[] = $item;
719
+            if ($includeCollections && $collectionTypes && !in_array('folder', $collectionTypes)) {
720
+                $placeholders = implode(',', array_fill(0, count($collectionTypes), '?'));
721
+                $where .= ' OR `item_type` IN ('.$placeholders.'))';
722
+                $queryArgs = array_merge($queryArgs, $collectionTypes);
723
+            }
724
+        }
725
+
726
+        if ($shareType == self::$shareTypeUserAndGroups && $limit === 1) {
727
+            // Make sure the unique user target is returned if it exists,
728
+            // unique targets should follow the group share in the database
729
+            // If the limit is not 1, the filtering can be done later
730
+            $where .= ' ORDER BY `*PREFIX*share`.`id` DESC';
731
+        } else {
732
+            $where .= ' ORDER BY `*PREFIX*share`.`id` ASC';
733
+        }
734
+
735
+        if ($limit != -1 && !$includeCollections) {
736
+            // The limit must be at least 3, because filtering needs to be done
737
+            if ($limit < 3) {
738
+                $queryLimit = 3;
739
+            } else {
740
+                $queryLimit = $limit;
741
+            }
742
+        } else {
743
+            $queryLimit = null;
744
+        }
745
+        $select = self::createSelectStatement($format, $fileDependent, $uidOwner);
746
+        $root = strlen($root);
747
+        $query = \OC_DB::prepare('SELECT '.$select.' FROM `*PREFIX*share` '.$where, $queryLimit);
748
+        $result = $query->execute($queryArgs);
749
+        if ($result === false) {
750
+            \OCP\Util::writeLog('OCP\Share',
751
+                \OC_DB::getErrorMessage() . ', select=' . $select . ' where=',
752
+                ILogger::ERROR);
753
+        }
754
+        $items = [];
755
+        $targets = [];
756
+        $switchedItems = [];
757
+        $mounts = [];
758
+        while ($row = $result->fetchRow()) {
759
+            self::transformDBResults($row);
760
+            // Filter out duplicate group shares for users with unique targets
761
+            if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) {
762
+                continue;
763
+            }
764
+            if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) {
765
+                $row['share_type'] = IShare::TYPE_GROUP;
766
+                $row['unique_name'] = true; // remember that we use a unique name for this user
767
+                $row['share_with'] = $items[$row['parent']]['share_with'];
768
+                // if the group share was unshared from the user we keep the permission, otherwise
769
+                // we take the permission from the parent because this is always the up-to-date
770
+                // permission for the group share
771
+                if ($row['permissions'] > 0) {
772
+                    $row['permissions'] = $items[$row['parent']]['permissions'];
773
+                }
774
+                // Remove the parent group share
775
+                unset($items[$row['parent']]);
776
+                if ($row['permissions'] == 0) {
777
+                    continue;
778
+                }
779
+            } elseif (!isset($uidOwner)) {
780
+                // Check if the same target already exists
781
+                if (isset($targets[$row['id']])) {
782
+                    // Check if the same owner shared with the user twice
783
+                    // through a group and user share - this is allowed
784
+                    $id = $targets[$row['id']];
785
+                    if (isset($items[$id]) && $items[$id]['uid_owner'] == $row['uid_owner']) {
786
+                        // Switch to group share type to ensure resharing conditions aren't bypassed
787
+                        if ($items[$id]['share_type'] != IShare::TYPE_GROUP) {
788
+                            $items[$id]['share_type'] = IShare::TYPE_GROUP;
789
+                            $items[$id]['share_with'] = $row['share_with'];
790
+                        }
791
+                        // Switch ids if sharing permission is granted on only
792
+                        // one share to ensure correct parent is used if resharing
793
+                        if (~(int)$items[$id]['permissions'] & \OCP\Constants::PERMISSION_SHARE
794
+                            && (int)$row['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
795
+                            $items[$row['id']] = $items[$id];
796
+                            $switchedItems[$id] = $row['id'];
797
+                            unset($items[$id]);
798
+                            $id = $row['id'];
799
+                        }
800
+                        $items[$id]['permissions'] |= (int)$row['permissions'];
801
+                    }
802
+                    continue;
803
+                } elseif (!empty($row['parent'])) {
804
+                    $targets[$row['parent']] = $row['id'];
805
+                }
806
+            }
807
+            // Remove root from file source paths if retrieving own shared items
808
+            if (isset($uidOwner) && isset($row['path'])) {
809
+                if (isset($row['parent'])) {
810
+                    $query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?');
811
+                    $parentResult = $query->execute([$row['parent']]);
812
+                    if ($result === false) {
813
+                        \OCP\Util::writeLog('OCP\Share', 'Can\'t select parent: ' .
814
+                            \OC_DB::getErrorMessage() . ', select=' . $select . ' where=' . $where,
815
+                            ILogger::ERROR);
816
+                    } else {
817
+                        $parentRow = $parentResult->fetchRow();
818
+                        $tmpPath = $parentRow['file_target'];
819
+                        // find the right position where the row path continues from the target path
820
+                        $pos = strrpos($row['path'], $parentRow['file_target']);
821
+                        $subPath = substr($row['path'], $pos);
822
+                        $splitPath = explode('/', $subPath);
823
+                        foreach (array_slice($splitPath, 2) as $pathPart) {
824
+                            $tmpPath = $tmpPath . '/' . $pathPart;
825
+                        }
826
+                        $row['path'] = $tmpPath;
827
+                    }
828
+                } else {
829
+                    if (!isset($mounts[$row['storage']])) {
830
+                        $mountPoints = \OC\Files\Filesystem::getMountByNumericId($row['storage']);
831
+                        if (is_array($mountPoints) && !empty($mountPoints)) {
832
+                            $mounts[$row['storage']] = current($mountPoints);
833
+                        }
834
+                    }
835
+                    if (!empty($mounts[$row['storage']])) {
836
+                        $path = $mounts[$row['storage']]->getMountPoint().$row['path'];
837
+                        $relPath = substr($path, $root); // path relative to data/user
838
+                        $row['path'] = rtrim($relPath, '/');
839
+                    }
840
+                }
841
+            }
842
+
843
+            if ($checkExpireDate) {
844
+                if (self::expireItem($row)) {
845
+                    continue;
846
+                }
847
+            }
848
+            // Check if resharing is allowed, if not remove share permission
849
+            if (isset($row['permissions']) && (!self::isResharingAllowed() | \OCP\Util::isSharingDisabledForUser())) {
850
+                $row['permissions'] &= ~\OCP\Constants::PERMISSION_SHARE;
851
+            }
852
+            // Add display names to result
853
+            $row['share_with_displayname'] = $row['share_with'];
854
+            if (isset($row['share_with']) && $row['share_with'] != '' &&
855
+                $row['share_type'] === IShare::TYPE_USER) {
856
+                $shareWithUser = \OC::$server->getUserManager()->get($row['share_with']);
857
+                $row['share_with_displayname'] = $shareWithUser === null ? $row['share_with'] : $shareWithUser->getDisplayName();
858
+            } elseif (isset($row['share_with']) && $row['share_with'] != '' &&
859
+                $row['share_type'] === IShare::TYPE_REMOTE) {
860
+                $addressBookEntries = \OC::$server->getContactsManager()->search($row['share_with'], ['CLOUD']);
861
+                foreach ($addressBookEntries as $entry) {
862
+                    foreach ($entry['CLOUD'] as $cloudID) {
863
+                        if ($cloudID === $row['share_with']) {
864
+                            $row['share_with_displayname'] = $entry['FN'];
865
+                        }
866
+                    }
867
+                }
868
+            }
869
+            if (isset($row['uid_owner']) && $row['uid_owner'] != '') {
870
+                $ownerUser = \OC::$server->getUserManager()->get($row['uid_owner']);
871
+                $row['displayname_owner'] = $ownerUser === null ? $row['uid_owner'] : $ownerUser->getDisplayName();
872
+            }
873
+
874
+            if ($row['permissions'] > 0) {
875
+                $items[$row['id']] = $row;
876
+            }
877
+        }
878
+
879
+        // group items if we are looking for items shared with the current user
880
+        if (isset($shareWith) && $shareWith === \OCP\User::getUser()) {
881
+            $items = self::groupItems($items, $itemType);
882
+        }
883
+
884
+        if (!empty($items)) {
885
+            $collectionItems = [];
886
+            foreach ($items as &$row) {
887
+                // Return only the item instead of a 2-dimensional array
888
+                if ($limit == 1 && $row[$column] == $item && ($row['item_type'] == $itemType || $itemType == 'file')) {
889
+                    if ($format == self::FORMAT_NONE) {
890
+                        return $row;
891
+                    } else {
892
+                        break;
893
+                    }
894
+                }
895
+                // Check if this is a collection of the requested item type
896
+                if ($includeCollections && $collectionTypes && $row['item_type'] !== 'folder' && in_array($row['item_type'], $collectionTypes)) {
897
+                    if (($collectionBackend = self::getBackend($row['item_type']))
898
+                        && $collectionBackend instanceof \OCP\Share_Backend_Collection) {
899
+                        // Collections can be inside collections, check if the item is a collection
900
+                        if (isset($item) && $row['item_type'] == $itemType && $row[$column] == $item) {
901
+                            $collectionItems[] = $row;
902
+                        } else {
903
+                            $collection = [];
904
+                            $collection['item_type'] = $row['item_type'];
905
+                            if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') {
906
+                                $collection['path'] = basename($row['path']);
907
+                            }
908
+                            $row['collection'] = $collection;
909
+                            // Fetch all of the children sources
910
+                            $children = $collectionBackend->getChildren($row[$column]);
911
+                            foreach ($children as $child) {
912
+                                $childItem = $row;
913
+                                $childItem['item_type'] = $itemType;
914
+                                if ($row['item_type'] != 'file' && $row['item_type'] != 'folder') {
915
+                                    $childItem['item_source'] = $child['source'];
916
+                                    $childItem['item_target'] = $child['target'];
917
+                                }
918
+                                if ($backend instanceof \OCP\Share_Backend_File_Dependent) {
919
+                                    if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') {
920
+                                        $childItem['file_source'] = $child['source'];
921
+                                    } else { // TODO is this really needed if we already know that we use the file backend?
922
+                                        $meta = \OC\Files\Filesystem::getFileInfo($child['file_path']);
923
+                                        $childItem['file_source'] = $meta['fileid'];
924
+                                    }
925
+                                    $childItem['file_target'] =
926
+                                        \OC\Files\Filesystem::normalizePath($child['file_path']);
927
+                                }
928
+                                if (isset($item)) {
929
+                                    if ($childItem[$column] == $item) {
930
+                                        // Return only the item instead of a 2-dimensional array
931
+                                        if ($limit == 1) {
932
+                                            if ($format == self::FORMAT_NONE) {
933
+                                                return $childItem;
934
+                                            } else {
935
+                                                // Unset the items array and break out of both loops
936
+                                                $items = [];
937
+                                                $items[] = $childItem;
938
+                                                break 2;
939
+                                            }
940
+                                        } else {
941
+                                            $collectionItems[] = $childItem;
942
+                                        }
943
+                                    }
944
+                                } else {
945
+                                    $collectionItems[] = $childItem;
946
+                                }
947
+                            }
948
+                        }
949
+                    }
950
+                    // Remove collection item
951
+                    $toRemove = $row['id'];
952
+                    if (array_key_exists($toRemove, $switchedItems)) {
953
+                        $toRemove = $switchedItems[$toRemove];
954
+                    }
955
+                    unset($items[$toRemove]);
956
+                } elseif ($includeCollections && $collectionTypes && in_array($row['item_type'], $collectionTypes)) {
957
+                    // FIXME: Thats a dirty hack to improve file sharing performance,
958
+                    // see github issue #10588 for more details
959
+                    // Need to find a solution which works for all back-ends
960
+                    $collectionBackend = self::getBackend($row['item_type']);
961
+                    $sharedParents = $collectionBackend->getParents($row['item_source']);
962
+                    foreach ($sharedParents as $parent) {
963
+                        $collectionItems[] = $parent;
964
+                    }
965
+                }
966
+            }
967
+            if (!empty($collectionItems)) {
968
+                $collectionItems = array_unique($collectionItems, SORT_REGULAR);
969
+                $items = array_merge($items, $collectionItems);
970
+            }
971
+
972
+            // filter out invalid items, these can appear when subshare entries exist
973
+            // for a group in which the requested user isn't a member any more
974
+            $items = array_filter($items, function ($item) {
975
+                return $item['share_type'] !== self::$shareTypeGroupUserUnique;
976
+            });
977
+
978
+            return self::formatResult($items, $column, $backend, $format, $parameters);
979
+        } elseif ($includeCollections && $collectionTypes && in_array('folder', $collectionTypes)) {
980
+            // FIXME: Thats a dirty hack to improve file sharing performance,
981
+            // see github issue #10588 for more details
982
+            // Need to find a solution which works for all back-ends
983
+            $collectionItems = [];
984
+            $collectionBackend = self::getBackend('folder');
985
+            $sharedParents = $collectionBackend->getParents($item, $shareWith, $uidOwner);
986
+            foreach ($sharedParents as $parent) {
987
+                $collectionItems[] = $parent;
988
+            }
989
+            if ($limit === 1) {
990
+                return reset($collectionItems);
991
+            }
992
+            return self::formatResult($collectionItems, $column, $backend, $format, $parameters);
993
+        }
994
+
995
+        return [];
996
+    }
997
+
998
+    /**
999
+     * group items with link to the same source
1000
+     *
1001
+     * @param array $items
1002
+     * @param string $itemType
1003
+     * @return array of grouped items
1004
+     */
1005
+    protected static function groupItems($items, $itemType) {
1006
+        $fileSharing = $itemType === 'file' || $itemType === 'folder';
1007
+
1008
+        $result = [];
1009
+
1010
+        foreach ($items as $item) {
1011
+            $grouped = false;
1012
+            foreach ($result as $key => $r) {
1013
+                // for file/folder shares we need to compare file_source, otherwise we compare item_source
1014
+                // only group shares if they already point to the same target, otherwise the file where shared
1015
+                // before grouping of shares was added. In this case we don't group them toi avoid confusions
1016
+                if (($fileSharing && $item['file_source'] === $r['file_source'] && $item['file_target'] === $r['file_target']) ||
1017
+                    (!$fileSharing && $item['item_source'] === $r['item_source'] && $item['item_target'] === $r['item_target'])) {
1018
+                    // add the first item to the list of grouped shares
1019
+                    if (!isset($result[$key]['grouped'])) {
1020
+                        $result[$key]['grouped'][] = $result[$key];
1021
+                    }
1022
+                    $result[$key]['permissions'] = (int) $item['permissions'] | (int) $r['permissions'];
1023
+                    $result[$key]['grouped'][] = $item;
1024
+                    $grouped = true;
1025
+                    break;
1026
+                }
1027
+            }
1028
+
1029
+            if (!$grouped) {
1030
+                $result[] = $item;
1031
+            }
1032
+        }
1033
+
1034
+        return $result;
1035
+    }
1036
+
1037
+    /**
1038
+     * Put shared item into the database
1039
+     * @param string $itemType Item type
1040
+     * @param string $itemSource Item source
1041
+     * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
1042
+     * @param string $shareWith User or group the item is being shared with
1043
+     * @param string $uidOwner User that is the owner of shared item
1044
+     * @param int $permissions CRUDS permissions
1045
+     * @throws \Exception
1046
+     * @return mixed id of the new share or false
1047
+     * @deprecated TESTS ONLY - this methods is only used by tests
1048
+     * called like this:
1049
+     * self::put('test', $itemSource, IShare::TYPE_USER, $shareWith, $uidOwner, $permissions);
1050
+     */
1051
+    private static function put($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
1052
+                                $permissions) {
1053
+        $queriesToExecute = [];
1054
+        $suggestedItemTarget = null;
1055
+        $groupFileTarget = $fileTarget = $suggestedFileTarget = $filePath = '';
1056
+        $groupItemTarget = $itemTarget = $fileSource = $parent = 0;
1057
+
1058
+        $result = self::checkReshare('test', $itemSource, IShare::TYPE_USER, $shareWith, $uidOwner, $permissions, null, null);
1059
+        if (!empty($result)) {
1060
+            $parent = $result['parent'];
1061
+            $itemSource = $result['itemSource'];
1062
+            $fileSource = $result['fileSource'];
1063
+            $suggestedItemTarget = $result['suggestedItemTarget'];
1064
+            $suggestedFileTarget = $result['suggestedFileTarget'];
1065
+            $filePath = $result['filePath'];
1066
+        }
1067
+
1068
+        $isGroupShare = false;
1069
+        $users = [$shareWith];
1070
+        $itemTarget = Helper::generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
1071
+                $suggestedItemTarget);
1072
+
1073
+        $run = true;
1074
+        $error = '';
1075
+        $preHookData = [
1076
+            'itemType' => $itemType,
1077
+            'itemSource' => $itemSource,
1078
+            'shareType' => $shareType,
1079
+            'uidOwner' => $uidOwner,
1080
+            'permissions' => $permissions,
1081
+            'fileSource' => $fileSource,
1082
+            'expiration' => null,
1083
+            'token' => null,
1084
+            'run' => &$run,
1085
+            'error' => &$error
1086
+        ];
1087
+
1088
+        $preHookData['itemTarget'] = $itemTarget;
1089
+        $preHookData['shareWith'] = $shareWith;
1090
+
1091
+        \OC_Hook::emit(\OCP\Share::class, 'pre_shared', $preHookData);
1092
+
1093
+        if ($run === false) {
1094
+            throw new \Exception($error);
1095
+        }
1096
+
1097
+        foreach ($users as $user) {
1098
+            $sourceId = ($itemType === 'file' || $itemType === 'folder') ? $fileSource : $itemSource;
1099
+            $sourceExists = self::getItemSharedWithBySource($itemType, $sourceId, self::FORMAT_NONE, null, true, $user);
1100
+
1101
+            $userShareType = $shareType;
1102
+
1103
+            if ($sourceExists && $sourceExists['item_source'] === $itemSource) {
1104
+                $fileTarget = $sourceExists['file_target'];
1105
+                $itemTarget = $sourceExists['item_target'];
1106
+            } elseif (!$sourceExists) {
1107
+                $itemTarget = Helper::generateTarget($itemType, $itemSource, $userShareType, $user,
1108
+                    $uidOwner, $suggestedItemTarget, $parent);
1109
+                if (isset($fileSource)) {
1110
+                    $fileTarget = Helper::generateTarget('file', $filePath, $userShareType,
1111
+                            $user, $uidOwner, $suggestedFileTarget, $parent);
1112
+                } else {
1113
+                    $fileTarget = null;
1114
+                }
1115
+            } else {
1116
+
1117
+                // group share which doesn't exists until now, check if we need a unique target for this user
1118
+
1119
+                $itemTarget = Helper::generateTarget($itemType, $itemSource, IShare::TYPE_USER, $user,
1120
+                    $uidOwner, $suggestedItemTarget, $parent);
1121
+
1122
+                // do we also need a file target
1123
+                if (isset($fileSource)) {
1124
+                    $fileTarget = Helper::generateTarget('file', $filePath, IShare::TYPE_USER, $user,
1125
+                        $uidOwner, $suggestedFileTarget, $parent);
1126
+                } else {
1127
+                    $fileTarget = null;
1128
+                }
1129
+
1130
+                if (($itemTarget === $groupItemTarget) &&
1131
+                    (!isset($fileSource) || $fileTarget === $groupFileTarget)) {
1132
+                    continue;
1133
+                }
1134
+            }
1135
+
1136
+            $queriesToExecute[] = [
1137
+                'itemType'			=> $itemType,
1138
+                'itemSource'		=> $itemSource,
1139
+                'itemTarget'		=> $itemTarget,
1140
+                'shareType'			=> $userShareType,
1141
+                'shareWith'			=> $user,
1142
+                'uidOwner'			=> $uidOwner,
1143
+                'permissions'		=> $permissions,
1144
+                'shareTime'			=> time(),
1145
+                'fileSource'		=> $fileSource,
1146
+                'fileTarget'		=> $fileTarget,
1147
+                'token'				=> null,
1148
+                'parent'			=> $parent,
1149
+                'expiration'		=> null,
1150
+            ];
1151
+        }
1152
+
1153
+        $id = false;
1154
+
1155
+        foreach ($queriesToExecute as $shareQuery) {
1156
+            $shareQuery['parent'] = $parent;
1157
+            $id = self::insertShare($shareQuery);
1158
+        }
1159
+
1160
+        $postHookData = [
1161
+            'itemType' => $itemType,
1162
+            'itemSource' => $itemSource,
1163
+            'parent' => $parent,
1164
+            'shareType' => $shareType,
1165
+            'uidOwner' => $uidOwner,
1166
+            'permissions' => $permissions,
1167
+            'fileSource' => $fileSource,
1168
+            'id' => $parent,
1169
+            'token' => null,
1170
+            'expirationDate' => null,
1171
+        ];
1172
+
1173
+        $postHookData['shareWith'] = $isGroupShare ? $shareWith['group'] : $shareWith;
1174
+        $postHookData['itemTarget'] = $isGroupShare ? $groupItemTarget : $itemTarget;
1175
+        $postHookData['fileTarget'] = $isGroupShare ? $groupFileTarget : $fileTarget;
1176
+
1177
+        \OC_Hook::emit(\OCP\Share::class, 'post_shared', $postHookData);
1178
+
1179
+
1180
+        return $id ? $id : false;
1181
+    }
1182
+
1183
+    /**
1184
+     * @param string $itemType
1185
+     * @param string $itemSource
1186
+     * @param int $shareType
1187
+     * @param string $shareWith
1188
+     * @param string $uidOwner
1189
+     * @param int $permissions
1190
+     * @param string|null $itemSourceName
1191
+     * @param null|\DateTime $expirationDate
1192
+     * @deprecated TESTS ONLY - this methods is only used by tests
1193
+     * called like this:
1194
+     * self::checkReshare('test', $itemSource, IShare::TYPE_USER, $shareWith, $uidOwner, $permissions, null, null);
1195
+     */
1196
+    private static function checkReshare($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $itemSourceName, $expirationDate) {
1197
+        $backend = self::getBackend($itemType);
1198
+
1199
+        $result = [];
1200
+
1201
+        $column = ($itemType === 'file' || $itemType === 'folder') ? 'file_source' : 'item_source';
1202
+
1203
+        $checkReshare = self::getItemSharedWithBySource($itemType, $itemSource, self::FORMAT_NONE, null, true);
1204
+        if ($checkReshare) {
1205
+            // Check if attempting to share back to owner
1206
+            if ($checkReshare['uid_owner'] == $shareWith) {
1207
+                $message = 'Sharing %1$s failed, because the user %2$s is the original sharer';
1208
+                throw new \Exception(sprintf($message, $itemSourceName, $shareWith));
1209
+            }
1210
+        }
1211
+
1212
+        if ($checkReshare && $checkReshare['uid_owner'] !== \OC_User::getUser()) {
1213
+            // Check if share permissions is granted
1214
+            if (self::isResharingAllowed() && (int)$checkReshare['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
1215
+                if (~(int)$checkReshare['permissions'] & $permissions) {
1216
+                    $message = 'Sharing %1$s failed, because the permissions exceed permissions granted to %2$s';
1217
+                    throw new \Exception(sprintf($message, $itemSourceName, $uidOwner));
1218
+                } else {
1219
+                    // TODO Don't check if inside folder
1220
+                    $result['parent'] = $checkReshare['id'];
1221
+
1222
+                    $result['expirationDate'] = $expirationDate;
1223
+                    // $checkReshare['expiration'] could be null and then is always less than any value
1224
+                    if (isset($checkReshare['expiration']) && $checkReshare['expiration'] < $expirationDate) {
1225
+                        $result['expirationDate'] = $checkReshare['expiration'];
1226
+                    }
1227
+
1228
+                    // only suggest the same name as new target if it is a reshare of the
1229
+                    // same file/folder and not the reshare of a child
1230
+                    if ($checkReshare[$column] === $itemSource) {
1231
+                        $result['filePath'] = $checkReshare['file_target'];
1232
+                        $result['itemSource'] = $checkReshare['item_source'];
1233
+                        $result['fileSource'] = $checkReshare['file_source'];
1234
+                        $result['suggestedItemTarget'] = $checkReshare['item_target'];
1235
+                        $result['suggestedFileTarget'] = $checkReshare['file_target'];
1236
+                    } else {
1237
+                        $result['filePath'] = ($backend instanceof \OCP\Share_Backend_File_Dependent) ? $backend->getFilePath($itemSource, $uidOwner) : null;
1238
+                        $result['suggestedItemTarget'] = null;
1239
+                        $result['suggestedFileTarget'] = null;
1240
+                        $result['itemSource'] = $itemSource;
1241
+                        $result['fileSource'] = ($backend instanceof \OCP\Share_Backend_File_Dependent) ? $itemSource : null;
1242
+                    }
1243
+                }
1244
+            } else {
1245
+                $message = 'Sharing %s failed, because resharing is not allowed';
1246
+                throw new \Exception(sprintf($message, $itemSourceName));
1247
+            }
1248
+        } else {
1249
+            $result['parent'] = null;
1250
+            $result['suggestedItemTarget'] = null;
1251
+            $result['suggestedFileTarget'] = null;
1252
+            $result['itemSource'] = $itemSource;
1253
+            $result['expirationDate'] = $expirationDate;
1254
+            if (!$backend->isValidSource($itemSource, $uidOwner)) {
1255
+                $message = 'Sharing %1$s failed, because the sharing backend for '
1256
+                    .'%2$s could not find its source';
1257
+                throw new \Exception(sprintf($message, $itemSource, $itemType));
1258
+            }
1259
+            if ($backend instanceof \OCP\Share_Backend_File_Dependent) {
1260
+                $result['filePath'] = $backend->getFilePath($itemSource, $uidOwner);
1261
+                $meta = \OC\Files\Filesystem::getFileInfo($result['filePath']);
1262
+                $result['fileSource'] = $meta['fileid'];
1263
+                if ($result['fileSource'] == -1) {
1264
+                    $message = 'Sharing %s failed, because the file could not be found in the file cache';
1265
+                    throw new \Exception(sprintf($message, $itemSource));
1266
+                }
1267
+            } else {
1268
+                $result['filePath'] = null;
1269
+                $result['fileSource'] = null;
1270
+            }
1271
+        }
1272
+
1273
+        return $result;
1274
+    }
1275
+
1276
+    /**
1277
+     *
1278
+     * @param array $shareData
1279
+     * @return mixed false in case of a failure or the id of the new share
1280
+     */
1281
+    private static function insertShare(array $shareData) {
1282
+        $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` ('
1283
+            .' `item_type`, `item_source`, `item_target`, `share_type`,'
1284
+            .' `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,'
1285
+            .' `file_target`, `token`, `parent`, `expiration`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)');
1286
+        $query->bindValue(1, $shareData['itemType']);
1287
+        $query->bindValue(2, $shareData['itemSource']);
1288
+        $query->bindValue(3, $shareData['itemTarget']);
1289
+        $query->bindValue(4, $shareData['shareType']);
1290
+        $query->bindValue(5, $shareData['shareWith']);
1291
+        $query->bindValue(6, $shareData['uidOwner']);
1292
+        $query->bindValue(7, $shareData['permissions']);
1293
+        $query->bindValue(8, $shareData['shareTime']);
1294
+        $query->bindValue(9, $shareData['fileSource']);
1295
+        $query->bindValue(10, $shareData['fileTarget']);
1296
+        $query->bindValue(11, $shareData['token']);
1297
+        $query->bindValue(12, $shareData['parent']);
1298
+        $query->bindValue(13, $shareData['expiration'], 'datetime');
1299
+        $result = $query->execute();
1300
+
1301
+        $id = false;
1302
+        if ($result) {
1303
+            $id =  \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share');
1304
+        }
1305
+
1306
+        return $id;
1307
+    }
1308
+
1309
+    /**
1310
+     * construct select statement
1311
+     * @param int $format
1312
+     * @param boolean $fileDependent ist it a file/folder share or a generla share
1313
+     * @param string $uidOwner
1314
+     * @return string select statement
1315
+     */
1316
+    private static function createSelectStatement($format, $fileDependent, $uidOwner = null) {
1317
+        $select = '*';
1318
+        if ($format == self::FORMAT_STATUSES) {
1319
+            if ($fileDependent) {
1320
+                $select = '`*PREFIX*share`.`id`, `*PREFIX*share`.`parent`, `share_type`, `path`, `storage`, '
1321
+                    . '`share_with`, `uid_owner` , `file_source`, `stime`, `*PREFIX*share`.`permissions`, '
1322
+                    . '`*PREFIX*storages`.`id` AS `storage_id`, `*PREFIX*filecache`.`parent` as `file_parent`, '
1323
+                    . '`uid_initiator`';
1324
+            } else {
1325
+                $select = '`id`, `parent`, `share_type`, `share_with`, `uid_owner`, `item_source`, `stime`, `*PREFIX*share`.`permissions`';
1326
+            }
1327
+        } else {
1328
+            if (isset($uidOwner)) {
1329
+                if ($fileDependent) {
1330
+                    $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`,'
1331
+                        . ' `share_type`, `share_with`, `file_source`, `file_target`, `path`, `*PREFIX*share`.`permissions`, `stime`,'
1332
+                        . ' `expiration`, `token`, `storage`, `mail_send`, `uid_owner`, '
1333
+                        . '`*PREFIX*storages`.`id` AS `storage_id`, `*PREFIX*filecache`.`parent` as `file_parent`';
1334
+                } else {
1335
+                    $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `*PREFIX*share`.`permissions`,'
1336
+                        . ' `stime`, `file_source`, `expiration`, `token`, `mail_send`, `uid_owner`';
1337
+                }
1338
+            } else {
1339
+                if ($fileDependent) {
1340
+                    if ($format == \OCA\Files_Sharing\ShareBackend\File::FORMAT_GET_FOLDER_CONTENTS || $format == \OCA\Files_Sharing\ShareBackend\File::FORMAT_FILE_APP_ROOT) {
1341
+                        $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`, `uid_owner`, '
1342
+                            . '`share_type`, `share_with`, `file_source`, `path`, `file_target`, `stime`, '
1343
+                            . '`*PREFIX*share`.`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, '
1344
+                            . '`name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`, `etag`, `mail_send`';
1345
+                    } else {
1346
+                        $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`,'
1347
+                            . '`*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`,'
1348
+                            . '`file_source`, `path`, `file_target`, `*PREFIX*share`.`permissions`,'
1349
+                            . '`stime`, `expiration`, `token`, `storage`, `mail_send`,'
1350
+                            . '`*PREFIX*storages`.`id` AS `storage_id`, `*PREFIX*filecache`.`parent` as `file_parent`';
1351
+                    }
1352
+                }
1353
+            }
1354
+        }
1355
+        return $select;
1356
+    }
1357
+
1358
+
1359
+    /**
1360
+     * transform db results
1361
+     * @param array $row result
1362
+     */
1363
+    private static function transformDBResults(&$row) {
1364
+        if (isset($row['id'])) {
1365
+            $row['id'] = (int) $row['id'];
1366
+        }
1367
+        if (isset($row['share_type'])) {
1368
+            $row['share_type'] = (int) $row['share_type'];
1369
+        }
1370
+        if (isset($row['parent'])) {
1371
+            $row['parent'] = (int) $row['parent'];
1372
+        }
1373
+        if (isset($row['file_parent'])) {
1374
+            $row['file_parent'] = (int) $row['file_parent'];
1375
+        }
1376
+        if (isset($row['file_source'])) {
1377
+            $row['file_source'] = (int) $row['file_source'];
1378
+        }
1379
+        if (isset($row['permissions'])) {
1380
+            $row['permissions'] = (int) $row['permissions'];
1381
+        }
1382
+        if (isset($row['storage'])) {
1383
+            $row['storage'] = (int) $row['storage'];
1384
+        }
1385
+        if (isset($row['stime'])) {
1386
+            $row['stime'] = (int) $row['stime'];
1387
+        }
1388
+        if (isset($row['expiration']) && $row['share_type'] !== IShare::TYPE_LINK) {
1389
+            // discard expiration date for non-link shares, which might have been
1390
+            // set by ancient bugs
1391
+            $row['expiration'] = null;
1392
+        }
1393
+    }
1394
+
1395
+    /**
1396
+     * format result
1397
+     * @param array $items result
1398
+     * @param string $column is it a file share or a general share ('file_target' or 'item_target')
1399
+     * @param \OCP\Share_Backend $backend sharing backend
1400
+     * @param int $format
1401
+     * @param array $parameters additional format parameters
1402
+     * @return array format result
1403
+     */
1404
+    private static function formatResult($items, $column, $backend, $format = self::FORMAT_NONE , $parameters = null) {
1405
+        if ($format === self::FORMAT_NONE) {
1406
+            return $items;
1407
+        } elseif ($format === self::FORMAT_STATUSES) {
1408
+            $statuses = [];
1409
+            foreach ($items as $item) {
1410
+                if ($item['share_type'] === IShare::TYPE_LINK) {
1411
+                    if ($item['uid_initiator'] !== \OC::$server->getUserSession()->getUser()->getUID()) {
1412
+                        continue;
1413
+                    }
1414
+                    $statuses[$item[$column]]['link'] = true;
1415
+                } elseif (!isset($statuses[$item[$column]])) {
1416
+                    $statuses[$item[$column]]['link'] = false;
1417
+                }
1418
+                if (!empty($item['file_target'])) {
1419
+                    $statuses[$item[$column]]['path'] = $item['path'];
1420
+                }
1421
+            }
1422
+            return $statuses;
1423
+        } else {
1424
+            return $backend->formatItems($items, $format, $parameters);
1425
+        }
1426
+    }
1427
+
1428
+    /**
1429
+     * remove protocol from URL
1430
+     *
1431
+     * @param string $url
1432
+     * @return string
1433
+     */
1434
+    public static function removeProtocolFromUrl($url) {
1435
+        if (strpos($url, 'https://') === 0) {
1436
+            return substr($url, strlen('https://'));
1437
+        } elseif (strpos($url, 'http://') === 0) {
1438
+            return substr($url, strlen('http://'));
1439
+        }
1440
+
1441
+        return $url;
1442
+    }
1443
+
1444
+    /**
1445
+     * try http post first with https and then with http as a fallback
1446
+     *
1447
+     * @param string $remoteDomain
1448
+     * @param string $urlSuffix
1449
+     * @param array $fields post parameters
1450
+     * @return array
1451
+     */
1452
+    private static function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields) {
1453
+        $protocol = 'https://';
1454
+        $result = [
1455
+            'success' => false,
1456
+            'result' => '',
1457
+        ];
1458
+        $try = 0;
1459
+        $discoveryService = \OC::$server->query(\OCP\OCS\IDiscoveryService::class);
1460
+        while ($result['success'] === false && $try < 2) {
1461
+            $federationEndpoints = $discoveryService->discover($protocol . $remoteDomain, 'FEDERATED_SHARING');
1462
+            $endpoint = isset($federationEndpoints['share']) ? $federationEndpoints['share'] : '/ocs/v2.php/cloud/shares';
1463
+            $client = \OC::$server->getHTTPClientService()->newClient();
1464
+
1465
+            try {
1466
+                $response = $client->post(
1467
+                    $protocol . $remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT,
1468
+                    [
1469
+                        'body' => $fields,
1470
+                        'connect_timeout' => 10,
1471
+                    ]
1472
+                );
1473
+
1474
+                $result = ['success' => true, 'result' => $response->getBody()];
1475
+            } catch (\Exception $e) {
1476
+                $result = ['success' => false, 'result' => $e->getMessage()];
1477
+            }
1478
+
1479
+            $try++;
1480
+            $protocol = 'http://';
1481
+        }
1482
+
1483
+        return $result;
1484
+    }
1485
+
1486
+    /**
1487
+     * send server-to-server unshare to remote server
1488
+     *
1489
+     * @param string $remote url
1490
+     * @param int $id share id
1491
+     * @param string $token
1492
+     * @return bool
1493
+     */
1494
+    private static function sendRemoteUnshare($remote, $id, $token) {
1495
+        $url = rtrim($remote, '/');
1496
+        $fields = ['token' => $token, 'format' => 'json'];
1497
+        $url = self::removeProtocolFromUrl($url);
1498
+        $result = self::tryHttpPostToShareEndpoint($url, '/'.$id.'/unshare', $fields);
1499
+        $status = json_decode($result['result'], true);
1500
+
1501
+        return ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200));
1502
+    }
1503
+
1504
+    /**
1505
+     * @return int
1506
+     */
1507
+    public static function getExpireInterval() {
1508
+        return (int)\OC::$server->getConfig()->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1509
+    }
1510
+
1511
+    /**
1512
+     * Checks whether the given path is reachable for the given owner
1513
+     *
1514
+     * @param string $path path relative to files
1515
+     * @param string $ownerStorageId storage id of the owner
1516
+     *
1517
+     * @return boolean true if file is reachable, false otherwise
1518
+     */
1519
+    private static function isFileReachable($path, $ownerStorageId) {
1520
+        // if outside the home storage, file is always considered reachable
1521
+        if (!(substr($ownerStorageId, 0, 6) === 'home::' ||
1522
+            substr($ownerStorageId, 0, 13) === 'object::user:'
1523
+        )) {
1524
+            return true;
1525
+        }
1526
+
1527
+        // if inside the home storage, the file has to be under "/files/"
1528
+        $path = ltrim($path, '/');
1529
+        if (substr($path, 0, 6) === 'files/') {
1530
+            return true;
1531
+        }
1532
+
1533
+        return false;
1534
+    }
1535 1535
 }
Please login to merge, or discard this patch.
Spacing   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -150,7 +150,7 @@  discard block
 block discarded – undo
150 150
 
151 151
 		$select = self::createSelectStatement(self::FORMAT_NONE, $fileDependent);
152 152
 
153
-		$where .= ' `' . $column . '` = ? AND `item_type` = ? ';
153
+		$where .= ' `'.$column.'` = ? AND `item_type` = ? ';
154 154
 		$arguments = [$itemSource, $itemType];
155 155
 		// for link shares $user === null
156 156
 		if ($user !== null) {
@@ -168,7 +168,7 @@  discard block
 block discarded – undo
168 168
 			$arguments[] = $owner;
169 169
 		}
170 170
 
171
-		$query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` '. $fileDependentWhere . $where);
171
+		$query = \OC_DB::prepare('SELECT '.$select.' FROM `*PREFIX*share` '.$fileDependentWhere.$where);
172 172
 
173 173
 		$result = \OC_DB::executeAudited($query, $arguments);
174 174
 
@@ -176,7 +176,7 @@  discard block
 block discarded – undo
176 176
 			if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) {
177 177
 				continue;
178 178
 			}
179
-			if ($fileDependent && (int)$row['file_parent'] === -1) {
179
+			if ($fileDependent && (int) $row['file_parent'] === -1) {
180 180
 				// if it is a mount point we need to get the path from the mount manager
181 181
 				$mountManager = \OC\Files\Filesystem::getMountManager();
182 182
 				$mountPoint = $mountManager->findByStorageId($row['storage_id']);
@@ -187,7 +187,7 @@  discard block
 block discarded – undo
187 187
 					$row['path'] = $path;
188 188
 				} else {
189 189
 					\OC::$server->getLogger()->warning(
190
-						'Could not resolve mount point for ' . $row['storage_id'],
190
+						'Could not resolve mount point for '.$row['storage_id'],
191 191
 						['app' => 'OCP\Share']
192 192
 					);
193 193
 				}
@@ -204,7 +204,7 @@  discard block
 block discarded – undo
204 204
 			}
205 205
 
206 206
 			if (!empty($groups)) {
207
-				$where = $fileDependentWhere . ' WHERE `' . $column . '` = ? AND `item_type` = ? AND `share_with` in (?)';
207
+				$where = $fileDependentWhere.' WHERE `'.$column.'` = ? AND `item_type` = ? AND `share_with` in (?)';
208 208
 				$arguments = [$itemSource, $itemType, $groups];
209 209
 				$types = [null, null, IQueryBuilder::PARAM_STR_ARRAY];
210 210
 
@@ -218,7 +218,7 @@  discard block
 block discarded – undo
218 218
 				// class isn't static anymore...
219 219
 				$conn = \OC::$server->getDatabaseConnection();
220 220
 				$result = $conn->executeQuery(
221
-					'SELECT ' . $select . ' FROM `*PREFIX*share` ' . $where,
221
+					'SELECT '.$select.' FROM `*PREFIX*share` '.$where,
222 222
 					$arguments,
223 223
 					$types
224 224
 				);
@@ -351,12 +351,12 @@  discard block
 block discarded – undo
351 351
 		$currentUser = $owner ? $owner : \OC_User::getUser();
352 352
 		foreach ($items as $item) {
353 353
 			// delete the item with the expected share_type and owner
354
-			if ((int)$item['share_type'] === (int)$shareType && $item['uid_owner'] === $currentUser) {
354
+			if ((int) $item['share_type'] === (int) $shareType && $item['uid_owner'] === $currentUser) {
355 355
 				$toDelete = $item;
356 356
 			// if there is more then one result we don't have to delete the children
357 357
 				// but update their parent. For group shares the new parent should always be
358 358
 				// the original group share and not the db entry with the unique name
359
-			} elseif ((int)$item['share_type'] === self::$shareTypeGroupUserUnique) {
359
+			} elseif ((int) $item['share_type'] === self::$shareTypeGroupUserUnique) {
360 360
 				$newParent = $item['parent'];
361 361
 			} else {
362 362
 				$newParent = $item['id'];
@@ -413,7 +413,7 @@  discard block
 block discarded – undo
413 413
 	 * @return null
414 414
 	 */
415 415
 	protected static function unshareItem(array $item, $newParent = null) {
416
-		$shareType = (int)$item['share_type'];
416
+		$shareType = (int) $item['share_type'];
417 417
 		$shareWith = null;
418 418
 		if ($shareType !== IShare::TYPE_LINK) {
419 419
 			$shareWith = $item['share_with'];
@@ -439,7 +439,7 @@  discard block
 block discarded – undo
439 439
 		$deletedShares[] = $hookParams;
440 440
 		$hookParams['deletedShares'] = $deletedShares;
441 441
 		\OC_Hook::emit(\OCP\Share::class, 'post_unshare', $hookParams);
442
-		if ((int)$item['share_type'] === IShare::TYPE_REMOTE && \OC::$server->getUserSession()->getUser()) {
442
+		if ((int) $item['share_type'] === IShare::TYPE_REMOTE && \OC::$server->getUserSession()->getUser()) {
443 443
 			list(, $remote) = Helper::splitUserRemote($item['share_with']);
444 444
 			self::sendRemoteUnshare($remote, $item['id'], $item['token']);
445 445
 		}
@@ -748,7 +748,7 @@  discard block
 block discarded – undo
748 748
 		$result = $query->execute($queryArgs);
749 749
 		if ($result === false) {
750 750
 			\OCP\Util::writeLog('OCP\Share',
751
-				\OC_DB::getErrorMessage() . ', select=' . $select . ' where=',
751
+				\OC_DB::getErrorMessage().', select='.$select.' where=',
752 752
 				ILogger::ERROR);
753 753
 		}
754 754
 		$items = [];
@@ -790,14 +790,14 @@  discard block
 block discarded – undo
790 790
 						}
791 791
 						// Switch ids if sharing permission is granted on only
792 792
 						// one share to ensure correct parent is used if resharing
793
-						if (~(int)$items[$id]['permissions'] & \OCP\Constants::PERMISSION_SHARE
794
-							&& (int)$row['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
793
+						if (~(int) $items[$id]['permissions'] & \OCP\Constants::PERMISSION_SHARE
794
+							&& (int) $row['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
795 795
 							$items[$row['id']] = $items[$id];
796 796
 							$switchedItems[$id] = $row['id'];
797 797
 							unset($items[$id]);
798 798
 							$id = $row['id'];
799 799
 						}
800
-						$items[$id]['permissions'] |= (int)$row['permissions'];
800
+						$items[$id]['permissions'] |= (int) $row['permissions'];
801 801
 					}
802 802
 					continue;
803 803
 				} elseif (!empty($row['parent'])) {
@@ -810,8 +810,8 @@  discard block
 block discarded – undo
810 810
 					$query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?');
811 811
 					$parentResult = $query->execute([$row['parent']]);
812 812
 					if ($result === false) {
813
-						\OCP\Util::writeLog('OCP\Share', 'Can\'t select parent: ' .
814
-							\OC_DB::getErrorMessage() . ', select=' . $select . ' where=' . $where,
813
+						\OCP\Util::writeLog('OCP\Share', 'Can\'t select parent: '.
814
+							\OC_DB::getErrorMessage().', select='.$select.' where='.$where,
815 815
 							ILogger::ERROR);
816 816
 					} else {
817 817
 						$parentRow = $parentResult->fetchRow();
@@ -821,7 +821,7 @@  discard block
 block discarded – undo
821 821
 						$subPath = substr($row['path'], $pos);
822 822
 						$splitPath = explode('/', $subPath);
823 823
 						foreach (array_slice($splitPath, 2) as $pathPart) {
824
-							$tmpPath = $tmpPath . '/' . $pathPart;
824
+							$tmpPath = $tmpPath.'/'.$pathPart;
825 825
 						}
826 826
 						$row['path'] = $tmpPath;
827 827
 					}
@@ -971,7 +971,7 @@  discard block
 block discarded – undo
971 971
 
972 972
 			// filter out invalid items, these can appear when subshare entries exist
973 973
 			// for a group in which the requested user isn't a member any more
974
-			$items = array_filter($items, function ($item) {
974
+			$items = array_filter($items, function($item) {
975 975
 				return $item['share_type'] !== self::$shareTypeGroupUserUnique;
976 976
 			});
977 977
 
@@ -1211,8 +1211,8 @@  discard block
 block discarded – undo
1211 1211
 
1212 1212
 		if ($checkReshare && $checkReshare['uid_owner'] !== \OC_User::getUser()) {
1213 1213
 			// Check if share permissions is granted
1214
-			if (self::isResharingAllowed() && (int)$checkReshare['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
1215
-				if (~(int)$checkReshare['permissions'] & $permissions) {
1214
+			if (self::isResharingAllowed() && (int) $checkReshare['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
1215
+				if (~(int) $checkReshare['permissions'] & $permissions) {
1216 1216
 					$message = 'Sharing %1$s failed, because the permissions exceed permissions granted to %2$s';
1217 1217
 					throw new \Exception(sprintf($message, $itemSourceName, $uidOwner));
1218 1218
 				} else {
@@ -1300,7 +1300,7 @@  discard block
 block discarded – undo
1300 1300
 
1301 1301
 		$id = false;
1302 1302
 		if ($result) {
1303
-			$id =  \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share');
1303
+			$id = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share');
1304 1304
 		}
1305 1305
 
1306 1306
 		return $id;
@@ -1401,7 +1401,7 @@  discard block
 block discarded – undo
1401 1401
 	 * @param array $parameters additional format parameters
1402 1402
 	 * @return array format result
1403 1403
 	 */
1404
-	private static function formatResult($items, $column, $backend, $format = self::FORMAT_NONE , $parameters = null) {
1404
+	private static function formatResult($items, $column, $backend, $format = self::FORMAT_NONE, $parameters = null) {
1405 1405
 		if ($format === self::FORMAT_NONE) {
1406 1406
 			return $items;
1407 1407
 		} elseif ($format === self::FORMAT_STATUSES) {
@@ -1458,13 +1458,13 @@  discard block
 block discarded – undo
1458 1458
 		$try = 0;
1459 1459
 		$discoveryService = \OC::$server->query(\OCP\OCS\IDiscoveryService::class);
1460 1460
 		while ($result['success'] === false && $try < 2) {
1461
-			$federationEndpoints = $discoveryService->discover($protocol . $remoteDomain, 'FEDERATED_SHARING');
1461
+			$federationEndpoints = $discoveryService->discover($protocol.$remoteDomain, 'FEDERATED_SHARING');
1462 1462
 			$endpoint = isset($federationEndpoints['share']) ? $federationEndpoints['share'] : '/ocs/v2.php/cloud/shares';
1463 1463
 			$client = \OC::$server->getHTTPClientService()->newClient();
1464 1464
 
1465 1465
 			try {
1466 1466
 				$response = $client->post(
1467
-					$protocol . $remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT,
1467
+					$protocol.$remoteDomain.$endpoint.$urlSuffix.'?format='.self::RESPONSE_FORMAT,
1468 1468
 					[
1469 1469
 						'body' => $fields,
1470 1470
 						'connect_timeout' => 10,
@@ -1505,7 +1505,7 @@  discard block
 block discarded – undo
1505 1505
 	 * @return int
1506 1506
 	 */
1507 1507
 	public static function getExpireInterval() {
1508
-		return (int)\OC::$server->getConfig()->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1508
+		return (int) \OC::$server->getConfig()->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1509 1509
 	}
1510 1510
 
1511 1511
 	/**
Please login to merge, or discard this patch.
lib/private/Federation/CloudFederationShare.php 1 patch
Indentation   +302 added lines, -302 removed lines patch added patch discarded remove patch
@@ -27,331 +27,331 @@
 block discarded – undo
27 27
 use OCP\Share\IShare;
28 28
 
29 29
 class CloudFederationShare implements ICloudFederationShare {
30
-	private $share = [
31
-		'shareWith' => '',
32
-		'shareType' => '',
33
-		'name' => '',
34
-		'resourceType' => '',
35
-		'description' => '',
36
-		'providerId' => '',
37
-		'owner' => '',
38
-		'ownerDisplayName' => '',
39
-		'sharedBy' => '',
40
-		'sharedByDisplayName' => '',
41
-		'protocol' => []
42
-	];
30
+    private $share = [
31
+        'shareWith' => '',
32
+        'shareType' => '',
33
+        'name' => '',
34
+        'resourceType' => '',
35
+        'description' => '',
36
+        'providerId' => '',
37
+        'owner' => '',
38
+        'ownerDisplayName' => '',
39
+        'sharedBy' => '',
40
+        'sharedByDisplayName' => '',
41
+        'protocol' => []
42
+    ];
43 43
 
44
-	/**
45
-	 * get a CloudFederationShare Object to prepare a share you want to send
46
-	 *
47
-	 * @param string $shareWith
48
-	 * @param string $name resource name (e.g. document.odt)
49
-	 * @param string $description share description (optional)
50
-	 * @param string $providerId resource UID on the provider side
51
-	 * @param string $owner provider specific UID of the user who owns the resource
52
-	 * @param string $ownerDisplayName display name of the user who shared the item
53
-	 * @param string $sharedBy provider specific UID of the user who shared the resource
54
-	 * @param string $sharedByDisplayName display name of the user who shared the resource
55
-	 * @param string $shareType ('group' or 'user' share)
56
-	 * @param string $resourceType ('file', 'calendar',...)
57
-	 * @param string $sharedSecret
58
-	 */
59
-	public function __construct($shareWith = '',
60
-								$name = '',
61
-								$description = '',
62
-								$providerId = '',
63
-								$owner = '',
64
-								$ownerDisplayName = '',
65
-								$sharedBy = '',
66
-								$sharedByDisplayName = '',
67
-								$shareType = '',
68
-								$resourceType = '',
69
-								$sharedSecret = ''
70
-	) {
71
-		$this->setShareWith($shareWith);
72
-		$this->setResourceName($name);
73
-		$this->setDescription($description);
74
-		$this->setProviderId($providerId);
75
-		$this->setOwner($owner);
76
-		$this->setOwnerDisplayName($ownerDisplayName);
77
-		$this->setSharedBy($sharedBy);
78
-		$this->setSharedByDisplayName($sharedByDisplayName);
79
-		$this->setProtocol([
80
-			'name' => 'webdav',
81
-			'options' => [
82
-				'sharedSecret' => $sharedSecret,
83
-				'permissions' => '{http://open-cloud-mesh.org/ns}share-permissions'
84
-			]
85
-		]);
86
-		$this->setShareType($shareType);
87
-		$this->setResourceType($resourceType);
88
-	}
44
+    /**
45
+     * get a CloudFederationShare Object to prepare a share you want to send
46
+     *
47
+     * @param string $shareWith
48
+     * @param string $name resource name (e.g. document.odt)
49
+     * @param string $description share description (optional)
50
+     * @param string $providerId resource UID on the provider side
51
+     * @param string $owner provider specific UID of the user who owns the resource
52
+     * @param string $ownerDisplayName display name of the user who shared the item
53
+     * @param string $sharedBy provider specific UID of the user who shared the resource
54
+     * @param string $sharedByDisplayName display name of the user who shared the resource
55
+     * @param string $shareType ('group' or 'user' share)
56
+     * @param string $resourceType ('file', 'calendar',...)
57
+     * @param string $sharedSecret
58
+     */
59
+    public function __construct($shareWith = '',
60
+                                $name = '',
61
+                                $description = '',
62
+                                $providerId = '',
63
+                                $owner = '',
64
+                                $ownerDisplayName = '',
65
+                                $sharedBy = '',
66
+                                $sharedByDisplayName = '',
67
+                                $shareType = '',
68
+                                $resourceType = '',
69
+                                $sharedSecret = ''
70
+    ) {
71
+        $this->setShareWith($shareWith);
72
+        $this->setResourceName($name);
73
+        $this->setDescription($description);
74
+        $this->setProviderId($providerId);
75
+        $this->setOwner($owner);
76
+        $this->setOwnerDisplayName($ownerDisplayName);
77
+        $this->setSharedBy($sharedBy);
78
+        $this->setSharedByDisplayName($sharedByDisplayName);
79
+        $this->setProtocol([
80
+            'name' => 'webdav',
81
+            'options' => [
82
+                'sharedSecret' => $sharedSecret,
83
+                'permissions' => '{http://open-cloud-mesh.org/ns}share-permissions'
84
+            ]
85
+        ]);
86
+        $this->setShareType($shareType);
87
+        $this->setResourceType($resourceType);
88
+    }
89 89
 
90
-	/**
91
-	 * set uid of the recipient
92
-	 *
93
-	 * @param string $user
94
-	 *
95
-	 * @since 14.0.0
96
-	 */
97
-	public function setShareWith($user) {
98
-		$this->share['shareWith'] = $user;
99
-	}
90
+    /**
91
+     * set uid of the recipient
92
+     *
93
+     * @param string $user
94
+     *
95
+     * @since 14.0.0
96
+     */
97
+    public function setShareWith($user) {
98
+        $this->share['shareWith'] = $user;
99
+    }
100 100
 
101
-	/**
102
-	 * set resource name (e.g. document.odt)
103
-	 *
104
-	 * @param string $name
105
-	 *
106
-	 * @since 14.0.0
107
-	 */
108
-	public function setResourceName($name) {
109
-		$this->share['name'] = $name;
110
-	}
101
+    /**
102
+     * set resource name (e.g. document.odt)
103
+     *
104
+     * @param string $name
105
+     *
106
+     * @since 14.0.0
107
+     */
108
+    public function setResourceName($name) {
109
+        $this->share['name'] = $name;
110
+    }
111 111
 
112
-	/**
113
-	 * set resource type (e.g. file, calendar, contact,...)
114
-	 *
115
-	 * @param string $resourceType
116
-	 *
117
-	 * @since 14.0.0
118
-	 */
119
-	public function setResourceType($resourceType) {
120
-		$this->share['resourceType'] = $resourceType;
121
-	}
112
+    /**
113
+     * set resource type (e.g. file, calendar, contact,...)
114
+     *
115
+     * @param string $resourceType
116
+     *
117
+     * @since 14.0.0
118
+     */
119
+    public function setResourceType($resourceType) {
120
+        $this->share['resourceType'] = $resourceType;
121
+    }
122 122
 
123
-	/**
124
-	 * set resource description (optional)
125
-	 *
126
-	 * @param string $description
127
-	 *
128
-	 * @since 14.0.0
129
-	 */
130
-	public function setDescription($description) {
131
-		$this->share['description'] = $description;
132
-	}
123
+    /**
124
+     * set resource description (optional)
125
+     *
126
+     * @param string $description
127
+     *
128
+     * @since 14.0.0
129
+     */
130
+    public function setDescription($description) {
131
+        $this->share['description'] = $description;
132
+    }
133 133
 
134
-	/**
135
-	 * set provider ID (e.g. file ID)
136
-	 *
137
-	 * @param string $providerId
138
-	 *
139
-	 * @since 14.0.0
140
-	 */
141
-	public function setProviderId($providerId) {
142
-		$this->share['providerId'] = $providerId;
143
-	}
134
+    /**
135
+     * set provider ID (e.g. file ID)
136
+     *
137
+     * @param string $providerId
138
+     *
139
+     * @since 14.0.0
140
+     */
141
+    public function setProviderId($providerId) {
142
+        $this->share['providerId'] = $providerId;
143
+    }
144 144
 
145
-	/**
146
-	 * set owner UID
147
-	 *
148
-	 * @param string $owner
149
-	 *
150
-	 * @since 14.0.0
151
-	 */
152
-	public function setOwner($owner) {
153
-		$this->share['owner'] = $owner;
154
-	}
145
+    /**
146
+     * set owner UID
147
+     *
148
+     * @param string $owner
149
+     *
150
+     * @since 14.0.0
151
+     */
152
+    public function setOwner($owner) {
153
+        $this->share['owner'] = $owner;
154
+    }
155 155
 
156
-	/**
157
-	 * set owner display name
158
-	 *
159
-	 * @param string $ownerDisplayName
160
-	 *
161
-	 * @since 14.0.0
162
-	 */
163
-	public function setOwnerDisplayName($ownerDisplayName) {
164
-		$this->share['ownerDisplayName'] = $ownerDisplayName;
165
-	}
156
+    /**
157
+     * set owner display name
158
+     *
159
+     * @param string $ownerDisplayName
160
+     *
161
+     * @since 14.0.0
162
+     */
163
+    public function setOwnerDisplayName($ownerDisplayName) {
164
+        $this->share['ownerDisplayName'] = $ownerDisplayName;
165
+    }
166 166
 
167
-	/**
168
-	 * set UID of the user who sends the share
169
-	 *
170
-	 * @param string $sharedBy
171
-	 *
172
-	 * @since 14.0.0
173
-	 */
174
-	public function setSharedBy($sharedBy) {
175
-		$this->share['sharedBy'] = $sharedBy;
176
-	}
167
+    /**
168
+     * set UID of the user who sends the share
169
+     *
170
+     * @param string $sharedBy
171
+     *
172
+     * @since 14.0.0
173
+     */
174
+    public function setSharedBy($sharedBy) {
175
+        $this->share['sharedBy'] = $sharedBy;
176
+    }
177 177
 
178
-	/**
179
-	 * set display name of the user who sends the share
180
-	 *
181
-	 * @param $sharedByDisplayName
182
-	 *
183
-	 * @since 14.0.0
184
-	 */
185
-	public function setSharedByDisplayName($sharedByDisplayName) {
186
-		$this->share['sharedByDisplayName'] = $sharedByDisplayName;
187
-	}
178
+    /**
179
+     * set display name of the user who sends the share
180
+     *
181
+     * @param $sharedByDisplayName
182
+     *
183
+     * @since 14.0.0
184
+     */
185
+    public function setSharedByDisplayName($sharedByDisplayName) {
186
+        $this->share['sharedByDisplayName'] = $sharedByDisplayName;
187
+    }
188 188
 
189
-	/**
190
-	 * set protocol specification
191
-	 *
192
-	 * @param array $protocol
193
-	 *
194
-	 * @since 14.0.0
195
-	 */
196
-	public function setProtocol(array $protocol) {
197
-		$this->share['protocol'] = $protocol;
198
-	}
189
+    /**
190
+     * set protocol specification
191
+     *
192
+     * @param array $protocol
193
+     *
194
+     * @since 14.0.0
195
+     */
196
+    public function setProtocol(array $protocol) {
197
+        $this->share['protocol'] = $protocol;
198
+    }
199 199
 
200
-	/**
201
-	 * share type (group or user)
202
-	 *
203
-	 * @param string $shareType
204
-	 *
205
-	 * @since 14.0.0
206
-	 */
207
-	public function setShareType($shareType) {
208
-		if ($shareType === 'group' || $shareType === IShare::TYPE_REMOTE_GROUP) {
209
-			$this->share['shareType'] = 'group';
210
-		} else {
211
-			$this->share['shareType'] = 'user';
212
-		}
213
-	}
200
+    /**
201
+     * share type (group or user)
202
+     *
203
+     * @param string $shareType
204
+     *
205
+     * @since 14.0.0
206
+     */
207
+    public function setShareType($shareType) {
208
+        if ($shareType === 'group' || $shareType === IShare::TYPE_REMOTE_GROUP) {
209
+            $this->share['shareType'] = 'group';
210
+        } else {
211
+            $this->share['shareType'] = 'user';
212
+        }
213
+    }
214 214
 
215
-	/**
216
-	 * get the whole share, ready to send out
217
-	 *
218
-	 * @return array
219
-	 *
220
-	 * @since 14.0.0
221
-	 */
222
-	public function getShare() {
223
-		return $this->share;
224
-	}
215
+    /**
216
+     * get the whole share, ready to send out
217
+     *
218
+     * @return array
219
+     *
220
+     * @since 14.0.0
221
+     */
222
+    public function getShare() {
223
+        return $this->share;
224
+    }
225 225
 
226
-	/**
227
-	 * get uid of the recipient
228
-	 *
229
-	 * @return string
230
-	 *
231
-	 * @since 14.0.0
232
-	 */
233
-	public function getShareWith() {
234
-		return $this->share['shareWith'];
235
-	}
226
+    /**
227
+     * get uid of the recipient
228
+     *
229
+     * @return string
230
+     *
231
+     * @since 14.0.0
232
+     */
233
+    public function getShareWith() {
234
+        return $this->share['shareWith'];
235
+    }
236 236
 
237
-	/**
238
-	 * get resource name (e.g. file, calendar, contact,...)
239
-	 *
240
-	 * @return string
241
-	 *
242
-	 * @since 14.0.0
243
-	 */
244
-	public function getResourceName() {
245
-		return $this->share['name'];
246
-	}
237
+    /**
238
+     * get resource name (e.g. file, calendar, contact,...)
239
+     *
240
+     * @return string
241
+     *
242
+     * @since 14.0.0
243
+     */
244
+    public function getResourceName() {
245
+        return $this->share['name'];
246
+    }
247 247
 
248
-	/**
249
-	 * get resource type (e.g. file, calendar, contact,...)
250
-	 *
251
-	 * @return string
252
-	 *
253
-	 * @since 14.0.0
254
-	 */
255
-	public function getResourceType() {
256
-		return $this->share['resourceType'];
257
-	}
248
+    /**
249
+     * get resource type (e.g. file, calendar, contact,...)
250
+     *
251
+     * @return string
252
+     *
253
+     * @since 14.0.0
254
+     */
255
+    public function getResourceType() {
256
+        return $this->share['resourceType'];
257
+    }
258 258
 
259
-	/**
260
-	 * get resource description (optional)
261
-	 *
262
-	 * @return string
263
-	 *
264
-	 * @since 14.0.0
265
-	 */
266
-	public function getDescription() {
267
-		return $this->share['description'];
268
-	}
259
+    /**
260
+     * get resource description (optional)
261
+     *
262
+     * @return string
263
+     *
264
+     * @since 14.0.0
265
+     */
266
+    public function getDescription() {
267
+        return $this->share['description'];
268
+    }
269 269
 
270
-	/**
271
-	 * get provider ID (e.g. file ID)
272
-	 *
273
-	 * @return string
274
-	 *
275
-	 * @since 14.0.0
276
-	 */
277
-	public function getProviderId() {
278
-		return $this->share['providerId'];
279
-	}
270
+    /**
271
+     * get provider ID (e.g. file ID)
272
+     *
273
+     * @return string
274
+     *
275
+     * @since 14.0.0
276
+     */
277
+    public function getProviderId() {
278
+        return $this->share['providerId'];
279
+    }
280 280
 
281
-	/**
282
-	 * get owner UID
283
-	 *
284
-	 * @return string
285
-	 *
286
-	 * @since 14.0.0
287
-	 */
288
-	public function getOwner() {
289
-		return $this->share['owner'];
290
-	}
281
+    /**
282
+     * get owner UID
283
+     *
284
+     * @return string
285
+     *
286
+     * @since 14.0.0
287
+     */
288
+    public function getOwner() {
289
+        return $this->share['owner'];
290
+    }
291 291
 
292
-	/**
293
-	 * get owner display name
294
-	 *
295
-	 * @return string
296
-	 *
297
-	 * @since 14.0.0
298
-	 */
299
-	public function getOwnerDisplayName() {
300
-		return $this->share['ownerDisplayName'];
301
-	}
292
+    /**
293
+     * get owner display name
294
+     *
295
+     * @return string
296
+     *
297
+     * @since 14.0.0
298
+     */
299
+    public function getOwnerDisplayName() {
300
+        return $this->share['ownerDisplayName'];
301
+    }
302 302
 
303
-	/**
304
-	 * get UID of the user who sends the share
305
-	 *
306
-	 * @return string
307
-	 *
308
-	 * @since 14.0.0
309
-	 */
310
-	public function getSharedBy() {
311
-		return $this->share['sharedBy'];
312
-	}
303
+    /**
304
+     * get UID of the user who sends the share
305
+     *
306
+     * @return string
307
+     *
308
+     * @since 14.0.0
309
+     */
310
+    public function getSharedBy() {
311
+        return $this->share['sharedBy'];
312
+    }
313 313
 
314
-	/**
315
-	 * get display name of the user who sends the share
316
-	 *
317
-	 * @return string
318
-	 *
319
-	 * @since 14.0.0
320
-	 */
321
-	public function getSharedByDisplayName() {
322
-		return $this->share['sharedByDisplayName'];
323
-	}
314
+    /**
315
+     * get display name of the user who sends the share
316
+     *
317
+     * @return string
318
+     *
319
+     * @since 14.0.0
320
+     */
321
+    public function getSharedByDisplayName() {
322
+        return $this->share['sharedByDisplayName'];
323
+    }
324 324
 
325
-	/**
326
-	 * get share type (group or user)
327
-	 *
328
-	 * @return string
329
-	 *
330
-	 * @since 14.0.0
331
-	 */
332
-	public function getShareType() {
333
-		return $this->share['shareType'];
334
-	}
325
+    /**
326
+     * get share type (group or user)
327
+     *
328
+     * @return string
329
+     *
330
+     * @since 14.0.0
331
+     */
332
+    public function getShareType() {
333
+        return $this->share['shareType'];
334
+    }
335 335
 
336
-	/**
337
-	 * get share Secret
338
-	 *
339
-	 * @return string
340
-	 *
341
-	 * @since 14.0.0
342
-	 */
343
-	public function getShareSecret() {
344
-		return $this->share['protocol']['options']['sharedSecret'];
345
-	}
336
+    /**
337
+     * get share Secret
338
+     *
339
+     * @return string
340
+     *
341
+     * @since 14.0.0
342
+     */
343
+    public function getShareSecret() {
344
+        return $this->share['protocol']['options']['sharedSecret'];
345
+    }
346 346
 
347
-	/**
348
-	 * get protocol specification
349
-	 *
350
-	 * @return array
351
-	 *
352
-	 * @since 14.0.0
353
-	 */
354
-	public function getProtocol() {
355
-		return $this->share['protocol'];
356
-	}
347
+    /**
348
+     * get protocol specification
349
+     *
350
+     * @return array
351
+     *
352
+     * @since 14.0.0
353
+     */
354
+    public function getProtocol() {
355
+        return $this->share['protocol'];
356
+    }
357 357
 }
Please login to merge, or discard this patch.
lib/private/Share20/LegacyHooks.php 1 patch
Indentation   +140 added lines, -140 removed lines patch added patch discarded remove patch
@@ -34,144 +34,144 @@
 block discarded – undo
34 34
 
35 35
 class LegacyHooks {
36 36
 
37
-	/** @var EventDispatcherInterface */
38
-	private $eventDispatcher;
39
-
40
-	/**
41
-	 * LegacyHooks constructor.
42
-	 *
43
-	 * @param EventDispatcherInterface $eventDispatcher
44
-	 */
45
-	public function __construct(EventDispatcherInterface $eventDispatcher) {
46
-		$this->eventDispatcher = $eventDispatcher;
47
-
48
-		$this->eventDispatcher->addListener('OCP\Share::preUnshare', [$this, 'preUnshare']);
49
-		$this->eventDispatcher->addListener('OCP\Share::postUnshare', [$this, 'postUnshare']);
50
-		$this->eventDispatcher->addListener('OCP\Share::postUnshareFromSelf', [$this, 'postUnshareFromSelf']);
51
-		$this->eventDispatcher->addListener('OCP\Share::preShare', [$this, 'preShare']);
52
-		$this->eventDispatcher->addListener('OCP\Share::postShare', [$this, 'postShare']);
53
-	}
54
-
55
-	/**
56
-	 * @param GenericEvent $e
57
-	 */
58
-	public function preUnshare(GenericEvent $e) {
59
-		/** @var IShare $share */
60
-		$share = $e->getSubject();
61
-
62
-		$formatted = $this->formatHookParams($share);
63
-		\OC_Hook::emit(Share::class, 'pre_unshare', $formatted);
64
-	}
65
-
66
-	/**
67
-	 * @param GenericEvent $e
68
-	 */
69
-	public function postUnshare(GenericEvent $e) {
70
-		/** @var IShare $share */
71
-		$share = $e->getSubject();
72
-
73
-		$formatted = $this->formatHookParams($share);
74
-
75
-		/** @var IShare[] $deletedShares */
76
-		$deletedShares = $e->getArgument('deletedShares');
77
-
78
-		$formattedDeletedShares = array_map(function ($share) {
79
-			return $this->formatHookParams($share);
80
-		}, $deletedShares);
81
-
82
-		$formatted['deletedShares'] = $formattedDeletedShares;
83
-
84
-		\OC_Hook::emit(Share::class, 'post_unshare', $formatted);
85
-	}
86
-
87
-	/**
88
-	 * @param GenericEvent $e
89
-	 */
90
-	public function postUnshareFromSelf(GenericEvent $e) {
91
-		/** @var IShare $share */
92
-		$share = $e->getSubject();
93
-
94
-		$formatted = $this->formatHookParams($share);
95
-		$formatted['itemTarget'] = $formatted['fileTarget'];
96
-		$formatted['unsharedItems'] = [$formatted];
97
-
98
-		\OC_Hook::emit(Share::class, 'post_unshareFromSelf', $formatted);
99
-	}
100
-
101
-	private function formatHookParams(IShare $share) {
102
-		// Prepare hook
103
-		$shareType = $share->getShareType();
104
-		$sharedWith = '';
105
-		if ($shareType === IShare::TYPE_USER ||
106
-			$shareType === IShare::TYPE_GROUP ||
107
-			$shareType === IShare::TYPE_REMOTE) {
108
-			$sharedWith = $share->getSharedWith();
109
-		}
110
-
111
-		$hookParams = [
112
-			'id' => $share->getId(),
113
-			'itemType' => $share->getNodeType(),
114
-			'itemSource' => $share->getNodeId(),
115
-			'shareType' => $shareType,
116
-			'shareWith' => $sharedWith,
117
-			'itemparent' => method_exists($share, 'getParent') ? $share->getParent() : '',
118
-			'uidOwner' => $share->getSharedBy(),
119
-			'fileSource' => $share->getNodeId(),
120
-			'fileTarget' => $share->getTarget()
121
-		];
122
-		return $hookParams;
123
-	}
124
-
125
-	public function preShare(GenericEvent $e) {
126
-		/** @var IShare $share */
127
-		$share = $e->getSubject();
128
-
129
-		// Pre share hook
130
-		$run = true;
131
-		$error = '';
132
-		$preHookData = [
133
-			'itemType' => $share->getNode() instanceof File ? 'file' : 'folder',
134
-			'itemSource' => $share->getNode()->getId(),
135
-			'shareType' => $share->getShareType(),
136
-			'uidOwner' => $share->getSharedBy(),
137
-			'permissions' => $share->getPermissions(),
138
-			'fileSource' => $share->getNode()->getId(),
139
-			'expiration' => $share->getExpirationDate(),
140
-			'token' => $share->getToken(),
141
-			'itemTarget' => $share->getTarget(),
142
-			'shareWith' => $share->getSharedWith(),
143
-			'run' => &$run,
144
-			'error' => &$error,
145
-		];
146
-		\OC_Hook::emit(Share::class, 'pre_shared', $preHookData);
147
-
148
-		if ($run === false) {
149
-			$e->setArgument('error', $error);
150
-			$e->stopPropagation();
151
-		}
152
-
153
-		return $e;
154
-	}
155
-
156
-	public function postShare(GenericEvent $e) {
157
-		/** @var IShare $share */
158
-		$share = $e->getSubject();
159
-
160
-		$postHookData = [
161
-			'itemType' => $share->getNode() instanceof File ? 'file' : 'folder',
162
-			'itemSource' => $share->getNode()->getId(),
163
-			'shareType' => $share->getShareType(),
164
-			'uidOwner' => $share->getSharedBy(),
165
-			'permissions' => $share->getPermissions(),
166
-			'fileSource' => $share->getNode()->getId(),
167
-			'expiration' => $share->getExpirationDate(),
168
-			'token' => $share->getToken(),
169
-			'id' => $share->getId(),
170
-			'shareWith' => $share->getSharedWith(),
171
-			'itemTarget' => $share->getTarget(),
172
-			'fileTarget' => $share->getTarget(),
173
-		];
174
-
175
-		\OC_Hook::emit(Share::class, 'post_shared', $postHookData);
176
-	}
37
+    /** @var EventDispatcherInterface */
38
+    private $eventDispatcher;
39
+
40
+    /**
41
+     * LegacyHooks constructor.
42
+     *
43
+     * @param EventDispatcherInterface $eventDispatcher
44
+     */
45
+    public function __construct(EventDispatcherInterface $eventDispatcher) {
46
+        $this->eventDispatcher = $eventDispatcher;
47
+
48
+        $this->eventDispatcher->addListener('OCP\Share::preUnshare', [$this, 'preUnshare']);
49
+        $this->eventDispatcher->addListener('OCP\Share::postUnshare', [$this, 'postUnshare']);
50
+        $this->eventDispatcher->addListener('OCP\Share::postUnshareFromSelf', [$this, 'postUnshareFromSelf']);
51
+        $this->eventDispatcher->addListener('OCP\Share::preShare', [$this, 'preShare']);
52
+        $this->eventDispatcher->addListener('OCP\Share::postShare', [$this, 'postShare']);
53
+    }
54
+
55
+    /**
56
+     * @param GenericEvent $e
57
+     */
58
+    public function preUnshare(GenericEvent $e) {
59
+        /** @var IShare $share */
60
+        $share = $e->getSubject();
61
+
62
+        $formatted = $this->formatHookParams($share);
63
+        \OC_Hook::emit(Share::class, 'pre_unshare', $formatted);
64
+    }
65
+
66
+    /**
67
+     * @param GenericEvent $e
68
+     */
69
+    public function postUnshare(GenericEvent $e) {
70
+        /** @var IShare $share */
71
+        $share = $e->getSubject();
72
+
73
+        $formatted = $this->formatHookParams($share);
74
+
75
+        /** @var IShare[] $deletedShares */
76
+        $deletedShares = $e->getArgument('deletedShares');
77
+
78
+        $formattedDeletedShares = array_map(function ($share) {
79
+            return $this->formatHookParams($share);
80
+        }, $deletedShares);
81
+
82
+        $formatted['deletedShares'] = $formattedDeletedShares;
83
+
84
+        \OC_Hook::emit(Share::class, 'post_unshare', $formatted);
85
+    }
86
+
87
+    /**
88
+     * @param GenericEvent $e
89
+     */
90
+    public function postUnshareFromSelf(GenericEvent $e) {
91
+        /** @var IShare $share */
92
+        $share = $e->getSubject();
93
+
94
+        $formatted = $this->formatHookParams($share);
95
+        $formatted['itemTarget'] = $formatted['fileTarget'];
96
+        $formatted['unsharedItems'] = [$formatted];
97
+
98
+        \OC_Hook::emit(Share::class, 'post_unshareFromSelf', $formatted);
99
+    }
100
+
101
+    private function formatHookParams(IShare $share) {
102
+        // Prepare hook
103
+        $shareType = $share->getShareType();
104
+        $sharedWith = '';
105
+        if ($shareType === IShare::TYPE_USER ||
106
+            $shareType === IShare::TYPE_GROUP ||
107
+            $shareType === IShare::TYPE_REMOTE) {
108
+            $sharedWith = $share->getSharedWith();
109
+        }
110
+
111
+        $hookParams = [
112
+            'id' => $share->getId(),
113
+            'itemType' => $share->getNodeType(),
114
+            'itemSource' => $share->getNodeId(),
115
+            'shareType' => $shareType,
116
+            'shareWith' => $sharedWith,
117
+            'itemparent' => method_exists($share, 'getParent') ? $share->getParent() : '',
118
+            'uidOwner' => $share->getSharedBy(),
119
+            'fileSource' => $share->getNodeId(),
120
+            'fileTarget' => $share->getTarget()
121
+        ];
122
+        return $hookParams;
123
+    }
124
+
125
+    public function preShare(GenericEvent $e) {
126
+        /** @var IShare $share */
127
+        $share = $e->getSubject();
128
+
129
+        // Pre share hook
130
+        $run = true;
131
+        $error = '';
132
+        $preHookData = [
133
+            'itemType' => $share->getNode() instanceof File ? 'file' : 'folder',
134
+            'itemSource' => $share->getNode()->getId(),
135
+            'shareType' => $share->getShareType(),
136
+            'uidOwner' => $share->getSharedBy(),
137
+            'permissions' => $share->getPermissions(),
138
+            'fileSource' => $share->getNode()->getId(),
139
+            'expiration' => $share->getExpirationDate(),
140
+            'token' => $share->getToken(),
141
+            'itemTarget' => $share->getTarget(),
142
+            'shareWith' => $share->getSharedWith(),
143
+            'run' => &$run,
144
+            'error' => &$error,
145
+        ];
146
+        \OC_Hook::emit(Share::class, 'pre_shared', $preHookData);
147
+
148
+        if ($run === false) {
149
+            $e->setArgument('error', $error);
150
+            $e->stopPropagation();
151
+        }
152
+
153
+        return $e;
154
+    }
155
+
156
+    public function postShare(GenericEvent $e) {
157
+        /** @var IShare $share */
158
+        $share = $e->getSubject();
159
+
160
+        $postHookData = [
161
+            'itemType' => $share->getNode() instanceof File ? 'file' : 'folder',
162
+            'itemSource' => $share->getNode()->getId(),
163
+            'shareType' => $share->getShareType(),
164
+            'uidOwner' => $share->getSharedBy(),
165
+            'permissions' => $share->getPermissions(),
166
+            'fileSource' => $share->getNode()->getId(),
167
+            'expiration' => $share->getExpirationDate(),
168
+            'token' => $share->getToken(),
169
+            'id' => $share->getId(),
170
+            'shareWith' => $share->getSharedWith(),
171
+            'itemTarget' => $share->getTarget(),
172
+            'fileTarget' => $share->getTarget(),
173
+        ];
174
+
175
+        \OC_Hook::emit(Share::class, 'post_shared', $postHookData);
176
+    }
177 177
 }
Please login to merge, or discard this patch.
lib/private/Share20/ProviderFactory.php 1 patch
Indentation   +260 added lines, -260 removed lines patch added patch discarded remove patch
@@ -50,273 +50,273 @@
 block discarded – undo
50 50
  */
51 51
 class ProviderFactory implements IProviderFactory {
52 52
 
53
-	/** @var IServerContainer */
54
-	private $serverContainer;
55
-	/** @var DefaultShareProvider */
56
-	private $defaultProvider = null;
57
-	/** @var FederatedShareProvider */
58
-	private $federatedProvider = null;
59
-	/** @var  ShareByMailProvider */
60
-	private $shareByMailProvider;
61
-	/** @var  \OCA\Circles\ShareByCircleProvider */
62
-	private $shareByCircleProvider = null;
63
-	/** @var bool */
64
-	private $circlesAreNotAvailable = false;
65
-	/** @var \OCA\Talk\Share\RoomShareProvider */
66
-	private $roomShareProvider = null;
67
-
68
-	/**
69
-	 * IProviderFactory constructor.
70
-	 *
71
-	 * @param IServerContainer $serverContainer
72
-	 */
73
-	public function __construct(IServerContainer $serverContainer) {
74
-		$this->serverContainer = $serverContainer;
75
-	}
76
-
77
-	/**
78
-	 * Create the default share provider.
79
-	 *
80
-	 * @return DefaultShareProvider
81
-	 */
82
-	protected function defaultShareProvider() {
83
-		if ($this->defaultProvider === null) {
84
-			$this->defaultProvider = new DefaultShareProvider(
85
-				$this->serverContainer->getDatabaseConnection(),
86
-				$this->serverContainer->getUserManager(),
87
-				$this->serverContainer->getGroupManager(),
88
-				$this->serverContainer->getLazyRootFolder(),
89
-				$this->serverContainer->getMailer(),
90
-				$this->serverContainer->query(Defaults::class),
91
-				$this->serverContainer->getL10NFactory(),
92
-				$this->serverContainer->getURLGenerator(),
93
-				$this->serverContainer->getConfig()
94
-			);
95
-		}
96
-
97
-		return $this->defaultProvider;
98
-	}
99
-
100
-	/**
101
-	 * Create the federated share provider
102
-	 *
103
-	 * @return FederatedShareProvider
104
-	 */
105
-	protected function federatedShareProvider() {
106
-		if ($this->federatedProvider === null) {
107
-			/*
53
+    /** @var IServerContainer */
54
+    private $serverContainer;
55
+    /** @var DefaultShareProvider */
56
+    private $defaultProvider = null;
57
+    /** @var FederatedShareProvider */
58
+    private $federatedProvider = null;
59
+    /** @var  ShareByMailProvider */
60
+    private $shareByMailProvider;
61
+    /** @var  \OCA\Circles\ShareByCircleProvider */
62
+    private $shareByCircleProvider = null;
63
+    /** @var bool */
64
+    private $circlesAreNotAvailable = false;
65
+    /** @var \OCA\Talk\Share\RoomShareProvider */
66
+    private $roomShareProvider = null;
67
+
68
+    /**
69
+     * IProviderFactory constructor.
70
+     *
71
+     * @param IServerContainer $serverContainer
72
+     */
73
+    public function __construct(IServerContainer $serverContainer) {
74
+        $this->serverContainer = $serverContainer;
75
+    }
76
+
77
+    /**
78
+     * Create the default share provider.
79
+     *
80
+     * @return DefaultShareProvider
81
+     */
82
+    protected function defaultShareProvider() {
83
+        if ($this->defaultProvider === null) {
84
+            $this->defaultProvider = new DefaultShareProvider(
85
+                $this->serverContainer->getDatabaseConnection(),
86
+                $this->serverContainer->getUserManager(),
87
+                $this->serverContainer->getGroupManager(),
88
+                $this->serverContainer->getLazyRootFolder(),
89
+                $this->serverContainer->getMailer(),
90
+                $this->serverContainer->query(Defaults::class),
91
+                $this->serverContainer->getL10NFactory(),
92
+                $this->serverContainer->getURLGenerator(),
93
+                $this->serverContainer->getConfig()
94
+            );
95
+        }
96
+
97
+        return $this->defaultProvider;
98
+    }
99
+
100
+    /**
101
+     * Create the federated share provider
102
+     *
103
+     * @return FederatedShareProvider
104
+     */
105
+    protected function federatedShareProvider() {
106
+        if ($this->federatedProvider === null) {
107
+            /*
108 108
 			 * Check if the app is enabled
109 109
 			 */
110
-			$appManager = $this->serverContainer->getAppManager();
111
-			if (!$appManager->isEnabledForUser('federatedfilesharing')) {
112
-				return null;
113
-			}
110
+            $appManager = $this->serverContainer->getAppManager();
111
+            if (!$appManager->isEnabledForUser('federatedfilesharing')) {
112
+                return null;
113
+            }
114 114
 
115
-			/*
115
+            /*
116 116
 			 * TODO: add factory to federated sharing app
117 117
 			 */
118
-			$l = $this->serverContainer->getL10N('federatedfilesharing');
119
-			$addressHandler = new AddressHandler(
120
-				$this->serverContainer->getURLGenerator(),
121
-				$l,
122
-				$this->serverContainer->getCloudIdManager()
123
-			);
124
-			$notifications = new Notifications(
125
-				$addressHandler,
126
-				$this->serverContainer->getHTTPClientService(),
127
-				$this->serverContainer->query(\OCP\OCS\IDiscoveryService::class),
128
-				$this->serverContainer->getJobList(),
129
-				\OC::$server->getCloudFederationProviderManager(),
130
-				\OC::$server->getCloudFederationFactory()
131
-			);
132
-			$tokenHandler = new TokenHandler(
133
-				$this->serverContainer->getSecureRandom()
134
-			);
135
-
136
-			$this->federatedProvider = new FederatedShareProvider(
137
-				$this->serverContainer->getDatabaseConnection(),
138
-				$addressHandler,
139
-				$notifications,
140
-				$tokenHandler,
141
-				$l,
142
-				$this->serverContainer->getLogger(),
143
-				$this->serverContainer->getLazyRootFolder(),
144
-				$this->serverContainer->getConfig(),
145
-				$this->serverContainer->getUserManager(),
146
-				$this->serverContainer->getCloudIdManager(),
147
-				$this->serverContainer->getGlobalScaleConfig(),
148
-				$this->serverContainer->getCloudFederationProviderManager()
149
-			);
150
-		}
151
-
152
-		return $this->federatedProvider;
153
-	}
154
-
155
-	/**
156
-	 * Create the federated share provider
157
-	 *
158
-	 * @return ShareByMailProvider
159
-	 */
160
-	protected function getShareByMailProvider() {
161
-		if ($this->shareByMailProvider === null) {
162
-			/*
118
+            $l = $this->serverContainer->getL10N('federatedfilesharing');
119
+            $addressHandler = new AddressHandler(
120
+                $this->serverContainer->getURLGenerator(),
121
+                $l,
122
+                $this->serverContainer->getCloudIdManager()
123
+            );
124
+            $notifications = new Notifications(
125
+                $addressHandler,
126
+                $this->serverContainer->getHTTPClientService(),
127
+                $this->serverContainer->query(\OCP\OCS\IDiscoveryService::class),
128
+                $this->serverContainer->getJobList(),
129
+                \OC::$server->getCloudFederationProviderManager(),
130
+                \OC::$server->getCloudFederationFactory()
131
+            );
132
+            $tokenHandler = new TokenHandler(
133
+                $this->serverContainer->getSecureRandom()
134
+            );
135
+
136
+            $this->federatedProvider = new FederatedShareProvider(
137
+                $this->serverContainer->getDatabaseConnection(),
138
+                $addressHandler,
139
+                $notifications,
140
+                $tokenHandler,
141
+                $l,
142
+                $this->serverContainer->getLogger(),
143
+                $this->serverContainer->getLazyRootFolder(),
144
+                $this->serverContainer->getConfig(),
145
+                $this->serverContainer->getUserManager(),
146
+                $this->serverContainer->getCloudIdManager(),
147
+                $this->serverContainer->getGlobalScaleConfig(),
148
+                $this->serverContainer->getCloudFederationProviderManager()
149
+            );
150
+        }
151
+
152
+        return $this->federatedProvider;
153
+    }
154
+
155
+    /**
156
+     * Create the federated share provider
157
+     *
158
+     * @return ShareByMailProvider
159
+     */
160
+    protected function getShareByMailProvider() {
161
+        if ($this->shareByMailProvider === null) {
162
+            /*
163 163
 			 * Check if the app is enabled
164 164
 			 */
165
-			$appManager = $this->serverContainer->getAppManager();
166
-			if (!$appManager->isEnabledForUser('sharebymail')) {
167
-				return null;
168
-			}
169
-
170
-			$settingsManager = new SettingsManager($this->serverContainer->getConfig());
171
-
172
-			$this->shareByMailProvider = new ShareByMailProvider(
173
-				$this->serverContainer->getDatabaseConnection(),
174
-				$this->serverContainer->getSecureRandom(),
175
-				$this->serverContainer->getUserManager(),
176
-				$this->serverContainer->getLazyRootFolder(),
177
-				$this->serverContainer->getL10N('sharebymail'),
178
-				$this->serverContainer->getLogger(),
179
-				$this->serverContainer->getMailer(),
180
-				$this->serverContainer->getURLGenerator(),
181
-				$this->serverContainer->getActivityManager(),
182
-				$settingsManager,
183
-				$this->serverContainer->query(Defaults::class),
184
-				$this->serverContainer->getHasher(),
185
-				$this->serverContainer->query(CapabilitiesManager::class)
186
-			);
187
-		}
188
-
189
-		return $this->shareByMailProvider;
190
-	}
191
-
192
-
193
-	/**
194
-	 * Create the circle share provider
195
-	 *
196
-	 * @return FederatedShareProvider
197
-	 *
198
-	 * @suppress PhanUndeclaredClassMethod
199
-	 */
200
-	protected function getShareByCircleProvider() {
201
-		if ($this->circlesAreNotAvailable) {
202
-			return null;
203
-		}
204
-
205
-		if (!$this->serverContainer->getAppManager()->isEnabledForUser('circles') ||
206
-			!class_exists('\OCA\Circles\ShareByCircleProvider')
207
-		) {
208
-			$this->circlesAreNotAvailable = true;
209
-			return null;
210
-		}
211
-
212
-		if ($this->shareByCircleProvider === null) {
213
-			$this->shareByCircleProvider = new \OCA\Circles\ShareByCircleProvider(
214
-				$this->serverContainer->getDatabaseConnection(),
215
-				$this->serverContainer->getSecureRandom(),
216
-				$this->serverContainer->getUserManager(),
217
-				$this->serverContainer->getLazyRootFolder(),
218
-				$this->serverContainer->getL10N('circles'),
219
-				$this->serverContainer->getLogger(),
220
-				$this->serverContainer->getURLGenerator()
221
-			);
222
-		}
223
-
224
-		return $this->shareByCircleProvider;
225
-	}
226
-
227
-	/**
228
-	 * Create the room share provider
229
-	 *
230
-	 * @return RoomShareProvider
231
-	 */
232
-	protected function getRoomShareProvider() {
233
-		if ($this->roomShareProvider === null) {
234
-			/*
165
+            $appManager = $this->serverContainer->getAppManager();
166
+            if (!$appManager->isEnabledForUser('sharebymail')) {
167
+                return null;
168
+            }
169
+
170
+            $settingsManager = new SettingsManager($this->serverContainer->getConfig());
171
+
172
+            $this->shareByMailProvider = new ShareByMailProvider(
173
+                $this->serverContainer->getDatabaseConnection(),
174
+                $this->serverContainer->getSecureRandom(),
175
+                $this->serverContainer->getUserManager(),
176
+                $this->serverContainer->getLazyRootFolder(),
177
+                $this->serverContainer->getL10N('sharebymail'),
178
+                $this->serverContainer->getLogger(),
179
+                $this->serverContainer->getMailer(),
180
+                $this->serverContainer->getURLGenerator(),
181
+                $this->serverContainer->getActivityManager(),
182
+                $settingsManager,
183
+                $this->serverContainer->query(Defaults::class),
184
+                $this->serverContainer->getHasher(),
185
+                $this->serverContainer->query(CapabilitiesManager::class)
186
+            );
187
+        }
188
+
189
+        return $this->shareByMailProvider;
190
+    }
191
+
192
+
193
+    /**
194
+     * Create the circle share provider
195
+     *
196
+     * @return FederatedShareProvider
197
+     *
198
+     * @suppress PhanUndeclaredClassMethod
199
+     */
200
+    protected function getShareByCircleProvider() {
201
+        if ($this->circlesAreNotAvailable) {
202
+            return null;
203
+        }
204
+
205
+        if (!$this->serverContainer->getAppManager()->isEnabledForUser('circles') ||
206
+            !class_exists('\OCA\Circles\ShareByCircleProvider')
207
+        ) {
208
+            $this->circlesAreNotAvailable = true;
209
+            return null;
210
+        }
211
+
212
+        if ($this->shareByCircleProvider === null) {
213
+            $this->shareByCircleProvider = new \OCA\Circles\ShareByCircleProvider(
214
+                $this->serverContainer->getDatabaseConnection(),
215
+                $this->serverContainer->getSecureRandom(),
216
+                $this->serverContainer->getUserManager(),
217
+                $this->serverContainer->getLazyRootFolder(),
218
+                $this->serverContainer->getL10N('circles'),
219
+                $this->serverContainer->getLogger(),
220
+                $this->serverContainer->getURLGenerator()
221
+            );
222
+        }
223
+
224
+        return $this->shareByCircleProvider;
225
+    }
226
+
227
+    /**
228
+     * Create the room share provider
229
+     *
230
+     * @return RoomShareProvider
231
+     */
232
+    protected function getRoomShareProvider() {
233
+        if ($this->roomShareProvider === null) {
234
+            /*
235 235
 			 * Check if the app is enabled
236 236
 			 */
237
-			$appManager = $this->serverContainer->getAppManager();
238
-			if (!$appManager->isEnabledForUser('spreed')) {
239
-				return null;
240
-			}
241
-
242
-			try {
243
-				$this->roomShareProvider = $this->serverContainer->query('\OCA\Talk\Share\RoomShareProvider');
244
-			} catch (\OCP\AppFramework\QueryException $e) {
245
-				return null;
246
-			}
247
-		}
248
-
249
-		return $this->roomShareProvider;
250
-	}
251
-
252
-	/**
253
-	 * @inheritdoc
254
-	 */
255
-	public function getProvider($id) {
256
-		$provider = null;
257
-		if ($id === 'ocinternal') {
258
-			$provider = $this->defaultShareProvider();
259
-		} elseif ($id === 'ocFederatedSharing') {
260
-			$provider = $this->federatedShareProvider();
261
-		} elseif ($id === 'ocMailShare') {
262
-			$provider = $this->getShareByMailProvider();
263
-		} elseif ($id === 'ocCircleShare') {
264
-			$provider = $this->getShareByCircleProvider();
265
-		} elseif ($id === 'ocRoomShare') {
266
-			$provider = $this->getRoomShareProvider();
267
-		}
268
-
269
-		if ($provider === null) {
270
-			throw new ProviderException('No provider with id .' . $id . ' found.');
271
-		}
272
-
273
-		return $provider;
274
-	}
275
-
276
-	/**
277
-	 * @inheritdoc
278
-	 */
279
-	public function getProviderForType($shareType) {
280
-		$provider = null;
281
-
282
-		if ($shareType === IShare::TYPE_USER ||
283
-			$shareType === IShare::TYPE_GROUP ||
284
-			$shareType === IShare::TYPE_LINK
285
-		) {
286
-			$provider = $this->defaultShareProvider();
287
-		} elseif ($shareType === IShare::TYPE_REMOTE || $shareType === IShare::TYPE_REMOTE_GROUP) {
288
-			$provider = $this->federatedShareProvider();
289
-		} elseif ($shareType === IShare::TYPE_EMAIL) {
290
-			$provider = $this->getShareByMailProvider();
291
-		} elseif ($shareType === IShare::TYPE_CIRCLE) {
292
-			$provider = $this->getShareByCircleProvider();
293
-		} elseif ($shareType === IShare::TYPE_ROOM) {
294
-			$provider = $this->getRoomShareProvider();
295
-		}
296
-
297
-
298
-		if ($provider === null) {
299
-			throw new ProviderException('No share provider for share type ' . $shareType);
300
-		}
301
-
302
-		return $provider;
303
-	}
304
-
305
-	public function getAllProviders() {
306
-		$shares = [$this->defaultShareProvider(), $this->federatedShareProvider()];
307
-		$shareByMail = $this->getShareByMailProvider();
308
-		if ($shareByMail !== null) {
309
-			$shares[] = $shareByMail;
310
-		}
311
-		$shareByCircle = $this->getShareByCircleProvider();
312
-		if ($shareByCircle !== null) {
313
-			$shares[] = $shareByCircle;
314
-		}
315
-		$roomShare = $this->getRoomShareProvider();
316
-		if ($roomShare !== null) {
317
-			$shares[] = $roomShare;
318
-		}
319
-
320
-		return $shares;
321
-	}
237
+            $appManager = $this->serverContainer->getAppManager();
238
+            if (!$appManager->isEnabledForUser('spreed')) {
239
+                return null;
240
+            }
241
+
242
+            try {
243
+                $this->roomShareProvider = $this->serverContainer->query('\OCA\Talk\Share\RoomShareProvider');
244
+            } catch (\OCP\AppFramework\QueryException $e) {
245
+                return null;
246
+            }
247
+        }
248
+
249
+        return $this->roomShareProvider;
250
+    }
251
+
252
+    /**
253
+     * @inheritdoc
254
+     */
255
+    public function getProvider($id) {
256
+        $provider = null;
257
+        if ($id === 'ocinternal') {
258
+            $provider = $this->defaultShareProvider();
259
+        } elseif ($id === 'ocFederatedSharing') {
260
+            $provider = $this->federatedShareProvider();
261
+        } elseif ($id === 'ocMailShare') {
262
+            $provider = $this->getShareByMailProvider();
263
+        } elseif ($id === 'ocCircleShare') {
264
+            $provider = $this->getShareByCircleProvider();
265
+        } elseif ($id === 'ocRoomShare') {
266
+            $provider = $this->getRoomShareProvider();
267
+        }
268
+
269
+        if ($provider === null) {
270
+            throw new ProviderException('No provider with id .' . $id . ' found.');
271
+        }
272
+
273
+        return $provider;
274
+    }
275
+
276
+    /**
277
+     * @inheritdoc
278
+     */
279
+    public function getProviderForType($shareType) {
280
+        $provider = null;
281
+
282
+        if ($shareType === IShare::TYPE_USER ||
283
+            $shareType === IShare::TYPE_GROUP ||
284
+            $shareType === IShare::TYPE_LINK
285
+        ) {
286
+            $provider = $this->defaultShareProvider();
287
+        } elseif ($shareType === IShare::TYPE_REMOTE || $shareType === IShare::TYPE_REMOTE_GROUP) {
288
+            $provider = $this->federatedShareProvider();
289
+        } elseif ($shareType === IShare::TYPE_EMAIL) {
290
+            $provider = $this->getShareByMailProvider();
291
+        } elseif ($shareType === IShare::TYPE_CIRCLE) {
292
+            $provider = $this->getShareByCircleProvider();
293
+        } elseif ($shareType === IShare::TYPE_ROOM) {
294
+            $provider = $this->getRoomShareProvider();
295
+        }
296
+
297
+
298
+        if ($provider === null) {
299
+            throw new ProviderException('No share provider for share type ' . $shareType);
300
+        }
301
+
302
+        return $provider;
303
+    }
304
+
305
+    public function getAllProviders() {
306
+        $shares = [$this->defaultShareProvider(), $this->federatedShareProvider()];
307
+        $shareByMail = $this->getShareByMailProvider();
308
+        if ($shareByMail !== null) {
309
+            $shares[] = $shareByMail;
310
+        }
311
+        $shareByCircle = $this->getShareByCircleProvider();
312
+        if ($shareByCircle !== null) {
313
+            $shares[] = $shareByCircle;
314
+        }
315
+        $roomShare = $this->getRoomShareProvider();
316
+        if ($roomShare !== null) {
317
+            $shares[] = $roomShare;
318
+        }
319
+
320
+        return $shares;
321
+    }
322 322
 }
Please login to merge, or discard this patch.
lib/private/Share20/Manager.php 2 patches
Indentation   +1780 added lines, -1780 removed lines patch added patch discarded remove patch
@@ -76,1807 +76,1807 @@
 block discarded – undo
76 76
  */
77 77
 class Manager implements IManager {
78 78
 
79
-	/** @var IProviderFactory */
80
-	private $factory;
81
-	/** @var ILogger */
82
-	private $logger;
83
-	/** @var IConfig */
84
-	private $config;
85
-	/** @var ISecureRandom */
86
-	private $secureRandom;
87
-	/** @var IHasher */
88
-	private $hasher;
89
-	/** @var IMountManager */
90
-	private $mountManager;
91
-	/** @var IGroupManager */
92
-	private $groupManager;
93
-	/** @var IL10N */
94
-	private $l;
95
-	/** @var IFactory */
96
-	private $l10nFactory;
97
-	/** @var IUserManager */
98
-	private $userManager;
99
-	/** @var IRootFolder */
100
-	private $rootFolder;
101
-	/** @var CappedMemoryCache */
102
-	private $sharingDisabledForUsersCache;
103
-	/** @var EventDispatcherInterface */
104
-	private $legacyDispatcher;
105
-	/** @var LegacyHooks */
106
-	private $legacyHooks;
107
-	/** @var IMailer */
108
-	private $mailer;
109
-	/** @var IURLGenerator */
110
-	private $urlGenerator;
111
-	/** @var \OC_Defaults */
112
-	private $defaults;
113
-	/** @var IEventDispatcher */
114
-	private $dispatcher;
115
-
116
-
117
-	/**
118
-	 * Manager constructor.
119
-	 *
120
-	 * @param ILogger $logger
121
-	 * @param IConfig $config
122
-	 * @param ISecureRandom $secureRandom
123
-	 * @param IHasher $hasher
124
-	 * @param IMountManager $mountManager
125
-	 * @param IGroupManager $groupManager
126
-	 * @param IL10N $l
127
-	 * @param IFactory $l10nFactory
128
-	 * @param IProviderFactory $factory
129
-	 * @param IUserManager $userManager
130
-	 * @param IRootFolder $rootFolder
131
-	 * @param EventDispatcherInterface $eventDispatcher
132
-	 * @param IMailer $mailer
133
-	 * @param IURLGenerator $urlGenerator
134
-	 * @param \OC_Defaults $defaults
135
-	 */
136
-	public function __construct(
137
-			ILogger $logger,
138
-			IConfig $config,
139
-			ISecureRandom $secureRandom,
140
-			IHasher $hasher,
141
-			IMountManager $mountManager,
142
-			IGroupManager $groupManager,
143
-			IL10N $l,
144
-			IFactory $l10nFactory,
145
-			IProviderFactory $factory,
146
-			IUserManager $userManager,
147
-			IRootFolder $rootFolder,
148
-			EventDispatcherInterface $legacyDispatcher,
149
-			IMailer $mailer,
150
-			IURLGenerator $urlGenerator,
151
-			\OC_Defaults $defaults,
152
-			IEventDispatcher $dispatcher
153
-	) {
154
-		$this->logger = $logger;
155
-		$this->config = $config;
156
-		$this->secureRandom = $secureRandom;
157
-		$this->hasher = $hasher;
158
-		$this->mountManager = $mountManager;
159
-		$this->groupManager = $groupManager;
160
-		$this->l = $l;
161
-		$this->l10nFactory = $l10nFactory;
162
-		$this->factory = $factory;
163
-		$this->userManager = $userManager;
164
-		$this->rootFolder = $rootFolder;
165
-		$this->legacyDispatcher = $legacyDispatcher;
166
-		$this->sharingDisabledForUsersCache = new CappedMemoryCache();
167
-		$this->legacyHooks = new LegacyHooks($this->legacyDispatcher);
168
-		$this->mailer = $mailer;
169
-		$this->urlGenerator = $urlGenerator;
170
-		$this->defaults = $defaults;
171
-		$this->dispatcher = $dispatcher;
172
-	}
173
-
174
-	/**
175
-	 * Convert from a full share id to a tuple (providerId, shareId)
176
-	 *
177
-	 * @param string $id
178
-	 * @return string[]
179
-	 */
180
-	private function splitFullId($id) {
181
-		return explode(':', $id, 2);
182
-	}
183
-
184
-	/**
185
-	 * Verify if a password meets all requirements
186
-	 *
187
-	 * @param string $password
188
-	 * @throws \Exception
189
-	 */
190
-	protected function verifyPassword($password) {
191
-		if ($password === null) {
192
-			// No password is set, check if this is allowed.
193
-			if ($this->shareApiLinkEnforcePassword()) {
194
-				throw new \InvalidArgumentException('Passwords are enforced for link shares');
195
-			}
196
-
197
-			return;
198
-		}
199
-
200
-		// Let others verify the password
201
-		try {
202
-			$this->legacyDispatcher->dispatch(new ValidatePasswordPolicyEvent($password));
203
-		} catch (HintException $e) {
204
-			throw new \Exception($e->getHint());
205
-		}
206
-	}
207
-
208
-	/**
209
-	 * Check for generic requirements before creating a share
210
-	 *
211
-	 * @param IShare $share
212
-	 * @throws \InvalidArgumentException
213
-	 * @throws GenericShareException
214
-	 *
215
-	 * @suppress PhanUndeclaredClassMethod
216
-	 */
217
-	protected function generalCreateChecks(IShare $share) {
218
-		if ($share->getShareType() === IShare::TYPE_USER) {
219
-			// We expect a valid user as sharedWith for user shares
220
-			if (!$this->userManager->userExists($share->getSharedWith())) {
221
-				throw new \InvalidArgumentException('SharedWith is not a valid user');
222
-			}
223
-		} elseif ($share->getShareType() === IShare::TYPE_GROUP) {
224
-			// We expect a valid group as sharedWith for group shares
225
-			if (!$this->groupManager->groupExists($share->getSharedWith())) {
226
-				throw new \InvalidArgumentException('SharedWith is not a valid group');
227
-			}
228
-		} elseif ($share->getShareType() === IShare::TYPE_LINK) {
229
-			if ($share->getSharedWith() !== null) {
230
-				throw new \InvalidArgumentException('SharedWith should be empty');
231
-			}
232
-		} elseif ($share->getShareType() === IShare::TYPE_REMOTE) {
233
-			if ($share->getSharedWith() === null) {
234
-				throw new \InvalidArgumentException('SharedWith should not be empty');
235
-			}
236
-		} elseif ($share->getShareType() === IShare::TYPE_REMOTE_GROUP) {
237
-			if ($share->getSharedWith() === null) {
238
-				throw new \InvalidArgumentException('SharedWith should not be empty');
239
-			}
240
-		} elseif ($share->getShareType() === IShare::TYPE_EMAIL) {
241
-			if ($share->getSharedWith() === null) {
242
-				throw new \InvalidArgumentException('SharedWith should not be empty');
243
-			}
244
-		} elseif ($share->getShareType() === IShare::TYPE_CIRCLE) {
245
-			$circle = \OCA\Circles\Api\v1\Circles::detailsCircle($share->getSharedWith());
246
-			if ($circle === null) {
247
-				throw new \InvalidArgumentException('SharedWith is not a valid circle');
248
-			}
249
-		} elseif ($share->getShareType() === IShare::TYPE_ROOM) {
250
-		} else {
251
-			// We can't handle other types yet
252
-			throw new \InvalidArgumentException('unknown share type');
253
-		}
254
-
255
-		// Verify the initiator of the share is set
256
-		if ($share->getSharedBy() === null) {
257
-			throw new \InvalidArgumentException('SharedBy should be set');
258
-		}
259
-
260
-		// Cannot share with yourself
261
-		if ($share->getShareType() === IShare::TYPE_USER &&
262
-			$share->getSharedWith() === $share->getSharedBy()) {
263
-			throw new \InvalidArgumentException('Can’t share with yourself');
264
-		}
265
-
266
-		// The path should be set
267
-		if ($share->getNode() === null) {
268
-			throw new \InvalidArgumentException('Path should be set');
269
-		}
270
-
271
-		// And it should be a file or a folder
272
-		if (!($share->getNode() instanceof \OCP\Files\File) &&
273
-				!($share->getNode() instanceof \OCP\Files\Folder)) {
274
-			throw new \InvalidArgumentException('Path should be either a file or a folder');
275
-		}
276
-
277
-		// And you can't share your rootfolder
278
-		if ($this->userManager->userExists($share->getSharedBy())) {
279
-			$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
280
-		} else {
281
-			$userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
282
-		}
283
-		if ($userFolder->getId() === $share->getNode()->getId()) {
284
-			throw new \InvalidArgumentException('You can’t share your root folder');
285
-		}
286
-
287
-		// Check if we actually have share permissions
288
-		if (!$share->getNode()->isShareable()) {
289
-			$path = $userFolder->getRelativePath($share->getNode()->getPath());
290
-			$message_t = $this->l->t('You are not allowed to share %s', [$path]);
291
-			throw new GenericShareException($message_t, $message_t, 404);
292
-		}
293
-
294
-		// Permissions should be set
295
-		if ($share->getPermissions() === null) {
296
-			throw new \InvalidArgumentException('A share requires permissions');
297
-		}
298
-
299
-		$isFederatedShare = $share->getNode()->getStorage()->instanceOfStorage('\OCA\Files_Sharing\External\Storage');
300
-		$permissions = 0;
301
-		$mount = $share->getNode()->getMountPoint();
302
-		if (!$isFederatedShare && $share->getNode()->getOwner() && $share->getNode()->getOwner()->getUID() !== $share->getSharedBy()) {
303
-			// When it's a reshare use the parent share permissions as maximum
304
-			$userMountPointId = $mount->getStorageRootId();
305
-			$userMountPoints = $userFolder->getById($userMountPointId);
306
-			$userMountPoint = array_shift($userMountPoints);
307
-
308
-			/* Check if this is an incoming share */
309
-			$incomingShares = $this->getSharedWith($share->getSharedBy(), IShare::TYPE_USER, $userMountPoint, -1, 0);
310
-			$incomingShares = array_merge($incomingShares, $this->getSharedWith($share->getSharedBy(), IShare::TYPE_GROUP, $userMountPoint, -1, 0));
311
-			$incomingShares = array_merge($incomingShares, $this->getSharedWith($share->getSharedBy(), IShare::TYPE_CIRCLE, $userMountPoint, -1, 0));
312
-			$incomingShares = array_merge($incomingShares, $this->getSharedWith($share->getSharedBy(), IShare::TYPE_ROOM, $userMountPoint, -1, 0));
313
-
314
-			/** @var IShare[] $incomingShares */
315
-			if (!empty($incomingShares)) {
316
-				foreach ($incomingShares as $incomingShare) {
317
-					$permissions |= $incomingShare->getPermissions();
318
-				}
319
-			}
320
-		} else {
321
-			/*
79
+    /** @var IProviderFactory */
80
+    private $factory;
81
+    /** @var ILogger */
82
+    private $logger;
83
+    /** @var IConfig */
84
+    private $config;
85
+    /** @var ISecureRandom */
86
+    private $secureRandom;
87
+    /** @var IHasher */
88
+    private $hasher;
89
+    /** @var IMountManager */
90
+    private $mountManager;
91
+    /** @var IGroupManager */
92
+    private $groupManager;
93
+    /** @var IL10N */
94
+    private $l;
95
+    /** @var IFactory */
96
+    private $l10nFactory;
97
+    /** @var IUserManager */
98
+    private $userManager;
99
+    /** @var IRootFolder */
100
+    private $rootFolder;
101
+    /** @var CappedMemoryCache */
102
+    private $sharingDisabledForUsersCache;
103
+    /** @var EventDispatcherInterface */
104
+    private $legacyDispatcher;
105
+    /** @var LegacyHooks */
106
+    private $legacyHooks;
107
+    /** @var IMailer */
108
+    private $mailer;
109
+    /** @var IURLGenerator */
110
+    private $urlGenerator;
111
+    /** @var \OC_Defaults */
112
+    private $defaults;
113
+    /** @var IEventDispatcher */
114
+    private $dispatcher;
115
+
116
+
117
+    /**
118
+     * Manager constructor.
119
+     *
120
+     * @param ILogger $logger
121
+     * @param IConfig $config
122
+     * @param ISecureRandom $secureRandom
123
+     * @param IHasher $hasher
124
+     * @param IMountManager $mountManager
125
+     * @param IGroupManager $groupManager
126
+     * @param IL10N $l
127
+     * @param IFactory $l10nFactory
128
+     * @param IProviderFactory $factory
129
+     * @param IUserManager $userManager
130
+     * @param IRootFolder $rootFolder
131
+     * @param EventDispatcherInterface $eventDispatcher
132
+     * @param IMailer $mailer
133
+     * @param IURLGenerator $urlGenerator
134
+     * @param \OC_Defaults $defaults
135
+     */
136
+    public function __construct(
137
+            ILogger $logger,
138
+            IConfig $config,
139
+            ISecureRandom $secureRandom,
140
+            IHasher $hasher,
141
+            IMountManager $mountManager,
142
+            IGroupManager $groupManager,
143
+            IL10N $l,
144
+            IFactory $l10nFactory,
145
+            IProviderFactory $factory,
146
+            IUserManager $userManager,
147
+            IRootFolder $rootFolder,
148
+            EventDispatcherInterface $legacyDispatcher,
149
+            IMailer $mailer,
150
+            IURLGenerator $urlGenerator,
151
+            \OC_Defaults $defaults,
152
+            IEventDispatcher $dispatcher
153
+    ) {
154
+        $this->logger = $logger;
155
+        $this->config = $config;
156
+        $this->secureRandom = $secureRandom;
157
+        $this->hasher = $hasher;
158
+        $this->mountManager = $mountManager;
159
+        $this->groupManager = $groupManager;
160
+        $this->l = $l;
161
+        $this->l10nFactory = $l10nFactory;
162
+        $this->factory = $factory;
163
+        $this->userManager = $userManager;
164
+        $this->rootFolder = $rootFolder;
165
+        $this->legacyDispatcher = $legacyDispatcher;
166
+        $this->sharingDisabledForUsersCache = new CappedMemoryCache();
167
+        $this->legacyHooks = new LegacyHooks($this->legacyDispatcher);
168
+        $this->mailer = $mailer;
169
+        $this->urlGenerator = $urlGenerator;
170
+        $this->defaults = $defaults;
171
+        $this->dispatcher = $dispatcher;
172
+    }
173
+
174
+    /**
175
+     * Convert from a full share id to a tuple (providerId, shareId)
176
+     *
177
+     * @param string $id
178
+     * @return string[]
179
+     */
180
+    private function splitFullId($id) {
181
+        return explode(':', $id, 2);
182
+    }
183
+
184
+    /**
185
+     * Verify if a password meets all requirements
186
+     *
187
+     * @param string $password
188
+     * @throws \Exception
189
+     */
190
+    protected function verifyPassword($password) {
191
+        if ($password === null) {
192
+            // No password is set, check if this is allowed.
193
+            if ($this->shareApiLinkEnforcePassword()) {
194
+                throw new \InvalidArgumentException('Passwords are enforced for link shares');
195
+            }
196
+
197
+            return;
198
+        }
199
+
200
+        // Let others verify the password
201
+        try {
202
+            $this->legacyDispatcher->dispatch(new ValidatePasswordPolicyEvent($password));
203
+        } catch (HintException $e) {
204
+            throw new \Exception($e->getHint());
205
+        }
206
+    }
207
+
208
+    /**
209
+     * Check for generic requirements before creating a share
210
+     *
211
+     * @param IShare $share
212
+     * @throws \InvalidArgumentException
213
+     * @throws GenericShareException
214
+     *
215
+     * @suppress PhanUndeclaredClassMethod
216
+     */
217
+    protected function generalCreateChecks(IShare $share) {
218
+        if ($share->getShareType() === IShare::TYPE_USER) {
219
+            // We expect a valid user as sharedWith for user shares
220
+            if (!$this->userManager->userExists($share->getSharedWith())) {
221
+                throw new \InvalidArgumentException('SharedWith is not a valid user');
222
+            }
223
+        } elseif ($share->getShareType() === IShare::TYPE_GROUP) {
224
+            // We expect a valid group as sharedWith for group shares
225
+            if (!$this->groupManager->groupExists($share->getSharedWith())) {
226
+                throw new \InvalidArgumentException('SharedWith is not a valid group');
227
+            }
228
+        } elseif ($share->getShareType() === IShare::TYPE_LINK) {
229
+            if ($share->getSharedWith() !== null) {
230
+                throw new \InvalidArgumentException('SharedWith should be empty');
231
+            }
232
+        } elseif ($share->getShareType() === IShare::TYPE_REMOTE) {
233
+            if ($share->getSharedWith() === null) {
234
+                throw new \InvalidArgumentException('SharedWith should not be empty');
235
+            }
236
+        } elseif ($share->getShareType() === IShare::TYPE_REMOTE_GROUP) {
237
+            if ($share->getSharedWith() === null) {
238
+                throw new \InvalidArgumentException('SharedWith should not be empty');
239
+            }
240
+        } elseif ($share->getShareType() === IShare::TYPE_EMAIL) {
241
+            if ($share->getSharedWith() === null) {
242
+                throw new \InvalidArgumentException('SharedWith should not be empty');
243
+            }
244
+        } elseif ($share->getShareType() === IShare::TYPE_CIRCLE) {
245
+            $circle = \OCA\Circles\Api\v1\Circles::detailsCircle($share->getSharedWith());
246
+            if ($circle === null) {
247
+                throw new \InvalidArgumentException('SharedWith is not a valid circle');
248
+            }
249
+        } elseif ($share->getShareType() === IShare::TYPE_ROOM) {
250
+        } else {
251
+            // We can't handle other types yet
252
+            throw new \InvalidArgumentException('unknown share type');
253
+        }
254
+
255
+        // Verify the initiator of the share is set
256
+        if ($share->getSharedBy() === null) {
257
+            throw new \InvalidArgumentException('SharedBy should be set');
258
+        }
259
+
260
+        // Cannot share with yourself
261
+        if ($share->getShareType() === IShare::TYPE_USER &&
262
+            $share->getSharedWith() === $share->getSharedBy()) {
263
+            throw new \InvalidArgumentException('Can’t share with yourself');
264
+        }
265
+
266
+        // The path should be set
267
+        if ($share->getNode() === null) {
268
+            throw new \InvalidArgumentException('Path should be set');
269
+        }
270
+
271
+        // And it should be a file or a folder
272
+        if (!($share->getNode() instanceof \OCP\Files\File) &&
273
+                !($share->getNode() instanceof \OCP\Files\Folder)) {
274
+            throw new \InvalidArgumentException('Path should be either a file or a folder');
275
+        }
276
+
277
+        // And you can't share your rootfolder
278
+        if ($this->userManager->userExists($share->getSharedBy())) {
279
+            $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
280
+        } else {
281
+            $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
282
+        }
283
+        if ($userFolder->getId() === $share->getNode()->getId()) {
284
+            throw new \InvalidArgumentException('You can’t share your root folder');
285
+        }
286
+
287
+        // Check if we actually have share permissions
288
+        if (!$share->getNode()->isShareable()) {
289
+            $path = $userFolder->getRelativePath($share->getNode()->getPath());
290
+            $message_t = $this->l->t('You are not allowed to share %s', [$path]);
291
+            throw new GenericShareException($message_t, $message_t, 404);
292
+        }
293
+
294
+        // Permissions should be set
295
+        if ($share->getPermissions() === null) {
296
+            throw new \InvalidArgumentException('A share requires permissions');
297
+        }
298
+
299
+        $isFederatedShare = $share->getNode()->getStorage()->instanceOfStorage('\OCA\Files_Sharing\External\Storage');
300
+        $permissions = 0;
301
+        $mount = $share->getNode()->getMountPoint();
302
+        if (!$isFederatedShare && $share->getNode()->getOwner() && $share->getNode()->getOwner()->getUID() !== $share->getSharedBy()) {
303
+            // When it's a reshare use the parent share permissions as maximum
304
+            $userMountPointId = $mount->getStorageRootId();
305
+            $userMountPoints = $userFolder->getById($userMountPointId);
306
+            $userMountPoint = array_shift($userMountPoints);
307
+
308
+            /* Check if this is an incoming share */
309
+            $incomingShares = $this->getSharedWith($share->getSharedBy(), IShare::TYPE_USER, $userMountPoint, -1, 0);
310
+            $incomingShares = array_merge($incomingShares, $this->getSharedWith($share->getSharedBy(), IShare::TYPE_GROUP, $userMountPoint, -1, 0));
311
+            $incomingShares = array_merge($incomingShares, $this->getSharedWith($share->getSharedBy(), IShare::TYPE_CIRCLE, $userMountPoint, -1, 0));
312
+            $incomingShares = array_merge($incomingShares, $this->getSharedWith($share->getSharedBy(), IShare::TYPE_ROOM, $userMountPoint, -1, 0));
313
+
314
+            /** @var IShare[] $incomingShares */
315
+            if (!empty($incomingShares)) {
316
+                foreach ($incomingShares as $incomingShare) {
317
+                    $permissions |= $incomingShare->getPermissions();
318
+                }
319
+            }
320
+        } else {
321
+            /*
322 322
 			 * Quick fix for #23536
323 323
 			 * Non moveable mount points do not have update and delete permissions
324 324
 			 * while we 'most likely' do have that on the storage.
325 325
 			 */
326
-			$permissions = $share->getNode()->getPermissions();
327
-			if (!($mount instanceof MoveableMount)) {
328
-				$permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
329
-			}
330
-		}
331
-
332
-		// Check that we do not share with more permissions than we have
333
-		if ($share->getPermissions() & ~$permissions) {
334
-			$path = $userFolder->getRelativePath($share->getNode()->getPath());
335
-			$message_t = $this->l->t('Can’t increase permissions of %s', [$path]);
336
-			throw new GenericShareException($message_t, $message_t, 404);
337
-		}
338
-
339
-
340
-		// Check that read permissions are always set
341
-		// Link shares are allowed to have no read permissions to allow upload to hidden folders
342
-		$noReadPermissionRequired = $share->getShareType() === IShare::TYPE_LINK
343
-			|| $share->getShareType() === IShare::TYPE_EMAIL;
344
-		if (!$noReadPermissionRequired &&
345
-			($share->getPermissions() & \OCP\Constants::PERMISSION_READ) === 0) {
346
-			throw new \InvalidArgumentException('Shares need at least read permissions');
347
-		}
348
-
349
-		if ($share->getNode() instanceof \OCP\Files\File) {
350
-			if ($share->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
351
-				$message_t = $this->l->t('Files can’t be shared with delete permissions');
352
-				throw new GenericShareException($message_t);
353
-			}
354
-			if ($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE) {
355
-				$message_t = $this->l->t('Files can’t be shared with create permissions');
356
-				throw new GenericShareException($message_t);
357
-			}
358
-		}
359
-	}
360
-
361
-	/**
362
-	 * Validate if the expiration date fits the system settings
363
-	 *
364
-	 * @param IShare $share The share to validate the expiration date of
365
-	 * @return IShare The modified share object
366
-	 * @throws GenericShareException
367
-	 * @throws \InvalidArgumentException
368
-	 * @throws \Exception
369
-	 */
370
-	protected function validateExpirationDateInternal(IShare $share) {
371
-		$expirationDate = $share->getExpirationDate();
372
-
373
-		if ($expirationDate !== null) {
374
-			//Make sure the expiration date is a date
375
-			$expirationDate->setTime(0, 0, 0);
376
-
377
-			$date = new \DateTime();
378
-			$date->setTime(0, 0, 0);
379
-			if ($date >= $expirationDate) {
380
-				$message = $this->l->t('Expiration date is in the past');
381
-				throw new GenericShareException($message, $message, 404);
382
-			}
383
-		}
384
-
385
-		// If expiredate is empty set a default one if there is a default
386
-		$fullId = null;
387
-		try {
388
-			$fullId = $share->getFullId();
389
-		} catch (\UnexpectedValueException $e) {
390
-			// This is a new share
391
-		}
392
-
393
-		if ($fullId === null && $expirationDate === null && $this->shareApiInternalDefaultExpireDate()) {
394
-			$expirationDate = new \DateTime();
395
-			$expirationDate->setTime(0,0,0);
396
-
397
-			$days = (int)$this->config->getAppValue('core', 'internal_defaultExpDays', $this->shareApiLinkDefaultExpireDays());
398
-			if ($days > $this->shareApiLinkDefaultExpireDays()) {
399
-				$days = $this->shareApiLinkDefaultExpireDays();
400
-			}
401
-			$expirationDate->add(new \DateInterval('P'.$days.'D'));
402
-		}
403
-
404
-		// If we enforce the expiration date check that is does not exceed
405
-		if ($this->shareApiInternalDefaultExpireDateEnforced()) {
406
-			if ($expirationDate === null) {
407
-				throw new \InvalidArgumentException('Expiration date is enforced');
408
-			}
409
-
410
-			$date = new \DateTime();
411
-			$date->setTime(0, 0, 0);
412
-			$date->add(new \DateInterval('P' . $this->shareApiInternalDefaultExpireDays() . 'D'));
413
-			if ($date < $expirationDate) {
414
-				$message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiInternalDefaultExpireDays()]);
415
-				throw new GenericShareException($message, $message, 404);
416
-			}
417
-		}
418
-
419
-		$accepted = true;
420
-		$message = '';
421
-		\OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
422
-			'expirationDate' => &$expirationDate,
423
-			'accepted' => &$accepted,
424
-			'message' => &$message,
425
-			'passwordSet' => $share->getPassword() !== null,
426
-		]);
427
-
428
-		if (!$accepted) {
429
-			throw new \Exception($message);
430
-		}
431
-
432
-		$share->setExpirationDate($expirationDate);
433
-
434
-		return $share;
435
-	}
436
-
437
-	/**
438
-	 * Validate if the expiration date fits the system settings
439
-	 *
440
-	 * @param IShare $share The share to validate the expiration date of
441
-	 * @return IShare The modified share object
442
-	 * @throws GenericShareException
443
-	 * @throws \InvalidArgumentException
444
-	 * @throws \Exception
445
-	 */
446
-	protected function validateExpirationDate(IShare $share) {
447
-		$expirationDate = $share->getExpirationDate();
448
-
449
-		if ($expirationDate !== null) {
450
-			//Make sure the expiration date is a date
451
-			$expirationDate->setTime(0, 0, 0);
452
-
453
-			$date = new \DateTime();
454
-			$date->setTime(0, 0, 0);
455
-			if ($date >= $expirationDate) {
456
-				$message = $this->l->t('Expiration date is in the past');
457
-				throw new GenericShareException($message, $message, 404);
458
-			}
459
-		}
460
-
461
-		// If expiredate is empty set a default one if there is a default
462
-		$fullId = null;
463
-		try {
464
-			$fullId = $share->getFullId();
465
-		} catch (\UnexpectedValueException $e) {
466
-			// This is a new share
467
-		}
468
-
469
-		if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
470
-			$expirationDate = new \DateTime();
471
-			$expirationDate->setTime(0,0,0);
472
-
473
-			$days = (int)$this->config->getAppValue('core', 'link_defaultExpDays', $this->shareApiLinkDefaultExpireDays());
474
-			if ($days > $this->shareApiLinkDefaultExpireDays()) {
475
-				$days = $this->shareApiLinkDefaultExpireDays();
476
-			}
477
-			$expirationDate->add(new \DateInterval('P'.$days.'D'));
478
-		}
479
-
480
-		// If we enforce the expiration date check that is does not exceed
481
-		if ($this->shareApiLinkDefaultExpireDateEnforced()) {
482
-			if ($expirationDate === null) {
483
-				throw new \InvalidArgumentException('Expiration date is enforced');
484
-			}
485
-
486
-			$date = new \DateTime();
487
-			$date->setTime(0, 0, 0);
488
-			$date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
489
-			if ($date < $expirationDate) {
490
-				$message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
491
-				throw new GenericShareException($message, $message, 404);
492
-			}
493
-		}
494
-
495
-		$accepted = true;
496
-		$message = '';
497
-		\OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
498
-			'expirationDate' => &$expirationDate,
499
-			'accepted' => &$accepted,
500
-			'message' => &$message,
501
-			'passwordSet' => $share->getPassword() !== null,
502
-		]);
503
-
504
-		if (!$accepted) {
505
-			throw new \Exception($message);
506
-		}
507
-
508
-		$share->setExpirationDate($expirationDate);
509
-
510
-		return $share;
511
-	}
512
-
513
-	/**
514
-	 * Check for pre share requirements for user shares
515
-	 *
516
-	 * @param IShare $share
517
-	 * @throws \Exception
518
-	 */
519
-	protected function userCreateChecks(IShare $share) {
520
-		// Check if we can share with group members only
521
-		if ($this->shareWithGroupMembersOnly()) {
522
-			$sharedBy = $this->userManager->get($share->getSharedBy());
523
-			$sharedWith = $this->userManager->get($share->getSharedWith());
524
-			// Verify we can share with this user
525
-			$groups = array_intersect(
526
-					$this->groupManager->getUserGroupIds($sharedBy),
527
-					$this->groupManager->getUserGroupIds($sharedWith)
528
-			);
529
-			if (empty($groups)) {
530
-				throw new \Exception('Sharing is only allowed with group members');
531
-			}
532
-		}
533
-
534
-		/*
326
+            $permissions = $share->getNode()->getPermissions();
327
+            if (!($mount instanceof MoveableMount)) {
328
+                $permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
329
+            }
330
+        }
331
+
332
+        // Check that we do not share with more permissions than we have
333
+        if ($share->getPermissions() & ~$permissions) {
334
+            $path = $userFolder->getRelativePath($share->getNode()->getPath());
335
+            $message_t = $this->l->t('Can’t increase permissions of %s', [$path]);
336
+            throw new GenericShareException($message_t, $message_t, 404);
337
+        }
338
+
339
+
340
+        // Check that read permissions are always set
341
+        // Link shares are allowed to have no read permissions to allow upload to hidden folders
342
+        $noReadPermissionRequired = $share->getShareType() === IShare::TYPE_LINK
343
+            || $share->getShareType() === IShare::TYPE_EMAIL;
344
+        if (!$noReadPermissionRequired &&
345
+            ($share->getPermissions() & \OCP\Constants::PERMISSION_READ) === 0) {
346
+            throw new \InvalidArgumentException('Shares need at least read permissions');
347
+        }
348
+
349
+        if ($share->getNode() instanceof \OCP\Files\File) {
350
+            if ($share->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
351
+                $message_t = $this->l->t('Files can’t be shared with delete permissions');
352
+                throw new GenericShareException($message_t);
353
+            }
354
+            if ($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE) {
355
+                $message_t = $this->l->t('Files can’t be shared with create permissions');
356
+                throw new GenericShareException($message_t);
357
+            }
358
+        }
359
+    }
360
+
361
+    /**
362
+     * Validate if the expiration date fits the system settings
363
+     *
364
+     * @param IShare $share The share to validate the expiration date of
365
+     * @return IShare The modified share object
366
+     * @throws GenericShareException
367
+     * @throws \InvalidArgumentException
368
+     * @throws \Exception
369
+     */
370
+    protected function validateExpirationDateInternal(IShare $share) {
371
+        $expirationDate = $share->getExpirationDate();
372
+
373
+        if ($expirationDate !== null) {
374
+            //Make sure the expiration date is a date
375
+            $expirationDate->setTime(0, 0, 0);
376
+
377
+            $date = new \DateTime();
378
+            $date->setTime(0, 0, 0);
379
+            if ($date >= $expirationDate) {
380
+                $message = $this->l->t('Expiration date is in the past');
381
+                throw new GenericShareException($message, $message, 404);
382
+            }
383
+        }
384
+
385
+        // If expiredate is empty set a default one if there is a default
386
+        $fullId = null;
387
+        try {
388
+            $fullId = $share->getFullId();
389
+        } catch (\UnexpectedValueException $e) {
390
+            // This is a new share
391
+        }
392
+
393
+        if ($fullId === null && $expirationDate === null && $this->shareApiInternalDefaultExpireDate()) {
394
+            $expirationDate = new \DateTime();
395
+            $expirationDate->setTime(0,0,0);
396
+
397
+            $days = (int)$this->config->getAppValue('core', 'internal_defaultExpDays', $this->shareApiLinkDefaultExpireDays());
398
+            if ($days > $this->shareApiLinkDefaultExpireDays()) {
399
+                $days = $this->shareApiLinkDefaultExpireDays();
400
+            }
401
+            $expirationDate->add(new \DateInterval('P'.$days.'D'));
402
+        }
403
+
404
+        // If we enforce the expiration date check that is does not exceed
405
+        if ($this->shareApiInternalDefaultExpireDateEnforced()) {
406
+            if ($expirationDate === null) {
407
+                throw new \InvalidArgumentException('Expiration date is enforced');
408
+            }
409
+
410
+            $date = new \DateTime();
411
+            $date->setTime(0, 0, 0);
412
+            $date->add(new \DateInterval('P' . $this->shareApiInternalDefaultExpireDays() . 'D'));
413
+            if ($date < $expirationDate) {
414
+                $message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiInternalDefaultExpireDays()]);
415
+                throw new GenericShareException($message, $message, 404);
416
+            }
417
+        }
418
+
419
+        $accepted = true;
420
+        $message = '';
421
+        \OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
422
+            'expirationDate' => &$expirationDate,
423
+            'accepted' => &$accepted,
424
+            'message' => &$message,
425
+            'passwordSet' => $share->getPassword() !== null,
426
+        ]);
427
+
428
+        if (!$accepted) {
429
+            throw new \Exception($message);
430
+        }
431
+
432
+        $share->setExpirationDate($expirationDate);
433
+
434
+        return $share;
435
+    }
436
+
437
+    /**
438
+     * Validate if the expiration date fits the system settings
439
+     *
440
+     * @param IShare $share The share to validate the expiration date of
441
+     * @return IShare The modified share object
442
+     * @throws GenericShareException
443
+     * @throws \InvalidArgumentException
444
+     * @throws \Exception
445
+     */
446
+    protected function validateExpirationDate(IShare $share) {
447
+        $expirationDate = $share->getExpirationDate();
448
+
449
+        if ($expirationDate !== null) {
450
+            //Make sure the expiration date is a date
451
+            $expirationDate->setTime(0, 0, 0);
452
+
453
+            $date = new \DateTime();
454
+            $date->setTime(0, 0, 0);
455
+            if ($date >= $expirationDate) {
456
+                $message = $this->l->t('Expiration date is in the past');
457
+                throw new GenericShareException($message, $message, 404);
458
+            }
459
+        }
460
+
461
+        // If expiredate is empty set a default one if there is a default
462
+        $fullId = null;
463
+        try {
464
+            $fullId = $share->getFullId();
465
+        } catch (\UnexpectedValueException $e) {
466
+            // This is a new share
467
+        }
468
+
469
+        if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
470
+            $expirationDate = new \DateTime();
471
+            $expirationDate->setTime(0,0,0);
472
+
473
+            $days = (int)$this->config->getAppValue('core', 'link_defaultExpDays', $this->shareApiLinkDefaultExpireDays());
474
+            if ($days > $this->shareApiLinkDefaultExpireDays()) {
475
+                $days = $this->shareApiLinkDefaultExpireDays();
476
+            }
477
+            $expirationDate->add(new \DateInterval('P'.$days.'D'));
478
+        }
479
+
480
+        // If we enforce the expiration date check that is does not exceed
481
+        if ($this->shareApiLinkDefaultExpireDateEnforced()) {
482
+            if ($expirationDate === null) {
483
+                throw new \InvalidArgumentException('Expiration date is enforced');
484
+            }
485
+
486
+            $date = new \DateTime();
487
+            $date->setTime(0, 0, 0);
488
+            $date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
489
+            if ($date < $expirationDate) {
490
+                $message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
491
+                throw new GenericShareException($message, $message, 404);
492
+            }
493
+        }
494
+
495
+        $accepted = true;
496
+        $message = '';
497
+        \OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
498
+            'expirationDate' => &$expirationDate,
499
+            'accepted' => &$accepted,
500
+            'message' => &$message,
501
+            'passwordSet' => $share->getPassword() !== null,
502
+        ]);
503
+
504
+        if (!$accepted) {
505
+            throw new \Exception($message);
506
+        }
507
+
508
+        $share->setExpirationDate($expirationDate);
509
+
510
+        return $share;
511
+    }
512
+
513
+    /**
514
+     * Check for pre share requirements for user shares
515
+     *
516
+     * @param IShare $share
517
+     * @throws \Exception
518
+     */
519
+    protected function userCreateChecks(IShare $share) {
520
+        // Check if we can share with group members only
521
+        if ($this->shareWithGroupMembersOnly()) {
522
+            $sharedBy = $this->userManager->get($share->getSharedBy());
523
+            $sharedWith = $this->userManager->get($share->getSharedWith());
524
+            // Verify we can share with this user
525
+            $groups = array_intersect(
526
+                    $this->groupManager->getUserGroupIds($sharedBy),
527
+                    $this->groupManager->getUserGroupIds($sharedWith)
528
+            );
529
+            if (empty($groups)) {
530
+                throw new \Exception('Sharing is only allowed with group members');
531
+            }
532
+        }
533
+
534
+        /*
535 535
 		 * TODO: Could be costly, fix
536 536
 		 *
537 537
 		 * Also this is not what we want in the future.. then we want to squash identical shares.
538 538
 		 */
539
-		$provider = $this->factory->getProviderForType(IShare::TYPE_USER);
540
-		$existingShares = $provider->getSharesByPath($share->getNode());
541
-		foreach ($existingShares as $existingShare) {
542
-			// Ignore if it is the same share
543
-			try {
544
-				if ($existingShare->getFullId() === $share->getFullId()) {
545
-					continue;
546
-				}
547
-			} catch (\UnexpectedValueException $e) {
548
-				//Shares are not identical
549
-			}
550
-
551
-			// Identical share already existst
552
-			if ($existingShare->getSharedWith() === $share->getSharedWith() && $existingShare->getShareType() === $share->getShareType()) {
553
-				throw new \Exception('Path is already shared with this user');
554
-			}
555
-
556
-			// The share is already shared with this user via a group share
557
-			if ($existingShare->getShareType() === IShare::TYPE_GROUP) {
558
-				$group = $this->groupManager->get($existingShare->getSharedWith());
559
-				if (!is_null($group)) {
560
-					$user = $this->userManager->get($share->getSharedWith());
561
-
562
-					if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
563
-						throw new \Exception('Path is already shared with this user');
564
-					}
565
-				}
566
-			}
567
-		}
568
-	}
569
-
570
-	/**
571
-	 * Check for pre share requirements for group shares
572
-	 *
573
-	 * @param IShare $share
574
-	 * @throws \Exception
575
-	 */
576
-	protected function groupCreateChecks(IShare $share) {
577
-		// Verify group shares are allowed
578
-		if (!$this->allowGroupSharing()) {
579
-			throw new \Exception('Group sharing is now allowed');
580
-		}
581
-
582
-		// Verify if the user can share with this group
583
-		if ($this->shareWithGroupMembersOnly()) {
584
-			$sharedBy = $this->userManager->get($share->getSharedBy());
585
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
586
-			if (is_null($sharedWith) || !$sharedWith->inGroup($sharedBy)) {
587
-				throw new \Exception('Sharing is only allowed within your own groups');
588
-			}
589
-		}
590
-
591
-		/*
539
+        $provider = $this->factory->getProviderForType(IShare::TYPE_USER);
540
+        $existingShares = $provider->getSharesByPath($share->getNode());
541
+        foreach ($existingShares as $existingShare) {
542
+            // Ignore if it is the same share
543
+            try {
544
+                if ($existingShare->getFullId() === $share->getFullId()) {
545
+                    continue;
546
+                }
547
+            } catch (\UnexpectedValueException $e) {
548
+                //Shares are not identical
549
+            }
550
+
551
+            // Identical share already existst
552
+            if ($existingShare->getSharedWith() === $share->getSharedWith() && $existingShare->getShareType() === $share->getShareType()) {
553
+                throw new \Exception('Path is already shared with this user');
554
+            }
555
+
556
+            // The share is already shared with this user via a group share
557
+            if ($existingShare->getShareType() === IShare::TYPE_GROUP) {
558
+                $group = $this->groupManager->get($existingShare->getSharedWith());
559
+                if (!is_null($group)) {
560
+                    $user = $this->userManager->get($share->getSharedWith());
561
+
562
+                    if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
563
+                        throw new \Exception('Path is already shared with this user');
564
+                    }
565
+                }
566
+            }
567
+        }
568
+    }
569
+
570
+    /**
571
+     * Check for pre share requirements for group shares
572
+     *
573
+     * @param IShare $share
574
+     * @throws \Exception
575
+     */
576
+    protected function groupCreateChecks(IShare $share) {
577
+        // Verify group shares are allowed
578
+        if (!$this->allowGroupSharing()) {
579
+            throw new \Exception('Group sharing is now allowed');
580
+        }
581
+
582
+        // Verify if the user can share with this group
583
+        if ($this->shareWithGroupMembersOnly()) {
584
+            $sharedBy = $this->userManager->get($share->getSharedBy());
585
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
586
+            if (is_null($sharedWith) || !$sharedWith->inGroup($sharedBy)) {
587
+                throw new \Exception('Sharing is only allowed within your own groups');
588
+            }
589
+        }
590
+
591
+        /*
592 592
 		 * TODO: Could be costly, fix
593 593
 		 *
594 594
 		 * Also this is not what we want in the future.. then we want to squash identical shares.
595 595
 		 */
596
-		$provider = $this->factory->getProviderForType(IShare::TYPE_GROUP);
597
-		$existingShares = $provider->getSharesByPath($share->getNode());
598
-		foreach ($existingShares as $existingShare) {
599
-			try {
600
-				if ($existingShare->getFullId() === $share->getFullId()) {
601
-					continue;
602
-				}
603
-			} catch (\UnexpectedValueException $e) {
604
-				//It is a new share so just continue
605
-			}
606
-
607
-			if ($existingShare->getSharedWith() === $share->getSharedWith() && $existingShare->getShareType() === $share->getShareType()) {
608
-				throw new \Exception('Path is already shared with this group');
609
-			}
610
-		}
611
-	}
612
-
613
-	/**
614
-	 * Check for pre share requirements for link shares
615
-	 *
616
-	 * @param IShare $share
617
-	 * @throws \Exception
618
-	 */
619
-	protected function linkCreateChecks(IShare $share) {
620
-		// Are link shares allowed?
621
-		if (!$this->shareApiAllowLinks()) {
622
-			throw new \Exception('Link sharing is not allowed');
623
-		}
624
-
625
-		// Check if public upload is allowed
626
-		if (!$this->shareApiLinkAllowPublicUpload() &&
627
-			($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE))) {
628
-			throw new \InvalidArgumentException('Public upload is not allowed');
629
-		}
630
-	}
631
-
632
-	/**
633
-	 * To make sure we don't get invisible link shares we set the parent
634
-	 * of a link if it is a reshare. This is a quick word around
635
-	 * until we can properly display multiple link shares in the UI
636
-	 *
637
-	 * See: https://github.com/owncloud/core/issues/22295
638
-	 *
639
-	 * FIXME: Remove once multiple link shares can be properly displayed
640
-	 *
641
-	 * @param IShare $share
642
-	 */
643
-	protected function setLinkParent(IShare $share) {
644
-
645
-		// No sense in checking if the method is not there.
646
-		if (method_exists($share, 'setParent')) {
647
-			$storage = $share->getNode()->getStorage();
648
-			if ($storage->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
649
-				/** @var \OCA\Files_Sharing\SharedStorage $storage */
650
-				$share->setParent($storage->getShareId());
651
-			}
652
-		}
653
-	}
654
-
655
-	/**
656
-	 * @param File|Folder $path
657
-	 */
658
-	protected function pathCreateChecks($path) {
659
-		// Make sure that we do not share a path that contains a shared mountpoint
660
-		if ($path instanceof \OCP\Files\Folder) {
661
-			$mounts = $this->mountManager->findIn($path->getPath());
662
-			foreach ($mounts as $mount) {
663
-				if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
664
-					throw new \InvalidArgumentException('Path contains files shared with you');
665
-				}
666
-			}
667
-		}
668
-	}
669
-
670
-	/**
671
-	 * Check if the user that is sharing can actually share
672
-	 *
673
-	 * @param IShare $share
674
-	 * @throws \Exception
675
-	 */
676
-	protected function canShare(IShare $share) {
677
-		if (!$this->shareApiEnabled()) {
678
-			throw new \Exception('Sharing is disabled');
679
-		}
680
-
681
-		if ($this->sharingDisabledForUser($share->getSharedBy())) {
682
-			throw new \Exception('Sharing is disabled for you');
683
-		}
684
-	}
685
-
686
-	/**
687
-	 * Share a path
688
-	 *
689
-	 * @param IShare $share
690
-	 * @return Share The share object
691
-	 * @throws \Exception
692
-	 *
693
-	 * TODO: handle link share permissions or check them
694
-	 */
695
-	public function createShare(IShare $share) {
696
-		$this->canShare($share);
697
-
698
-		$this->generalCreateChecks($share);
699
-
700
-		// Verify if there are any issues with the path
701
-		$this->pathCreateChecks($share->getNode());
702
-
703
-		/*
596
+        $provider = $this->factory->getProviderForType(IShare::TYPE_GROUP);
597
+        $existingShares = $provider->getSharesByPath($share->getNode());
598
+        foreach ($existingShares as $existingShare) {
599
+            try {
600
+                if ($existingShare->getFullId() === $share->getFullId()) {
601
+                    continue;
602
+                }
603
+            } catch (\UnexpectedValueException $e) {
604
+                //It is a new share so just continue
605
+            }
606
+
607
+            if ($existingShare->getSharedWith() === $share->getSharedWith() && $existingShare->getShareType() === $share->getShareType()) {
608
+                throw new \Exception('Path is already shared with this group');
609
+            }
610
+        }
611
+    }
612
+
613
+    /**
614
+     * Check for pre share requirements for link shares
615
+     *
616
+     * @param IShare $share
617
+     * @throws \Exception
618
+     */
619
+    protected function linkCreateChecks(IShare $share) {
620
+        // Are link shares allowed?
621
+        if (!$this->shareApiAllowLinks()) {
622
+            throw new \Exception('Link sharing is not allowed');
623
+        }
624
+
625
+        // Check if public upload is allowed
626
+        if (!$this->shareApiLinkAllowPublicUpload() &&
627
+            ($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE))) {
628
+            throw new \InvalidArgumentException('Public upload is not allowed');
629
+        }
630
+    }
631
+
632
+    /**
633
+     * To make sure we don't get invisible link shares we set the parent
634
+     * of a link if it is a reshare. This is a quick word around
635
+     * until we can properly display multiple link shares in the UI
636
+     *
637
+     * See: https://github.com/owncloud/core/issues/22295
638
+     *
639
+     * FIXME: Remove once multiple link shares can be properly displayed
640
+     *
641
+     * @param IShare $share
642
+     */
643
+    protected function setLinkParent(IShare $share) {
644
+
645
+        // No sense in checking if the method is not there.
646
+        if (method_exists($share, 'setParent')) {
647
+            $storage = $share->getNode()->getStorage();
648
+            if ($storage->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
649
+                /** @var \OCA\Files_Sharing\SharedStorage $storage */
650
+                $share->setParent($storage->getShareId());
651
+            }
652
+        }
653
+    }
654
+
655
+    /**
656
+     * @param File|Folder $path
657
+     */
658
+    protected function pathCreateChecks($path) {
659
+        // Make sure that we do not share a path that contains a shared mountpoint
660
+        if ($path instanceof \OCP\Files\Folder) {
661
+            $mounts = $this->mountManager->findIn($path->getPath());
662
+            foreach ($mounts as $mount) {
663
+                if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
664
+                    throw new \InvalidArgumentException('Path contains files shared with you');
665
+                }
666
+            }
667
+        }
668
+    }
669
+
670
+    /**
671
+     * Check if the user that is sharing can actually share
672
+     *
673
+     * @param IShare $share
674
+     * @throws \Exception
675
+     */
676
+    protected function canShare(IShare $share) {
677
+        if (!$this->shareApiEnabled()) {
678
+            throw new \Exception('Sharing is disabled');
679
+        }
680
+
681
+        if ($this->sharingDisabledForUser($share->getSharedBy())) {
682
+            throw new \Exception('Sharing is disabled for you');
683
+        }
684
+    }
685
+
686
+    /**
687
+     * Share a path
688
+     *
689
+     * @param IShare $share
690
+     * @return Share The share object
691
+     * @throws \Exception
692
+     *
693
+     * TODO: handle link share permissions or check them
694
+     */
695
+    public function createShare(IShare $share) {
696
+        $this->canShare($share);
697
+
698
+        $this->generalCreateChecks($share);
699
+
700
+        // Verify if there are any issues with the path
701
+        $this->pathCreateChecks($share->getNode());
702
+
703
+        /*
704 704
 		 * On creation of a share the owner is always the owner of the path
705 705
 		 * Except for mounted federated shares.
706 706
 		 */
707
-		$storage = $share->getNode()->getStorage();
708
-		if ($storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
709
-			$parent = $share->getNode()->getParent();
710
-			while ($parent->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
711
-				$parent = $parent->getParent();
712
-			}
713
-			$share->setShareOwner($parent->getOwner()->getUID());
714
-		} else {
715
-			if ($share->getNode()->getOwner()) {
716
-				$share->setShareOwner($share->getNode()->getOwner()->getUID());
717
-			} else {
718
-				$share->setShareOwner($share->getSharedBy());
719
-			}
720
-		}
721
-
722
-		//Verify share type
723
-		if ($share->getShareType() === IShare::TYPE_USER) {
724
-			$this->userCreateChecks($share);
725
-
726
-			//Verify the expiration date
727
-			$share = $this->validateExpirationDateInternal($share);
728
-		} elseif ($share->getShareType() === IShare::TYPE_GROUP) {
729
-			$this->groupCreateChecks($share);
730
-
731
-			//Verify the expiration date
732
-			$share = $this->validateExpirationDateInternal($share);
733
-		} elseif ($share->getShareType() === IShare::TYPE_LINK) {
734
-			$this->linkCreateChecks($share);
735
-			$this->setLinkParent($share);
736
-
737
-			/*
707
+        $storage = $share->getNode()->getStorage();
708
+        if ($storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
709
+            $parent = $share->getNode()->getParent();
710
+            while ($parent->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
711
+                $parent = $parent->getParent();
712
+            }
713
+            $share->setShareOwner($parent->getOwner()->getUID());
714
+        } else {
715
+            if ($share->getNode()->getOwner()) {
716
+                $share->setShareOwner($share->getNode()->getOwner()->getUID());
717
+            } else {
718
+                $share->setShareOwner($share->getSharedBy());
719
+            }
720
+        }
721
+
722
+        //Verify share type
723
+        if ($share->getShareType() === IShare::TYPE_USER) {
724
+            $this->userCreateChecks($share);
725
+
726
+            //Verify the expiration date
727
+            $share = $this->validateExpirationDateInternal($share);
728
+        } elseif ($share->getShareType() === IShare::TYPE_GROUP) {
729
+            $this->groupCreateChecks($share);
730
+
731
+            //Verify the expiration date
732
+            $share = $this->validateExpirationDateInternal($share);
733
+        } elseif ($share->getShareType() === IShare::TYPE_LINK) {
734
+            $this->linkCreateChecks($share);
735
+            $this->setLinkParent($share);
736
+
737
+            /*
738 738
 			 * For now ignore a set token.
739 739
 			 */
740
-			$share->setToken(
741
-				$this->secureRandom->generate(
742
-					\OC\Share\Constants::TOKEN_LENGTH,
743
-					\OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
744
-				)
745
-			);
746
-
747
-			//Verify the expiration date
748
-			$share = $this->validateExpirationDate($share);
749
-
750
-			//Verify the password
751
-			$this->verifyPassword($share->getPassword());
752
-
753
-			// If a password is set. Hash it!
754
-			if ($share->getPassword() !== null) {
755
-				$share->setPassword($this->hasher->hash($share->getPassword()));
756
-			}
757
-		} elseif ($share->getShareType() === IShare::TYPE_EMAIL) {
758
-			$share->setToken(
759
-				$this->secureRandom->generate(
760
-					\OC\Share\Constants::TOKEN_LENGTH,
761
-					\OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
762
-				)
763
-			);
764
-		}
765
-
766
-		// Cannot share with the owner
767
-		if ($share->getShareType() === IShare::TYPE_USER &&
768
-			$share->getSharedWith() === $share->getShareOwner()) {
769
-			throw new \InvalidArgumentException('Can’t share with the share owner');
770
-		}
771
-
772
-		// Generate the target
773
-		$target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName();
774
-		$target = \OC\Files\Filesystem::normalizePath($target);
775
-		$share->setTarget($target);
776
-
777
-		// Pre share event
778
-		$event = new GenericEvent($share);
779
-		$this->legacyDispatcher->dispatch('OCP\Share::preShare', $event);
780
-		if ($event->isPropagationStopped() && $event->hasArgument('error')) {
781
-			throw new \Exception($event->getArgument('error'));
782
-		}
783
-
784
-		$oldShare = $share;
785
-		$provider = $this->factory->getProviderForType($share->getShareType());
786
-		$share = $provider->create($share);
787
-		//reuse the node we already have
788
-		$share->setNode($oldShare->getNode());
789
-
790
-		// Reset the target if it is null for the new share
791
-		if ($share->getTarget() === '') {
792
-			$share->setTarget($target);
793
-		}
794
-
795
-		// Post share event
796
-		$event = new GenericEvent($share);
797
-		$this->legacyDispatcher->dispatch('OCP\Share::postShare', $event);
798
-
799
-		$this->dispatcher->dispatchTyped(new Share\Events\ShareCreatedEvent($share));
800
-
801
-		if ($share->getShareType() === IShare::TYPE_USER) {
802
-			$mailSend = $share->getMailSend();
803
-			if ($mailSend === true) {
804
-				$user = $this->userManager->get($share->getSharedWith());
805
-				if ($user !== null) {
806
-					$emailAddress = $user->getEMailAddress();
807
-					if ($emailAddress !== null && $emailAddress !== '') {
808
-						$userLang = $this->config->getUserValue($share->getSharedWith(), 'core', 'lang', null);
809
-						$l = $this->l10nFactory->get('lib', $userLang);
810
-						$this->sendMailNotification(
811
-							$l,
812
-							$share->getNode()->getName(),
813
-							$this->urlGenerator->linkToRouteAbsolute('files_sharing.Accept.accept', ['shareId' => $share->getFullId()]),
814
-							$share->getSharedBy(),
815
-							$emailAddress,
816
-							$share->getExpirationDate()
817
-						);
818
-						$this->logger->debug('Sent share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
819
-					} else {
820
-						$this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
821
-					}
822
-				} else {
823
-					$this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
824
-				}
825
-			} else {
826
-				$this->logger->debug('Share notification not sent because mailsend is false.', ['app' => 'share']);
827
-			}
828
-		}
829
-
830
-		return $share;
831
-	}
832
-
833
-	/**
834
-	 * Send mail notifications
835
-	 *
836
-	 * This method will catch and log mail transmission errors
837
-	 *
838
-	 * @param IL10N $l Language of the recipient
839
-	 * @param string $filename file/folder name
840
-	 * @param string $link link to the file/folder
841
-	 * @param string $initiator user ID of share sender
842
-	 * @param string $shareWith email address of share receiver
843
-	 * @param \DateTime|null $expiration
844
-	 */
845
-	protected function sendMailNotification(IL10N $l,
846
-											$filename,
847
-											$link,
848
-											$initiator,
849
-											$shareWith,
850
-											\DateTime $expiration = null) {
851
-		$initiatorUser = $this->userManager->get($initiator);
852
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
853
-
854
-		$message = $this->mailer->createMessage();
855
-
856
-		$emailTemplate = $this->mailer->createEMailTemplate('files_sharing.RecipientNotification', [
857
-			'filename' => $filename,
858
-			'link' => $link,
859
-			'initiator' => $initiatorDisplayName,
860
-			'expiration' => $expiration,
861
-			'shareWith' => $shareWith,
862
-		]);
863
-
864
-		$emailTemplate->setSubject($l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]));
865
-		$emailTemplate->addHeader();
866
-		$emailTemplate->addHeading($l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]), false);
867
-		$text = $l->t('%1$s shared »%2$s« with you.', [$initiatorDisplayName, $filename]);
868
-
869
-		$emailTemplate->addBodyText(
870
-			htmlspecialchars($text . ' ' . $l->t('Click the button below to open it.')),
871
-			$text
872
-		);
873
-		$emailTemplate->addBodyButton(
874
-			$l->t('Open »%s«', [$filename]),
875
-			$link
876
-		);
877
-
878
-		$message->setTo([$shareWith]);
879
-
880
-		// The "From" contains the sharers name
881
-		$instanceName = $this->defaults->getName();
882
-		$senderName = $l->t(
883
-			'%1$s via %2$s',
884
-			[
885
-				$initiatorDisplayName,
886
-				$instanceName
887
-			]
888
-		);
889
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
890
-
891
-		// The "Reply-To" is set to the sharer if an mail address is configured
892
-		// also the default footer contains a "Do not reply" which needs to be adjusted.
893
-		$initiatorEmail = $initiatorUser->getEMailAddress();
894
-		if ($initiatorEmail !== null) {
895
-			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
896
-			$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan($l->getLanguageCode()) !== '' ? ' - ' . $this->defaults->getSlogan($l->getLanguageCode()) : ''));
897
-		} else {
898
-			$emailTemplate->addFooter('', $l->getLanguageCode());
899
-		}
900
-
901
-		$message->useTemplate($emailTemplate);
902
-		try {
903
-			$failedRecipients = $this->mailer->send($message);
904
-			if (!empty($failedRecipients)) {
905
-				$this->logger->error('Share notification mail could not be sent to: ' . implode(', ', $failedRecipients));
906
-				return;
907
-			}
908
-		} catch (\Exception $e) {
909
-			$this->logger->logException($e, ['message' => 'Share notification mail could not be sent']);
910
-		}
911
-	}
912
-
913
-	/**
914
-	 * Update a share
915
-	 *
916
-	 * @param IShare $share
917
-	 * @return IShare The share object
918
-	 * @throws \InvalidArgumentException
919
-	 */
920
-	public function updateShare(IShare $share) {
921
-		$expirationDateUpdated = false;
922
-
923
-		$this->canShare($share);
924
-
925
-		try {
926
-			$originalShare = $this->getShareById($share->getFullId());
927
-		} catch (\UnexpectedValueException $e) {
928
-			throw new \InvalidArgumentException('Share does not have a full id');
929
-		}
930
-
931
-		// We can't change the share type!
932
-		if ($share->getShareType() !== $originalShare->getShareType()) {
933
-			throw new \InvalidArgumentException('Can’t change share type');
934
-		}
935
-
936
-		// We can only change the recipient on user shares
937
-		if ($share->getSharedWith() !== $originalShare->getSharedWith() &&
938
-			$share->getShareType() !== IShare::TYPE_USER) {
939
-			throw new \InvalidArgumentException('Can only update recipient on user shares');
940
-		}
941
-
942
-		// Cannot share with the owner
943
-		if ($share->getShareType() === IShare::TYPE_USER &&
944
-			$share->getSharedWith() === $share->getShareOwner()) {
945
-			throw new \InvalidArgumentException('Can’t share with the share owner');
946
-		}
947
-
948
-		$this->generalCreateChecks($share);
949
-
950
-		if ($share->getShareType() === IShare::TYPE_USER) {
951
-			$this->userCreateChecks($share);
952
-
953
-			if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
954
-				//Verify the expiration date
955
-				$this->validateExpirationDate($share);
956
-				$expirationDateUpdated = true;
957
-			}
958
-		} elseif ($share->getShareType() === IShare::TYPE_GROUP) {
959
-			$this->groupCreateChecks($share);
960
-
961
-			if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
962
-				//Verify the expiration date
963
-				$this->validateExpirationDate($share);
964
-				$expirationDateUpdated = true;
965
-			}
966
-		} elseif ($share->getShareType() === IShare::TYPE_LINK) {
967
-			$this->linkCreateChecks($share);
968
-
969
-			$plainTextPassword = $share->getPassword();
970
-
971
-			$this->updateSharePasswordIfNeeded($share, $originalShare);
972
-
973
-			if (empty($plainTextPassword) && $share->getSendPasswordByTalk()) {
974
-				throw new \InvalidArgumentException('Can’t enable sending the password by Talk with an empty password');
975
-			}
976
-
977
-			if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
978
-				//Verify the expiration date
979
-				$this->validateExpirationDate($share);
980
-				$expirationDateUpdated = true;
981
-			}
982
-		} elseif ($share->getShareType() === IShare::TYPE_EMAIL) {
983
-			// The new password is not set again if it is the same as the old
984
-			// one.
985
-			$plainTextPassword = $share->getPassword();
986
-			if (!empty($plainTextPassword) && !$this->updateSharePasswordIfNeeded($share, $originalShare)) {
987
-				$plainTextPassword = null;
988
-			}
989
-			if (empty($plainTextPassword) && !$originalShare->getSendPasswordByTalk() && $share->getSendPasswordByTalk()) {
990
-				// If the same password was already sent by mail the recipient
991
-				// would already have access to the share without having to call
992
-				// the sharer to verify her identity
993
-				throw new \InvalidArgumentException('Can’t enable sending the password by Talk without setting a new password');
994
-			} elseif (empty($plainTextPassword) && $originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk()) {
995
-				throw new \InvalidArgumentException('Can’t disable sending the password by Talk without setting a new password');
996
-			}
997
-		}
998
-
999
-		$this->pathCreateChecks($share->getNode());
1000
-
1001
-		// Now update the share!
1002
-		$provider = $this->factory->getProviderForType($share->getShareType());
1003
-		if ($share->getShareType() === IShare::TYPE_EMAIL) {
1004
-			$share = $provider->update($share, $plainTextPassword);
1005
-		} else {
1006
-			$share = $provider->update($share);
1007
-		}
1008
-
1009
-		if ($expirationDateUpdated === true) {
1010
-			\OC_Hook::emit(Share::class, 'post_set_expiration_date', [
1011
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
1012
-				'itemSource' => $share->getNode()->getId(),
1013
-				'date' => $share->getExpirationDate(),
1014
-				'uidOwner' => $share->getSharedBy(),
1015
-			]);
1016
-		}
1017
-
1018
-		if ($share->getPassword() !== $originalShare->getPassword()) {
1019
-			\OC_Hook::emit(Share::class, 'post_update_password', [
1020
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
1021
-				'itemSource' => $share->getNode()->getId(),
1022
-				'uidOwner' => $share->getSharedBy(),
1023
-				'token' => $share->getToken(),
1024
-				'disabled' => is_null($share->getPassword()),
1025
-			]);
1026
-		}
1027
-
1028
-		if ($share->getPermissions() !== $originalShare->getPermissions()) {
1029
-			if ($this->userManager->userExists($share->getShareOwner())) {
1030
-				$userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
1031
-			} else {
1032
-				$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
1033
-			}
1034
-			\OC_Hook::emit(Share::class, 'post_update_permissions', [
1035
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
1036
-				'itemSource' => $share->getNode()->getId(),
1037
-				'shareType' => $share->getShareType(),
1038
-				'shareWith' => $share->getSharedWith(),
1039
-				'uidOwner' => $share->getSharedBy(),
1040
-				'permissions' => $share->getPermissions(),
1041
-				'path' => $userFolder->getRelativePath($share->getNode()->getPath()),
1042
-			]);
1043
-		}
1044
-
1045
-		return $share;
1046
-	}
1047
-
1048
-	/**
1049
-	 * Accept a share.
1050
-	 *
1051
-	 * @param IShare $share
1052
-	 * @param string $recipientId
1053
-	 * @return IShare The share object
1054
-	 * @throws \InvalidArgumentException
1055
-	 * @since 9.0.0
1056
-	 */
1057
-	public function acceptShare(IShare $share, string $recipientId): IShare {
1058
-		[$providerId, ] = $this->splitFullId($share->getFullId());
1059
-		$provider = $this->factory->getProvider($providerId);
1060
-
1061
-		if (!method_exists($provider, 'acceptShare')) {
1062
-			// TODO FIX ME
1063
-			throw new \InvalidArgumentException('Share provider does not support accepting');
1064
-		}
1065
-		$provider->acceptShare($share, $recipientId);
1066
-		$event = new GenericEvent($share);
1067
-		$this->legacyDispatcher->dispatch('OCP\Share::postAcceptShare', $event);
1068
-
1069
-		return $share;
1070
-	}
1071
-
1072
-	/**
1073
-	 * Updates the password of the given share if it is not the same as the
1074
-	 * password of the original share.
1075
-	 *
1076
-	 * @param IShare $share the share to update its password.
1077
-	 * @param IShare $originalShare the original share to compare its
1078
-	 *        password with.
1079
-	 * @return boolean whether the password was updated or not.
1080
-	 */
1081
-	private function updateSharePasswordIfNeeded(IShare $share, IShare $originalShare) {
1082
-		$passwordsAreDifferent = ($share->getPassword() !== $originalShare->getPassword()) &&
1083
-									(($share->getPassword() !== null && $originalShare->getPassword() === null) ||
1084
-									 ($share->getPassword() === null && $originalShare->getPassword() !== null) ||
1085
-									 ($share->getPassword() !== null && $originalShare->getPassword() !== null &&
1086
-										!$this->hasher->verify($share->getPassword(), $originalShare->getPassword())));
1087
-
1088
-		// Password updated.
1089
-		if ($passwordsAreDifferent) {
1090
-			//Verify the password
1091
-			$this->verifyPassword($share->getPassword());
1092
-
1093
-			// If a password is set. Hash it!
1094
-			if ($share->getPassword() !== null) {
1095
-				$share->setPassword($this->hasher->hash($share->getPassword()));
1096
-
1097
-				return true;
1098
-			}
1099
-		} else {
1100
-			// Reset the password to the original one, as it is either the same
1101
-			// as the "new" password or a hashed version of it.
1102
-			$share->setPassword($originalShare->getPassword());
1103
-		}
1104
-
1105
-		return false;
1106
-	}
1107
-
1108
-	/**
1109
-	 * Delete all the children of this share
1110
-	 * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
1111
-	 *
1112
-	 * @param IShare $share
1113
-	 * @return IShare[] List of deleted shares
1114
-	 */
1115
-	protected function deleteChildren(IShare $share) {
1116
-		$deletedShares = [];
1117
-
1118
-		$provider = $this->factory->getProviderForType($share->getShareType());
1119
-
1120
-		foreach ($provider->getChildren($share) as $child) {
1121
-			$deletedChildren = $this->deleteChildren($child);
1122
-			$deletedShares = array_merge($deletedShares, $deletedChildren);
1123
-
1124
-			$provider->delete($child);
1125
-			$deletedShares[] = $child;
1126
-		}
1127
-
1128
-		return $deletedShares;
1129
-	}
1130
-
1131
-	/**
1132
-	 * Delete a share
1133
-	 *
1134
-	 * @param IShare $share
1135
-	 * @throws ShareNotFound
1136
-	 * @throws \InvalidArgumentException
1137
-	 */
1138
-	public function deleteShare(IShare $share) {
1139
-		try {
1140
-			$share->getFullId();
1141
-		} catch (\UnexpectedValueException $e) {
1142
-			throw new \InvalidArgumentException('Share does not have a full id');
1143
-		}
1144
-
1145
-		$event = new GenericEvent($share);
1146
-		$this->legacyDispatcher->dispatch('OCP\Share::preUnshare', $event);
1147
-
1148
-		// Get all children and delete them as well
1149
-		$deletedShares = $this->deleteChildren($share);
1150
-
1151
-		// Do the actual delete
1152
-		$provider = $this->factory->getProviderForType($share->getShareType());
1153
-		$provider->delete($share);
1154
-
1155
-		// All the deleted shares caused by this delete
1156
-		$deletedShares[] = $share;
1157
-
1158
-		// Emit post hook
1159
-		$event->setArgument('deletedShares', $deletedShares);
1160
-		$this->legacyDispatcher->dispatch('OCP\Share::postUnshare', $event);
1161
-	}
1162
-
1163
-
1164
-	/**
1165
-	 * Unshare a file as the recipient.
1166
-	 * This can be different from a regular delete for example when one of
1167
-	 * the users in a groups deletes that share. But the provider should
1168
-	 * handle this.
1169
-	 *
1170
-	 * @param IShare $share
1171
-	 * @param string $recipientId
1172
-	 */
1173
-	public function deleteFromSelf(IShare $share, $recipientId) {
1174
-		list($providerId, ) = $this->splitFullId($share->getFullId());
1175
-		$provider = $this->factory->getProvider($providerId);
1176
-
1177
-		$provider->deleteFromSelf($share, $recipientId);
1178
-		$event = new GenericEvent($share);
1179
-		$this->legacyDispatcher->dispatch('OCP\Share::postUnshareFromSelf', $event);
1180
-	}
1181
-
1182
-	public function restoreShare(IShare $share, string $recipientId): IShare {
1183
-		list($providerId, ) = $this->splitFullId($share->getFullId());
1184
-		$provider = $this->factory->getProvider($providerId);
1185
-
1186
-		return $provider->restore($share, $recipientId);
1187
-	}
1188
-
1189
-	/**
1190
-	 * @inheritdoc
1191
-	 */
1192
-	public function moveShare(IShare $share, $recipientId) {
1193
-		if ($share->getShareType() === IShare::TYPE_LINK) {
1194
-			throw new \InvalidArgumentException('Can’t change target of link share');
1195
-		}
1196
-
1197
-		if ($share->getShareType() === IShare::TYPE_USER && $share->getSharedWith() !== $recipientId) {
1198
-			throw new \InvalidArgumentException('Invalid recipient');
1199
-		}
1200
-
1201
-		if ($share->getShareType() === IShare::TYPE_GROUP) {
1202
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
1203
-			if (is_null($sharedWith)) {
1204
-				throw new \InvalidArgumentException('Group "' . $share->getSharedWith() . '" does not exist');
1205
-			}
1206
-			$recipient = $this->userManager->get($recipientId);
1207
-			if (!$sharedWith->inGroup($recipient)) {
1208
-				throw new \InvalidArgumentException('Invalid recipient');
1209
-			}
1210
-		}
1211
-
1212
-		list($providerId, ) = $this->splitFullId($share->getFullId());
1213
-		$provider = $this->factory->getProvider($providerId);
1214
-
1215
-		$provider->move($share, $recipientId);
1216
-	}
1217
-
1218
-	public function getSharesInFolder($userId, Folder $node, $reshares = false) {
1219
-		$providers = $this->factory->getAllProviders();
1220
-
1221
-		return array_reduce($providers, function ($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
1222
-			$newShares = $provider->getSharesInFolder($userId, $node, $reshares);
1223
-			foreach ($newShares as $fid => $data) {
1224
-				if (!isset($shares[$fid])) {
1225
-					$shares[$fid] = [];
1226
-				}
1227
-
1228
-				$shares[$fid] = array_merge($shares[$fid], $data);
1229
-			}
1230
-			return $shares;
1231
-		}, []);
1232
-	}
1233
-
1234
-	/**
1235
-	 * @inheritdoc
1236
-	 */
1237
-	public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) {
1238
-		if ($path !== null &&
1239
-				!($path instanceof \OCP\Files\File) &&
1240
-				!($path instanceof \OCP\Files\Folder)) {
1241
-			throw new \InvalidArgumentException('invalid path');
1242
-		}
1243
-
1244
-		try {
1245
-			$provider = $this->factory->getProviderForType($shareType);
1246
-		} catch (ProviderException $e) {
1247
-			return [];
1248
-		}
1249
-
1250
-		$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1251
-
1252
-		/*
740
+            $share->setToken(
741
+                $this->secureRandom->generate(
742
+                    \OC\Share\Constants::TOKEN_LENGTH,
743
+                    \OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
744
+                )
745
+            );
746
+
747
+            //Verify the expiration date
748
+            $share = $this->validateExpirationDate($share);
749
+
750
+            //Verify the password
751
+            $this->verifyPassword($share->getPassword());
752
+
753
+            // If a password is set. Hash it!
754
+            if ($share->getPassword() !== null) {
755
+                $share->setPassword($this->hasher->hash($share->getPassword()));
756
+            }
757
+        } elseif ($share->getShareType() === IShare::TYPE_EMAIL) {
758
+            $share->setToken(
759
+                $this->secureRandom->generate(
760
+                    \OC\Share\Constants::TOKEN_LENGTH,
761
+                    \OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
762
+                )
763
+            );
764
+        }
765
+
766
+        // Cannot share with the owner
767
+        if ($share->getShareType() === IShare::TYPE_USER &&
768
+            $share->getSharedWith() === $share->getShareOwner()) {
769
+            throw new \InvalidArgumentException('Can’t share with the share owner');
770
+        }
771
+
772
+        // Generate the target
773
+        $target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName();
774
+        $target = \OC\Files\Filesystem::normalizePath($target);
775
+        $share->setTarget($target);
776
+
777
+        // Pre share event
778
+        $event = new GenericEvent($share);
779
+        $this->legacyDispatcher->dispatch('OCP\Share::preShare', $event);
780
+        if ($event->isPropagationStopped() && $event->hasArgument('error')) {
781
+            throw new \Exception($event->getArgument('error'));
782
+        }
783
+
784
+        $oldShare = $share;
785
+        $provider = $this->factory->getProviderForType($share->getShareType());
786
+        $share = $provider->create($share);
787
+        //reuse the node we already have
788
+        $share->setNode($oldShare->getNode());
789
+
790
+        // Reset the target if it is null for the new share
791
+        if ($share->getTarget() === '') {
792
+            $share->setTarget($target);
793
+        }
794
+
795
+        // Post share event
796
+        $event = new GenericEvent($share);
797
+        $this->legacyDispatcher->dispatch('OCP\Share::postShare', $event);
798
+
799
+        $this->dispatcher->dispatchTyped(new Share\Events\ShareCreatedEvent($share));
800
+
801
+        if ($share->getShareType() === IShare::TYPE_USER) {
802
+            $mailSend = $share->getMailSend();
803
+            if ($mailSend === true) {
804
+                $user = $this->userManager->get($share->getSharedWith());
805
+                if ($user !== null) {
806
+                    $emailAddress = $user->getEMailAddress();
807
+                    if ($emailAddress !== null && $emailAddress !== '') {
808
+                        $userLang = $this->config->getUserValue($share->getSharedWith(), 'core', 'lang', null);
809
+                        $l = $this->l10nFactory->get('lib', $userLang);
810
+                        $this->sendMailNotification(
811
+                            $l,
812
+                            $share->getNode()->getName(),
813
+                            $this->urlGenerator->linkToRouteAbsolute('files_sharing.Accept.accept', ['shareId' => $share->getFullId()]),
814
+                            $share->getSharedBy(),
815
+                            $emailAddress,
816
+                            $share->getExpirationDate()
817
+                        );
818
+                        $this->logger->debug('Sent share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
819
+                    } else {
820
+                        $this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
821
+                    }
822
+                } else {
823
+                    $this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
824
+                }
825
+            } else {
826
+                $this->logger->debug('Share notification not sent because mailsend is false.', ['app' => 'share']);
827
+            }
828
+        }
829
+
830
+        return $share;
831
+    }
832
+
833
+    /**
834
+     * Send mail notifications
835
+     *
836
+     * This method will catch and log mail transmission errors
837
+     *
838
+     * @param IL10N $l Language of the recipient
839
+     * @param string $filename file/folder name
840
+     * @param string $link link to the file/folder
841
+     * @param string $initiator user ID of share sender
842
+     * @param string $shareWith email address of share receiver
843
+     * @param \DateTime|null $expiration
844
+     */
845
+    protected function sendMailNotification(IL10N $l,
846
+                                            $filename,
847
+                                            $link,
848
+                                            $initiator,
849
+                                            $shareWith,
850
+                                            \DateTime $expiration = null) {
851
+        $initiatorUser = $this->userManager->get($initiator);
852
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
853
+
854
+        $message = $this->mailer->createMessage();
855
+
856
+        $emailTemplate = $this->mailer->createEMailTemplate('files_sharing.RecipientNotification', [
857
+            'filename' => $filename,
858
+            'link' => $link,
859
+            'initiator' => $initiatorDisplayName,
860
+            'expiration' => $expiration,
861
+            'shareWith' => $shareWith,
862
+        ]);
863
+
864
+        $emailTemplate->setSubject($l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]));
865
+        $emailTemplate->addHeader();
866
+        $emailTemplate->addHeading($l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]), false);
867
+        $text = $l->t('%1$s shared »%2$s« with you.', [$initiatorDisplayName, $filename]);
868
+
869
+        $emailTemplate->addBodyText(
870
+            htmlspecialchars($text . ' ' . $l->t('Click the button below to open it.')),
871
+            $text
872
+        );
873
+        $emailTemplate->addBodyButton(
874
+            $l->t('Open »%s«', [$filename]),
875
+            $link
876
+        );
877
+
878
+        $message->setTo([$shareWith]);
879
+
880
+        // The "From" contains the sharers name
881
+        $instanceName = $this->defaults->getName();
882
+        $senderName = $l->t(
883
+            '%1$s via %2$s',
884
+            [
885
+                $initiatorDisplayName,
886
+                $instanceName
887
+            ]
888
+        );
889
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
890
+
891
+        // The "Reply-To" is set to the sharer if an mail address is configured
892
+        // also the default footer contains a "Do not reply" which needs to be adjusted.
893
+        $initiatorEmail = $initiatorUser->getEMailAddress();
894
+        if ($initiatorEmail !== null) {
895
+            $message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
896
+            $emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan($l->getLanguageCode()) !== '' ? ' - ' . $this->defaults->getSlogan($l->getLanguageCode()) : ''));
897
+        } else {
898
+            $emailTemplate->addFooter('', $l->getLanguageCode());
899
+        }
900
+
901
+        $message->useTemplate($emailTemplate);
902
+        try {
903
+            $failedRecipients = $this->mailer->send($message);
904
+            if (!empty($failedRecipients)) {
905
+                $this->logger->error('Share notification mail could not be sent to: ' . implode(', ', $failedRecipients));
906
+                return;
907
+            }
908
+        } catch (\Exception $e) {
909
+            $this->logger->logException($e, ['message' => 'Share notification mail could not be sent']);
910
+        }
911
+    }
912
+
913
+    /**
914
+     * Update a share
915
+     *
916
+     * @param IShare $share
917
+     * @return IShare The share object
918
+     * @throws \InvalidArgumentException
919
+     */
920
+    public function updateShare(IShare $share) {
921
+        $expirationDateUpdated = false;
922
+
923
+        $this->canShare($share);
924
+
925
+        try {
926
+            $originalShare = $this->getShareById($share->getFullId());
927
+        } catch (\UnexpectedValueException $e) {
928
+            throw new \InvalidArgumentException('Share does not have a full id');
929
+        }
930
+
931
+        // We can't change the share type!
932
+        if ($share->getShareType() !== $originalShare->getShareType()) {
933
+            throw new \InvalidArgumentException('Can’t change share type');
934
+        }
935
+
936
+        // We can only change the recipient on user shares
937
+        if ($share->getSharedWith() !== $originalShare->getSharedWith() &&
938
+            $share->getShareType() !== IShare::TYPE_USER) {
939
+            throw new \InvalidArgumentException('Can only update recipient on user shares');
940
+        }
941
+
942
+        // Cannot share with the owner
943
+        if ($share->getShareType() === IShare::TYPE_USER &&
944
+            $share->getSharedWith() === $share->getShareOwner()) {
945
+            throw new \InvalidArgumentException('Can’t share with the share owner');
946
+        }
947
+
948
+        $this->generalCreateChecks($share);
949
+
950
+        if ($share->getShareType() === IShare::TYPE_USER) {
951
+            $this->userCreateChecks($share);
952
+
953
+            if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
954
+                //Verify the expiration date
955
+                $this->validateExpirationDate($share);
956
+                $expirationDateUpdated = true;
957
+            }
958
+        } elseif ($share->getShareType() === IShare::TYPE_GROUP) {
959
+            $this->groupCreateChecks($share);
960
+
961
+            if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
962
+                //Verify the expiration date
963
+                $this->validateExpirationDate($share);
964
+                $expirationDateUpdated = true;
965
+            }
966
+        } elseif ($share->getShareType() === IShare::TYPE_LINK) {
967
+            $this->linkCreateChecks($share);
968
+
969
+            $plainTextPassword = $share->getPassword();
970
+
971
+            $this->updateSharePasswordIfNeeded($share, $originalShare);
972
+
973
+            if (empty($plainTextPassword) && $share->getSendPasswordByTalk()) {
974
+                throw new \InvalidArgumentException('Can’t enable sending the password by Talk with an empty password');
975
+            }
976
+
977
+            if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
978
+                //Verify the expiration date
979
+                $this->validateExpirationDate($share);
980
+                $expirationDateUpdated = true;
981
+            }
982
+        } elseif ($share->getShareType() === IShare::TYPE_EMAIL) {
983
+            // The new password is not set again if it is the same as the old
984
+            // one.
985
+            $plainTextPassword = $share->getPassword();
986
+            if (!empty($plainTextPassword) && !$this->updateSharePasswordIfNeeded($share, $originalShare)) {
987
+                $plainTextPassword = null;
988
+            }
989
+            if (empty($plainTextPassword) && !$originalShare->getSendPasswordByTalk() && $share->getSendPasswordByTalk()) {
990
+                // If the same password was already sent by mail the recipient
991
+                // would already have access to the share without having to call
992
+                // the sharer to verify her identity
993
+                throw new \InvalidArgumentException('Can’t enable sending the password by Talk without setting a new password');
994
+            } elseif (empty($plainTextPassword) && $originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk()) {
995
+                throw new \InvalidArgumentException('Can’t disable sending the password by Talk without setting a new password');
996
+            }
997
+        }
998
+
999
+        $this->pathCreateChecks($share->getNode());
1000
+
1001
+        // Now update the share!
1002
+        $provider = $this->factory->getProviderForType($share->getShareType());
1003
+        if ($share->getShareType() === IShare::TYPE_EMAIL) {
1004
+            $share = $provider->update($share, $plainTextPassword);
1005
+        } else {
1006
+            $share = $provider->update($share);
1007
+        }
1008
+
1009
+        if ($expirationDateUpdated === true) {
1010
+            \OC_Hook::emit(Share::class, 'post_set_expiration_date', [
1011
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
1012
+                'itemSource' => $share->getNode()->getId(),
1013
+                'date' => $share->getExpirationDate(),
1014
+                'uidOwner' => $share->getSharedBy(),
1015
+            ]);
1016
+        }
1017
+
1018
+        if ($share->getPassword() !== $originalShare->getPassword()) {
1019
+            \OC_Hook::emit(Share::class, 'post_update_password', [
1020
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
1021
+                'itemSource' => $share->getNode()->getId(),
1022
+                'uidOwner' => $share->getSharedBy(),
1023
+                'token' => $share->getToken(),
1024
+                'disabled' => is_null($share->getPassword()),
1025
+            ]);
1026
+        }
1027
+
1028
+        if ($share->getPermissions() !== $originalShare->getPermissions()) {
1029
+            if ($this->userManager->userExists($share->getShareOwner())) {
1030
+                $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
1031
+            } else {
1032
+                $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
1033
+            }
1034
+            \OC_Hook::emit(Share::class, 'post_update_permissions', [
1035
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
1036
+                'itemSource' => $share->getNode()->getId(),
1037
+                'shareType' => $share->getShareType(),
1038
+                'shareWith' => $share->getSharedWith(),
1039
+                'uidOwner' => $share->getSharedBy(),
1040
+                'permissions' => $share->getPermissions(),
1041
+                'path' => $userFolder->getRelativePath($share->getNode()->getPath()),
1042
+            ]);
1043
+        }
1044
+
1045
+        return $share;
1046
+    }
1047
+
1048
+    /**
1049
+     * Accept a share.
1050
+     *
1051
+     * @param IShare $share
1052
+     * @param string $recipientId
1053
+     * @return IShare The share object
1054
+     * @throws \InvalidArgumentException
1055
+     * @since 9.0.0
1056
+     */
1057
+    public function acceptShare(IShare $share, string $recipientId): IShare {
1058
+        [$providerId, ] = $this->splitFullId($share->getFullId());
1059
+        $provider = $this->factory->getProvider($providerId);
1060
+
1061
+        if (!method_exists($provider, 'acceptShare')) {
1062
+            // TODO FIX ME
1063
+            throw new \InvalidArgumentException('Share provider does not support accepting');
1064
+        }
1065
+        $provider->acceptShare($share, $recipientId);
1066
+        $event = new GenericEvent($share);
1067
+        $this->legacyDispatcher->dispatch('OCP\Share::postAcceptShare', $event);
1068
+
1069
+        return $share;
1070
+    }
1071
+
1072
+    /**
1073
+     * Updates the password of the given share if it is not the same as the
1074
+     * password of the original share.
1075
+     *
1076
+     * @param IShare $share the share to update its password.
1077
+     * @param IShare $originalShare the original share to compare its
1078
+     *        password with.
1079
+     * @return boolean whether the password was updated or not.
1080
+     */
1081
+    private function updateSharePasswordIfNeeded(IShare $share, IShare $originalShare) {
1082
+        $passwordsAreDifferent = ($share->getPassword() !== $originalShare->getPassword()) &&
1083
+                                    (($share->getPassword() !== null && $originalShare->getPassword() === null) ||
1084
+                                     ($share->getPassword() === null && $originalShare->getPassword() !== null) ||
1085
+                                     ($share->getPassword() !== null && $originalShare->getPassword() !== null &&
1086
+                                        !$this->hasher->verify($share->getPassword(), $originalShare->getPassword())));
1087
+
1088
+        // Password updated.
1089
+        if ($passwordsAreDifferent) {
1090
+            //Verify the password
1091
+            $this->verifyPassword($share->getPassword());
1092
+
1093
+            // If a password is set. Hash it!
1094
+            if ($share->getPassword() !== null) {
1095
+                $share->setPassword($this->hasher->hash($share->getPassword()));
1096
+
1097
+                return true;
1098
+            }
1099
+        } else {
1100
+            // Reset the password to the original one, as it is either the same
1101
+            // as the "new" password or a hashed version of it.
1102
+            $share->setPassword($originalShare->getPassword());
1103
+        }
1104
+
1105
+        return false;
1106
+    }
1107
+
1108
+    /**
1109
+     * Delete all the children of this share
1110
+     * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
1111
+     *
1112
+     * @param IShare $share
1113
+     * @return IShare[] List of deleted shares
1114
+     */
1115
+    protected function deleteChildren(IShare $share) {
1116
+        $deletedShares = [];
1117
+
1118
+        $provider = $this->factory->getProviderForType($share->getShareType());
1119
+
1120
+        foreach ($provider->getChildren($share) as $child) {
1121
+            $deletedChildren = $this->deleteChildren($child);
1122
+            $deletedShares = array_merge($deletedShares, $deletedChildren);
1123
+
1124
+            $provider->delete($child);
1125
+            $deletedShares[] = $child;
1126
+        }
1127
+
1128
+        return $deletedShares;
1129
+    }
1130
+
1131
+    /**
1132
+     * Delete a share
1133
+     *
1134
+     * @param IShare $share
1135
+     * @throws ShareNotFound
1136
+     * @throws \InvalidArgumentException
1137
+     */
1138
+    public function deleteShare(IShare $share) {
1139
+        try {
1140
+            $share->getFullId();
1141
+        } catch (\UnexpectedValueException $e) {
1142
+            throw new \InvalidArgumentException('Share does not have a full id');
1143
+        }
1144
+
1145
+        $event = new GenericEvent($share);
1146
+        $this->legacyDispatcher->dispatch('OCP\Share::preUnshare', $event);
1147
+
1148
+        // Get all children and delete them as well
1149
+        $deletedShares = $this->deleteChildren($share);
1150
+
1151
+        // Do the actual delete
1152
+        $provider = $this->factory->getProviderForType($share->getShareType());
1153
+        $provider->delete($share);
1154
+
1155
+        // All the deleted shares caused by this delete
1156
+        $deletedShares[] = $share;
1157
+
1158
+        // Emit post hook
1159
+        $event->setArgument('deletedShares', $deletedShares);
1160
+        $this->legacyDispatcher->dispatch('OCP\Share::postUnshare', $event);
1161
+    }
1162
+
1163
+
1164
+    /**
1165
+     * Unshare a file as the recipient.
1166
+     * This can be different from a regular delete for example when one of
1167
+     * the users in a groups deletes that share. But the provider should
1168
+     * handle this.
1169
+     *
1170
+     * @param IShare $share
1171
+     * @param string $recipientId
1172
+     */
1173
+    public function deleteFromSelf(IShare $share, $recipientId) {
1174
+        list($providerId, ) = $this->splitFullId($share->getFullId());
1175
+        $provider = $this->factory->getProvider($providerId);
1176
+
1177
+        $provider->deleteFromSelf($share, $recipientId);
1178
+        $event = new GenericEvent($share);
1179
+        $this->legacyDispatcher->dispatch('OCP\Share::postUnshareFromSelf', $event);
1180
+    }
1181
+
1182
+    public function restoreShare(IShare $share, string $recipientId): IShare {
1183
+        list($providerId, ) = $this->splitFullId($share->getFullId());
1184
+        $provider = $this->factory->getProvider($providerId);
1185
+
1186
+        return $provider->restore($share, $recipientId);
1187
+    }
1188
+
1189
+    /**
1190
+     * @inheritdoc
1191
+     */
1192
+    public function moveShare(IShare $share, $recipientId) {
1193
+        if ($share->getShareType() === IShare::TYPE_LINK) {
1194
+            throw new \InvalidArgumentException('Can’t change target of link share');
1195
+        }
1196
+
1197
+        if ($share->getShareType() === IShare::TYPE_USER && $share->getSharedWith() !== $recipientId) {
1198
+            throw new \InvalidArgumentException('Invalid recipient');
1199
+        }
1200
+
1201
+        if ($share->getShareType() === IShare::TYPE_GROUP) {
1202
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
1203
+            if (is_null($sharedWith)) {
1204
+                throw new \InvalidArgumentException('Group "' . $share->getSharedWith() . '" does not exist');
1205
+            }
1206
+            $recipient = $this->userManager->get($recipientId);
1207
+            if (!$sharedWith->inGroup($recipient)) {
1208
+                throw new \InvalidArgumentException('Invalid recipient');
1209
+            }
1210
+        }
1211
+
1212
+        list($providerId, ) = $this->splitFullId($share->getFullId());
1213
+        $provider = $this->factory->getProvider($providerId);
1214
+
1215
+        $provider->move($share, $recipientId);
1216
+    }
1217
+
1218
+    public function getSharesInFolder($userId, Folder $node, $reshares = false) {
1219
+        $providers = $this->factory->getAllProviders();
1220
+
1221
+        return array_reduce($providers, function ($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
1222
+            $newShares = $provider->getSharesInFolder($userId, $node, $reshares);
1223
+            foreach ($newShares as $fid => $data) {
1224
+                if (!isset($shares[$fid])) {
1225
+                    $shares[$fid] = [];
1226
+                }
1227
+
1228
+                $shares[$fid] = array_merge($shares[$fid], $data);
1229
+            }
1230
+            return $shares;
1231
+        }, []);
1232
+    }
1233
+
1234
+    /**
1235
+     * @inheritdoc
1236
+     */
1237
+    public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) {
1238
+        if ($path !== null &&
1239
+                !($path instanceof \OCP\Files\File) &&
1240
+                !($path instanceof \OCP\Files\Folder)) {
1241
+            throw new \InvalidArgumentException('invalid path');
1242
+        }
1243
+
1244
+        try {
1245
+            $provider = $this->factory->getProviderForType($shareType);
1246
+        } catch (ProviderException $e) {
1247
+            return [];
1248
+        }
1249
+
1250
+        $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1251
+
1252
+        /*
1253 1253
 		 * Work around so we don't return expired shares but still follow
1254 1254
 		 * proper pagination.
1255 1255
 		 */
1256 1256
 
1257
-		$shares2 = [];
1258
-
1259
-		while (true) {
1260
-			$added = 0;
1261
-			foreach ($shares as $share) {
1262
-				try {
1263
-					$this->checkExpireDate($share);
1264
-				} catch (ShareNotFound $e) {
1265
-					//Ignore since this basically means the share is deleted
1266
-					continue;
1267
-				}
1268
-
1269
-				$added++;
1270
-				$shares2[] = $share;
1271
-
1272
-				if (count($shares2) === $limit) {
1273
-					break;
1274
-				}
1275
-			}
1276
-
1277
-			// If we did not fetch more shares than the limit then there are no more shares
1278
-			if (count($shares) < $limit) {
1279
-				break;
1280
-			}
1281
-
1282
-			if (count($shares2) === $limit) {
1283
-				break;
1284
-			}
1285
-
1286
-			// If there was no limit on the select we are done
1287
-			if ($limit === -1) {
1288
-				break;
1289
-			}
1290
-
1291
-			$offset += $added;
1292
-
1293
-			// Fetch again $limit shares
1294
-			$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1295
-
1296
-			// No more shares means we are done
1297
-			if (empty($shares)) {
1298
-				break;
1299
-			}
1300
-		}
1301
-
1302
-		$shares = $shares2;
1303
-
1304
-		return $shares;
1305
-	}
1306
-
1307
-	/**
1308
-	 * @inheritdoc
1309
-	 */
1310
-	public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1311
-		try {
1312
-			$provider = $this->factory->getProviderForType($shareType);
1313
-		} catch (ProviderException $e) {
1314
-			return [];
1315
-		}
1316
-
1317
-		$shares = $provider->getSharedWith($userId, $shareType, $node, $limit, $offset);
1318
-
1319
-		// remove all shares which are already expired
1320
-		foreach ($shares as $key => $share) {
1321
-			try {
1322
-				$this->checkExpireDate($share);
1323
-			} catch (ShareNotFound $e) {
1324
-				unset($shares[$key]);
1325
-			}
1326
-		}
1327
-
1328
-		return $shares;
1329
-	}
1330
-
1331
-	/**
1332
-	 * @inheritdoc
1333
-	 */
1334
-	public function getDeletedSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1335
-		$shares = $this->getSharedWith($userId, $shareType, $node, $limit, $offset);
1336
-
1337
-		// Only get deleted shares
1338
-		$shares = array_filter($shares, function (IShare $share) {
1339
-			return $share->getPermissions() === 0;
1340
-		});
1341
-
1342
-		// Only get shares where the owner still exists
1343
-		$shares = array_filter($shares, function (IShare $share) {
1344
-			return $this->userManager->userExists($share->getShareOwner());
1345
-		});
1346
-
1347
-		return $shares;
1348
-	}
1349
-
1350
-	/**
1351
-	 * @inheritdoc
1352
-	 */
1353
-	public function getShareById($id, $recipient = null) {
1354
-		if ($id === null) {
1355
-			throw new ShareNotFound();
1356
-		}
1357
-
1358
-		list($providerId, $id) = $this->splitFullId($id);
1359
-
1360
-		try {
1361
-			$provider = $this->factory->getProvider($providerId);
1362
-		} catch (ProviderException $e) {
1363
-			throw new ShareNotFound();
1364
-		}
1365
-
1366
-		$share = $provider->getShareById($id, $recipient);
1367
-
1368
-		$this->checkExpireDate($share);
1369
-
1370
-		return $share;
1371
-	}
1372
-
1373
-	/**
1374
-	 * Get all the shares for a given path
1375
-	 *
1376
-	 * @param \OCP\Files\Node $path
1377
-	 * @param int $page
1378
-	 * @param int $perPage
1379
-	 *
1380
-	 * @return Share[]
1381
-	 */
1382
-	public function getSharesByPath(\OCP\Files\Node $path, $page=0, $perPage=50) {
1383
-		return [];
1384
-	}
1385
-
1386
-	/**
1387
-	 * Get the share by token possible with password
1388
-	 *
1389
-	 * @param string $token
1390
-	 * @return Share
1391
-	 *
1392
-	 * @throws ShareNotFound
1393
-	 */
1394
-	public function getShareByToken($token) {
1395
-		// tokens can't be valid local user names
1396
-		if ($this->userManager->userExists($token)) {
1397
-			throw new ShareNotFound();
1398
-		}
1399
-		$share = null;
1400
-		try {
1401
-			if ($this->shareApiAllowLinks()) {
1402
-				$provider = $this->factory->getProviderForType(IShare::TYPE_LINK);
1403
-				$share = $provider->getShareByToken($token);
1404
-			}
1405
-		} catch (ProviderException $e) {
1406
-		} catch (ShareNotFound $e) {
1407
-		}
1408
-
1409
-
1410
-		// If it is not a link share try to fetch a federated share by token
1411
-		if ($share === null) {
1412
-			try {
1413
-				$provider = $this->factory->getProviderForType(IShare::TYPE_REMOTE);
1414
-				$share = $provider->getShareByToken($token);
1415
-			} catch (ProviderException $e) {
1416
-			} catch (ShareNotFound $e) {
1417
-			}
1418
-		}
1419
-
1420
-		// If it is not a link share try to fetch a mail share by token
1421
-		if ($share === null && $this->shareProviderExists(IShare::TYPE_EMAIL)) {
1422
-			try {
1423
-				$provider = $this->factory->getProviderForType(IShare::TYPE_EMAIL);
1424
-				$share = $provider->getShareByToken($token);
1425
-			} catch (ProviderException $e) {
1426
-			} catch (ShareNotFound $e) {
1427
-			}
1428
-		}
1429
-
1430
-		if ($share === null && $this->shareProviderExists(IShare::TYPE_CIRCLE)) {
1431
-			try {
1432
-				$provider = $this->factory->getProviderForType(IShare::TYPE_CIRCLE);
1433
-				$share = $provider->getShareByToken($token);
1434
-			} catch (ProviderException $e) {
1435
-			} catch (ShareNotFound $e) {
1436
-			}
1437
-		}
1438
-
1439
-		if ($share === null && $this->shareProviderExists(IShare::TYPE_ROOM)) {
1440
-			try {
1441
-				$provider = $this->factory->getProviderForType(IShare::TYPE_ROOM);
1442
-				$share = $provider->getShareByToken($token);
1443
-			} catch (ProviderException $e) {
1444
-			} catch (ShareNotFound $e) {
1445
-			}
1446
-		}
1447
-
1448
-		if ($share === null) {
1449
-			throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1450
-		}
1451
-
1452
-		$this->checkExpireDate($share);
1453
-
1454
-		/*
1257
+        $shares2 = [];
1258
+
1259
+        while (true) {
1260
+            $added = 0;
1261
+            foreach ($shares as $share) {
1262
+                try {
1263
+                    $this->checkExpireDate($share);
1264
+                } catch (ShareNotFound $e) {
1265
+                    //Ignore since this basically means the share is deleted
1266
+                    continue;
1267
+                }
1268
+
1269
+                $added++;
1270
+                $shares2[] = $share;
1271
+
1272
+                if (count($shares2) === $limit) {
1273
+                    break;
1274
+                }
1275
+            }
1276
+
1277
+            // If we did not fetch more shares than the limit then there are no more shares
1278
+            if (count($shares) < $limit) {
1279
+                break;
1280
+            }
1281
+
1282
+            if (count($shares2) === $limit) {
1283
+                break;
1284
+            }
1285
+
1286
+            // If there was no limit on the select we are done
1287
+            if ($limit === -1) {
1288
+                break;
1289
+            }
1290
+
1291
+            $offset += $added;
1292
+
1293
+            // Fetch again $limit shares
1294
+            $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1295
+
1296
+            // No more shares means we are done
1297
+            if (empty($shares)) {
1298
+                break;
1299
+            }
1300
+        }
1301
+
1302
+        $shares = $shares2;
1303
+
1304
+        return $shares;
1305
+    }
1306
+
1307
+    /**
1308
+     * @inheritdoc
1309
+     */
1310
+    public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1311
+        try {
1312
+            $provider = $this->factory->getProviderForType($shareType);
1313
+        } catch (ProviderException $e) {
1314
+            return [];
1315
+        }
1316
+
1317
+        $shares = $provider->getSharedWith($userId, $shareType, $node, $limit, $offset);
1318
+
1319
+        // remove all shares which are already expired
1320
+        foreach ($shares as $key => $share) {
1321
+            try {
1322
+                $this->checkExpireDate($share);
1323
+            } catch (ShareNotFound $e) {
1324
+                unset($shares[$key]);
1325
+            }
1326
+        }
1327
+
1328
+        return $shares;
1329
+    }
1330
+
1331
+    /**
1332
+     * @inheritdoc
1333
+     */
1334
+    public function getDeletedSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1335
+        $shares = $this->getSharedWith($userId, $shareType, $node, $limit, $offset);
1336
+
1337
+        // Only get deleted shares
1338
+        $shares = array_filter($shares, function (IShare $share) {
1339
+            return $share->getPermissions() === 0;
1340
+        });
1341
+
1342
+        // Only get shares where the owner still exists
1343
+        $shares = array_filter($shares, function (IShare $share) {
1344
+            return $this->userManager->userExists($share->getShareOwner());
1345
+        });
1346
+
1347
+        return $shares;
1348
+    }
1349
+
1350
+    /**
1351
+     * @inheritdoc
1352
+     */
1353
+    public function getShareById($id, $recipient = null) {
1354
+        if ($id === null) {
1355
+            throw new ShareNotFound();
1356
+        }
1357
+
1358
+        list($providerId, $id) = $this->splitFullId($id);
1359
+
1360
+        try {
1361
+            $provider = $this->factory->getProvider($providerId);
1362
+        } catch (ProviderException $e) {
1363
+            throw new ShareNotFound();
1364
+        }
1365
+
1366
+        $share = $provider->getShareById($id, $recipient);
1367
+
1368
+        $this->checkExpireDate($share);
1369
+
1370
+        return $share;
1371
+    }
1372
+
1373
+    /**
1374
+     * Get all the shares for a given path
1375
+     *
1376
+     * @param \OCP\Files\Node $path
1377
+     * @param int $page
1378
+     * @param int $perPage
1379
+     *
1380
+     * @return Share[]
1381
+     */
1382
+    public function getSharesByPath(\OCP\Files\Node $path, $page=0, $perPage=50) {
1383
+        return [];
1384
+    }
1385
+
1386
+    /**
1387
+     * Get the share by token possible with password
1388
+     *
1389
+     * @param string $token
1390
+     * @return Share
1391
+     *
1392
+     * @throws ShareNotFound
1393
+     */
1394
+    public function getShareByToken($token) {
1395
+        // tokens can't be valid local user names
1396
+        if ($this->userManager->userExists($token)) {
1397
+            throw new ShareNotFound();
1398
+        }
1399
+        $share = null;
1400
+        try {
1401
+            if ($this->shareApiAllowLinks()) {
1402
+                $provider = $this->factory->getProviderForType(IShare::TYPE_LINK);
1403
+                $share = $provider->getShareByToken($token);
1404
+            }
1405
+        } catch (ProviderException $e) {
1406
+        } catch (ShareNotFound $e) {
1407
+        }
1408
+
1409
+
1410
+        // If it is not a link share try to fetch a federated share by token
1411
+        if ($share === null) {
1412
+            try {
1413
+                $provider = $this->factory->getProviderForType(IShare::TYPE_REMOTE);
1414
+                $share = $provider->getShareByToken($token);
1415
+            } catch (ProviderException $e) {
1416
+            } catch (ShareNotFound $e) {
1417
+            }
1418
+        }
1419
+
1420
+        // If it is not a link share try to fetch a mail share by token
1421
+        if ($share === null && $this->shareProviderExists(IShare::TYPE_EMAIL)) {
1422
+            try {
1423
+                $provider = $this->factory->getProviderForType(IShare::TYPE_EMAIL);
1424
+                $share = $provider->getShareByToken($token);
1425
+            } catch (ProviderException $e) {
1426
+            } catch (ShareNotFound $e) {
1427
+            }
1428
+        }
1429
+
1430
+        if ($share === null && $this->shareProviderExists(IShare::TYPE_CIRCLE)) {
1431
+            try {
1432
+                $provider = $this->factory->getProviderForType(IShare::TYPE_CIRCLE);
1433
+                $share = $provider->getShareByToken($token);
1434
+            } catch (ProviderException $e) {
1435
+            } catch (ShareNotFound $e) {
1436
+            }
1437
+        }
1438
+
1439
+        if ($share === null && $this->shareProviderExists(IShare::TYPE_ROOM)) {
1440
+            try {
1441
+                $provider = $this->factory->getProviderForType(IShare::TYPE_ROOM);
1442
+                $share = $provider->getShareByToken($token);
1443
+            } catch (ProviderException $e) {
1444
+            } catch (ShareNotFound $e) {
1445
+            }
1446
+        }
1447
+
1448
+        if ($share === null) {
1449
+            throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1450
+        }
1451
+
1452
+        $this->checkExpireDate($share);
1453
+
1454
+        /*
1455 1455
 		 * Reduce the permissions for link shares if public upload is not enabled
1456 1456
 		 */
1457
-		if ($share->getShareType() === IShare::TYPE_LINK &&
1458
-			!$this->shareApiLinkAllowPublicUpload()) {
1459
-			$share->setPermissions($share->getPermissions() & ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE));
1460
-		}
1461
-
1462
-		return $share;
1463
-	}
1464
-
1465
-	protected function checkExpireDate($share) {
1466
-		if ($share->isExpired()) {
1467
-			$this->deleteShare($share);
1468
-			throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1469
-		}
1470
-	}
1471
-
1472
-	/**
1473
-	 * Verify the password of a public share
1474
-	 *
1475
-	 * @param IShare $share
1476
-	 * @param string $password
1477
-	 * @return bool
1478
-	 */
1479
-	public function checkPassword(IShare $share, $password) {
1480
-		$passwordProtected = $share->getShareType() !== IShare::TYPE_LINK
1481
-							 || $share->getShareType() !== IShare::TYPE_EMAIL
1482
-							 || $share->getShareType() !== IShare::TYPE_CIRCLE;
1483
-		if (!$passwordProtected) {
1484
-			//TODO maybe exception?
1485
-			return false;
1486
-		}
1487
-
1488
-		if ($password === null || $share->getPassword() === null) {
1489
-			return false;
1490
-		}
1491
-
1492
-		$newHash = '';
1493
-		if (!$this->hasher->verify($password, $share->getPassword(), $newHash)) {
1494
-			return false;
1495
-		}
1496
-
1497
-		if (!empty($newHash)) {
1498
-			$share->setPassword($newHash);
1499
-			$provider = $this->factory->getProviderForType($share->getShareType());
1500
-			$provider->update($share);
1501
-		}
1502
-
1503
-		return true;
1504
-	}
1505
-
1506
-	/**
1507
-	 * @inheritdoc
1508
-	 */
1509
-	public function userDeleted($uid) {
1510
-		$types = [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_LINK, IShare::TYPE_REMOTE, IShare::TYPE_EMAIL];
1511
-
1512
-		foreach ($types as $type) {
1513
-			try {
1514
-				$provider = $this->factory->getProviderForType($type);
1515
-			} catch (ProviderException $e) {
1516
-				continue;
1517
-			}
1518
-			$provider->userDeleted($uid, $type);
1519
-		}
1520
-	}
1521
-
1522
-	/**
1523
-	 * @inheritdoc
1524
-	 */
1525
-	public function groupDeleted($gid) {
1526
-		$provider = $this->factory->getProviderForType(IShare::TYPE_GROUP);
1527
-		$provider->groupDeleted($gid);
1528
-
1529
-		$excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1530
-		if ($excludedGroups === '') {
1531
-			return;
1532
-		}
1533
-
1534
-		$excludedGroups = json_decode($excludedGroups, true);
1535
-		if (json_last_error() !== JSON_ERROR_NONE) {
1536
-			return;
1537
-		}
1538
-
1539
-		$excludedGroups = array_diff($excludedGroups, [$gid]);
1540
-		$this->config->setAppValue('core', 'shareapi_exclude_groups_list', json_encode($excludedGroups));
1541
-	}
1542
-
1543
-	/**
1544
-	 * @inheritdoc
1545
-	 */
1546
-	public function userDeletedFromGroup($uid, $gid) {
1547
-		$provider = $this->factory->getProviderForType(IShare::TYPE_GROUP);
1548
-		$provider->userDeletedFromGroup($uid, $gid);
1549
-	}
1550
-
1551
-	/**
1552
-	 * Get access list to a path. This means
1553
-	 * all the users that can access a given path.
1554
-	 *
1555
-	 * Consider:
1556
-	 * -root
1557
-	 * |-folder1 (23)
1558
-	 *  |-folder2 (32)
1559
-	 *   |-fileA (42)
1560
-	 *
1561
-	 * fileA is shared with user1 and user1@server1
1562
-	 * folder2 is shared with group2 (user4 is a member of group2)
1563
-	 * folder1 is shared with user2 (renamed to "folder (1)") and user2@server2
1564
-	 *
1565
-	 * Then the access list to '/folder1/folder2/fileA' with $currentAccess is:
1566
-	 * [
1567
-	 *  users  => [
1568
-	 *      'user1' => ['node_id' => 42, 'node_path' => '/fileA'],
1569
-	 *      'user4' => ['node_id' => 32, 'node_path' => '/folder2'],
1570
-	 *      'user2' => ['node_id' => 23, 'node_path' => '/folder (1)'],
1571
-	 *  ],
1572
-	 *  remote => [
1573
-	 *      'user1@server1' => ['node_id' => 42, 'token' => 'SeCr3t'],
1574
-	 *      'user2@server2' => ['node_id' => 23, 'token' => 'FooBaR'],
1575
-	 *  ],
1576
-	 *  public => bool
1577
-	 *  mail => bool
1578
-	 * ]
1579
-	 *
1580
-	 * The access list to '/folder1/folder2/fileA' **without** $currentAccess is:
1581
-	 * [
1582
-	 *  users  => ['user1', 'user2', 'user4'],
1583
-	 *  remote => bool,
1584
-	 *  public => bool
1585
-	 *  mail => bool
1586
-	 * ]
1587
-	 *
1588
-	 * This is required for encryption/activity
1589
-	 *
1590
-	 * @param \OCP\Files\Node $path
1591
-	 * @param bool $recursive Should we check all parent folders as well
1592
-	 * @param bool $currentAccess Ensure the recipient has access to the file (e.g. did not unshare it)
1593
-	 * @return array
1594
-	 */
1595
-	public function getAccessList(\OCP\Files\Node $path, $recursive = true, $currentAccess = false) {
1596
-		$owner = $path->getOwner();
1597
-
1598
-		if ($owner === null) {
1599
-			return [];
1600
-		}
1601
-
1602
-		$owner = $owner->getUID();
1603
-
1604
-		if ($currentAccess) {
1605
-			$al = ['users' => [], 'remote' => [], 'public' => false];
1606
-		} else {
1607
-			$al = ['users' => [], 'remote' => false, 'public' => false];
1608
-		}
1609
-		if (!$this->userManager->userExists($owner)) {
1610
-			return $al;
1611
-		}
1612
-
1613
-		//Get node for the owner and correct the owner in case of external storages
1614
-		$userFolder = $this->rootFolder->getUserFolder($owner);
1615
-		if ($path->getId() !== $userFolder->getId() && !$userFolder->isSubNode($path)) {
1616
-			$nodes = $userFolder->getById($path->getId());
1617
-			$path = array_shift($nodes);
1618
-			if ($path->getOwner() === null) {
1619
-				return [];
1620
-			}
1621
-			$owner = $path->getOwner()->getUID();
1622
-		}
1623
-
1624
-		$providers = $this->factory->getAllProviders();
1625
-
1626
-		/** @var Node[] $nodes */
1627
-		$nodes = [];
1628
-
1629
-
1630
-		if ($currentAccess) {
1631
-			$ownerPath = $path->getPath();
1632
-			$ownerPath = explode('/', $ownerPath, 4);
1633
-			if (count($ownerPath) < 4) {
1634
-				$ownerPath = '';
1635
-			} else {
1636
-				$ownerPath = $ownerPath[3];
1637
-			}
1638
-			$al['users'][$owner] = [
1639
-				'node_id' => $path->getId(),
1640
-				'node_path' => '/' . $ownerPath,
1641
-			];
1642
-		} else {
1643
-			$al['users'][] = $owner;
1644
-		}
1645
-
1646
-		// Collect all the shares
1647
-		while ($path->getPath() !== $userFolder->getPath()) {
1648
-			$nodes[] = $path;
1649
-			if (!$recursive) {
1650
-				break;
1651
-			}
1652
-			$path = $path->getParent();
1653
-		}
1654
-
1655
-		foreach ($providers as $provider) {
1656
-			$tmp = $provider->getAccessList($nodes, $currentAccess);
1657
-
1658
-			foreach ($tmp as $k => $v) {
1659
-				if (isset($al[$k])) {
1660
-					if (is_array($al[$k])) {
1661
-						if ($currentAccess) {
1662
-							$al[$k] += $v;
1663
-						} else {
1664
-							$al[$k] = array_merge($al[$k], $v);
1665
-							$al[$k] = array_unique($al[$k]);
1666
-							$al[$k] = array_values($al[$k]);
1667
-						}
1668
-					} else {
1669
-						$al[$k] = $al[$k] || $v;
1670
-					}
1671
-				} else {
1672
-					$al[$k] = $v;
1673
-				}
1674
-			}
1675
-		}
1676
-
1677
-		return $al;
1678
-	}
1679
-
1680
-	/**
1681
-	 * Create a new share
1682
-	 *
1683
-	 * @return IShare
1684
-	 */
1685
-	public function newShare() {
1686
-		return new \OC\Share20\Share($this->rootFolder, $this->userManager);
1687
-	}
1688
-
1689
-	/**
1690
-	 * Is the share API enabled
1691
-	 *
1692
-	 * @return bool
1693
-	 */
1694
-	public function shareApiEnabled() {
1695
-		return $this->config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes';
1696
-	}
1697
-
1698
-	/**
1699
-	 * Is public link sharing enabled
1700
-	 *
1701
-	 * @return bool
1702
-	 */
1703
-	public function shareApiAllowLinks() {
1704
-		return $this->config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes';
1705
-	}
1706
-
1707
-	/**
1708
-	 * Is password on public link requires
1709
-	 *
1710
-	 * @return bool
1711
-	 */
1712
-	public function shareApiLinkEnforcePassword() {
1713
-		return $this->config->getAppValue('core', 'shareapi_enforce_links_password', 'no') === 'yes';
1714
-	}
1715
-
1716
-	/**
1717
-	 * Is default link expire date enabled
1718
-	 *
1719
-	 * @return bool
1720
-	 */
1721
-	public function shareApiLinkDefaultExpireDate() {
1722
-		return $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes';
1723
-	}
1724
-
1725
-	/**
1726
-	 * Is default link expire date enforced
1727
-	 *`
1728
-	 * @return bool
1729
-	 */
1730
-	public function shareApiLinkDefaultExpireDateEnforced() {
1731
-		return $this->shareApiLinkDefaultExpireDate() &&
1732
-			$this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes';
1733
-	}
1734
-
1735
-
1736
-	/**
1737
-	 * Number of default link expire days
1738
-	 * @return int
1739
-	 */
1740
-	public function shareApiLinkDefaultExpireDays() {
1741
-		return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1742
-	}
1743
-
1744
-	/**
1745
-	 * Is default internal expire date enabled
1746
-	 *
1747
-	 * @return bool
1748
-	 */
1749
-	public function shareApiInternalDefaultExpireDate(): bool {
1750
-		return $this->config->getAppValue('core', 'shareapi_default_internal_expire_date', 'no') === 'yes';
1751
-	}
1752
-
1753
-	/**
1754
-	 * Is default expire date enforced
1755
-	 *`
1756
-	 * @return bool
1757
-	 */
1758
-	public function shareApiInternalDefaultExpireDateEnforced(): bool {
1759
-		return $this->shareApiInternalDefaultExpireDate() &&
1760
-			$this->config->getAppValue('core', 'shareapi_enforce_internal_expire_date', 'no') === 'yes';
1761
-	}
1762
-
1763
-
1764
-	/**
1765
-	 * Number of default expire days
1766
-	 * @return int
1767
-	 */
1768
-	public function shareApiInternalDefaultExpireDays(): int {
1769
-		return (int)$this->config->getAppValue('core', 'shareapi_internal_expire_after_n_days', '7');
1770
-	}
1771
-
1772
-	/**
1773
-	 * Allow public upload on link shares
1774
-	 *
1775
-	 * @return bool
1776
-	 */
1777
-	public function shareApiLinkAllowPublicUpload() {
1778
-		return $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') === 'yes';
1779
-	}
1780
-
1781
-	/**
1782
-	 * check if user can only share with group members
1783
-	 * @return bool
1784
-	 */
1785
-	public function shareWithGroupMembersOnly() {
1786
-		return $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
1787
-	}
1788
-
1789
-	/**
1790
-	 * Check if users can share with groups
1791
-	 * @return bool
1792
-	 */
1793
-	public function allowGroupSharing() {
1794
-		return $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes';
1795
-	}
1796
-
1797
-	public function allowEnumeration(): bool {
1798
-		return $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
1799
-	}
1800
-
1801
-	public function limitEnumerationToGroups(): bool {
1802
-		return $this->allowEnumeration() &&
1803
-			$this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
1804
-	}
1805
-
1806
-	/**
1807
-	 * Copied from \OC_Util::isSharingDisabledForUser
1808
-	 *
1809
-	 * TODO: Deprecate fuction from OC_Util
1810
-	 *
1811
-	 * @param string $userId
1812
-	 * @return bool
1813
-	 */
1814
-	public function sharingDisabledForUser($userId) {
1815
-		if ($userId === null) {
1816
-			return false;
1817
-		}
1818
-
1819
-		if (isset($this->sharingDisabledForUsersCache[$userId])) {
1820
-			return $this->sharingDisabledForUsersCache[$userId];
1821
-		}
1822
-
1823
-		if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
1824
-			$groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1825
-			$excludedGroups = json_decode($groupsList);
1826
-			if (is_null($excludedGroups)) {
1827
-				$excludedGroups = explode(',', $groupsList);
1828
-				$newValue = json_encode($excludedGroups);
1829
-				$this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
1830
-			}
1831
-			$user = $this->userManager->get($userId);
1832
-			$usersGroups = $this->groupManager->getUserGroupIds($user);
1833
-			if (!empty($usersGroups)) {
1834
-				$remainingGroups = array_diff($usersGroups, $excludedGroups);
1835
-				// if the user is only in groups which are disabled for sharing then
1836
-				// sharing is also disabled for the user
1837
-				if (empty($remainingGroups)) {
1838
-					$this->sharingDisabledForUsersCache[$userId] = true;
1839
-					return true;
1840
-				}
1841
-			}
1842
-		}
1843
-
1844
-		$this->sharingDisabledForUsersCache[$userId] = false;
1845
-		return false;
1846
-	}
1847
-
1848
-	/**
1849
-	 * @inheritdoc
1850
-	 */
1851
-	public function outgoingServer2ServerSharesAllowed() {
1852
-		return $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes';
1853
-	}
1854
-
1855
-	/**
1856
-	 * @inheritdoc
1857
-	 */
1858
-	public function outgoingServer2ServerGroupSharesAllowed() {
1859
-		return $this->config->getAppValue('files_sharing', 'outgoing_server2server_group_share_enabled', 'no') === 'yes';
1860
-	}
1861
-
1862
-	/**
1863
-	 * @inheritdoc
1864
-	 */
1865
-	public function shareProviderExists($shareType) {
1866
-		try {
1867
-			$this->factory->getProviderForType($shareType);
1868
-		} catch (ProviderException $e) {
1869
-			return false;
1870
-		}
1871
-
1872
-		return true;
1873
-	}
1874
-
1875
-	public function getAllShares(): iterable {
1876
-		$providers = $this->factory->getAllProviders();
1877
-
1878
-		foreach ($providers as $provider) {
1879
-			yield from $provider->getAllShares();
1880
-		}
1881
-	}
1457
+        if ($share->getShareType() === IShare::TYPE_LINK &&
1458
+            !$this->shareApiLinkAllowPublicUpload()) {
1459
+            $share->setPermissions($share->getPermissions() & ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE));
1460
+        }
1461
+
1462
+        return $share;
1463
+    }
1464
+
1465
+    protected function checkExpireDate($share) {
1466
+        if ($share->isExpired()) {
1467
+            $this->deleteShare($share);
1468
+            throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1469
+        }
1470
+    }
1471
+
1472
+    /**
1473
+     * Verify the password of a public share
1474
+     *
1475
+     * @param IShare $share
1476
+     * @param string $password
1477
+     * @return bool
1478
+     */
1479
+    public function checkPassword(IShare $share, $password) {
1480
+        $passwordProtected = $share->getShareType() !== IShare::TYPE_LINK
1481
+                             || $share->getShareType() !== IShare::TYPE_EMAIL
1482
+                             || $share->getShareType() !== IShare::TYPE_CIRCLE;
1483
+        if (!$passwordProtected) {
1484
+            //TODO maybe exception?
1485
+            return false;
1486
+        }
1487
+
1488
+        if ($password === null || $share->getPassword() === null) {
1489
+            return false;
1490
+        }
1491
+
1492
+        $newHash = '';
1493
+        if (!$this->hasher->verify($password, $share->getPassword(), $newHash)) {
1494
+            return false;
1495
+        }
1496
+
1497
+        if (!empty($newHash)) {
1498
+            $share->setPassword($newHash);
1499
+            $provider = $this->factory->getProviderForType($share->getShareType());
1500
+            $provider->update($share);
1501
+        }
1502
+
1503
+        return true;
1504
+    }
1505
+
1506
+    /**
1507
+     * @inheritdoc
1508
+     */
1509
+    public function userDeleted($uid) {
1510
+        $types = [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_LINK, IShare::TYPE_REMOTE, IShare::TYPE_EMAIL];
1511
+
1512
+        foreach ($types as $type) {
1513
+            try {
1514
+                $provider = $this->factory->getProviderForType($type);
1515
+            } catch (ProviderException $e) {
1516
+                continue;
1517
+            }
1518
+            $provider->userDeleted($uid, $type);
1519
+        }
1520
+    }
1521
+
1522
+    /**
1523
+     * @inheritdoc
1524
+     */
1525
+    public function groupDeleted($gid) {
1526
+        $provider = $this->factory->getProviderForType(IShare::TYPE_GROUP);
1527
+        $provider->groupDeleted($gid);
1528
+
1529
+        $excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1530
+        if ($excludedGroups === '') {
1531
+            return;
1532
+        }
1533
+
1534
+        $excludedGroups = json_decode($excludedGroups, true);
1535
+        if (json_last_error() !== JSON_ERROR_NONE) {
1536
+            return;
1537
+        }
1538
+
1539
+        $excludedGroups = array_diff($excludedGroups, [$gid]);
1540
+        $this->config->setAppValue('core', 'shareapi_exclude_groups_list', json_encode($excludedGroups));
1541
+    }
1542
+
1543
+    /**
1544
+     * @inheritdoc
1545
+     */
1546
+    public function userDeletedFromGroup($uid, $gid) {
1547
+        $provider = $this->factory->getProviderForType(IShare::TYPE_GROUP);
1548
+        $provider->userDeletedFromGroup($uid, $gid);
1549
+    }
1550
+
1551
+    /**
1552
+     * Get access list to a path. This means
1553
+     * all the users that can access a given path.
1554
+     *
1555
+     * Consider:
1556
+     * -root
1557
+     * |-folder1 (23)
1558
+     *  |-folder2 (32)
1559
+     *   |-fileA (42)
1560
+     *
1561
+     * fileA is shared with user1 and user1@server1
1562
+     * folder2 is shared with group2 (user4 is a member of group2)
1563
+     * folder1 is shared with user2 (renamed to "folder (1)") and user2@server2
1564
+     *
1565
+     * Then the access list to '/folder1/folder2/fileA' with $currentAccess is:
1566
+     * [
1567
+     *  users  => [
1568
+     *      'user1' => ['node_id' => 42, 'node_path' => '/fileA'],
1569
+     *      'user4' => ['node_id' => 32, 'node_path' => '/folder2'],
1570
+     *      'user2' => ['node_id' => 23, 'node_path' => '/folder (1)'],
1571
+     *  ],
1572
+     *  remote => [
1573
+     *      'user1@server1' => ['node_id' => 42, 'token' => 'SeCr3t'],
1574
+     *      'user2@server2' => ['node_id' => 23, 'token' => 'FooBaR'],
1575
+     *  ],
1576
+     *  public => bool
1577
+     *  mail => bool
1578
+     * ]
1579
+     *
1580
+     * The access list to '/folder1/folder2/fileA' **without** $currentAccess is:
1581
+     * [
1582
+     *  users  => ['user1', 'user2', 'user4'],
1583
+     *  remote => bool,
1584
+     *  public => bool
1585
+     *  mail => bool
1586
+     * ]
1587
+     *
1588
+     * This is required for encryption/activity
1589
+     *
1590
+     * @param \OCP\Files\Node $path
1591
+     * @param bool $recursive Should we check all parent folders as well
1592
+     * @param bool $currentAccess Ensure the recipient has access to the file (e.g. did not unshare it)
1593
+     * @return array
1594
+     */
1595
+    public function getAccessList(\OCP\Files\Node $path, $recursive = true, $currentAccess = false) {
1596
+        $owner = $path->getOwner();
1597
+
1598
+        if ($owner === null) {
1599
+            return [];
1600
+        }
1601
+
1602
+        $owner = $owner->getUID();
1603
+
1604
+        if ($currentAccess) {
1605
+            $al = ['users' => [], 'remote' => [], 'public' => false];
1606
+        } else {
1607
+            $al = ['users' => [], 'remote' => false, 'public' => false];
1608
+        }
1609
+        if (!$this->userManager->userExists($owner)) {
1610
+            return $al;
1611
+        }
1612
+
1613
+        //Get node for the owner and correct the owner in case of external storages
1614
+        $userFolder = $this->rootFolder->getUserFolder($owner);
1615
+        if ($path->getId() !== $userFolder->getId() && !$userFolder->isSubNode($path)) {
1616
+            $nodes = $userFolder->getById($path->getId());
1617
+            $path = array_shift($nodes);
1618
+            if ($path->getOwner() === null) {
1619
+                return [];
1620
+            }
1621
+            $owner = $path->getOwner()->getUID();
1622
+        }
1623
+
1624
+        $providers = $this->factory->getAllProviders();
1625
+
1626
+        /** @var Node[] $nodes */
1627
+        $nodes = [];
1628
+
1629
+
1630
+        if ($currentAccess) {
1631
+            $ownerPath = $path->getPath();
1632
+            $ownerPath = explode('/', $ownerPath, 4);
1633
+            if (count($ownerPath) < 4) {
1634
+                $ownerPath = '';
1635
+            } else {
1636
+                $ownerPath = $ownerPath[3];
1637
+            }
1638
+            $al['users'][$owner] = [
1639
+                'node_id' => $path->getId(),
1640
+                'node_path' => '/' . $ownerPath,
1641
+            ];
1642
+        } else {
1643
+            $al['users'][] = $owner;
1644
+        }
1645
+
1646
+        // Collect all the shares
1647
+        while ($path->getPath() !== $userFolder->getPath()) {
1648
+            $nodes[] = $path;
1649
+            if (!$recursive) {
1650
+                break;
1651
+            }
1652
+            $path = $path->getParent();
1653
+        }
1654
+
1655
+        foreach ($providers as $provider) {
1656
+            $tmp = $provider->getAccessList($nodes, $currentAccess);
1657
+
1658
+            foreach ($tmp as $k => $v) {
1659
+                if (isset($al[$k])) {
1660
+                    if (is_array($al[$k])) {
1661
+                        if ($currentAccess) {
1662
+                            $al[$k] += $v;
1663
+                        } else {
1664
+                            $al[$k] = array_merge($al[$k], $v);
1665
+                            $al[$k] = array_unique($al[$k]);
1666
+                            $al[$k] = array_values($al[$k]);
1667
+                        }
1668
+                    } else {
1669
+                        $al[$k] = $al[$k] || $v;
1670
+                    }
1671
+                } else {
1672
+                    $al[$k] = $v;
1673
+                }
1674
+            }
1675
+        }
1676
+
1677
+        return $al;
1678
+    }
1679
+
1680
+    /**
1681
+     * Create a new share
1682
+     *
1683
+     * @return IShare
1684
+     */
1685
+    public function newShare() {
1686
+        return new \OC\Share20\Share($this->rootFolder, $this->userManager);
1687
+    }
1688
+
1689
+    /**
1690
+     * Is the share API enabled
1691
+     *
1692
+     * @return bool
1693
+     */
1694
+    public function shareApiEnabled() {
1695
+        return $this->config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes';
1696
+    }
1697
+
1698
+    /**
1699
+     * Is public link sharing enabled
1700
+     *
1701
+     * @return bool
1702
+     */
1703
+    public function shareApiAllowLinks() {
1704
+        return $this->config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes';
1705
+    }
1706
+
1707
+    /**
1708
+     * Is password on public link requires
1709
+     *
1710
+     * @return bool
1711
+     */
1712
+    public function shareApiLinkEnforcePassword() {
1713
+        return $this->config->getAppValue('core', 'shareapi_enforce_links_password', 'no') === 'yes';
1714
+    }
1715
+
1716
+    /**
1717
+     * Is default link expire date enabled
1718
+     *
1719
+     * @return bool
1720
+     */
1721
+    public function shareApiLinkDefaultExpireDate() {
1722
+        return $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes';
1723
+    }
1724
+
1725
+    /**
1726
+     * Is default link expire date enforced
1727
+     *`
1728
+     * @return bool
1729
+     */
1730
+    public function shareApiLinkDefaultExpireDateEnforced() {
1731
+        return $this->shareApiLinkDefaultExpireDate() &&
1732
+            $this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes';
1733
+    }
1734
+
1735
+
1736
+    /**
1737
+     * Number of default link expire days
1738
+     * @return int
1739
+     */
1740
+    public function shareApiLinkDefaultExpireDays() {
1741
+        return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1742
+    }
1743
+
1744
+    /**
1745
+     * Is default internal expire date enabled
1746
+     *
1747
+     * @return bool
1748
+     */
1749
+    public function shareApiInternalDefaultExpireDate(): bool {
1750
+        return $this->config->getAppValue('core', 'shareapi_default_internal_expire_date', 'no') === 'yes';
1751
+    }
1752
+
1753
+    /**
1754
+     * Is default expire date enforced
1755
+     *`
1756
+     * @return bool
1757
+     */
1758
+    public function shareApiInternalDefaultExpireDateEnforced(): bool {
1759
+        return $this->shareApiInternalDefaultExpireDate() &&
1760
+            $this->config->getAppValue('core', 'shareapi_enforce_internal_expire_date', 'no') === 'yes';
1761
+    }
1762
+
1763
+
1764
+    /**
1765
+     * Number of default expire days
1766
+     * @return int
1767
+     */
1768
+    public function shareApiInternalDefaultExpireDays(): int {
1769
+        return (int)$this->config->getAppValue('core', 'shareapi_internal_expire_after_n_days', '7');
1770
+    }
1771
+
1772
+    /**
1773
+     * Allow public upload on link shares
1774
+     *
1775
+     * @return bool
1776
+     */
1777
+    public function shareApiLinkAllowPublicUpload() {
1778
+        return $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') === 'yes';
1779
+    }
1780
+
1781
+    /**
1782
+     * check if user can only share with group members
1783
+     * @return bool
1784
+     */
1785
+    public function shareWithGroupMembersOnly() {
1786
+        return $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
1787
+    }
1788
+
1789
+    /**
1790
+     * Check if users can share with groups
1791
+     * @return bool
1792
+     */
1793
+    public function allowGroupSharing() {
1794
+        return $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes';
1795
+    }
1796
+
1797
+    public function allowEnumeration(): bool {
1798
+        return $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
1799
+    }
1800
+
1801
+    public function limitEnumerationToGroups(): bool {
1802
+        return $this->allowEnumeration() &&
1803
+            $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
1804
+    }
1805
+
1806
+    /**
1807
+     * Copied from \OC_Util::isSharingDisabledForUser
1808
+     *
1809
+     * TODO: Deprecate fuction from OC_Util
1810
+     *
1811
+     * @param string $userId
1812
+     * @return bool
1813
+     */
1814
+    public function sharingDisabledForUser($userId) {
1815
+        if ($userId === null) {
1816
+            return false;
1817
+        }
1818
+
1819
+        if (isset($this->sharingDisabledForUsersCache[$userId])) {
1820
+            return $this->sharingDisabledForUsersCache[$userId];
1821
+        }
1822
+
1823
+        if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
1824
+            $groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1825
+            $excludedGroups = json_decode($groupsList);
1826
+            if (is_null($excludedGroups)) {
1827
+                $excludedGroups = explode(',', $groupsList);
1828
+                $newValue = json_encode($excludedGroups);
1829
+                $this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
1830
+            }
1831
+            $user = $this->userManager->get($userId);
1832
+            $usersGroups = $this->groupManager->getUserGroupIds($user);
1833
+            if (!empty($usersGroups)) {
1834
+                $remainingGroups = array_diff($usersGroups, $excludedGroups);
1835
+                // if the user is only in groups which are disabled for sharing then
1836
+                // sharing is also disabled for the user
1837
+                if (empty($remainingGroups)) {
1838
+                    $this->sharingDisabledForUsersCache[$userId] = true;
1839
+                    return true;
1840
+                }
1841
+            }
1842
+        }
1843
+
1844
+        $this->sharingDisabledForUsersCache[$userId] = false;
1845
+        return false;
1846
+    }
1847
+
1848
+    /**
1849
+     * @inheritdoc
1850
+     */
1851
+    public function outgoingServer2ServerSharesAllowed() {
1852
+        return $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes';
1853
+    }
1854
+
1855
+    /**
1856
+     * @inheritdoc
1857
+     */
1858
+    public function outgoingServer2ServerGroupSharesAllowed() {
1859
+        return $this->config->getAppValue('files_sharing', 'outgoing_server2server_group_share_enabled', 'no') === 'yes';
1860
+    }
1861
+
1862
+    /**
1863
+     * @inheritdoc
1864
+     */
1865
+    public function shareProviderExists($shareType) {
1866
+        try {
1867
+            $this->factory->getProviderForType($shareType);
1868
+        } catch (ProviderException $e) {
1869
+            return false;
1870
+        }
1871
+
1872
+        return true;
1873
+    }
1874
+
1875
+    public function getAllShares(): iterable {
1876
+        $providers = $this->factory->getAllProviders();
1877
+
1878
+        foreach ($providers as $provider) {
1879
+            yield from $provider->getAllShares();
1880
+        }
1881
+    }
1882 1882
 }
Please login to merge, or discard this patch.
Spacing   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -392,9 +392,9 @@  discard block
 block discarded – undo
392 392
 
393 393
 		if ($fullId === null && $expirationDate === null && $this->shareApiInternalDefaultExpireDate()) {
394 394
 			$expirationDate = new \DateTime();
395
-			$expirationDate->setTime(0,0,0);
395
+			$expirationDate->setTime(0, 0, 0);
396 396
 
397
-			$days = (int)$this->config->getAppValue('core', 'internal_defaultExpDays', $this->shareApiLinkDefaultExpireDays());
397
+			$days = (int) $this->config->getAppValue('core', 'internal_defaultExpDays', $this->shareApiLinkDefaultExpireDays());
398 398
 			if ($days > $this->shareApiLinkDefaultExpireDays()) {
399 399
 				$days = $this->shareApiLinkDefaultExpireDays();
400 400
 			}
@@ -409,7 +409,7 @@  discard block
 block discarded – undo
409 409
 
410 410
 			$date = new \DateTime();
411 411
 			$date->setTime(0, 0, 0);
412
-			$date->add(new \DateInterval('P' . $this->shareApiInternalDefaultExpireDays() . 'D'));
412
+			$date->add(new \DateInterval('P'.$this->shareApiInternalDefaultExpireDays().'D'));
413 413
 			if ($date < $expirationDate) {
414 414
 				$message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiInternalDefaultExpireDays()]);
415 415
 				throw new GenericShareException($message, $message, 404);
@@ -468,9 +468,9 @@  discard block
 block discarded – undo
468 468
 
469 469
 		if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
470 470
 			$expirationDate = new \DateTime();
471
-			$expirationDate->setTime(0,0,0);
471
+			$expirationDate->setTime(0, 0, 0);
472 472
 
473
-			$days = (int)$this->config->getAppValue('core', 'link_defaultExpDays', $this->shareApiLinkDefaultExpireDays());
473
+			$days = (int) $this->config->getAppValue('core', 'link_defaultExpDays', $this->shareApiLinkDefaultExpireDays());
474 474
 			if ($days > $this->shareApiLinkDefaultExpireDays()) {
475 475
 				$days = $this->shareApiLinkDefaultExpireDays();
476 476
 			}
@@ -485,7 +485,7 @@  discard block
 block discarded – undo
485 485
 
486 486
 			$date = new \DateTime();
487 487
 			$date->setTime(0, 0, 0);
488
-			$date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
488
+			$date->add(new \DateInterval('P'.$this->shareApiLinkDefaultExpireDays().'D'));
489 489
 			if ($date < $expirationDate) {
490 490
 				$message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
491 491
 				throw new GenericShareException($message, $message, 404);
@@ -770,7 +770,7 @@  discard block
 block discarded – undo
770 770
 		}
771 771
 
772 772
 		// Generate the target
773
-		$target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName();
773
+		$target = $this->config->getSystemValue('share_folder', '/').'/'.$share->getNode()->getName();
774 774
 		$target = \OC\Files\Filesystem::normalizePath($target);
775 775
 		$share->setTarget($target);
776 776
 
@@ -815,12 +815,12 @@  discard block
 block discarded – undo
815 815
 							$emailAddress,
816 816
 							$share->getExpirationDate()
817 817
 						);
818
-						$this->logger->debug('Sent share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
818
+						$this->logger->debug('Sent share notification to '.$emailAddress.' for share with ID '.$share->getId(), ['app' => 'share']);
819 819
 					} else {
820
-						$this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
820
+						$this->logger->debug('Share notification not sent to '.$share->getSharedWith().' because email address is not set.', ['app' => 'share']);
821 821
 					}
822 822
 				} else {
823
-					$this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
823
+					$this->logger->debug('Share notification not sent to '.$share->getSharedWith().' because user could not be found.', ['app' => 'share']);
824 824
 				}
825 825
 			} else {
826 826
 				$this->logger->debug('Share notification not sent because mailsend is false.', ['app' => 'share']);
@@ -867,7 +867,7 @@  discard block
 block discarded – undo
867 867
 		$text = $l->t('%1$s shared »%2$s« with you.', [$initiatorDisplayName, $filename]);
868 868
 
869 869
 		$emailTemplate->addBodyText(
870
-			htmlspecialchars($text . ' ' . $l->t('Click the button below to open it.')),
870
+			htmlspecialchars($text.' '.$l->t('Click the button below to open it.')),
871 871
 			$text
872 872
 		);
873 873
 		$emailTemplate->addBodyButton(
@@ -893,7 +893,7 @@  discard block
 block discarded – undo
893 893
 		$initiatorEmail = $initiatorUser->getEMailAddress();
894 894
 		if ($initiatorEmail !== null) {
895 895
 			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
896
-			$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan($l->getLanguageCode()) !== '' ? ' - ' . $this->defaults->getSlogan($l->getLanguageCode()) : ''));
896
+			$emailTemplate->addFooter($instanceName.($this->defaults->getSlogan($l->getLanguageCode()) !== '' ? ' - '.$this->defaults->getSlogan($l->getLanguageCode()) : ''));
897 897
 		} else {
898 898
 			$emailTemplate->addFooter('', $l->getLanguageCode());
899 899
 		}
@@ -902,7 +902,7 @@  discard block
 block discarded – undo
902 902
 		try {
903 903
 			$failedRecipients = $this->mailer->send($message);
904 904
 			if (!empty($failedRecipients)) {
905
-				$this->logger->error('Share notification mail could not be sent to: ' . implode(', ', $failedRecipients));
905
+				$this->logger->error('Share notification mail could not be sent to: '.implode(', ', $failedRecipients));
906 906
 				return;
907 907
 			}
908 908
 		} catch (\Exception $e) {
@@ -1171,7 +1171,7 @@  discard block
 block discarded – undo
1171 1171
 	 * @param string $recipientId
1172 1172
 	 */
1173 1173
 	public function deleteFromSelf(IShare $share, $recipientId) {
1174
-		list($providerId, ) = $this->splitFullId($share->getFullId());
1174
+		list($providerId,) = $this->splitFullId($share->getFullId());
1175 1175
 		$provider = $this->factory->getProvider($providerId);
1176 1176
 
1177 1177
 		$provider->deleteFromSelf($share, $recipientId);
@@ -1180,7 +1180,7 @@  discard block
 block discarded – undo
1180 1180
 	}
1181 1181
 
1182 1182
 	public function restoreShare(IShare $share, string $recipientId): IShare {
1183
-		list($providerId, ) = $this->splitFullId($share->getFullId());
1183
+		list($providerId,) = $this->splitFullId($share->getFullId());
1184 1184
 		$provider = $this->factory->getProvider($providerId);
1185 1185
 
1186 1186
 		return $provider->restore($share, $recipientId);
@@ -1201,7 +1201,7 @@  discard block
 block discarded – undo
1201 1201
 		if ($share->getShareType() === IShare::TYPE_GROUP) {
1202 1202
 			$sharedWith = $this->groupManager->get($share->getSharedWith());
1203 1203
 			if (is_null($sharedWith)) {
1204
-				throw new \InvalidArgumentException('Group "' . $share->getSharedWith() . '" does not exist');
1204
+				throw new \InvalidArgumentException('Group "'.$share->getSharedWith().'" does not exist');
1205 1205
 			}
1206 1206
 			$recipient = $this->userManager->get($recipientId);
1207 1207
 			if (!$sharedWith->inGroup($recipient)) {
@@ -1209,7 +1209,7 @@  discard block
 block discarded – undo
1209 1209
 			}
1210 1210
 		}
1211 1211
 
1212
-		list($providerId, ) = $this->splitFullId($share->getFullId());
1212
+		list($providerId,) = $this->splitFullId($share->getFullId());
1213 1213
 		$provider = $this->factory->getProvider($providerId);
1214 1214
 
1215 1215
 		$provider->move($share, $recipientId);
@@ -1218,7 +1218,7 @@  discard block
 block discarded – undo
1218 1218
 	public function getSharesInFolder($userId, Folder $node, $reshares = false) {
1219 1219
 		$providers = $this->factory->getAllProviders();
1220 1220
 
1221
-		return array_reduce($providers, function ($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
1221
+		return array_reduce($providers, function($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
1222 1222
 			$newShares = $provider->getSharesInFolder($userId, $node, $reshares);
1223 1223
 			foreach ($newShares as $fid => $data) {
1224 1224
 				if (!isset($shares[$fid])) {
@@ -1335,12 +1335,12 @@  discard block
 block discarded – undo
1335 1335
 		$shares = $this->getSharedWith($userId, $shareType, $node, $limit, $offset);
1336 1336
 
1337 1337
 		// Only get deleted shares
1338
-		$shares = array_filter($shares, function (IShare $share) {
1338
+		$shares = array_filter($shares, function(IShare $share) {
1339 1339
 			return $share->getPermissions() === 0;
1340 1340
 		});
1341 1341
 
1342 1342
 		// Only get shares where the owner still exists
1343
-		$shares = array_filter($shares, function (IShare $share) {
1343
+		$shares = array_filter($shares, function(IShare $share) {
1344 1344
 			return $this->userManager->userExists($share->getShareOwner());
1345 1345
 		});
1346 1346
 
@@ -1379,7 +1379,7 @@  discard block
 block discarded – undo
1379 1379
 	 *
1380 1380
 	 * @return Share[]
1381 1381
 	 */
1382
-	public function getSharesByPath(\OCP\Files\Node $path, $page=0, $perPage=50) {
1382
+	public function getSharesByPath(\OCP\Files\Node $path, $page = 0, $perPage = 50) {
1383 1383
 		return [];
1384 1384
 	}
1385 1385
 
@@ -1637,7 +1637,7 @@  discard block
 block discarded – undo
1637 1637
 			}
1638 1638
 			$al['users'][$owner] = [
1639 1639
 				'node_id' => $path->getId(),
1640
-				'node_path' => '/' . $ownerPath,
1640
+				'node_path' => '/'.$ownerPath,
1641 1641
 			];
1642 1642
 		} else {
1643 1643
 			$al['users'][] = $owner;
@@ -1738,7 +1738,7 @@  discard block
 block discarded – undo
1738 1738
 	 * @return int
1739 1739
 	 */
1740 1740
 	public function shareApiLinkDefaultExpireDays() {
1741
-		return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1741
+		return (int) $this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1742 1742
 	}
1743 1743
 
1744 1744
 	/**
@@ -1766,7 +1766,7 @@  discard block
 block discarded – undo
1766 1766
 	 * @return int
1767 1767
 	 */
1768 1768
 	public function shareApiInternalDefaultExpireDays(): int {
1769
-		return (int)$this->config->getAppValue('core', 'shareapi_internal_expire_after_n_days', '7');
1769
+		return (int) $this->config->getAppValue('core', 'shareapi_internal_expire_after_n_days', '7');
1770 1770
 	}
1771 1771
 
1772 1772
 	/**
Please login to merge, or discard this patch.
lib/private/Share20/DefaultShareProvider.php 2 patches
Indentation   +1399 added lines, -1399 removed lines patch added patch discarded remove patch
@@ -62,1439 +62,1439 @@
 block discarded – undo
62 62
  */
63 63
 class DefaultShareProvider implements IShareProvider {
64 64
 
65
-	// Special share type for user modified group shares
66
-	public const SHARE_TYPE_USERGROUP = 2;
67
-
68
-	/** @var IDBConnection */
69
-	private $dbConn;
70
-
71
-	/** @var IUserManager */
72
-	private $userManager;
73
-
74
-	/** @var IGroupManager */
75
-	private $groupManager;
76
-
77
-	/** @var IRootFolder */
78
-	private $rootFolder;
79
-
80
-	/** @var IMailer */
81
-	private $mailer;
82
-
83
-	/** @var Defaults */
84
-	private $defaults;
85
-
86
-	/** @var IFactory */
87
-	private $l10nFactory;
88
-
89
-	/** @var IURLGenerator */
90
-	private $urlGenerator;
91
-
92
-	/** @var IConfig */
93
-	private $config;
94
-
95
-	public function __construct(
96
-			IDBConnection $connection,
97
-			IUserManager $userManager,
98
-			IGroupManager $groupManager,
99
-			IRootFolder $rootFolder,
100
-			IMailer $mailer,
101
-			Defaults $defaults,
102
-			IFactory $l10nFactory,
103
-			IURLGenerator $urlGenerator,
104
-			IConfig $config) {
105
-		$this->dbConn = $connection;
106
-		$this->userManager = $userManager;
107
-		$this->groupManager = $groupManager;
108
-		$this->rootFolder = $rootFolder;
109
-		$this->mailer = $mailer;
110
-		$this->defaults = $defaults;
111
-		$this->l10nFactory = $l10nFactory;
112
-		$this->urlGenerator = $urlGenerator;
113
-		$this->config = $config;
114
-	}
115
-
116
-	/**
117
-	 * Return the identifier of this provider.
118
-	 *
119
-	 * @return string Containing only [a-zA-Z0-9]
120
-	 */
121
-	public function identifier() {
122
-		return 'ocinternal';
123
-	}
124
-
125
-	/**
126
-	 * Share a path
127
-	 *
128
-	 * @param \OCP\Share\IShare $share
129
-	 * @return \OCP\Share\IShare The share object
130
-	 * @throws ShareNotFound
131
-	 * @throws \Exception
132
-	 */
133
-	public function create(\OCP\Share\IShare $share) {
134
-		$qb = $this->dbConn->getQueryBuilder();
135
-
136
-		$qb->insert('share');
137
-		$qb->setValue('share_type', $qb->createNamedParameter($share->getShareType()));
138
-
139
-		if ($share->getShareType() === IShare::TYPE_USER) {
140
-			//Set the UID of the user we share with
141
-			$qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
142
-			$qb->setValue('accepted', $qb->createNamedParameter(IShare::STATUS_PENDING));
143
-
144
-			//If an expiration date is set store it
145
-			if ($share->getExpirationDate() !== null) {
146
-				$qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
147
-			}
148
-		} elseif ($share->getShareType() === IShare::TYPE_GROUP) {
149
-			//Set the GID of the group we share with
150
-			$qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
151
-
152
-			//If an expiration date is set store it
153
-			if ($share->getExpirationDate() !== null) {
154
-				$qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
155
-			}
156
-		} elseif ($share->getShareType() === IShare::TYPE_LINK) {
157
-			//set label for public link
158
-			$qb->setValue('label', $qb->createNamedParameter($share->getLabel()));
159
-			//Set the token of the share
160
-			$qb->setValue('token', $qb->createNamedParameter($share->getToken()));
161
-
162
-			//If a password is set store it
163
-			if ($share->getPassword() !== null) {
164
-				$qb->setValue('password', $qb->createNamedParameter($share->getPassword()));
165
-			}
166
-
167
-			$qb->setValue('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL));
168
-
169
-			//If an expiration date is set store it
170
-			if ($share->getExpirationDate() !== null) {
171
-				$qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
172
-			}
173
-
174
-			if (method_exists($share, 'getParent')) {
175
-				$qb->setValue('parent', $qb->createNamedParameter($share->getParent()));
176
-			}
177
-		} else {
178
-			throw new \Exception('invalid share type!');
179
-		}
180
-
181
-		// Set what is shares
182
-		$qb->setValue('item_type', $qb->createParameter('itemType'));
183
-		if ($share->getNode() instanceof \OCP\Files\File) {
184
-			$qb->setParameter('itemType', 'file');
185
-		} else {
186
-			$qb->setParameter('itemType', 'folder');
187
-		}
188
-
189
-		// Set the file id
190
-		$qb->setValue('item_source', $qb->createNamedParameter($share->getNode()->getId()));
191
-		$qb->setValue('file_source', $qb->createNamedParameter($share->getNode()->getId()));
192
-
193
-		// set the permissions
194
-		$qb->setValue('permissions', $qb->createNamedParameter($share->getPermissions()));
195
-
196
-		// Set who created this share
197
-		$qb->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()));
198
-
199
-		// Set who is the owner of this file/folder (and this the owner of the share)
200
-		$qb->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()));
201
-
202
-		// Set the file target
203
-		$qb->setValue('file_target', $qb->createNamedParameter($share->getTarget()));
204
-
205
-		// Set the time this share was created
206
-		$qb->setValue('stime', $qb->createNamedParameter(time()));
207
-
208
-		// insert the data and fetch the id of the share
209
-		$this->dbConn->beginTransaction();
210
-		$qb->execute();
211
-		$id = $this->dbConn->lastInsertId('*PREFIX*share');
212
-
213
-		// Now fetch the inserted share and create a complete share object
214
-		$qb = $this->dbConn->getQueryBuilder();
215
-		$qb->select('*')
216
-			->from('share')
217
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
218
-
219
-		$cursor = $qb->execute();
220
-		$data = $cursor->fetch();
221
-		$this->dbConn->commit();
222
-		$cursor->closeCursor();
223
-
224
-		if ($data === false) {
225
-			throw new ShareNotFound();
226
-		}
227
-
228
-		$mailSendValue = $share->getMailSend();
229
-		$data['mail_send'] = ($mailSendValue === null) ? true : $mailSendValue;
230
-
231
-		$share = $this->createShare($data);
232
-		return $share;
233
-	}
234
-
235
-	/**
236
-	 * Update a share
237
-	 *
238
-	 * @param \OCP\Share\IShare $share
239
-	 * @return \OCP\Share\IShare The share object
240
-	 * @throws ShareNotFound
241
-	 * @throws \OCP\Files\InvalidPathException
242
-	 * @throws \OCP\Files\NotFoundException
243
-	 */
244
-	public function update(\OCP\Share\IShare $share) {
245
-		$originalShare = $this->getShareById($share->getId());
246
-
247
-		if ($share->getShareType() === IShare::TYPE_USER) {
248
-			/*
65
+    // Special share type for user modified group shares
66
+    public const SHARE_TYPE_USERGROUP = 2;
67
+
68
+    /** @var IDBConnection */
69
+    private $dbConn;
70
+
71
+    /** @var IUserManager */
72
+    private $userManager;
73
+
74
+    /** @var IGroupManager */
75
+    private $groupManager;
76
+
77
+    /** @var IRootFolder */
78
+    private $rootFolder;
79
+
80
+    /** @var IMailer */
81
+    private $mailer;
82
+
83
+    /** @var Defaults */
84
+    private $defaults;
85
+
86
+    /** @var IFactory */
87
+    private $l10nFactory;
88
+
89
+    /** @var IURLGenerator */
90
+    private $urlGenerator;
91
+
92
+    /** @var IConfig */
93
+    private $config;
94
+
95
+    public function __construct(
96
+            IDBConnection $connection,
97
+            IUserManager $userManager,
98
+            IGroupManager $groupManager,
99
+            IRootFolder $rootFolder,
100
+            IMailer $mailer,
101
+            Defaults $defaults,
102
+            IFactory $l10nFactory,
103
+            IURLGenerator $urlGenerator,
104
+            IConfig $config) {
105
+        $this->dbConn = $connection;
106
+        $this->userManager = $userManager;
107
+        $this->groupManager = $groupManager;
108
+        $this->rootFolder = $rootFolder;
109
+        $this->mailer = $mailer;
110
+        $this->defaults = $defaults;
111
+        $this->l10nFactory = $l10nFactory;
112
+        $this->urlGenerator = $urlGenerator;
113
+        $this->config = $config;
114
+    }
115
+
116
+    /**
117
+     * Return the identifier of this provider.
118
+     *
119
+     * @return string Containing only [a-zA-Z0-9]
120
+     */
121
+    public function identifier() {
122
+        return 'ocinternal';
123
+    }
124
+
125
+    /**
126
+     * Share a path
127
+     *
128
+     * @param \OCP\Share\IShare $share
129
+     * @return \OCP\Share\IShare The share object
130
+     * @throws ShareNotFound
131
+     * @throws \Exception
132
+     */
133
+    public function create(\OCP\Share\IShare $share) {
134
+        $qb = $this->dbConn->getQueryBuilder();
135
+
136
+        $qb->insert('share');
137
+        $qb->setValue('share_type', $qb->createNamedParameter($share->getShareType()));
138
+
139
+        if ($share->getShareType() === IShare::TYPE_USER) {
140
+            //Set the UID of the user we share with
141
+            $qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
142
+            $qb->setValue('accepted', $qb->createNamedParameter(IShare::STATUS_PENDING));
143
+
144
+            //If an expiration date is set store it
145
+            if ($share->getExpirationDate() !== null) {
146
+                $qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
147
+            }
148
+        } elseif ($share->getShareType() === IShare::TYPE_GROUP) {
149
+            //Set the GID of the group we share with
150
+            $qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
151
+
152
+            //If an expiration date is set store it
153
+            if ($share->getExpirationDate() !== null) {
154
+                $qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
155
+            }
156
+        } elseif ($share->getShareType() === IShare::TYPE_LINK) {
157
+            //set label for public link
158
+            $qb->setValue('label', $qb->createNamedParameter($share->getLabel()));
159
+            //Set the token of the share
160
+            $qb->setValue('token', $qb->createNamedParameter($share->getToken()));
161
+
162
+            //If a password is set store it
163
+            if ($share->getPassword() !== null) {
164
+                $qb->setValue('password', $qb->createNamedParameter($share->getPassword()));
165
+            }
166
+
167
+            $qb->setValue('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL));
168
+
169
+            //If an expiration date is set store it
170
+            if ($share->getExpirationDate() !== null) {
171
+                $qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
172
+            }
173
+
174
+            if (method_exists($share, 'getParent')) {
175
+                $qb->setValue('parent', $qb->createNamedParameter($share->getParent()));
176
+            }
177
+        } else {
178
+            throw new \Exception('invalid share type!');
179
+        }
180
+
181
+        // Set what is shares
182
+        $qb->setValue('item_type', $qb->createParameter('itemType'));
183
+        if ($share->getNode() instanceof \OCP\Files\File) {
184
+            $qb->setParameter('itemType', 'file');
185
+        } else {
186
+            $qb->setParameter('itemType', 'folder');
187
+        }
188
+
189
+        // Set the file id
190
+        $qb->setValue('item_source', $qb->createNamedParameter($share->getNode()->getId()));
191
+        $qb->setValue('file_source', $qb->createNamedParameter($share->getNode()->getId()));
192
+
193
+        // set the permissions
194
+        $qb->setValue('permissions', $qb->createNamedParameter($share->getPermissions()));
195
+
196
+        // Set who created this share
197
+        $qb->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()));
198
+
199
+        // Set who is the owner of this file/folder (and this the owner of the share)
200
+        $qb->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()));
201
+
202
+        // Set the file target
203
+        $qb->setValue('file_target', $qb->createNamedParameter($share->getTarget()));
204
+
205
+        // Set the time this share was created
206
+        $qb->setValue('stime', $qb->createNamedParameter(time()));
207
+
208
+        // insert the data and fetch the id of the share
209
+        $this->dbConn->beginTransaction();
210
+        $qb->execute();
211
+        $id = $this->dbConn->lastInsertId('*PREFIX*share');
212
+
213
+        // Now fetch the inserted share and create a complete share object
214
+        $qb = $this->dbConn->getQueryBuilder();
215
+        $qb->select('*')
216
+            ->from('share')
217
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
218
+
219
+        $cursor = $qb->execute();
220
+        $data = $cursor->fetch();
221
+        $this->dbConn->commit();
222
+        $cursor->closeCursor();
223
+
224
+        if ($data === false) {
225
+            throw new ShareNotFound();
226
+        }
227
+
228
+        $mailSendValue = $share->getMailSend();
229
+        $data['mail_send'] = ($mailSendValue === null) ? true : $mailSendValue;
230
+
231
+        $share = $this->createShare($data);
232
+        return $share;
233
+    }
234
+
235
+    /**
236
+     * Update a share
237
+     *
238
+     * @param \OCP\Share\IShare $share
239
+     * @return \OCP\Share\IShare The share object
240
+     * @throws ShareNotFound
241
+     * @throws \OCP\Files\InvalidPathException
242
+     * @throws \OCP\Files\NotFoundException
243
+     */
244
+    public function update(\OCP\Share\IShare $share) {
245
+        $originalShare = $this->getShareById($share->getId());
246
+
247
+        if ($share->getShareType() === IShare::TYPE_USER) {
248
+            /*
249 249
 			 * We allow updating the recipient on user shares.
250 250
 			 */
251
-			$qb = $this->dbConn->getQueryBuilder();
252
-			$qb->update('share')
253
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
254
-				->set('share_with', $qb->createNamedParameter($share->getSharedWith()))
255
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
256
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
257
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
258
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
259
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
260
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
261
-				->set('note', $qb->createNamedParameter($share->getNote()))
262
-				->set('accepted', $qb->createNamedParameter($share->getStatus()))
263
-				->execute();
264
-		} elseif ($share->getShareType() === IShare::TYPE_GROUP) {
265
-			$qb = $this->dbConn->getQueryBuilder();
266
-			$qb->update('share')
267
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
268
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
269
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
270
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
271
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
272
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
273
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
274
-				->set('note', $qb->createNamedParameter($share->getNote()))
275
-				->execute();
276
-
277
-			/*
251
+            $qb = $this->dbConn->getQueryBuilder();
252
+            $qb->update('share')
253
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
254
+                ->set('share_with', $qb->createNamedParameter($share->getSharedWith()))
255
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
256
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
257
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
258
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
259
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
260
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
261
+                ->set('note', $qb->createNamedParameter($share->getNote()))
262
+                ->set('accepted', $qb->createNamedParameter($share->getStatus()))
263
+                ->execute();
264
+        } elseif ($share->getShareType() === IShare::TYPE_GROUP) {
265
+            $qb = $this->dbConn->getQueryBuilder();
266
+            $qb->update('share')
267
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
268
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
269
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
270
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
271
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
272
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
273
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
274
+                ->set('note', $qb->createNamedParameter($share->getNote()))
275
+                ->execute();
276
+
277
+            /*
278 278
 			 * Update all user defined group shares
279 279
 			 */
280
-			$qb = $this->dbConn->getQueryBuilder();
281
-			$qb->update('share')
282
-				->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
283
-				->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
284
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
285
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
286
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
287
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
288
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
289
-				->set('note', $qb->createNamedParameter($share->getNote()))
290
-				->execute();
291
-
292
-			/*
280
+            $qb = $this->dbConn->getQueryBuilder();
281
+            $qb->update('share')
282
+                ->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
283
+                ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
284
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
285
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
286
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
287
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
288
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
289
+                ->set('note', $qb->createNamedParameter($share->getNote()))
290
+                ->execute();
291
+
292
+            /*
293 293
 			 * Now update the permissions for all children that have not set it to 0
294 294
 			 */
295
-			$qb = $this->dbConn->getQueryBuilder();
296
-			$qb->update('share')
297
-				->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
298
-				->andWhere($qb->expr()->neq('permissions', $qb->createNamedParameter(0)))
299
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
300
-				->execute();
301
-		} elseif ($share->getShareType() === IShare::TYPE_LINK) {
302
-			$qb = $this->dbConn->getQueryBuilder();
303
-			$qb->update('share')
304
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
305
-				->set('password', $qb->createNamedParameter($share->getPassword()))
306
-				->set('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL))
307
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
308
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
309
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
310
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
311
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
312
-				->set('token', $qb->createNamedParameter($share->getToken()))
313
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
314
-				->set('note', $qb->createNamedParameter($share->getNote()))
315
-				->set('label', $qb->createNamedParameter($share->getLabel()))
316
-				->set('hide_download', $qb->createNamedParameter($share->getHideDownload() ? 1 : 0), IQueryBuilder::PARAM_INT)
317
-				->execute();
318
-		}
319
-
320
-		if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
321
-			$this->propagateNote($share);
322
-		}
323
-
324
-
325
-		return $share;
326
-	}
327
-
328
-	/**
329
-	 * Accept a share.
330
-	 *
331
-	 * @param IShare $share
332
-	 * @param string $recipient
333
-	 * @return IShare The share object
334
-	 * @since 9.0.0
335
-	 */
336
-	public function acceptShare(IShare $share, string $recipient): IShare {
337
-		if ($share->getShareType() === IShare::TYPE_GROUP) {
338
-			$group = $this->groupManager->get($share->getSharedWith());
339
-			$user = $this->userManager->get($recipient);
340
-
341
-			if (is_null($group)) {
342
-				throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
343
-			}
344
-
345
-			if (!$group->inGroup($user)) {
346
-				throw new ProviderException('Recipient not in receiving group');
347
-			}
348
-
349
-			// Try to fetch user specific share
350
-			$qb = $this->dbConn->getQueryBuilder();
351
-			$stmt = $qb->select('*')
352
-				->from('share')
353
-				->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
354
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
355
-				->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
356
-				->andWhere($qb->expr()->orX(
357
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
358
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
359
-				))
360
-				->execute();
361
-
362
-			$data = $stmt->fetch();
363
-			$stmt->closeCursor();
364
-
365
-			/*
295
+            $qb = $this->dbConn->getQueryBuilder();
296
+            $qb->update('share')
297
+                ->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
298
+                ->andWhere($qb->expr()->neq('permissions', $qb->createNamedParameter(0)))
299
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
300
+                ->execute();
301
+        } elseif ($share->getShareType() === IShare::TYPE_LINK) {
302
+            $qb = $this->dbConn->getQueryBuilder();
303
+            $qb->update('share')
304
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
305
+                ->set('password', $qb->createNamedParameter($share->getPassword()))
306
+                ->set('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL))
307
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
308
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
309
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
310
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
311
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
312
+                ->set('token', $qb->createNamedParameter($share->getToken()))
313
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
314
+                ->set('note', $qb->createNamedParameter($share->getNote()))
315
+                ->set('label', $qb->createNamedParameter($share->getLabel()))
316
+                ->set('hide_download', $qb->createNamedParameter($share->getHideDownload() ? 1 : 0), IQueryBuilder::PARAM_INT)
317
+                ->execute();
318
+        }
319
+
320
+        if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
321
+            $this->propagateNote($share);
322
+        }
323
+
324
+
325
+        return $share;
326
+    }
327
+
328
+    /**
329
+     * Accept a share.
330
+     *
331
+     * @param IShare $share
332
+     * @param string $recipient
333
+     * @return IShare The share object
334
+     * @since 9.0.0
335
+     */
336
+    public function acceptShare(IShare $share, string $recipient): IShare {
337
+        if ($share->getShareType() === IShare::TYPE_GROUP) {
338
+            $group = $this->groupManager->get($share->getSharedWith());
339
+            $user = $this->userManager->get($recipient);
340
+
341
+            if (is_null($group)) {
342
+                throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
343
+            }
344
+
345
+            if (!$group->inGroup($user)) {
346
+                throw new ProviderException('Recipient not in receiving group');
347
+            }
348
+
349
+            // Try to fetch user specific share
350
+            $qb = $this->dbConn->getQueryBuilder();
351
+            $stmt = $qb->select('*')
352
+                ->from('share')
353
+                ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
354
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
355
+                ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
356
+                ->andWhere($qb->expr()->orX(
357
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
358
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
359
+                ))
360
+                ->execute();
361
+
362
+            $data = $stmt->fetch();
363
+            $stmt->closeCursor();
364
+
365
+            /*
366 366
 			 * Check if there already is a user specific group share.
367 367
 			 * If there is update it (if required).
368 368
 			 */
369
-			if ($data === false) {
370
-				$id = $this->createUserSpecificGroupShare($share, $recipient);
371
-			} else {
372
-				$id = $data['id'];
373
-			}
374
-		} elseif ($share->getShareType() === IShare::TYPE_USER) {
375
-			if ($share->getSharedWith() !== $recipient) {
376
-				throw new ProviderException('Recipient does not match');
377
-			}
378
-
379
-			$id = $share->getId();
380
-		} else {
381
-			throw new ProviderException('Invalid shareType');
382
-		}
383
-
384
-		$qb = $this->dbConn->getQueryBuilder();
385
-		$qb->update('share')
386
-			->set('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
387
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
388
-			->execute();
389
-
390
-		return $share;
391
-	}
392
-
393
-	/**
394
-	 * Get all children of this share
395
-	 * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
396
-	 *
397
-	 * @param \OCP\Share\IShare $parent
398
-	 * @return \OCP\Share\IShare[]
399
-	 */
400
-	public function getChildren(\OCP\Share\IShare $parent) {
401
-		$children = [];
402
-
403
-		$qb = $this->dbConn->getQueryBuilder();
404
-		$qb->select('*')
405
-			->from('share')
406
-			->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
407
-			->andWhere(
408
-				$qb->expr()->in(
409
-					'share_type',
410
-					$qb->createNamedParameter([
411
-						IShare::TYPE_USER,
412
-						IShare::TYPE_GROUP,
413
-						IShare::TYPE_LINK,
414
-					], IQueryBuilder::PARAM_INT_ARRAY)
415
-				)
416
-			)
417
-			->andWhere($qb->expr()->orX(
418
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
419
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
420
-			))
421
-			->orderBy('id');
422
-
423
-		$cursor = $qb->execute();
424
-		while ($data = $cursor->fetch()) {
425
-			$children[] = $this->createShare($data);
426
-		}
427
-		$cursor->closeCursor();
428
-
429
-		return $children;
430
-	}
431
-
432
-	/**
433
-	 * Delete a share
434
-	 *
435
-	 * @param \OCP\Share\IShare $share
436
-	 */
437
-	public function delete(\OCP\Share\IShare $share) {
438
-		$qb = $this->dbConn->getQueryBuilder();
439
-		$qb->delete('share')
440
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())));
441
-
442
-		/*
369
+            if ($data === false) {
370
+                $id = $this->createUserSpecificGroupShare($share, $recipient);
371
+            } else {
372
+                $id = $data['id'];
373
+            }
374
+        } elseif ($share->getShareType() === IShare::TYPE_USER) {
375
+            if ($share->getSharedWith() !== $recipient) {
376
+                throw new ProviderException('Recipient does not match');
377
+            }
378
+
379
+            $id = $share->getId();
380
+        } else {
381
+            throw new ProviderException('Invalid shareType');
382
+        }
383
+
384
+        $qb = $this->dbConn->getQueryBuilder();
385
+        $qb->update('share')
386
+            ->set('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
387
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
388
+            ->execute();
389
+
390
+        return $share;
391
+    }
392
+
393
+    /**
394
+     * Get all children of this share
395
+     * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
396
+     *
397
+     * @param \OCP\Share\IShare $parent
398
+     * @return \OCP\Share\IShare[]
399
+     */
400
+    public function getChildren(\OCP\Share\IShare $parent) {
401
+        $children = [];
402
+
403
+        $qb = $this->dbConn->getQueryBuilder();
404
+        $qb->select('*')
405
+            ->from('share')
406
+            ->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
407
+            ->andWhere(
408
+                $qb->expr()->in(
409
+                    'share_type',
410
+                    $qb->createNamedParameter([
411
+                        IShare::TYPE_USER,
412
+                        IShare::TYPE_GROUP,
413
+                        IShare::TYPE_LINK,
414
+                    ], IQueryBuilder::PARAM_INT_ARRAY)
415
+                )
416
+            )
417
+            ->andWhere($qb->expr()->orX(
418
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
419
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
420
+            ))
421
+            ->orderBy('id');
422
+
423
+        $cursor = $qb->execute();
424
+        while ($data = $cursor->fetch()) {
425
+            $children[] = $this->createShare($data);
426
+        }
427
+        $cursor->closeCursor();
428
+
429
+        return $children;
430
+    }
431
+
432
+    /**
433
+     * Delete a share
434
+     *
435
+     * @param \OCP\Share\IShare $share
436
+     */
437
+    public function delete(\OCP\Share\IShare $share) {
438
+        $qb = $this->dbConn->getQueryBuilder();
439
+        $qb->delete('share')
440
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())));
441
+
442
+        /*
443 443
 		 * If the share is a group share delete all possible
444 444
 		 * user defined groups shares.
445 445
 		 */
446
-		if ($share->getShareType() === IShare::TYPE_GROUP) {
447
-			$qb->orWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())));
448
-		}
449
-
450
-		$qb->execute();
451
-	}
452
-
453
-	/**
454
-	 * Unshare a share from the recipient. If this is a group share
455
-	 * this means we need a special entry in the share db.
456
-	 *
457
-	 * @param IShare $share
458
-	 * @param string $recipient UserId of recipient
459
-	 * @throws BackendError
460
-	 * @throws ProviderException
461
-	 */
462
-	public function deleteFromSelf(IShare $share, $recipient) {
463
-		if ($share->getShareType() === IShare::TYPE_GROUP) {
464
-			$group = $this->groupManager->get($share->getSharedWith());
465
-			$user = $this->userManager->get($recipient);
466
-
467
-			if (is_null($group)) {
468
-				throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
469
-			}
470
-
471
-			if (!$group->inGroup($user)) {
472
-				throw new ProviderException('Recipient not in receiving group');
473
-			}
474
-
475
-			// Try to fetch user specific share
476
-			$qb = $this->dbConn->getQueryBuilder();
477
-			$stmt = $qb->select('*')
478
-				->from('share')
479
-				->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
480
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
481
-				->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
482
-				->andWhere($qb->expr()->orX(
483
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
484
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
485
-				))
486
-				->execute();
487
-
488
-			$data = $stmt->fetch();
489
-
490
-			/*
446
+        if ($share->getShareType() === IShare::TYPE_GROUP) {
447
+            $qb->orWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())));
448
+        }
449
+
450
+        $qb->execute();
451
+    }
452
+
453
+    /**
454
+     * Unshare a share from the recipient. If this is a group share
455
+     * this means we need a special entry in the share db.
456
+     *
457
+     * @param IShare $share
458
+     * @param string $recipient UserId of recipient
459
+     * @throws BackendError
460
+     * @throws ProviderException
461
+     */
462
+    public function deleteFromSelf(IShare $share, $recipient) {
463
+        if ($share->getShareType() === IShare::TYPE_GROUP) {
464
+            $group = $this->groupManager->get($share->getSharedWith());
465
+            $user = $this->userManager->get($recipient);
466
+
467
+            if (is_null($group)) {
468
+                throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
469
+            }
470
+
471
+            if (!$group->inGroup($user)) {
472
+                throw new ProviderException('Recipient not in receiving group');
473
+            }
474
+
475
+            // Try to fetch user specific share
476
+            $qb = $this->dbConn->getQueryBuilder();
477
+            $stmt = $qb->select('*')
478
+                ->from('share')
479
+                ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
480
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
481
+                ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
482
+                ->andWhere($qb->expr()->orX(
483
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
484
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
485
+                ))
486
+                ->execute();
487
+
488
+            $data = $stmt->fetch();
489
+
490
+            /*
491 491
 			 * Check if there already is a user specific group share.
492 492
 			 * If there is update it (if required).
493 493
 			 */
494
-			if ($data === false) {
495
-				$id = $this->createUserSpecificGroupShare($share, $recipient);
496
-				$permissions = $share->getPermissions();
497
-			} else {
498
-				$permissions = $data['permissions'];
499
-				$id = $data['id'];
500
-			}
501
-
502
-			if ($permissions !== 0) {
503
-				// Update existing usergroup share
504
-				$qb = $this->dbConn->getQueryBuilder();
505
-				$qb->update('share')
506
-					->set('permissions', $qb->createNamedParameter(0))
507
-					->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
508
-					->execute();
509
-			}
510
-		} elseif ($share->getShareType() === IShare::TYPE_USER) {
511
-			if ($share->getSharedWith() !== $recipient) {
512
-				throw new ProviderException('Recipient does not match');
513
-			}
514
-
515
-			// We can just delete user and link shares
516
-			$this->delete($share);
517
-		} else {
518
-			throw new ProviderException('Invalid shareType');
519
-		}
520
-	}
521
-
522
-	protected function createUserSpecificGroupShare(IShare $share, string $recipient): int {
523
-		$type = $share->getNodeType();
524
-
525
-		$qb = $this->dbConn->getQueryBuilder();
526
-		$qb->insert('share')
527
-			->values([
528
-				'share_type' => $qb->createNamedParameter(IShare::TYPE_USERGROUP),
529
-				'share_with' => $qb->createNamedParameter($recipient),
530
-				'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
531
-				'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
532
-				'parent' => $qb->createNamedParameter($share->getId()),
533
-				'item_type' => $qb->createNamedParameter($type),
534
-				'item_source' => $qb->createNamedParameter($share->getNodeId()),
535
-				'file_source' => $qb->createNamedParameter($share->getNodeId()),
536
-				'file_target' => $qb->createNamedParameter($share->getTarget()),
537
-				'permissions' => $qb->createNamedParameter($share->getPermissions()),
538
-				'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
539
-			])->execute();
540
-
541
-		return $qb->getLastInsertId();
542
-	}
543
-
544
-	/**
545
-	 * @inheritdoc
546
-	 *
547
-	 * For now this only works for group shares
548
-	 * If this gets implemented for normal shares we have to extend it
549
-	 */
550
-	public function restore(IShare $share, string $recipient): IShare {
551
-		$qb = $this->dbConn->getQueryBuilder();
552
-		$qb->select('permissions')
553
-			->from('share')
554
-			->where(
555
-				$qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))
556
-			);
557
-		$cursor = $qb->execute();
558
-		$data = $cursor->fetch();
559
-		$cursor->closeCursor();
560
-
561
-		$originalPermission = $data['permissions'];
562
-
563
-		$qb = $this->dbConn->getQueryBuilder();
564
-		$qb->update('share')
565
-			->set('permissions', $qb->createNamedParameter($originalPermission))
566
-			->where(
567
-				$qb->expr()->eq('parent', $qb->createNamedParameter($share->getParent()))
568
-			)->andWhere(
569
-				$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP))
570
-			)->andWhere(
571
-				$qb->expr()->eq('share_with', $qb->createNamedParameter($recipient))
572
-			);
573
-
574
-		$qb->execute();
575
-
576
-		return $this->getShareById($share->getId(), $recipient);
577
-	}
578
-
579
-	/**
580
-	 * @inheritdoc
581
-	 */
582
-	public function move(\OCP\Share\IShare $share, $recipient) {
583
-		if ($share->getShareType() === IShare::TYPE_USER) {
584
-			// Just update the target
585
-			$qb = $this->dbConn->getQueryBuilder();
586
-			$qb->update('share')
587
-				->set('file_target', $qb->createNamedParameter($share->getTarget()))
588
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
589
-				->execute();
590
-		} elseif ($share->getShareType() === IShare::TYPE_GROUP) {
591
-
592
-			// Check if there is a usergroup share
593
-			$qb = $this->dbConn->getQueryBuilder();
594
-			$stmt = $qb->select('id')
595
-				->from('share')
596
-				->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
597
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
598
-				->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
599
-				->andWhere($qb->expr()->orX(
600
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
601
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
602
-				))
603
-				->setMaxResults(1)
604
-				->execute();
605
-
606
-			$data = $stmt->fetch();
607
-			$stmt->closeCursor();
608
-
609
-			if ($data === false) {
610
-				// No usergroup share yet. Create one.
611
-				$qb = $this->dbConn->getQueryBuilder();
612
-				$qb->insert('share')
613
-					->values([
614
-						'share_type' => $qb->createNamedParameter(IShare::TYPE_USERGROUP),
615
-						'share_with' => $qb->createNamedParameter($recipient),
616
-						'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
617
-						'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
618
-						'parent' => $qb->createNamedParameter($share->getId()),
619
-						'item_type' => $qb->createNamedParameter($share->getNodeType()),
620
-						'item_source' => $qb->createNamedParameter($share->getNodeId()),
621
-						'file_source' => $qb->createNamedParameter($share->getNodeId()),
622
-						'file_target' => $qb->createNamedParameter($share->getTarget()),
623
-						'permissions' => $qb->createNamedParameter($share->getPermissions()),
624
-						'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
625
-					])->execute();
626
-			} else {
627
-				// Already a usergroup share. Update it.
628
-				$qb = $this->dbConn->getQueryBuilder();
629
-				$qb->update('share')
630
-					->set('file_target', $qb->createNamedParameter($share->getTarget()))
631
-					->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
632
-					->execute();
633
-			}
634
-		}
635
-
636
-		return $share;
637
-	}
638
-
639
-	public function getSharesInFolder($userId, Folder $node, $reshares) {
640
-		$qb = $this->dbConn->getQueryBuilder();
641
-		$qb->select('*')
642
-			->from('share', 's')
643
-			->andWhere($qb->expr()->orX(
644
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
645
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
646
-			));
647
-
648
-		$qb->andWhere($qb->expr()->orX(
649
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)),
650
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)),
651
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK))
652
-		));
653
-
654
-		/**
655
-		 * Reshares for this user are shares where they are the owner.
656
-		 */
657
-		if ($reshares === false) {
658
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
659
-		} else {
660
-			$qb->andWhere(
661
-				$qb->expr()->orX(
662
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
663
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
664
-				)
665
-			);
666
-		}
667
-
668
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
669
-		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
670
-
671
-		$qb->orderBy('id');
672
-
673
-		$cursor = $qb->execute();
674
-		$shares = [];
675
-		while ($data = $cursor->fetch()) {
676
-			$shares[$data['fileid']][] = $this->createShare($data);
677
-		}
678
-		$cursor->closeCursor();
679
-
680
-		return $shares;
681
-	}
682
-
683
-	/**
684
-	 * @inheritdoc
685
-	 */
686
-	public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
687
-		$qb = $this->dbConn->getQueryBuilder();
688
-		$qb->select('*')
689
-			->from('share')
690
-			->andWhere($qb->expr()->orX(
691
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
692
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
693
-			));
694
-
695
-		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter($shareType)));
696
-
697
-		/**
698
-		 * Reshares for this user are shares where they are the owner.
699
-		 */
700
-		if ($reshares === false) {
701
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
702
-		} else {
703
-			if ($node === null) {
704
-				$qb->andWhere(
705
-					$qb->expr()->orX(
706
-						$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
707
-						$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
708
-					)
709
-				);
710
-			}
711
-		}
712
-
713
-		if ($node !== null) {
714
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
715
-		}
716
-
717
-		if ($limit !== -1) {
718
-			$qb->setMaxResults($limit);
719
-		}
720
-
721
-		$qb->setFirstResult($offset);
722
-		$qb->orderBy('id');
723
-
724
-		$cursor = $qb->execute();
725
-		$shares = [];
726
-		while ($data = $cursor->fetch()) {
727
-			$shares[] = $this->createShare($data);
728
-		}
729
-		$cursor->closeCursor();
730
-
731
-		return $shares;
732
-	}
733
-
734
-	/**
735
-	 * @inheritdoc
736
-	 */
737
-	public function getShareById($id, $recipientId = null) {
738
-		$qb = $this->dbConn->getQueryBuilder();
739
-
740
-		$qb->select('*')
741
-			->from('share')
742
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
743
-			->andWhere(
744
-				$qb->expr()->in(
745
-					'share_type',
746
-					$qb->createNamedParameter([
747
-						IShare::TYPE_USER,
748
-						IShare::TYPE_GROUP,
749
-						IShare::TYPE_LINK,
750
-					], IQueryBuilder::PARAM_INT_ARRAY)
751
-				)
752
-			)
753
-			->andWhere($qb->expr()->orX(
754
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
755
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
756
-			));
757
-
758
-		$cursor = $qb->execute();
759
-		$data = $cursor->fetch();
760
-		$cursor->closeCursor();
761
-
762
-		if ($data === false) {
763
-			throw new ShareNotFound();
764
-		}
765
-
766
-		try {
767
-			$share = $this->createShare($data);
768
-		} catch (InvalidShare $e) {
769
-			throw new ShareNotFound();
770
-		}
771
-
772
-		// If the recipient is set for a group share resolve to that user
773
-		if ($recipientId !== null && $share->getShareType() === IShare::TYPE_GROUP) {
774
-			$share = $this->resolveGroupShares([$share], $recipientId)[0];
775
-		}
776
-
777
-		return $share;
778
-	}
779
-
780
-	/**
781
-	 * Get shares for a given path
782
-	 *
783
-	 * @param \OCP\Files\Node $path
784
-	 * @return \OCP\Share\IShare[]
785
-	 */
786
-	public function getSharesByPath(Node $path) {
787
-		$qb = $this->dbConn->getQueryBuilder();
788
-
789
-		$cursor = $qb->select('*')
790
-			->from('share')
791
-			->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
792
-			->andWhere(
793
-				$qb->expr()->orX(
794
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)),
795
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP))
796
-				)
797
-			)
798
-			->andWhere($qb->expr()->orX(
799
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
800
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
801
-			))
802
-			->execute();
803
-
804
-		$shares = [];
805
-		while ($data = $cursor->fetch()) {
806
-			$shares[] = $this->createShare($data);
807
-		}
808
-		$cursor->closeCursor();
809
-
810
-		return $shares;
811
-	}
812
-
813
-	/**
814
-	 * Returns whether the given database result can be interpreted as
815
-	 * a share with accessible file (not trashed, not deleted)
816
-	 */
817
-	private function isAccessibleResult($data) {
818
-		// exclude shares leading to deleted file entries
819
-		if ($data['fileid'] === null || $data['path'] === null) {
820
-			return false;
821
-		}
822
-
823
-		// exclude shares leading to trashbin on home storages
824
-		$pathSections = explode('/', $data['path'], 2);
825
-		// FIXME: would not detect rare md5'd home storage case properly
826
-		if ($pathSections[0] !== 'files'
827
-				&& in_array(explode(':', $data['storage_string_id'], 2)[0], ['home', 'object'])) {
828
-			return false;
829
-		}
830
-		return true;
831
-	}
832
-
833
-	/**
834
-	 * @inheritdoc
835
-	 */
836
-	public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
837
-		/** @var Share[] $shares */
838
-		$shares = [];
839
-
840
-		if ($shareType === IShare::TYPE_USER) {
841
-			//Get shares directly with this user
842
-			$qb = $this->dbConn->getQueryBuilder();
843
-			$qb->select('s.*',
844
-				'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
845
-				'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
846
-				'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
847
-			)
848
-				->selectAlias('st.id', 'storage_string_id')
849
-				->from('share', 's')
850
-				->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
851
-				->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'));
852
-
853
-			// Order by id
854
-			$qb->orderBy('s.id');
855
-
856
-			// Set limit and offset
857
-			if ($limit !== -1) {
858
-				$qb->setMaxResults($limit);
859
-			}
860
-			$qb->setFirstResult($offset);
861
-
862
-			$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)))
863
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
864
-				->andWhere($qb->expr()->orX(
865
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
866
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
867
-				));
868
-
869
-			// Filter by node if provided
870
-			if ($node !== null) {
871
-				$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
872
-			}
873
-
874
-			$cursor = $qb->execute();
875
-
876
-			while ($data = $cursor->fetch()) {
877
-				if ($this->isAccessibleResult($data)) {
878
-					$shares[] = $this->createShare($data);
879
-				}
880
-			}
881
-			$cursor->closeCursor();
882
-		} elseif ($shareType === IShare::TYPE_GROUP) {
883
-			$user = $this->userManager->get($userId);
884
-			$allGroups = $this->groupManager->getUserGroupIds($user);
885
-
886
-			/** @var Share[] $shares2 */
887
-			$shares2 = [];
888
-
889
-			$start = 0;
890
-			while (true) {
891
-				$groups = array_slice($allGroups, $start, 100);
892
-				$start += 100;
893
-
894
-				if ($groups === []) {
895
-					break;
896
-				}
897
-
898
-				$qb = $this->dbConn->getQueryBuilder();
899
-				$qb->select('s.*',
900
-					'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
901
-					'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
902
-					'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
903
-				)
904
-					->selectAlias('st.id', 'storage_string_id')
905
-					->from('share', 's')
906
-					->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
907
-					->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'))
908
-					->orderBy('s.id')
909
-					->setFirstResult(0);
910
-
911
-				if ($limit !== -1) {
912
-					$qb->setMaxResults($limit - count($shares));
913
-				}
914
-
915
-				// Filter by node if provided
916
-				if ($node !== null) {
917
-					$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
918
-				}
919
-
920
-
921
-				$groups = array_filter($groups);
922
-
923
-				$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
924
-					->andWhere($qb->expr()->in('share_with', $qb->createNamedParameter(
925
-						$groups,
926
-						IQueryBuilder::PARAM_STR_ARRAY
927
-					)))
928
-					->andWhere($qb->expr()->orX(
929
-						$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
930
-						$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
931
-					));
932
-
933
-				$cursor = $qb->execute();
934
-				while ($data = $cursor->fetch()) {
935
-					if ($offset > 0) {
936
-						$offset--;
937
-						continue;
938
-					}
939
-
940
-					if ($this->isAccessibleResult($data)) {
941
-						$shares2[] = $this->createShare($data);
942
-					}
943
-				}
944
-				$cursor->closeCursor();
945
-			}
946
-
947
-			/*
494
+            if ($data === false) {
495
+                $id = $this->createUserSpecificGroupShare($share, $recipient);
496
+                $permissions = $share->getPermissions();
497
+            } else {
498
+                $permissions = $data['permissions'];
499
+                $id = $data['id'];
500
+            }
501
+
502
+            if ($permissions !== 0) {
503
+                // Update existing usergroup share
504
+                $qb = $this->dbConn->getQueryBuilder();
505
+                $qb->update('share')
506
+                    ->set('permissions', $qb->createNamedParameter(0))
507
+                    ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
508
+                    ->execute();
509
+            }
510
+        } elseif ($share->getShareType() === IShare::TYPE_USER) {
511
+            if ($share->getSharedWith() !== $recipient) {
512
+                throw new ProviderException('Recipient does not match');
513
+            }
514
+
515
+            // We can just delete user and link shares
516
+            $this->delete($share);
517
+        } else {
518
+            throw new ProviderException('Invalid shareType');
519
+        }
520
+    }
521
+
522
+    protected function createUserSpecificGroupShare(IShare $share, string $recipient): int {
523
+        $type = $share->getNodeType();
524
+
525
+        $qb = $this->dbConn->getQueryBuilder();
526
+        $qb->insert('share')
527
+            ->values([
528
+                'share_type' => $qb->createNamedParameter(IShare::TYPE_USERGROUP),
529
+                'share_with' => $qb->createNamedParameter($recipient),
530
+                'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
531
+                'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
532
+                'parent' => $qb->createNamedParameter($share->getId()),
533
+                'item_type' => $qb->createNamedParameter($type),
534
+                'item_source' => $qb->createNamedParameter($share->getNodeId()),
535
+                'file_source' => $qb->createNamedParameter($share->getNodeId()),
536
+                'file_target' => $qb->createNamedParameter($share->getTarget()),
537
+                'permissions' => $qb->createNamedParameter($share->getPermissions()),
538
+                'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
539
+            ])->execute();
540
+
541
+        return $qb->getLastInsertId();
542
+    }
543
+
544
+    /**
545
+     * @inheritdoc
546
+     *
547
+     * For now this only works for group shares
548
+     * If this gets implemented for normal shares we have to extend it
549
+     */
550
+    public function restore(IShare $share, string $recipient): IShare {
551
+        $qb = $this->dbConn->getQueryBuilder();
552
+        $qb->select('permissions')
553
+            ->from('share')
554
+            ->where(
555
+                $qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))
556
+            );
557
+        $cursor = $qb->execute();
558
+        $data = $cursor->fetch();
559
+        $cursor->closeCursor();
560
+
561
+        $originalPermission = $data['permissions'];
562
+
563
+        $qb = $this->dbConn->getQueryBuilder();
564
+        $qb->update('share')
565
+            ->set('permissions', $qb->createNamedParameter($originalPermission))
566
+            ->where(
567
+                $qb->expr()->eq('parent', $qb->createNamedParameter($share->getParent()))
568
+            )->andWhere(
569
+                $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP))
570
+            )->andWhere(
571
+                $qb->expr()->eq('share_with', $qb->createNamedParameter($recipient))
572
+            );
573
+
574
+        $qb->execute();
575
+
576
+        return $this->getShareById($share->getId(), $recipient);
577
+    }
578
+
579
+    /**
580
+     * @inheritdoc
581
+     */
582
+    public function move(\OCP\Share\IShare $share, $recipient) {
583
+        if ($share->getShareType() === IShare::TYPE_USER) {
584
+            // Just update the target
585
+            $qb = $this->dbConn->getQueryBuilder();
586
+            $qb->update('share')
587
+                ->set('file_target', $qb->createNamedParameter($share->getTarget()))
588
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
589
+                ->execute();
590
+        } elseif ($share->getShareType() === IShare::TYPE_GROUP) {
591
+
592
+            // Check if there is a usergroup share
593
+            $qb = $this->dbConn->getQueryBuilder();
594
+            $stmt = $qb->select('id')
595
+                ->from('share')
596
+                ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
597
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
598
+                ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
599
+                ->andWhere($qb->expr()->orX(
600
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
601
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
602
+                ))
603
+                ->setMaxResults(1)
604
+                ->execute();
605
+
606
+            $data = $stmt->fetch();
607
+            $stmt->closeCursor();
608
+
609
+            if ($data === false) {
610
+                // No usergroup share yet. Create one.
611
+                $qb = $this->dbConn->getQueryBuilder();
612
+                $qb->insert('share')
613
+                    ->values([
614
+                        'share_type' => $qb->createNamedParameter(IShare::TYPE_USERGROUP),
615
+                        'share_with' => $qb->createNamedParameter($recipient),
616
+                        'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
617
+                        'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
618
+                        'parent' => $qb->createNamedParameter($share->getId()),
619
+                        'item_type' => $qb->createNamedParameter($share->getNodeType()),
620
+                        'item_source' => $qb->createNamedParameter($share->getNodeId()),
621
+                        'file_source' => $qb->createNamedParameter($share->getNodeId()),
622
+                        'file_target' => $qb->createNamedParameter($share->getTarget()),
623
+                        'permissions' => $qb->createNamedParameter($share->getPermissions()),
624
+                        'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
625
+                    ])->execute();
626
+            } else {
627
+                // Already a usergroup share. Update it.
628
+                $qb = $this->dbConn->getQueryBuilder();
629
+                $qb->update('share')
630
+                    ->set('file_target', $qb->createNamedParameter($share->getTarget()))
631
+                    ->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
632
+                    ->execute();
633
+            }
634
+        }
635
+
636
+        return $share;
637
+    }
638
+
639
+    public function getSharesInFolder($userId, Folder $node, $reshares) {
640
+        $qb = $this->dbConn->getQueryBuilder();
641
+        $qb->select('*')
642
+            ->from('share', 's')
643
+            ->andWhere($qb->expr()->orX(
644
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
645
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
646
+            ));
647
+
648
+        $qb->andWhere($qb->expr()->orX(
649
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)),
650
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)),
651
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK))
652
+        ));
653
+
654
+        /**
655
+         * Reshares for this user are shares where they are the owner.
656
+         */
657
+        if ($reshares === false) {
658
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
659
+        } else {
660
+            $qb->andWhere(
661
+                $qb->expr()->orX(
662
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
663
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
664
+                )
665
+            );
666
+        }
667
+
668
+        $qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
669
+        $qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
670
+
671
+        $qb->orderBy('id');
672
+
673
+        $cursor = $qb->execute();
674
+        $shares = [];
675
+        while ($data = $cursor->fetch()) {
676
+            $shares[$data['fileid']][] = $this->createShare($data);
677
+        }
678
+        $cursor->closeCursor();
679
+
680
+        return $shares;
681
+    }
682
+
683
+    /**
684
+     * @inheritdoc
685
+     */
686
+    public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
687
+        $qb = $this->dbConn->getQueryBuilder();
688
+        $qb->select('*')
689
+            ->from('share')
690
+            ->andWhere($qb->expr()->orX(
691
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
692
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
693
+            ));
694
+
695
+        $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter($shareType)));
696
+
697
+        /**
698
+         * Reshares for this user are shares where they are the owner.
699
+         */
700
+        if ($reshares === false) {
701
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
702
+        } else {
703
+            if ($node === null) {
704
+                $qb->andWhere(
705
+                    $qb->expr()->orX(
706
+                        $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
707
+                        $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
708
+                    )
709
+                );
710
+            }
711
+        }
712
+
713
+        if ($node !== null) {
714
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
715
+        }
716
+
717
+        if ($limit !== -1) {
718
+            $qb->setMaxResults($limit);
719
+        }
720
+
721
+        $qb->setFirstResult($offset);
722
+        $qb->orderBy('id');
723
+
724
+        $cursor = $qb->execute();
725
+        $shares = [];
726
+        while ($data = $cursor->fetch()) {
727
+            $shares[] = $this->createShare($data);
728
+        }
729
+        $cursor->closeCursor();
730
+
731
+        return $shares;
732
+    }
733
+
734
+    /**
735
+     * @inheritdoc
736
+     */
737
+    public function getShareById($id, $recipientId = null) {
738
+        $qb = $this->dbConn->getQueryBuilder();
739
+
740
+        $qb->select('*')
741
+            ->from('share')
742
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
743
+            ->andWhere(
744
+                $qb->expr()->in(
745
+                    'share_type',
746
+                    $qb->createNamedParameter([
747
+                        IShare::TYPE_USER,
748
+                        IShare::TYPE_GROUP,
749
+                        IShare::TYPE_LINK,
750
+                    ], IQueryBuilder::PARAM_INT_ARRAY)
751
+                )
752
+            )
753
+            ->andWhere($qb->expr()->orX(
754
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
755
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
756
+            ));
757
+
758
+        $cursor = $qb->execute();
759
+        $data = $cursor->fetch();
760
+        $cursor->closeCursor();
761
+
762
+        if ($data === false) {
763
+            throw new ShareNotFound();
764
+        }
765
+
766
+        try {
767
+            $share = $this->createShare($data);
768
+        } catch (InvalidShare $e) {
769
+            throw new ShareNotFound();
770
+        }
771
+
772
+        // If the recipient is set for a group share resolve to that user
773
+        if ($recipientId !== null && $share->getShareType() === IShare::TYPE_GROUP) {
774
+            $share = $this->resolveGroupShares([$share], $recipientId)[0];
775
+        }
776
+
777
+        return $share;
778
+    }
779
+
780
+    /**
781
+     * Get shares for a given path
782
+     *
783
+     * @param \OCP\Files\Node $path
784
+     * @return \OCP\Share\IShare[]
785
+     */
786
+    public function getSharesByPath(Node $path) {
787
+        $qb = $this->dbConn->getQueryBuilder();
788
+
789
+        $cursor = $qb->select('*')
790
+            ->from('share')
791
+            ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
792
+            ->andWhere(
793
+                $qb->expr()->orX(
794
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)),
795
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP))
796
+                )
797
+            )
798
+            ->andWhere($qb->expr()->orX(
799
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
800
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
801
+            ))
802
+            ->execute();
803
+
804
+        $shares = [];
805
+        while ($data = $cursor->fetch()) {
806
+            $shares[] = $this->createShare($data);
807
+        }
808
+        $cursor->closeCursor();
809
+
810
+        return $shares;
811
+    }
812
+
813
+    /**
814
+     * Returns whether the given database result can be interpreted as
815
+     * a share with accessible file (not trashed, not deleted)
816
+     */
817
+    private function isAccessibleResult($data) {
818
+        // exclude shares leading to deleted file entries
819
+        if ($data['fileid'] === null || $data['path'] === null) {
820
+            return false;
821
+        }
822
+
823
+        // exclude shares leading to trashbin on home storages
824
+        $pathSections = explode('/', $data['path'], 2);
825
+        // FIXME: would not detect rare md5'd home storage case properly
826
+        if ($pathSections[0] !== 'files'
827
+                && in_array(explode(':', $data['storage_string_id'], 2)[0], ['home', 'object'])) {
828
+            return false;
829
+        }
830
+        return true;
831
+    }
832
+
833
+    /**
834
+     * @inheritdoc
835
+     */
836
+    public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
837
+        /** @var Share[] $shares */
838
+        $shares = [];
839
+
840
+        if ($shareType === IShare::TYPE_USER) {
841
+            //Get shares directly with this user
842
+            $qb = $this->dbConn->getQueryBuilder();
843
+            $qb->select('s.*',
844
+                'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
845
+                'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
846
+                'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
847
+            )
848
+                ->selectAlias('st.id', 'storage_string_id')
849
+                ->from('share', 's')
850
+                ->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
851
+                ->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'));
852
+
853
+            // Order by id
854
+            $qb->orderBy('s.id');
855
+
856
+            // Set limit and offset
857
+            if ($limit !== -1) {
858
+                $qb->setMaxResults($limit);
859
+            }
860
+            $qb->setFirstResult($offset);
861
+
862
+            $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)))
863
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
864
+                ->andWhere($qb->expr()->orX(
865
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
866
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
867
+                ));
868
+
869
+            // Filter by node if provided
870
+            if ($node !== null) {
871
+                $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
872
+            }
873
+
874
+            $cursor = $qb->execute();
875
+
876
+            while ($data = $cursor->fetch()) {
877
+                if ($this->isAccessibleResult($data)) {
878
+                    $shares[] = $this->createShare($data);
879
+                }
880
+            }
881
+            $cursor->closeCursor();
882
+        } elseif ($shareType === IShare::TYPE_GROUP) {
883
+            $user = $this->userManager->get($userId);
884
+            $allGroups = $this->groupManager->getUserGroupIds($user);
885
+
886
+            /** @var Share[] $shares2 */
887
+            $shares2 = [];
888
+
889
+            $start = 0;
890
+            while (true) {
891
+                $groups = array_slice($allGroups, $start, 100);
892
+                $start += 100;
893
+
894
+                if ($groups === []) {
895
+                    break;
896
+                }
897
+
898
+                $qb = $this->dbConn->getQueryBuilder();
899
+                $qb->select('s.*',
900
+                    'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
901
+                    'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
902
+                    'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
903
+                )
904
+                    ->selectAlias('st.id', 'storage_string_id')
905
+                    ->from('share', 's')
906
+                    ->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
907
+                    ->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'))
908
+                    ->orderBy('s.id')
909
+                    ->setFirstResult(0);
910
+
911
+                if ($limit !== -1) {
912
+                    $qb->setMaxResults($limit - count($shares));
913
+                }
914
+
915
+                // Filter by node if provided
916
+                if ($node !== null) {
917
+                    $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
918
+                }
919
+
920
+
921
+                $groups = array_filter($groups);
922
+
923
+                $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
924
+                    ->andWhere($qb->expr()->in('share_with', $qb->createNamedParameter(
925
+                        $groups,
926
+                        IQueryBuilder::PARAM_STR_ARRAY
927
+                    )))
928
+                    ->andWhere($qb->expr()->orX(
929
+                        $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
930
+                        $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
931
+                    ));
932
+
933
+                $cursor = $qb->execute();
934
+                while ($data = $cursor->fetch()) {
935
+                    if ($offset > 0) {
936
+                        $offset--;
937
+                        continue;
938
+                    }
939
+
940
+                    if ($this->isAccessibleResult($data)) {
941
+                        $shares2[] = $this->createShare($data);
942
+                    }
943
+                }
944
+                $cursor->closeCursor();
945
+            }
946
+
947
+            /*
948 948
 			 * Resolve all group shares to user specific shares
949 949
 			 */
950
-			$shares = $this->resolveGroupShares($shares2, $userId);
951
-		} else {
952
-			throw new BackendError('Invalid backend');
953
-		}
954
-
955
-
956
-		return $shares;
957
-	}
958
-
959
-	/**
960
-	 * Get a share by token
961
-	 *
962
-	 * @param string $token
963
-	 * @return \OCP\Share\IShare
964
-	 * @throws ShareNotFound
965
-	 */
966
-	public function getShareByToken($token) {
967
-		$qb = $this->dbConn->getQueryBuilder();
968
-
969
-		$cursor = $qb->select('*')
970
-			->from('share')
971
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK)))
972
-			->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
973
-			->andWhere($qb->expr()->orX(
974
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
975
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
976
-			))
977
-			->execute();
978
-
979
-		$data = $cursor->fetch();
980
-
981
-		if ($data === false) {
982
-			throw new ShareNotFound();
983
-		}
984
-
985
-		try {
986
-			$share = $this->createShare($data);
987
-		} catch (InvalidShare $e) {
988
-			throw new ShareNotFound();
989
-		}
990
-
991
-		return $share;
992
-	}
993
-
994
-	/**
995
-	 * Create a share object from an database row
996
-	 *
997
-	 * @param mixed[] $data
998
-	 * @return \OCP\Share\IShare
999
-	 * @throws InvalidShare
1000
-	 */
1001
-	private function createShare($data) {
1002
-		$share = new Share($this->rootFolder, $this->userManager);
1003
-		$share->setId((int)$data['id'])
1004
-			->setShareType((int)$data['share_type'])
1005
-			->setPermissions((int)$data['permissions'])
1006
-			->setTarget($data['file_target'])
1007
-			->setNote($data['note'])
1008
-			->setMailSend((bool)$data['mail_send'])
1009
-			->setStatus((int)$data['accepted'])
1010
-			->setLabel($data['label']);
1011
-
1012
-		$shareTime = new \DateTime();
1013
-		$shareTime->setTimestamp((int)$data['stime']);
1014
-		$share->setShareTime($shareTime);
1015
-
1016
-		if ($share->getShareType() === IShare::TYPE_USER) {
1017
-			$share->setSharedWith($data['share_with']);
1018
-			$user = $this->userManager->get($data['share_with']);
1019
-			if ($user !== null) {
1020
-				$share->setSharedWithDisplayName($user->getDisplayName());
1021
-			}
1022
-		} elseif ($share->getShareType() === IShare::TYPE_GROUP) {
1023
-			$share->setSharedWith($data['share_with']);
1024
-		} elseif ($share->getShareType() === IShare::TYPE_LINK) {
1025
-			$share->setPassword($data['password']);
1026
-			$share->setSendPasswordByTalk((bool)$data['password_by_talk']);
1027
-			$share->setToken($data['token']);
1028
-		}
1029
-
1030
-		$share->setSharedBy($data['uid_initiator']);
1031
-		$share->setShareOwner($data['uid_owner']);
1032
-
1033
-		$share->setNodeId((int)$data['file_source']);
1034
-		$share->setNodeType($data['item_type']);
1035
-
1036
-		if ($data['expiration'] !== null) {
1037
-			$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
1038
-			$share->setExpirationDate($expiration);
1039
-		}
1040
-
1041
-		if (isset($data['f_permissions'])) {
1042
-			$entryData = $data;
1043
-			$entryData['permissions'] = $entryData['f_permissions'];
1044
-			$entryData['parent'] = $entryData['f_parent'];
1045
-			$share->setNodeCacheEntry(Cache::cacheEntryFromData($entryData,
1046
-				\OC::$server->getMimeTypeLoader()));
1047
-		}
1048
-
1049
-		$share->setProviderId($this->identifier());
1050
-		$share->setHideDownload((int)$data['hide_download'] === 1);
1051
-
1052
-		return $share;
1053
-	}
1054
-
1055
-	/**
1056
-	 * @param Share[] $shares
1057
-	 * @param $userId
1058
-	 * @return Share[] The updates shares if no update is found for a share return the original
1059
-	 */
1060
-	private function resolveGroupShares($shares, $userId) {
1061
-		$result = [];
1062
-
1063
-		$start = 0;
1064
-		while (true) {
1065
-			/** @var Share[] $shareSlice */
1066
-			$shareSlice = array_slice($shares, $start, 100);
1067
-			$start += 100;
1068
-
1069
-			if ($shareSlice === []) {
1070
-				break;
1071
-			}
1072
-
1073
-			/** @var int[] $ids */
1074
-			$ids = [];
1075
-			/** @var Share[] $shareMap */
1076
-			$shareMap = [];
1077
-
1078
-			foreach ($shareSlice as $share) {
1079
-				$ids[] = (int)$share->getId();
1080
-				$shareMap[$share->getId()] = $share;
1081
-			}
1082
-
1083
-			$qb = $this->dbConn->getQueryBuilder();
1084
-
1085
-			$query = $qb->select('*')
1086
-				->from('share')
1087
-				->where($qb->expr()->in('parent', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1088
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
1089
-				->andWhere($qb->expr()->orX(
1090
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1091
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1092
-				));
1093
-
1094
-			$stmt = $query->execute();
1095
-
1096
-			while ($data = $stmt->fetch()) {
1097
-				$shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
1098
-				$shareMap[$data['parent']]->setStatus((int)$data['accepted']);
1099
-				$shareMap[$data['parent']]->setTarget($data['file_target']);
1100
-				$shareMap[$data['parent']]->setParent($data['parent']);
1101
-			}
1102
-
1103
-			$stmt->closeCursor();
1104
-
1105
-			foreach ($shareMap as $share) {
1106
-				$result[] = $share;
1107
-			}
1108
-		}
1109
-
1110
-		return $result;
1111
-	}
1112
-
1113
-	/**
1114
-	 * A user is deleted from the system
1115
-	 * So clean up the relevant shares.
1116
-	 *
1117
-	 * @param string $uid
1118
-	 * @param int $shareType
1119
-	 */
1120
-	public function userDeleted($uid, $shareType) {
1121
-		$qb = $this->dbConn->getQueryBuilder();
1122
-
1123
-		$qb->delete('share');
1124
-
1125
-		if ($shareType === IShare::TYPE_USER) {
1126
-			/*
950
+            $shares = $this->resolveGroupShares($shares2, $userId);
951
+        } else {
952
+            throw new BackendError('Invalid backend');
953
+        }
954
+
955
+
956
+        return $shares;
957
+    }
958
+
959
+    /**
960
+     * Get a share by token
961
+     *
962
+     * @param string $token
963
+     * @return \OCP\Share\IShare
964
+     * @throws ShareNotFound
965
+     */
966
+    public function getShareByToken($token) {
967
+        $qb = $this->dbConn->getQueryBuilder();
968
+
969
+        $cursor = $qb->select('*')
970
+            ->from('share')
971
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK)))
972
+            ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
973
+            ->andWhere($qb->expr()->orX(
974
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
975
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
976
+            ))
977
+            ->execute();
978
+
979
+        $data = $cursor->fetch();
980
+
981
+        if ($data === false) {
982
+            throw new ShareNotFound();
983
+        }
984
+
985
+        try {
986
+            $share = $this->createShare($data);
987
+        } catch (InvalidShare $e) {
988
+            throw new ShareNotFound();
989
+        }
990
+
991
+        return $share;
992
+    }
993
+
994
+    /**
995
+     * Create a share object from an database row
996
+     *
997
+     * @param mixed[] $data
998
+     * @return \OCP\Share\IShare
999
+     * @throws InvalidShare
1000
+     */
1001
+    private function createShare($data) {
1002
+        $share = new Share($this->rootFolder, $this->userManager);
1003
+        $share->setId((int)$data['id'])
1004
+            ->setShareType((int)$data['share_type'])
1005
+            ->setPermissions((int)$data['permissions'])
1006
+            ->setTarget($data['file_target'])
1007
+            ->setNote($data['note'])
1008
+            ->setMailSend((bool)$data['mail_send'])
1009
+            ->setStatus((int)$data['accepted'])
1010
+            ->setLabel($data['label']);
1011
+
1012
+        $shareTime = new \DateTime();
1013
+        $shareTime->setTimestamp((int)$data['stime']);
1014
+        $share->setShareTime($shareTime);
1015
+
1016
+        if ($share->getShareType() === IShare::TYPE_USER) {
1017
+            $share->setSharedWith($data['share_with']);
1018
+            $user = $this->userManager->get($data['share_with']);
1019
+            if ($user !== null) {
1020
+                $share->setSharedWithDisplayName($user->getDisplayName());
1021
+            }
1022
+        } elseif ($share->getShareType() === IShare::TYPE_GROUP) {
1023
+            $share->setSharedWith($data['share_with']);
1024
+        } elseif ($share->getShareType() === IShare::TYPE_LINK) {
1025
+            $share->setPassword($data['password']);
1026
+            $share->setSendPasswordByTalk((bool)$data['password_by_talk']);
1027
+            $share->setToken($data['token']);
1028
+        }
1029
+
1030
+        $share->setSharedBy($data['uid_initiator']);
1031
+        $share->setShareOwner($data['uid_owner']);
1032
+
1033
+        $share->setNodeId((int)$data['file_source']);
1034
+        $share->setNodeType($data['item_type']);
1035
+
1036
+        if ($data['expiration'] !== null) {
1037
+            $expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
1038
+            $share->setExpirationDate($expiration);
1039
+        }
1040
+
1041
+        if (isset($data['f_permissions'])) {
1042
+            $entryData = $data;
1043
+            $entryData['permissions'] = $entryData['f_permissions'];
1044
+            $entryData['parent'] = $entryData['f_parent'];
1045
+            $share->setNodeCacheEntry(Cache::cacheEntryFromData($entryData,
1046
+                \OC::$server->getMimeTypeLoader()));
1047
+        }
1048
+
1049
+        $share->setProviderId($this->identifier());
1050
+        $share->setHideDownload((int)$data['hide_download'] === 1);
1051
+
1052
+        return $share;
1053
+    }
1054
+
1055
+    /**
1056
+     * @param Share[] $shares
1057
+     * @param $userId
1058
+     * @return Share[] The updates shares if no update is found for a share return the original
1059
+     */
1060
+    private function resolveGroupShares($shares, $userId) {
1061
+        $result = [];
1062
+
1063
+        $start = 0;
1064
+        while (true) {
1065
+            /** @var Share[] $shareSlice */
1066
+            $shareSlice = array_slice($shares, $start, 100);
1067
+            $start += 100;
1068
+
1069
+            if ($shareSlice === []) {
1070
+                break;
1071
+            }
1072
+
1073
+            /** @var int[] $ids */
1074
+            $ids = [];
1075
+            /** @var Share[] $shareMap */
1076
+            $shareMap = [];
1077
+
1078
+            foreach ($shareSlice as $share) {
1079
+                $ids[] = (int)$share->getId();
1080
+                $shareMap[$share->getId()] = $share;
1081
+            }
1082
+
1083
+            $qb = $this->dbConn->getQueryBuilder();
1084
+
1085
+            $query = $qb->select('*')
1086
+                ->from('share')
1087
+                ->where($qb->expr()->in('parent', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1088
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
1089
+                ->andWhere($qb->expr()->orX(
1090
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1091
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1092
+                ));
1093
+
1094
+            $stmt = $query->execute();
1095
+
1096
+            while ($data = $stmt->fetch()) {
1097
+                $shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
1098
+                $shareMap[$data['parent']]->setStatus((int)$data['accepted']);
1099
+                $shareMap[$data['parent']]->setTarget($data['file_target']);
1100
+                $shareMap[$data['parent']]->setParent($data['parent']);
1101
+            }
1102
+
1103
+            $stmt->closeCursor();
1104
+
1105
+            foreach ($shareMap as $share) {
1106
+                $result[] = $share;
1107
+            }
1108
+        }
1109
+
1110
+        return $result;
1111
+    }
1112
+
1113
+    /**
1114
+     * A user is deleted from the system
1115
+     * So clean up the relevant shares.
1116
+     *
1117
+     * @param string $uid
1118
+     * @param int $shareType
1119
+     */
1120
+    public function userDeleted($uid, $shareType) {
1121
+        $qb = $this->dbConn->getQueryBuilder();
1122
+
1123
+        $qb->delete('share');
1124
+
1125
+        if ($shareType === IShare::TYPE_USER) {
1126
+            /*
1127 1127
 			 * Delete all user shares that are owned by this user
1128 1128
 			 * or that are received by this user
1129 1129
 			 */
1130 1130
 
1131
-			$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)));
1131
+            $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)));
1132 1132
 
1133
-			$qb->andWhere(
1134
-				$qb->expr()->orX(
1135
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
1136
-					$qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
1137
-				)
1138
-			);
1139
-		} elseif ($shareType === IShare::TYPE_GROUP) {
1140
-			/*
1133
+            $qb->andWhere(
1134
+                $qb->expr()->orX(
1135
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
1136
+                    $qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
1137
+                )
1138
+            );
1139
+        } elseif ($shareType === IShare::TYPE_GROUP) {
1140
+            /*
1141 1141
 			 * Delete all group shares that are owned by this user
1142 1142
 			 * Or special user group shares that are received by this user
1143 1143
 			 */
1144
-			$qb->where(
1145
-				$qb->expr()->andX(
1146
-					$qb->expr()->orX(
1147
-						$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)),
1148
-						$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP))
1149
-					),
1150
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid))
1151
-				)
1152
-			);
1153
-
1154
-			$qb->orWhere(
1155
-				$qb->expr()->andX(
1156
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)),
1157
-					$qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
1158
-				)
1159
-			);
1160
-		} elseif ($shareType === IShare::TYPE_LINK) {
1161
-			/*
1144
+            $qb->where(
1145
+                $qb->expr()->andX(
1146
+                    $qb->expr()->orX(
1147
+                        $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)),
1148
+                        $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP))
1149
+                    ),
1150
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid))
1151
+                )
1152
+            );
1153
+
1154
+            $qb->orWhere(
1155
+                $qb->expr()->andX(
1156
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)),
1157
+                    $qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
1158
+                )
1159
+            );
1160
+        } elseif ($shareType === IShare::TYPE_LINK) {
1161
+            /*
1162 1162
 			 * Delete all link shares owned by this user.
1163 1163
 			 * And all link shares initiated by this user (until #22327 is in)
1164 1164
 			 */
1165
-			$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK)));
1166
-
1167
-			$qb->andWhere(
1168
-				$qb->expr()->orX(
1169
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
1170
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($uid))
1171
-				)
1172
-			);
1173
-		} else {
1174
-			\OC::$server->getLogger()->logException(new \InvalidArgumentException('Default share provider tried to delete all shares for type: ' . $shareType));
1175
-			return;
1176
-		}
1177
-
1178
-		$qb->execute();
1179
-	}
1180
-
1181
-	/**
1182
-	 * Delete all shares received by this group. As well as any custom group
1183
-	 * shares for group members.
1184
-	 *
1185
-	 * @param string $gid
1186
-	 */
1187
-	public function groupDeleted($gid) {
1188
-		/*
1165
+            $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK)));
1166
+
1167
+            $qb->andWhere(
1168
+                $qb->expr()->orX(
1169
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
1170
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($uid))
1171
+                )
1172
+            );
1173
+        } else {
1174
+            \OC::$server->getLogger()->logException(new \InvalidArgumentException('Default share provider tried to delete all shares for type: ' . $shareType));
1175
+            return;
1176
+        }
1177
+
1178
+        $qb->execute();
1179
+    }
1180
+
1181
+    /**
1182
+     * Delete all shares received by this group. As well as any custom group
1183
+     * shares for group members.
1184
+     *
1185
+     * @param string $gid
1186
+     */
1187
+    public function groupDeleted($gid) {
1188
+        /*
1189 1189
 		 * First delete all custom group shares for group members
1190 1190
 		 */
1191
-		$qb = $this->dbConn->getQueryBuilder();
1192
-		$qb->select('id')
1193
-			->from('share')
1194
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
1195
-			->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1196
-
1197
-		$cursor = $qb->execute();
1198
-		$ids = [];
1199
-		while ($row = $cursor->fetch()) {
1200
-			$ids[] = (int)$row['id'];
1201
-		}
1202
-		$cursor->closeCursor();
1203
-
1204
-		if (!empty($ids)) {
1205
-			$chunks = array_chunk($ids, 100);
1206
-			foreach ($chunks as $chunk) {
1207
-				$qb->delete('share')
1208
-					->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
1209
-					->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1210
-				$qb->execute();
1211
-			}
1212
-		}
1213
-
1214
-		/*
1191
+        $qb = $this->dbConn->getQueryBuilder();
1192
+        $qb->select('id')
1193
+            ->from('share')
1194
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
1195
+            ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1196
+
1197
+        $cursor = $qb->execute();
1198
+        $ids = [];
1199
+        while ($row = $cursor->fetch()) {
1200
+            $ids[] = (int)$row['id'];
1201
+        }
1202
+        $cursor->closeCursor();
1203
+
1204
+        if (!empty($ids)) {
1205
+            $chunks = array_chunk($ids, 100);
1206
+            foreach ($chunks as $chunk) {
1207
+                $qb->delete('share')
1208
+                    ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
1209
+                    ->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1210
+                $qb->execute();
1211
+            }
1212
+        }
1213
+
1214
+        /*
1215 1215
 		 * Now delete all the group shares
1216 1216
 		 */
1217
-		$qb = $this->dbConn->getQueryBuilder();
1218
-		$qb->delete('share')
1219
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
1220
-			->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1221
-		$qb->execute();
1222
-	}
1223
-
1224
-	/**
1225
-	 * Delete custom group shares to this group for this user
1226
-	 *
1227
-	 * @param string $uid
1228
-	 * @param string $gid
1229
-	 */
1230
-	public function userDeletedFromGroup($uid, $gid) {
1231
-		/*
1217
+        $qb = $this->dbConn->getQueryBuilder();
1218
+        $qb->delete('share')
1219
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
1220
+            ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1221
+        $qb->execute();
1222
+    }
1223
+
1224
+    /**
1225
+     * Delete custom group shares to this group for this user
1226
+     *
1227
+     * @param string $uid
1228
+     * @param string $gid
1229
+     */
1230
+    public function userDeletedFromGroup($uid, $gid) {
1231
+        /*
1232 1232
 		 * Get all group shares
1233 1233
 		 */
1234
-		$qb = $this->dbConn->getQueryBuilder();
1235
-		$qb->select('id')
1236
-			->from('share')
1237
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
1238
-			->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1239
-
1240
-		$cursor = $qb->execute();
1241
-		$ids = [];
1242
-		while ($row = $cursor->fetch()) {
1243
-			$ids[] = (int)$row['id'];
1244
-		}
1245
-		$cursor->closeCursor();
1246
-
1247
-		if (!empty($ids)) {
1248
-			$chunks = array_chunk($ids, 100);
1249
-			foreach ($chunks as $chunk) {
1250
-				/*
1234
+        $qb = $this->dbConn->getQueryBuilder();
1235
+        $qb->select('id')
1236
+            ->from('share')
1237
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
1238
+            ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1239
+
1240
+        $cursor = $qb->execute();
1241
+        $ids = [];
1242
+        while ($row = $cursor->fetch()) {
1243
+            $ids[] = (int)$row['id'];
1244
+        }
1245
+        $cursor->closeCursor();
1246
+
1247
+        if (!empty($ids)) {
1248
+            $chunks = array_chunk($ids, 100);
1249
+            foreach ($chunks as $chunk) {
1250
+                /*
1251 1251
 				 * Delete all special shares wit this users for the found group shares
1252 1252
 				 */
1253
-				$qb->delete('share')
1254
-					->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
1255
-					->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($uid)))
1256
-					->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1257
-				$qb->execute();
1258
-			}
1259
-		}
1260
-	}
1261
-
1262
-	/**
1263
-	 * @inheritdoc
1264
-	 */
1265
-	public function getAccessList($nodes, $currentAccess) {
1266
-		$ids = [];
1267
-		foreach ($nodes as $node) {
1268
-			$ids[] = $node->getId();
1269
-		}
1270
-
1271
-		$qb = $this->dbConn->getQueryBuilder();
1272
-
1273
-		$or = $qb->expr()->orX(
1274
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)),
1275
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)),
1276
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK))
1277
-		);
1278
-
1279
-		if ($currentAccess) {
1280
-			$or->add($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)));
1281
-		}
1282
-
1283
-		$qb->select('id', 'parent', 'share_type', 'share_with', 'file_source', 'file_target', 'permissions')
1284
-			->from('share')
1285
-			->where(
1286
-				$or
1287
-			)
1288
-			->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1289
-			->andWhere($qb->expr()->orX(
1290
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1291
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1292
-			));
1293
-		$cursor = $qb->execute();
1294
-
1295
-		$users = [];
1296
-		$link = false;
1297
-		while ($row = $cursor->fetch()) {
1298
-			$type = (int)$row['share_type'];
1299
-			if ($type === IShare::TYPE_USER) {
1300
-				$uid = $row['share_with'];
1301
-				$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1302
-				$users[$uid][$row['id']] = $row;
1303
-			} elseif ($type === IShare::TYPE_GROUP) {
1304
-				$gid = $row['share_with'];
1305
-				$group = $this->groupManager->get($gid);
1306
-
1307
-				if ($group === null) {
1308
-					continue;
1309
-				}
1310
-
1311
-				$userList = $group->getUsers();
1312
-				foreach ($userList as $user) {
1313
-					$uid = $user->getUID();
1314
-					$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1315
-					$users[$uid][$row['id']] = $row;
1316
-				}
1317
-			} elseif ($type === IShare::TYPE_LINK) {
1318
-				$link = true;
1319
-			} elseif ($type === IShare::TYPE_USERGROUP && $currentAccess === true) {
1320
-				$uid = $row['share_with'];
1321
-				$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1322
-				$users[$uid][$row['id']] = $row;
1323
-			}
1324
-		}
1325
-		$cursor->closeCursor();
1326
-
1327
-		if ($currentAccess === true) {
1328
-			$users = array_map([$this, 'filterSharesOfUser'], $users);
1329
-			$users = array_filter($users);
1330
-		} else {
1331
-			$users = array_keys($users);
1332
-		}
1333
-
1334
-		return ['users' => $users, 'public' => $link];
1335
-	}
1336
-
1337
-	/**
1338
-	 * For each user the path with the fewest slashes is returned
1339
-	 * @param array $shares
1340
-	 * @return array
1341
-	 */
1342
-	protected function filterSharesOfUser(array $shares) {
1343
-		// Group shares when the user has a share exception
1344
-		foreach ($shares as $id => $share) {
1345
-			$type = (int) $share['share_type'];
1346
-			$permissions = (int) $share['permissions'];
1347
-
1348
-			if ($type === IShare::TYPE_USERGROUP) {
1349
-				unset($shares[$share['parent']]);
1350
-
1351
-				if ($permissions === 0) {
1352
-					unset($shares[$id]);
1353
-				}
1354
-			}
1355
-		}
1356
-
1357
-		$best = [];
1358
-		$bestDepth = 0;
1359
-		foreach ($shares as $id => $share) {
1360
-			$depth = substr_count($share['file_target'], '/');
1361
-			if (empty($best) || $depth < $bestDepth) {
1362
-				$bestDepth = $depth;
1363
-				$best = [
1364
-					'node_id' => $share['file_source'],
1365
-					'node_path' => $share['file_target'],
1366
-				];
1367
-			}
1368
-		}
1369
-
1370
-		return $best;
1371
-	}
1372
-
1373
-	/**
1374
-	 * propagate notes to the recipients
1375
-	 *
1376
-	 * @param IShare $share
1377
-	 * @throws \OCP\Files\NotFoundException
1378
-	 */
1379
-	private function propagateNote(IShare $share) {
1380
-		if ($share->getShareType() === IShare::TYPE_USER) {
1381
-			$user = $this->userManager->get($share->getSharedWith());
1382
-			$this->sendNote([$user], $share);
1383
-		} elseif ($share->getShareType() === IShare::TYPE_GROUP) {
1384
-			$group = $this->groupManager->get($share->getSharedWith());
1385
-			$groupMembers = $group->getUsers();
1386
-			$this->sendNote($groupMembers, $share);
1387
-		}
1388
-	}
1389
-
1390
-	/**
1391
-	 * send note by mail
1392
-	 *
1393
-	 * @param array $recipients
1394
-	 * @param IShare $share
1395
-	 * @throws \OCP\Files\NotFoundException
1396
-	 */
1397
-	private function sendNote(array $recipients, IShare $share) {
1398
-		$toListByLanguage = [];
1399
-
1400
-		foreach ($recipients as $recipient) {
1401
-			/** @var IUser $recipient */
1402
-			$email = $recipient->getEMailAddress();
1403
-			if ($email) {
1404
-				$language = $this->config->getSystemValue('force_language', false);
1405
-				$language = \is_string($language) ? $language : $this->config->getUserValue($recipient->getUID(), 'core', 'lang', null);
1406
-				$language = $language ?? $this->config->getSystemValue('default_language', 'en');
1407
-
1408
-				if (!isset($toListByLanguage[$language])) {
1409
-					$toListByLanguage[$language] = [];
1410
-				}
1411
-				$toListByLanguage[$language][$email] = $recipient->getDisplayName();
1412
-			}
1413
-		}
1414
-
1415
-		if (empty($toListByLanguage)) {
1416
-			return;
1417
-		}
1418
-
1419
-		foreach ($toListByLanguage as $l10n => $toList) {
1420
-			$filename = $share->getNode()->getName();
1421
-			$initiator = $share->getSharedBy();
1422
-			$note = $share->getNote();
1423
-
1424
-			$l = $this->l10nFactory->get('lib', $l10n);
1425
-
1426
-			$initiatorUser = $this->userManager->get($initiator);
1427
-			$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
1428
-			$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
1429
-			$plainHeading = $l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]);
1430
-			$htmlHeading = $l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]);
1431
-			$message = $this->mailer->createMessage();
1432
-
1433
-			$emailTemplate = $this->mailer->createEMailTemplate('defaultShareProvider.sendNote');
1434
-
1435
-			$emailTemplate->setSubject($l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName]));
1436
-			$emailTemplate->addHeader();
1437
-			$emailTemplate->addHeading($htmlHeading, $plainHeading);
1438
-			$emailTemplate->addBodyText(htmlspecialchars($note), $note);
1439
-
1440
-			$link = $this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $share->getNode()->getId()]);
1441
-			$emailTemplate->addBodyButton(
1442
-				$l->t('Open »%s«', [$filename]),
1443
-				$link
1444
-			);
1445
-
1446
-
1447
-			// The "From" contains the sharers name
1448
-			$instanceName = $this->defaults->getName();
1449
-			$senderName = $l->t(
1450
-				'%1$s via %2$s',
1451
-				[
1452
-					$initiatorDisplayName,
1453
-					$instanceName
1454
-				]
1455
-			);
1456
-			$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
1457
-			if ($initiatorEmailAddress !== null) {
1458
-				$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
1459
-				$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
1460
-			} else {
1461
-				$emailTemplate->addFooter();
1462
-			}
1463
-
1464
-			if (count($toList) === 1) {
1465
-				$message->setTo($toList);
1466
-			} else {
1467
-				$message->setTo([]);
1468
-				$message->setBcc($toList);
1469
-			}
1470
-			$message->useTemplate($emailTemplate);
1471
-			$this->mailer->send($message);
1472
-		}
1473
-	}
1474
-
1475
-	public function getAllShares(): iterable {
1476
-		$qb = $this->dbConn->getQueryBuilder();
1477
-
1478
-		$qb->select('*')
1479
-			->from('share')
1480
-			->where(
1481
-				$qb->expr()->orX(
1482
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_USER)),
1483
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_GROUP)),
1484
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_LINK))
1485
-				)
1486
-			);
1487
-
1488
-		$cursor = $qb->execute();
1489
-		while ($data = $cursor->fetch()) {
1490
-			try {
1491
-				$share = $this->createShare($data);
1492
-			} catch (InvalidShare $e) {
1493
-				continue;
1494
-			}
1495
-
1496
-			yield $share;
1497
-		}
1498
-		$cursor->closeCursor();
1499
-	}
1253
+                $qb->delete('share')
1254
+                    ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
1255
+                    ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($uid)))
1256
+                    ->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1257
+                $qb->execute();
1258
+            }
1259
+        }
1260
+    }
1261
+
1262
+    /**
1263
+     * @inheritdoc
1264
+     */
1265
+    public function getAccessList($nodes, $currentAccess) {
1266
+        $ids = [];
1267
+        foreach ($nodes as $node) {
1268
+            $ids[] = $node->getId();
1269
+        }
1270
+
1271
+        $qb = $this->dbConn->getQueryBuilder();
1272
+
1273
+        $or = $qb->expr()->orX(
1274
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)),
1275
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)),
1276
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK))
1277
+        );
1278
+
1279
+        if ($currentAccess) {
1280
+            $or->add($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)));
1281
+        }
1282
+
1283
+        $qb->select('id', 'parent', 'share_type', 'share_with', 'file_source', 'file_target', 'permissions')
1284
+            ->from('share')
1285
+            ->where(
1286
+                $or
1287
+            )
1288
+            ->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1289
+            ->andWhere($qb->expr()->orX(
1290
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1291
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1292
+            ));
1293
+        $cursor = $qb->execute();
1294
+
1295
+        $users = [];
1296
+        $link = false;
1297
+        while ($row = $cursor->fetch()) {
1298
+            $type = (int)$row['share_type'];
1299
+            if ($type === IShare::TYPE_USER) {
1300
+                $uid = $row['share_with'];
1301
+                $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1302
+                $users[$uid][$row['id']] = $row;
1303
+            } elseif ($type === IShare::TYPE_GROUP) {
1304
+                $gid = $row['share_with'];
1305
+                $group = $this->groupManager->get($gid);
1306
+
1307
+                if ($group === null) {
1308
+                    continue;
1309
+                }
1310
+
1311
+                $userList = $group->getUsers();
1312
+                foreach ($userList as $user) {
1313
+                    $uid = $user->getUID();
1314
+                    $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1315
+                    $users[$uid][$row['id']] = $row;
1316
+                }
1317
+            } elseif ($type === IShare::TYPE_LINK) {
1318
+                $link = true;
1319
+            } elseif ($type === IShare::TYPE_USERGROUP && $currentAccess === true) {
1320
+                $uid = $row['share_with'];
1321
+                $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1322
+                $users[$uid][$row['id']] = $row;
1323
+            }
1324
+        }
1325
+        $cursor->closeCursor();
1326
+
1327
+        if ($currentAccess === true) {
1328
+            $users = array_map([$this, 'filterSharesOfUser'], $users);
1329
+            $users = array_filter($users);
1330
+        } else {
1331
+            $users = array_keys($users);
1332
+        }
1333
+
1334
+        return ['users' => $users, 'public' => $link];
1335
+    }
1336
+
1337
+    /**
1338
+     * For each user the path with the fewest slashes is returned
1339
+     * @param array $shares
1340
+     * @return array
1341
+     */
1342
+    protected function filterSharesOfUser(array $shares) {
1343
+        // Group shares when the user has a share exception
1344
+        foreach ($shares as $id => $share) {
1345
+            $type = (int) $share['share_type'];
1346
+            $permissions = (int) $share['permissions'];
1347
+
1348
+            if ($type === IShare::TYPE_USERGROUP) {
1349
+                unset($shares[$share['parent']]);
1350
+
1351
+                if ($permissions === 0) {
1352
+                    unset($shares[$id]);
1353
+                }
1354
+            }
1355
+        }
1356
+
1357
+        $best = [];
1358
+        $bestDepth = 0;
1359
+        foreach ($shares as $id => $share) {
1360
+            $depth = substr_count($share['file_target'], '/');
1361
+            if (empty($best) || $depth < $bestDepth) {
1362
+                $bestDepth = $depth;
1363
+                $best = [
1364
+                    'node_id' => $share['file_source'],
1365
+                    'node_path' => $share['file_target'],
1366
+                ];
1367
+            }
1368
+        }
1369
+
1370
+        return $best;
1371
+    }
1372
+
1373
+    /**
1374
+     * propagate notes to the recipients
1375
+     *
1376
+     * @param IShare $share
1377
+     * @throws \OCP\Files\NotFoundException
1378
+     */
1379
+    private function propagateNote(IShare $share) {
1380
+        if ($share->getShareType() === IShare::TYPE_USER) {
1381
+            $user = $this->userManager->get($share->getSharedWith());
1382
+            $this->sendNote([$user], $share);
1383
+        } elseif ($share->getShareType() === IShare::TYPE_GROUP) {
1384
+            $group = $this->groupManager->get($share->getSharedWith());
1385
+            $groupMembers = $group->getUsers();
1386
+            $this->sendNote($groupMembers, $share);
1387
+        }
1388
+    }
1389
+
1390
+    /**
1391
+     * send note by mail
1392
+     *
1393
+     * @param array $recipients
1394
+     * @param IShare $share
1395
+     * @throws \OCP\Files\NotFoundException
1396
+     */
1397
+    private function sendNote(array $recipients, IShare $share) {
1398
+        $toListByLanguage = [];
1399
+
1400
+        foreach ($recipients as $recipient) {
1401
+            /** @var IUser $recipient */
1402
+            $email = $recipient->getEMailAddress();
1403
+            if ($email) {
1404
+                $language = $this->config->getSystemValue('force_language', false);
1405
+                $language = \is_string($language) ? $language : $this->config->getUserValue($recipient->getUID(), 'core', 'lang', null);
1406
+                $language = $language ?? $this->config->getSystemValue('default_language', 'en');
1407
+
1408
+                if (!isset($toListByLanguage[$language])) {
1409
+                    $toListByLanguage[$language] = [];
1410
+                }
1411
+                $toListByLanguage[$language][$email] = $recipient->getDisplayName();
1412
+            }
1413
+        }
1414
+
1415
+        if (empty($toListByLanguage)) {
1416
+            return;
1417
+        }
1418
+
1419
+        foreach ($toListByLanguage as $l10n => $toList) {
1420
+            $filename = $share->getNode()->getName();
1421
+            $initiator = $share->getSharedBy();
1422
+            $note = $share->getNote();
1423
+
1424
+            $l = $this->l10nFactory->get('lib', $l10n);
1425
+
1426
+            $initiatorUser = $this->userManager->get($initiator);
1427
+            $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
1428
+            $initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
1429
+            $plainHeading = $l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]);
1430
+            $htmlHeading = $l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]);
1431
+            $message = $this->mailer->createMessage();
1432
+
1433
+            $emailTemplate = $this->mailer->createEMailTemplate('defaultShareProvider.sendNote');
1434
+
1435
+            $emailTemplate->setSubject($l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName]));
1436
+            $emailTemplate->addHeader();
1437
+            $emailTemplate->addHeading($htmlHeading, $plainHeading);
1438
+            $emailTemplate->addBodyText(htmlspecialchars($note), $note);
1439
+
1440
+            $link = $this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $share->getNode()->getId()]);
1441
+            $emailTemplate->addBodyButton(
1442
+                $l->t('Open »%s«', [$filename]),
1443
+                $link
1444
+            );
1445
+
1446
+
1447
+            // The "From" contains the sharers name
1448
+            $instanceName = $this->defaults->getName();
1449
+            $senderName = $l->t(
1450
+                '%1$s via %2$s',
1451
+                [
1452
+                    $initiatorDisplayName,
1453
+                    $instanceName
1454
+                ]
1455
+            );
1456
+            $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
1457
+            if ($initiatorEmailAddress !== null) {
1458
+                $message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
1459
+                $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
1460
+            } else {
1461
+                $emailTemplate->addFooter();
1462
+            }
1463
+
1464
+            if (count($toList) === 1) {
1465
+                $message->setTo($toList);
1466
+            } else {
1467
+                $message->setTo([]);
1468
+                $message->setBcc($toList);
1469
+            }
1470
+            $message->useTemplate($emailTemplate);
1471
+            $this->mailer->send($message);
1472
+        }
1473
+    }
1474
+
1475
+    public function getAllShares(): iterable {
1476
+        $qb = $this->dbConn->getQueryBuilder();
1477
+
1478
+        $qb->select('*')
1479
+            ->from('share')
1480
+            ->where(
1481
+                $qb->expr()->orX(
1482
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_USER)),
1483
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_GROUP)),
1484
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_LINK))
1485
+                )
1486
+            );
1487
+
1488
+        $cursor = $qb->execute();
1489
+        while ($data = $cursor->fetch()) {
1490
+            try {
1491
+                $share = $this->createShare($data);
1492
+            } catch (InvalidShare $e) {
1493
+                continue;
1494
+            }
1495
+
1496
+            yield $share;
1497
+        }
1498
+        $cursor->closeCursor();
1499
+    }
1500 1500
 }
Please login to merge, or discard this patch.
Spacing   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -339,7 +339,7 @@  discard block
 block discarded – undo
339 339
 			$user = $this->userManager->get($recipient);
340 340
 
341 341
 			if (is_null($group)) {
342
-				throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
342
+				throw new ProviderException('Group "'.$share->getSharedWith().'" does not exist');
343 343
 			}
344 344
 
345 345
 			if (!$group->inGroup($user)) {
@@ -465,7 +465,7 @@  discard block
 block discarded – undo
465 465
 			$user = $this->userManager->get($recipient);
466 466
 
467 467
 			if (is_null($group)) {
468
-				throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
468
+				throw new ProviderException('Group "'.$share->getSharedWith().'" does not exist');
469 469
 			}
470 470
 
471 471
 			if (!$group->inGroup($user)) {
@@ -665,7 +665,7 @@  discard block
 block discarded – undo
665 665
 			);
666 666
 		}
667 667
 
668
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
668
+		$qb->innerJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
669 669
 		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
670 670
 
671 671
 		$qb->orderBy('id');
@@ -1000,17 +1000,17 @@  discard block
 block discarded – undo
1000 1000
 	 */
1001 1001
 	private function createShare($data) {
1002 1002
 		$share = new Share($this->rootFolder, $this->userManager);
1003
-		$share->setId((int)$data['id'])
1004
-			->setShareType((int)$data['share_type'])
1005
-			->setPermissions((int)$data['permissions'])
1003
+		$share->setId((int) $data['id'])
1004
+			->setShareType((int) $data['share_type'])
1005
+			->setPermissions((int) $data['permissions'])
1006 1006
 			->setTarget($data['file_target'])
1007 1007
 			->setNote($data['note'])
1008
-			->setMailSend((bool)$data['mail_send'])
1009
-			->setStatus((int)$data['accepted'])
1008
+			->setMailSend((bool) $data['mail_send'])
1009
+			->setStatus((int) $data['accepted'])
1010 1010
 			->setLabel($data['label']);
1011 1011
 
1012 1012
 		$shareTime = new \DateTime();
1013
-		$shareTime->setTimestamp((int)$data['stime']);
1013
+		$shareTime->setTimestamp((int) $data['stime']);
1014 1014
 		$share->setShareTime($shareTime);
1015 1015
 
1016 1016
 		if ($share->getShareType() === IShare::TYPE_USER) {
@@ -1023,14 +1023,14 @@  discard block
 block discarded – undo
1023 1023
 			$share->setSharedWith($data['share_with']);
1024 1024
 		} elseif ($share->getShareType() === IShare::TYPE_LINK) {
1025 1025
 			$share->setPassword($data['password']);
1026
-			$share->setSendPasswordByTalk((bool)$data['password_by_talk']);
1026
+			$share->setSendPasswordByTalk((bool) $data['password_by_talk']);
1027 1027
 			$share->setToken($data['token']);
1028 1028
 		}
1029 1029
 
1030 1030
 		$share->setSharedBy($data['uid_initiator']);
1031 1031
 		$share->setShareOwner($data['uid_owner']);
1032 1032
 
1033
-		$share->setNodeId((int)$data['file_source']);
1033
+		$share->setNodeId((int) $data['file_source']);
1034 1034
 		$share->setNodeType($data['item_type']);
1035 1035
 
1036 1036
 		if ($data['expiration'] !== null) {
@@ -1047,7 +1047,7 @@  discard block
 block discarded – undo
1047 1047
 		}
1048 1048
 
1049 1049
 		$share->setProviderId($this->identifier());
1050
-		$share->setHideDownload((int)$data['hide_download'] === 1);
1050
+		$share->setHideDownload((int) $data['hide_download'] === 1);
1051 1051
 
1052 1052
 		return $share;
1053 1053
 	}
@@ -1076,7 +1076,7 @@  discard block
 block discarded – undo
1076 1076
 			$shareMap = [];
1077 1077
 
1078 1078
 			foreach ($shareSlice as $share) {
1079
-				$ids[] = (int)$share->getId();
1079
+				$ids[] = (int) $share->getId();
1080 1080
 				$shareMap[$share->getId()] = $share;
1081 1081
 			}
1082 1082
 
@@ -1094,8 +1094,8 @@  discard block
 block discarded – undo
1094 1094
 			$stmt = $query->execute();
1095 1095
 
1096 1096
 			while ($data = $stmt->fetch()) {
1097
-				$shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
1098
-				$shareMap[$data['parent']]->setStatus((int)$data['accepted']);
1097
+				$shareMap[$data['parent']]->setPermissions((int) $data['permissions']);
1098
+				$shareMap[$data['parent']]->setStatus((int) $data['accepted']);
1099 1099
 				$shareMap[$data['parent']]->setTarget($data['file_target']);
1100 1100
 				$shareMap[$data['parent']]->setParent($data['parent']);
1101 1101
 			}
@@ -1171,7 +1171,7 @@  discard block
 block discarded – undo
1171 1171
 				)
1172 1172
 			);
1173 1173
 		} else {
1174
-			\OC::$server->getLogger()->logException(new \InvalidArgumentException('Default share provider tried to delete all shares for type: ' . $shareType));
1174
+			\OC::$server->getLogger()->logException(new \InvalidArgumentException('Default share provider tried to delete all shares for type: '.$shareType));
1175 1175
 			return;
1176 1176
 		}
1177 1177
 
@@ -1197,7 +1197,7 @@  discard block
 block discarded – undo
1197 1197
 		$cursor = $qb->execute();
1198 1198
 		$ids = [];
1199 1199
 		while ($row = $cursor->fetch()) {
1200
-			$ids[] = (int)$row['id'];
1200
+			$ids[] = (int) $row['id'];
1201 1201
 		}
1202 1202
 		$cursor->closeCursor();
1203 1203
 
@@ -1240,7 +1240,7 @@  discard block
 block discarded – undo
1240 1240
 		$cursor = $qb->execute();
1241 1241
 		$ids = [];
1242 1242
 		while ($row = $cursor->fetch()) {
1243
-			$ids[] = (int)$row['id'];
1243
+			$ids[] = (int) $row['id'];
1244 1244
 		}
1245 1245
 		$cursor->closeCursor();
1246 1246
 
@@ -1295,7 +1295,7 @@  discard block
 block discarded – undo
1295 1295
 		$users = [];
1296 1296
 		$link = false;
1297 1297
 		while ($row = $cursor->fetch()) {
1298
-			$type = (int)$row['share_type'];
1298
+			$type = (int) $row['share_type'];
1299 1299
 			if ($type === IShare::TYPE_USER) {
1300 1300
 				$uid = $row['share_with'];
1301 1301
 				$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
@@ -1456,7 +1456,7 @@  discard block
 block discarded – undo
1456 1456
 			$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
1457 1457
 			if ($initiatorEmailAddress !== null) {
1458 1458
 				$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
1459
-				$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
1459
+				$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
1460 1460
 			} else {
1461 1461
 				$emailTemplate->addFooter();
1462 1462
 			}
Please login to merge, or discard this patch.
lib/private/Collaboration/Collaborators/LookupPlugin.php 1 patch
Indentation   +74 added lines, -74 removed lines patch added patch discarded remove patch
@@ -38,87 +38,87 @@
 block discarded – undo
38 38
 
39 39
 class LookupPlugin implements ISearchPlugin {
40 40
 
41
-	/** @var IConfig */
42
-	private $config;
43
-	/** @var IClientService */
44
-	private $clientService;
45
-	/** @var string remote part of the current user's cloud id */
46
-	private $currentUserRemote;
47
-	/** @var ICloudIdManager */
48
-	private $cloudIdManager;
49
-	/** @var ILogger */
50
-	private $logger;
41
+    /** @var IConfig */
42
+    private $config;
43
+    /** @var IClientService */
44
+    private $clientService;
45
+    /** @var string remote part of the current user's cloud id */
46
+    private $currentUserRemote;
47
+    /** @var ICloudIdManager */
48
+    private $cloudIdManager;
49
+    /** @var ILogger */
50
+    private $logger;
51 51
 
52
-	public function __construct(IConfig $config,
53
-								IClientService $clientService,
54
-								IUserSession $userSession,
55
-								ICloudIdManager $cloudIdManager,
56
-								ILogger $logger) {
57
-		$this->config = $config;
58
-		$this->clientService = $clientService;
59
-		$this->cloudIdManager = $cloudIdManager;
60
-		$currentUserCloudId = $userSession->getUser()->getCloudId();
61
-		$this->currentUserRemote = $cloudIdManager->resolveCloudId($currentUserCloudId)->getRemote();
62
-		$this->logger = $logger;
63
-	}
52
+    public function __construct(IConfig $config,
53
+                                IClientService $clientService,
54
+                                IUserSession $userSession,
55
+                                ICloudIdManager $cloudIdManager,
56
+                                ILogger $logger) {
57
+        $this->config = $config;
58
+        $this->clientService = $clientService;
59
+        $this->cloudIdManager = $cloudIdManager;
60
+        $currentUserCloudId = $userSession->getUser()->getCloudId();
61
+        $this->currentUserRemote = $cloudIdManager->resolveCloudId($currentUserCloudId)->getRemote();
62
+        $this->logger = $logger;
63
+    }
64 64
 
65
-	public function search($search, $limit, $offset, ISearchResult $searchResult) {
66
-		$isGlobalScaleEnabled = $this->config->getSystemValue('gs.enabled', false);
67
-		$isLookupServerEnabled = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'yes') === 'yes';
68
-		$hasInternetConnection = (bool)$this->config->getSystemValue('has_internet_connection', true);
65
+    public function search($search, $limit, $offset, ISearchResult $searchResult) {
66
+        $isGlobalScaleEnabled = $this->config->getSystemValue('gs.enabled', false);
67
+        $isLookupServerEnabled = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'yes') === 'yes';
68
+        $hasInternetConnection = (bool)$this->config->getSystemValue('has_internet_connection', true);
69 69
 
70
-		// if case of Global Scale we always search the lookup server
71
-		if (!$isGlobalScaleEnabled && (!$isLookupServerEnabled || !$hasInternetConnection)) {
72
-			return false;
73
-		}
70
+        // if case of Global Scale we always search the lookup server
71
+        if (!$isGlobalScaleEnabled && (!$isLookupServerEnabled || !$hasInternetConnection)) {
72
+            return false;
73
+        }
74 74
 
75
-		$lookupServerUrl = $this->config->getSystemValue('lookup_server', 'https://lookup.nextcloud.com');
76
-		if (empty($lookupServerUrl)) {
77
-			return false;
78
-		}
79
-		$lookupServerUrl = rtrim($lookupServerUrl, '/');
80
-		$result = [];
75
+        $lookupServerUrl = $this->config->getSystemValue('lookup_server', 'https://lookup.nextcloud.com');
76
+        if (empty($lookupServerUrl)) {
77
+            return false;
78
+        }
79
+        $lookupServerUrl = rtrim($lookupServerUrl, '/');
80
+        $result = [];
81 81
 
82
-		try {
83
-			$client = $this->clientService->newClient();
84
-			$response = $client->get(
85
-				$lookupServerUrl . '/users?search=' . urlencode($search),
86
-				[
87
-					'timeout' => 10,
88
-					'connect_timeout' => 3,
89
-				]
90
-			);
82
+        try {
83
+            $client = $this->clientService->newClient();
84
+            $response = $client->get(
85
+                $lookupServerUrl . '/users?search=' . urlencode($search),
86
+                [
87
+                    'timeout' => 10,
88
+                    'connect_timeout' => 3,
89
+                ]
90
+            );
91 91
 
92
-			$body = json_decode($response->getBody(), true);
92
+            $body = json_decode($response->getBody(), true);
93 93
 
94
-			foreach ($body as $lookup) {
95
-				try {
96
-					$remote = $this->cloudIdManager->resolveCloudId($lookup['federationId'])->getRemote();
97
-				} catch (\Exception $e) {
98
-					$this->logger->error('Can not parse federated cloud ID "' .  $lookup['federationId'] . '"');
99
-					$this->logger->error($e->getMessage());
100
-					continue;
101
-				}
102
-				if ($this->currentUserRemote === $remote) {
103
-					continue;
104
-				}
105
-				$name = isset($lookup['name']['value']) ? $lookup['name']['value'] : '';
106
-				$label = empty($name) ? $lookup['federationId'] : $name . ' (' . $lookup['federationId'] . ')';
107
-				$result[] = [
108
-					'label' => $label,
109
-					'value' => [
110
-						'shareType' => IShare::TYPE_REMOTE,
111
-						'shareWith' => $lookup['federationId'],
112
-					],
113
-					'extra' => $lookup,
114
-				];
115
-			}
116
-		} catch (\Exception $e) {
117
-		}
94
+            foreach ($body as $lookup) {
95
+                try {
96
+                    $remote = $this->cloudIdManager->resolveCloudId($lookup['federationId'])->getRemote();
97
+                } catch (\Exception $e) {
98
+                    $this->logger->error('Can not parse federated cloud ID "' .  $lookup['federationId'] . '"');
99
+                    $this->logger->error($e->getMessage());
100
+                    continue;
101
+                }
102
+                if ($this->currentUserRemote === $remote) {
103
+                    continue;
104
+                }
105
+                $name = isset($lookup['name']['value']) ? $lookup['name']['value'] : '';
106
+                $label = empty($name) ? $lookup['federationId'] : $name . ' (' . $lookup['federationId'] . ')';
107
+                $result[] = [
108
+                    'label' => $label,
109
+                    'value' => [
110
+                        'shareType' => IShare::TYPE_REMOTE,
111
+                        'shareWith' => $lookup['federationId'],
112
+                    ],
113
+                    'extra' => $lookup,
114
+                ];
115
+            }
116
+        } catch (\Exception $e) {
117
+        }
118 118
 
119
-		$type = new SearchResultType('lookup');
120
-		$searchResult->addResultSet($type, $result, []);
119
+        $type = new SearchResultType('lookup');
120
+        $searchResult->addResultSet($type, $result, []);
121 121
 
122
-		return false;
123
-	}
122
+        return false;
123
+    }
124 124
 }
Please login to merge, or discard this patch.
lib/private/Collaboration/Collaborators/GroupPlugin.php 1 patch
Indentation   +100 added lines, -100 removed lines patch added patch discarded remove patch
@@ -37,104 +37,104 @@
 block discarded – undo
37 37
 use OCP\Share\IShare;
38 38
 
39 39
 class GroupPlugin implements ISearchPlugin {
40
-	protected $shareeEnumeration;
41
-	protected $shareWithGroupOnly;
42
-
43
-	/** @var IGroupManager */
44
-	private $groupManager;
45
-	/** @var IConfig */
46
-	private $config;
47
-	/** @var IUserSession */
48
-	private $userSession;
49
-
50
-	public function __construct(IConfig $config, IGroupManager $groupManager, IUserSession $userSession) {
51
-		$this->groupManager = $groupManager;
52
-		$this->config = $config;
53
-		$this->userSession = $userSession;
54
-
55
-		$this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
56
-		$this->shareWithGroupOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
57
-		$this->shareeEnumerationInGroupOnly = $this->shareeEnumeration && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
58
-	}
59
-
60
-	public function search($search, $limit, $offset, ISearchResult $searchResult) {
61
-		$hasMoreResults = false;
62
-		$result = ['wide' => [], 'exact' => []];
63
-
64
-		$groups = $this->groupManager->search($search, $limit, $offset);
65
-		$groupIds = array_map(function (IGroup $group) {
66
-			return $group->getGID();
67
-		}, $groups);
68
-
69
-		if (!$this->shareeEnumeration || count($groups) < $limit) {
70
-			$hasMoreResults = true;
71
-		}
72
-
73
-		$userGroups =  [];
74
-		if (!empty($groups) && ($this->shareWithGroupOnly || $this->shareeEnumerationInGroupOnly)) {
75
-			// Intersect all the groups that match with the groups this user is a member of
76
-			$userGroups = $this->groupManager->getUserGroups($this->userSession->getUser());
77
-			$userGroups = array_map(function (IGroup $group) {
78
-				return $group->getGID();
79
-			}, $userGroups);
80
-			$groupIds = array_intersect($groupIds, $userGroups);
81
-		}
82
-
83
-		$lowerSearch = strtolower($search);
84
-		foreach ($groups as $group) {
85
-			if ($group->hideFromCollaboration()) {
86
-				continue;
87
-			}
88
-
89
-			// FIXME: use a more efficient approach
90
-			$gid = $group->getGID();
91
-			if (!in_array($gid, $groupIds)) {
92
-				continue;
93
-			}
94
-			if (strtolower($gid) === $lowerSearch || strtolower($group->getDisplayName()) === $lowerSearch) {
95
-				$result['exact'][] = [
96
-					'label' => $group->getDisplayName(),
97
-					'value' => [
98
-						'shareType' => IShare::TYPE_GROUP,
99
-						'shareWith' => $gid,
100
-					],
101
-				];
102
-			} else {
103
-				if ($this->shareeEnumerationInGroupOnly && !in_array($group->getGID(), $userGroups, true)) {
104
-					continue;
105
-				}
106
-				$result['wide'][] = [
107
-					'label' => $group->getDisplayName(),
108
-					'value' => [
109
-						'shareType' => IShare::TYPE_GROUP,
110
-						'shareWith' => $gid,
111
-					],
112
-				];
113
-			}
114
-		}
115
-
116
-		if ($offset === 0 && empty($result['exact'])) {
117
-			// On page one we try if the search result has a direct hit on the
118
-			// user id and if so, we add that to the exact match list
119
-			$group = $this->groupManager->get($search);
120
-			if ($group instanceof IGroup && (!$this->shareWithGroupOnly || in_array($group->getGID(), $userGroups))) {
121
-				$result['exact'][] = [
122
-					'label' => $group->getDisplayName(),
123
-					'value' => [
124
-						'shareType' => IShare::TYPE_GROUP,
125
-						'shareWith' => $group->getGID(),
126
-					],
127
-				];
128
-			}
129
-		}
130
-
131
-		if (!$this->shareeEnumeration) {
132
-			$result['wide'] = [];
133
-		}
134
-
135
-		$type = new SearchResultType('groups');
136
-		$searchResult->addResultSet($type, $result['wide'], $result['exact']);
137
-
138
-		return $hasMoreResults;
139
-	}
40
+    protected $shareeEnumeration;
41
+    protected $shareWithGroupOnly;
42
+
43
+    /** @var IGroupManager */
44
+    private $groupManager;
45
+    /** @var IConfig */
46
+    private $config;
47
+    /** @var IUserSession */
48
+    private $userSession;
49
+
50
+    public function __construct(IConfig $config, IGroupManager $groupManager, IUserSession $userSession) {
51
+        $this->groupManager = $groupManager;
52
+        $this->config = $config;
53
+        $this->userSession = $userSession;
54
+
55
+        $this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
56
+        $this->shareWithGroupOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
57
+        $this->shareeEnumerationInGroupOnly = $this->shareeEnumeration && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
58
+    }
59
+
60
+    public function search($search, $limit, $offset, ISearchResult $searchResult) {
61
+        $hasMoreResults = false;
62
+        $result = ['wide' => [], 'exact' => []];
63
+
64
+        $groups = $this->groupManager->search($search, $limit, $offset);
65
+        $groupIds = array_map(function (IGroup $group) {
66
+            return $group->getGID();
67
+        }, $groups);
68
+
69
+        if (!$this->shareeEnumeration || count($groups) < $limit) {
70
+            $hasMoreResults = true;
71
+        }
72
+
73
+        $userGroups =  [];
74
+        if (!empty($groups) && ($this->shareWithGroupOnly || $this->shareeEnumerationInGroupOnly)) {
75
+            // Intersect all the groups that match with the groups this user is a member of
76
+            $userGroups = $this->groupManager->getUserGroups($this->userSession->getUser());
77
+            $userGroups = array_map(function (IGroup $group) {
78
+                return $group->getGID();
79
+            }, $userGroups);
80
+            $groupIds = array_intersect($groupIds, $userGroups);
81
+        }
82
+
83
+        $lowerSearch = strtolower($search);
84
+        foreach ($groups as $group) {
85
+            if ($group->hideFromCollaboration()) {
86
+                continue;
87
+            }
88
+
89
+            // FIXME: use a more efficient approach
90
+            $gid = $group->getGID();
91
+            if (!in_array($gid, $groupIds)) {
92
+                continue;
93
+            }
94
+            if (strtolower($gid) === $lowerSearch || strtolower($group->getDisplayName()) === $lowerSearch) {
95
+                $result['exact'][] = [
96
+                    'label' => $group->getDisplayName(),
97
+                    'value' => [
98
+                        'shareType' => IShare::TYPE_GROUP,
99
+                        'shareWith' => $gid,
100
+                    ],
101
+                ];
102
+            } else {
103
+                if ($this->shareeEnumerationInGroupOnly && !in_array($group->getGID(), $userGroups, true)) {
104
+                    continue;
105
+                }
106
+                $result['wide'][] = [
107
+                    'label' => $group->getDisplayName(),
108
+                    'value' => [
109
+                        'shareType' => IShare::TYPE_GROUP,
110
+                        'shareWith' => $gid,
111
+                    ],
112
+                ];
113
+            }
114
+        }
115
+
116
+        if ($offset === 0 && empty($result['exact'])) {
117
+            // On page one we try if the search result has a direct hit on the
118
+            // user id and if so, we add that to the exact match list
119
+            $group = $this->groupManager->get($search);
120
+            if ($group instanceof IGroup && (!$this->shareWithGroupOnly || in_array($group->getGID(), $userGroups))) {
121
+                $result['exact'][] = [
122
+                    'label' => $group->getDisplayName(),
123
+                    'value' => [
124
+                        'shareType' => IShare::TYPE_GROUP,
125
+                        'shareWith' => $group->getGID(),
126
+                    ],
127
+                ];
128
+            }
129
+        }
130
+
131
+        if (!$this->shareeEnumeration) {
132
+            $result['wide'] = [];
133
+        }
134
+
135
+        $type = new SearchResultType('groups');
136
+        $searchResult->addResultSet($type, $result['wide'], $result['exact']);
137
+
138
+        return $hasMoreResults;
139
+    }
140 140
 }
Please login to merge, or discard this patch.