Completed
Push — master ( 60d45e...348d97 )
by Joas
14:45
created
lib/private/Share20/LegacyHooks.php 1 patch
Indentation   +58 added lines, -58 removed lines patch added patch discarded remove patch
@@ -27,74 +27,74 @@
 block discarded – undo
27 27
 use Symfony\Component\EventDispatcher\GenericEvent;
28 28
 
29 29
 class LegacyHooks {
30
-	/** @var EventDispatcher */
31
-	private $eventDispatcher;
30
+    /** @var EventDispatcher */
31
+    private $eventDispatcher;
32 32
 
33
-	/**
34
-	 * LegacyHooks constructor.
35
-	 *
36
-	 * @param EventDispatcher $eventDispatcher
37
-	 */
38
-	public function __construct(EventDispatcher $eventDispatcher) {
39
-		$this->eventDispatcher = $eventDispatcher;
33
+    /**
34
+     * LegacyHooks constructor.
35
+     *
36
+     * @param EventDispatcher $eventDispatcher
37
+     */
38
+    public function __construct(EventDispatcher $eventDispatcher) {
39
+        $this->eventDispatcher = $eventDispatcher;
40 40
 
41
-		$this->eventDispatcher->addListener('OCP\Share::preUnshare', [$this, 'preUnshare']);
42
-		$this->eventDispatcher->addListener('OCP\Share::postUnshare', [$this, 'postUnshare']);
43
-	}
41
+        $this->eventDispatcher->addListener('OCP\Share::preUnshare', [$this, 'preUnshare']);
42
+        $this->eventDispatcher->addListener('OCP\Share::postUnshare', [$this, 'postUnshare']);
43
+    }
44 44
 
45
-	/**
46
-	 * @param GenericEvent $e
47
-	 */
48
-	public function preUnshare(GenericEvent $e) {
49
-		/** @var IShare $share */
50
-		$share = $e->getSubject();
45
+    /**
46
+     * @param GenericEvent $e
47
+     */
48
+    public function preUnshare(GenericEvent $e) {
49
+        /** @var IShare $share */
50
+        $share = $e->getSubject();
51 51
 
52
-		$formatted = $this->formatHookParams($share);
53
-		\OC_Hook::emit('OCP\Share', 'pre_unshare', $formatted);
54
-	}
52
+        $formatted = $this->formatHookParams($share);
53
+        \OC_Hook::emit('OCP\Share', 'pre_unshare', $formatted);
54
+    }
55 55
 
56
-	/**
57
-	 * @param GenericEvent $e
58
-	 */
59
-	public function postUnshare(GenericEvent $e) {
60
-		/** @var IShare $share */
61
-		$share = $e->getSubject();
56
+    /**
57
+     * @param GenericEvent $e
58
+     */
59
+    public function postUnshare(GenericEvent $e) {
60
+        /** @var IShare $share */
61
+        $share = $e->getSubject();
62 62
 
63
-		$formatted = $this->formatHookParams($share);
63
+        $formatted = $this->formatHookParams($share);
64 64
 
65
-		/** @var IShare[] $deletedShares */
66
-		$deletedShares = $e->getArgument('deletedShares');
65
+        /** @var IShare[] $deletedShares */
66
+        $deletedShares = $e->getArgument('deletedShares');
67 67
 
68
-		$formattedDeletedShares = array_map(function($share) {
69
-			return $this->formatHookParams($share);
70
-		}, $deletedShares);
68
+        $formattedDeletedShares = array_map(function($share) {
69
+            return $this->formatHookParams($share);
70
+        }, $deletedShares);
71 71
 
72
-		$formatted['deletedShares'] = $formattedDeletedShares;
72
+        $formatted['deletedShares'] = $formattedDeletedShares;
73 73
 
74
-		\OC_Hook::emit('OCP\Share', 'pre_unshare', $formatted);
75
-	}
74
+        \OC_Hook::emit('OCP\Share', 'pre_unshare', $formatted);
75
+    }
76 76
 
77
-	private function formatHookParams(IShare $share) {
78
-		// Prepare hook
79
-		$shareType = $share->getShareType();
80
-		$sharedWith = '';
81
-		if ($shareType === \OCP\Share::SHARE_TYPE_USER ||
82
-			$shareType === \OCP\Share::SHARE_TYPE_GROUP ||
83
-			$shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
84
-			$sharedWith = $share->getSharedWith();
85
-		}
77
+    private function formatHookParams(IShare $share) {
78
+        // Prepare hook
79
+        $shareType = $share->getShareType();
80
+        $sharedWith = '';
81
+        if ($shareType === \OCP\Share::SHARE_TYPE_USER ||
82
+            $shareType === \OCP\Share::SHARE_TYPE_GROUP ||
83
+            $shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
84
+            $sharedWith = $share->getSharedWith();
85
+        }
86 86
 
87
-		$hookParams = [
88
-			'id' => $share->getId(),
89
-			'itemType' => $share->getNodeType(),
90
-			'itemSource' => $share->getNodeId(),
91
-			'shareType' => $shareType,
92
-			'shareWith' => $sharedWith,
93
-			'itemparent' => method_exists($share, 'getParent') ? $share->getParent() : '',
94
-			'uidOwner' => $share->getSharedBy(),
95
-			'fileSource' => $share->getNodeId(),
96
-			'fileTarget' => $share->getTarget()
97
-		];
98
-		return $hookParams;
99
-	}
87
+        $hookParams = [
88
+            'id' => $share->getId(),
89
+            'itemType' => $share->getNodeType(),
90
+            'itemSource' => $share->getNodeId(),
91
+            'shareType' => $shareType,
92
+            'shareWith' => $sharedWith,
93
+            'itemparent' => method_exists($share, 'getParent') ? $share->getParent() : '',
94
+            'uidOwner' => $share->getSharedBy(),
95
+            'fileSource' => $share->getNodeId(),
96
+            'fileTarget' => $share->getTarget()
97
+        ];
98
+        return $hookParams;
99
+    }
100 100
 }
Please login to merge, or discard this patch.
lib/private/Share20/Manager.php 1 patch
Indentation   +1243 added lines, -1243 removed lines patch added patch discarded remove patch
@@ -57,1270 +57,1270 @@
 block discarded – undo
57 57
  */
58 58
 class Manager implements IManager {
59 59
 
60
-	/** @var IProviderFactory */
61
-	private $factory;
62
-	/** @var ILogger */
63
-	private $logger;
64
-	/** @var IConfig */
65
-	private $config;
66
-	/** @var ISecureRandom */
67
-	private $secureRandom;
68
-	/** @var IHasher */
69
-	private $hasher;
70
-	/** @var IMountManager */
71
-	private $mountManager;
72
-	/** @var IGroupManager */
73
-	private $groupManager;
74
-	/** @var IL10N */
75
-	private $l;
76
-	/** @var IUserManager */
77
-	private $userManager;
78
-	/** @var IRootFolder */
79
-	private $rootFolder;
80
-	/** @var CappedMemoryCache */
81
-	private $sharingDisabledForUsersCache;
82
-	/** @var EventDispatcher */
83
-	private $eventDispatcher;
84
-	/** @var LegacyHooks */
85
-	private $legacyHooks;
86
-
87
-
88
-	/**
89
-	 * Manager constructor.
90
-	 *
91
-	 * @param ILogger $logger
92
-	 * @param IConfig $config
93
-	 * @param ISecureRandom $secureRandom
94
-	 * @param IHasher $hasher
95
-	 * @param IMountManager $mountManager
96
-	 * @param IGroupManager $groupManager
97
-	 * @param IL10N $l
98
-	 * @param IProviderFactory $factory
99
-	 * @param IUserManager $userManager
100
-	 * @param IRootFolder $rootFolder
101
-	 * @param EventDispatcher $eventDispatcher
102
-	 */
103
-	public function __construct(
104
-			ILogger $logger,
105
-			IConfig $config,
106
-			ISecureRandom $secureRandom,
107
-			IHasher $hasher,
108
-			IMountManager $mountManager,
109
-			IGroupManager $groupManager,
110
-			IL10N $l,
111
-			IProviderFactory $factory,
112
-			IUserManager $userManager,
113
-			IRootFolder $rootFolder,
114
-			EventDispatcher $eventDispatcher
115
-	) {
116
-		$this->logger = $logger;
117
-		$this->config = $config;
118
-		$this->secureRandom = $secureRandom;
119
-		$this->hasher = $hasher;
120
-		$this->mountManager = $mountManager;
121
-		$this->groupManager = $groupManager;
122
-		$this->l = $l;
123
-		$this->factory = $factory;
124
-		$this->userManager = $userManager;
125
-		$this->rootFolder = $rootFolder;
126
-		$this->eventDispatcher = $eventDispatcher;
127
-		$this->sharingDisabledForUsersCache = new CappedMemoryCache();
128
-		$this->legacyHooks = new LegacyHooks($this->eventDispatcher);
129
-	}
130
-
131
-	/**
132
-	 * Convert from a full share id to a tuple (providerId, shareId)
133
-	 *
134
-	 * @param string $id
135
-	 * @return string[]
136
-	 */
137
-	private function splitFullId($id) {
138
-		return explode(':', $id, 2);
139
-	}
140
-
141
-	/**
142
-	 * Verify if a password meets all requirements
143
-	 *
144
-	 * @param string $password
145
-	 * @throws \Exception
146
-	 */
147
-	protected function verifyPassword($password) {
148
-		if ($password === null) {
149
-			// No password is set, check if this is allowed.
150
-			if ($this->shareApiLinkEnforcePassword()) {
151
-				throw new \InvalidArgumentException('Passwords are enforced for link shares');
152
-			}
153
-
154
-			return;
155
-		}
156
-
157
-		// Let others verify the password
158
-		try {
159
-			$event = new GenericEvent($password);
160
-			$this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
161
-		} catch (HintException $e) {
162
-			throw new \Exception($e->getHint());
163
-		}
164
-	}
165
-
166
-	/**
167
-	 * Check for generic requirements before creating a share
168
-	 *
169
-	 * @param \OCP\Share\IShare $share
170
-	 * @throws \InvalidArgumentException
171
-	 * @throws GenericShareException
172
-	 */
173
-	protected function generalCreateChecks(\OCP\Share\IShare $share) {
174
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
175
-			// We expect a valid user as sharedWith for user shares
176
-			if (!$this->userManager->userExists($share->getSharedWith())) {
177
-				throw new \InvalidArgumentException('SharedWith is not a valid user');
178
-			}
179
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
180
-			// We expect a valid group as sharedWith for group shares
181
-			if (!$this->groupManager->groupExists($share->getSharedWith())) {
182
-				throw new \InvalidArgumentException('SharedWith is not a valid group');
183
-			}
184
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
185
-			if ($share->getSharedWith() !== null) {
186
-				throw new \InvalidArgumentException('SharedWith should be empty');
187
-			}
188
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
189
-			if ($share->getSharedWith() === null) {
190
-				throw new \InvalidArgumentException('SharedWith should not be empty');
191
-			}
192
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
193
-			if ($share->getSharedWith() === null) {
194
-				throw new \InvalidArgumentException('SharedWith should not be empty');
195
-			}
196
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
197
-			$circle = \OCA\Circles\Api\Circles::detailsCircle($share->getSharedWith());
198
-			if ($circle === null) {
199
-				throw new \InvalidArgumentException('SharedWith is not a valid circle');
200
-			}
201
-		} else {
202
-			// We can't handle other types yet
203
-			throw new \InvalidArgumentException('unknown share type');
204
-		}
205
-
206
-		// Verify the initiator of the share is set
207
-		if ($share->getSharedBy() === null) {
208
-			throw new \InvalidArgumentException('SharedBy should be set');
209
-		}
210
-
211
-		// Cannot share with yourself
212
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
213
-			$share->getSharedWith() === $share->getSharedBy()) {
214
-			throw new \InvalidArgumentException('Can\'t share with yourself');
215
-		}
216
-
217
-		// The path should be set
218
-		if ($share->getNode() === null) {
219
-			throw new \InvalidArgumentException('Path should be set');
220
-		}
221
-
222
-		// And it should be a file or a folder
223
-		if (!($share->getNode() instanceof \OCP\Files\File) &&
224
-				!($share->getNode() instanceof \OCP\Files\Folder)) {
225
-			throw new \InvalidArgumentException('Path should be either a file or a folder');
226
-		}
227
-
228
-		// And you can't share your rootfolder
229
-		if ($this->userManager->userExists($share->getSharedBy())) {
230
-			$sharedPath = $this->rootFolder->getUserFolder($share->getSharedBy())->getPath();
231
-		} else {
232
-			$sharedPath = $this->rootFolder->getUserFolder($share->getShareOwner())->getPath();
233
-		}
234
-		if ($sharedPath === $share->getNode()->getPath()) {
235
-			throw new \InvalidArgumentException('You can\'t share your root folder');
236
-		}
237
-
238
-		// Check if we actually have share permissions
239
-		if (!$share->getNode()->isShareable()) {
240
-			$message_t = $this->l->t('You are not allowed to share %s', [$share->getNode()->getPath()]);
241
-			throw new GenericShareException($message_t, $message_t, 404);
242
-		}
243
-
244
-		// Permissions should be set
245
-		if ($share->getPermissions() === null) {
246
-			throw new \InvalidArgumentException('A share requires permissions');
247
-		}
248
-
249
-		/*
60
+    /** @var IProviderFactory */
61
+    private $factory;
62
+    /** @var ILogger */
63
+    private $logger;
64
+    /** @var IConfig */
65
+    private $config;
66
+    /** @var ISecureRandom */
67
+    private $secureRandom;
68
+    /** @var IHasher */
69
+    private $hasher;
70
+    /** @var IMountManager */
71
+    private $mountManager;
72
+    /** @var IGroupManager */
73
+    private $groupManager;
74
+    /** @var IL10N */
75
+    private $l;
76
+    /** @var IUserManager */
77
+    private $userManager;
78
+    /** @var IRootFolder */
79
+    private $rootFolder;
80
+    /** @var CappedMemoryCache */
81
+    private $sharingDisabledForUsersCache;
82
+    /** @var EventDispatcher */
83
+    private $eventDispatcher;
84
+    /** @var LegacyHooks */
85
+    private $legacyHooks;
86
+
87
+
88
+    /**
89
+     * Manager constructor.
90
+     *
91
+     * @param ILogger $logger
92
+     * @param IConfig $config
93
+     * @param ISecureRandom $secureRandom
94
+     * @param IHasher $hasher
95
+     * @param IMountManager $mountManager
96
+     * @param IGroupManager $groupManager
97
+     * @param IL10N $l
98
+     * @param IProviderFactory $factory
99
+     * @param IUserManager $userManager
100
+     * @param IRootFolder $rootFolder
101
+     * @param EventDispatcher $eventDispatcher
102
+     */
103
+    public function __construct(
104
+            ILogger $logger,
105
+            IConfig $config,
106
+            ISecureRandom $secureRandom,
107
+            IHasher $hasher,
108
+            IMountManager $mountManager,
109
+            IGroupManager $groupManager,
110
+            IL10N $l,
111
+            IProviderFactory $factory,
112
+            IUserManager $userManager,
113
+            IRootFolder $rootFolder,
114
+            EventDispatcher $eventDispatcher
115
+    ) {
116
+        $this->logger = $logger;
117
+        $this->config = $config;
118
+        $this->secureRandom = $secureRandom;
119
+        $this->hasher = $hasher;
120
+        $this->mountManager = $mountManager;
121
+        $this->groupManager = $groupManager;
122
+        $this->l = $l;
123
+        $this->factory = $factory;
124
+        $this->userManager = $userManager;
125
+        $this->rootFolder = $rootFolder;
126
+        $this->eventDispatcher = $eventDispatcher;
127
+        $this->sharingDisabledForUsersCache = new CappedMemoryCache();
128
+        $this->legacyHooks = new LegacyHooks($this->eventDispatcher);
129
+    }
130
+
131
+    /**
132
+     * Convert from a full share id to a tuple (providerId, shareId)
133
+     *
134
+     * @param string $id
135
+     * @return string[]
136
+     */
137
+    private function splitFullId($id) {
138
+        return explode(':', $id, 2);
139
+    }
140
+
141
+    /**
142
+     * Verify if a password meets all requirements
143
+     *
144
+     * @param string $password
145
+     * @throws \Exception
146
+     */
147
+    protected function verifyPassword($password) {
148
+        if ($password === null) {
149
+            // No password is set, check if this is allowed.
150
+            if ($this->shareApiLinkEnforcePassword()) {
151
+                throw new \InvalidArgumentException('Passwords are enforced for link shares');
152
+            }
153
+
154
+            return;
155
+        }
156
+
157
+        // Let others verify the password
158
+        try {
159
+            $event = new GenericEvent($password);
160
+            $this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
161
+        } catch (HintException $e) {
162
+            throw new \Exception($e->getHint());
163
+        }
164
+    }
165
+
166
+    /**
167
+     * Check for generic requirements before creating a share
168
+     *
169
+     * @param \OCP\Share\IShare $share
170
+     * @throws \InvalidArgumentException
171
+     * @throws GenericShareException
172
+     */
173
+    protected function generalCreateChecks(\OCP\Share\IShare $share) {
174
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
175
+            // We expect a valid user as sharedWith for user shares
176
+            if (!$this->userManager->userExists($share->getSharedWith())) {
177
+                throw new \InvalidArgumentException('SharedWith is not a valid user');
178
+            }
179
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
180
+            // We expect a valid group as sharedWith for group shares
181
+            if (!$this->groupManager->groupExists($share->getSharedWith())) {
182
+                throw new \InvalidArgumentException('SharedWith is not a valid group');
183
+            }
184
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
185
+            if ($share->getSharedWith() !== null) {
186
+                throw new \InvalidArgumentException('SharedWith should be empty');
187
+            }
188
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
189
+            if ($share->getSharedWith() === null) {
190
+                throw new \InvalidArgumentException('SharedWith should not be empty');
191
+            }
192
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
193
+            if ($share->getSharedWith() === null) {
194
+                throw new \InvalidArgumentException('SharedWith should not be empty');
195
+            }
196
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
197
+            $circle = \OCA\Circles\Api\Circles::detailsCircle($share->getSharedWith());
198
+            if ($circle === null) {
199
+                throw new \InvalidArgumentException('SharedWith is not a valid circle');
200
+            }
201
+        } else {
202
+            // We can't handle other types yet
203
+            throw new \InvalidArgumentException('unknown share type');
204
+        }
205
+
206
+        // Verify the initiator of the share is set
207
+        if ($share->getSharedBy() === null) {
208
+            throw new \InvalidArgumentException('SharedBy should be set');
209
+        }
210
+
211
+        // Cannot share with yourself
212
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
213
+            $share->getSharedWith() === $share->getSharedBy()) {
214
+            throw new \InvalidArgumentException('Can\'t share with yourself');
215
+        }
216
+
217
+        // The path should be set
218
+        if ($share->getNode() === null) {
219
+            throw new \InvalidArgumentException('Path should be set');
220
+        }
221
+
222
+        // And it should be a file or a folder
223
+        if (!($share->getNode() instanceof \OCP\Files\File) &&
224
+                !($share->getNode() instanceof \OCP\Files\Folder)) {
225
+            throw new \InvalidArgumentException('Path should be either a file or a folder');
226
+        }
227
+
228
+        // And you can't share your rootfolder
229
+        if ($this->userManager->userExists($share->getSharedBy())) {
230
+            $sharedPath = $this->rootFolder->getUserFolder($share->getSharedBy())->getPath();
231
+        } else {
232
+            $sharedPath = $this->rootFolder->getUserFolder($share->getShareOwner())->getPath();
233
+        }
234
+        if ($sharedPath === $share->getNode()->getPath()) {
235
+            throw new \InvalidArgumentException('You can\'t share your root folder');
236
+        }
237
+
238
+        // Check if we actually have share permissions
239
+        if (!$share->getNode()->isShareable()) {
240
+            $message_t = $this->l->t('You are not allowed to share %s', [$share->getNode()->getPath()]);
241
+            throw new GenericShareException($message_t, $message_t, 404);
242
+        }
243
+
244
+        // Permissions should be set
245
+        if ($share->getPermissions() === null) {
246
+            throw new \InvalidArgumentException('A share requires permissions');
247
+        }
248
+
249
+        /*
250 250
 		 * Quick fix for #23536
251 251
 		 * Non moveable mount points do not have update and delete permissions
252 252
 		 * while we 'most likely' do have that on the storage.
253 253
 		 */
254
-		$permissions = $share->getNode()->getPermissions();
255
-		$mount = $share->getNode()->getMountPoint();
256
-		if (!($mount instanceof MoveableMount)) {
257
-			$permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
258
-		}
259
-
260
-		// Check that we do not share with more permissions than we have
261
-		if ($share->getPermissions() & ~$permissions) {
262
-			$message_t = $this->l->t('Cannot increase permissions of %s', [$share->getNode()->getPath()]);
263
-			throw new GenericShareException($message_t, $message_t, 404);
264
-		}
265
-
266
-
267
-		// Check that read permissions are always set
268
-		// Link shares are allowed to have no read permissions to allow upload to hidden folders
269
-		if ($share->getShareType() !== \OCP\Share::SHARE_TYPE_LINK &&
270
-			($share->getPermissions() & \OCP\Constants::PERMISSION_READ) === 0) {
271
-			throw new \InvalidArgumentException('Shares need at least read permissions');
272
-		}
273
-
274
-		if ($share->getNode() instanceof \OCP\Files\File) {
275
-			if ($share->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
276
-				$message_t = $this->l->t('Files can\'t be shared with delete permissions');
277
-				throw new GenericShareException($message_t);
278
-			}
279
-			if ($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE) {
280
-				$message_t = $this->l->t('Files can\'t be shared with create permissions');
281
-				throw new GenericShareException($message_t);
282
-			}
283
-		}
284
-	}
285
-
286
-	/**
287
-	 * Validate if the expiration date fits the system settings
288
-	 *
289
-	 * @param \OCP\Share\IShare $share The share to validate the expiration date of
290
-	 * @return \OCP\Share\IShare The modified share object
291
-	 * @throws GenericShareException
292
-	 * @throws \InvalidArgumentException
293
-	 * @throws \Exception
294
-	 */
295
-	protected function validateExpirationDate(\OCP\Share\IShare $share) {
296
-
297
-		$expirationDate = $share->getExpirationDate();
298
-
299
-		if ($expirationDate !== null) {
300
-			//Make sure the expiration date is a date
301
-			$expirationDate->setTime(0, 0, 0);
302
-
303
-			$date = new \DateTime();
304
-			$date->setTime(0, 0, 0);
305
-			if ($date >= $expirationDate) {
306
-				$message = $this->l->t('Expiration date is in the past');
307
-				throw new GenericShareException($message, $message, 404);
308
-			}
309
-		}
310
-
311
-		// If expiredate is empty set a default one if there is a default
312
-		$fullId = null;
313
-		try {
314
-			$fullId = $share->getFullId();
315
-		} catch (\UnexpectedValueException $e) {
316
-			// This is a new share
317
-		}
318
-
319
-		if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
320
-			$expirationDate = new \DateTime();
321
-			$expirationDate->setTime(0,0,0);
322
-			$expirationDate->add(new \DateInterval('P'.$this->shareApiLinkDefaultExpireDays().'D'));
323
-		}
324
-
325
-		// If we enforce the expiration date check that is does not exceed
326
-		if ($this->shareApiLinkDefaultExpireDateEnforced()) {
327
-			if ($expirationDate === null) {
328
-				throw new \InvalidArgumentException('Expiration date is enforced');
329
-			}
330
-
331
-			$date = new \DateTime();
332
-			$date->setTime(0, 0, 0);
333
-			$date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
334
-			if ($date < $expirationDate) {
335
-				$message = $this->l->t('Cannot set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
336
-				throw new GenericShareException($message, $message, 404);
337
-			}
338
-		}
339
-
340
-		$accepted = true;
341
-		$message = '';
342
-		\OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
343
-			'expirationDate' => &$expirationDate,
344
-			'accepted' => &$accepted,
345
-			'message' => &$message,
346
-			'passwordSet' => $share->getPassword() !== null,
347
-		]);
348
-
349
-		if (!$accepted) {
350
-			throw new \Exception($message);
351
-		}
352
-
353
-		$share->setExpirationDate($expirationDate);
354
-
355
-		return $share;
356
-	}
357
-
358
-	/**
359
-	 * Check for pre share requirements for user shares
360
-	 *
361
-	 * @param \OCP\Share\IShare $share
362
-	 * @throws \Exception
363
-	 */
364
-	protected function userCreateChecks(\OCP\Share\IShare $share) {
365
-		// Check if we can share with group members only
366
-		if ($this->shareWithGroupMembersOnly()) {
367
-			$sharedBy = $this->userManager->get($share->getSharedBy());
368
-			$sharedWith = $this->userManager->get($share->getSharedWith());
369
-			// Verify we can share with this user
370
-			$groups = array_intersect(
371
-					$this->groupManager->getUserGroupIds($sharedBy),
372
-					$this->groupManager->getUserGroupIds($sharedWith)
373
-			);
374
-			if (empty($groups)) {
375
-				throw new \Exception('Only sharing with group members is allowed');
376
-			}
377
-		}
378
-
379
-		/*
254
+        $permissions = $share->getNode()->getPermissions();
255
+        $mount = $share->getNode()->getMountPoint();
256
+        if (!($mount instanceof MoveableMount)) {
257
+            $permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
258
+        }
259
+
260
+        // Check that we do not share with more permissions than we have
261
+        if ($share->getPermissions() & ~$permissions) {
262
+            $message_t = $this->l->t('Cannot increase permissions of %s', [$share->getNode()->getPath()]);
263
+            throw new GenericShareException($message_t, $message_t, 404);
264
+        }
265
+
266
+
267
+        // Check that read permissions are always set
268
+        // Link shares are allowed to have no read permissions to allow upload to hidden folders
269
+        if ($share->getShareType() !== \OCP\Share::SHARE_TYPE_LINK &&
270
+            ($share->getPermissions() & \OCP\Constants::PERMISSION_READ) === 0) {
271
+            throw new \InvalidArgumentException('Shares need at least read permissions');
272
+        }
273
+
274
+        if ($share->getNode() instanceof \OCP\Files\File) {
275
+            if ($share->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
276
+                $message_t = $this->l->t('Files can\'t be shared with delete permissions');
277
+                throw new GenericShareException($message_t);
278
+            }
279
+            if ($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE) {
280
+                $message_t = $this->l->t('Files can\'t be shared with create permissions');
281
+                throw new GenericShareException($message_t);
282
+            }
283
+        }
284
+    }
285
+
286
+    /**
287
+     * Validate if the expiration date fits the system settings
288
+     *
289
+     * @param \OCP\Share\IShare $share The share to validate the expiration date of
290
+     * @return \OCP\Share\IShare The modified share object
291
+     * @throws GenericShareException
292
+     * @throws \InvalidArgumentException
293
+     * @throws \Exception
294
+     */
295
+    protected function validateExpirationDate(\OCP\Share\IShare $share) {
296
+
297
+        $expirationDate = $share->getExpirationDate();
298
+
299
+        if ($expirationDate !== null) {
300
+            //Make sure the expiration date is a date
301
+            $expirationDate->setTime(0, 0, 0);
302
+
303
+            $date = new \DateTime();
304
+            $date->setTime(0, 0, 0);
305
+            if ($date >= $expirationDate) {
306
+                $message = $this->l->t('Expiration date is in the past');
307
+                throw new GenericShareException($message, $message, 404);
308
+            }
309
+        }
310
+
311
+        // If expiredate is empty set a default one if there is a default
312
+        $fullId = null;
313
+        try {
314
+            $fullId = $share->getFullId();
315
+        } catch (\UnexpectedValueException $e) {
316
+            // This is a new share
317
+        }
318
+
319
+        if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
320
+            $expirationDate = new \DateTime();
321
+            $expirationDate->setTime(0,0,0);
322
+            $expirationDate->add(new \DateInterval('P'.$this->shareApiLinkDefaultExpireDays().'D'));
323
+        }
324
+
325
+        // If we enforce the expiration date check that is does not exceed
326
+        if ($this->shareApiLinkDefaultExpireDateEnforced()) {
327
+            if ($expirationDate === null) {
328
+                throw new \InvalidArgumentException('Expiration date is enforced');
329
+            }
330
+
331
+            $date = new \DateTime();
332
+            $date->setTime(0, 0, 0);
333
+            $date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
334
+            if ($date < $expirationDate) {
335
+                $message = $this->l->t('Cannot set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
336
+                throw new GenericShareException($message, $message, 404);
337
+            }
338
+        }
339
+
340
+        $accepted = true;
341
+        $message = '';
342
+        \OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
343
+            'expirationDate' => &$expirationDate,
344
+            'accepted' => &$accepted,
345
+            'message' => &$message,
346
+            'passwordSet' => $share->getPassword() !== null,
347
+        ]);
348
+
349
+        if (!$accepted) {
350
+            throw new \Exception($message);
351
+        }
352
+
353
+        $share->setExpirationDate($expirationDate);
354
+
355
+        return $share;
356
+    }
357
+
358
+    /**
359
+     * Check for pre share requirements for user shares
360
+     *
361
+     * @param \OCP\Share\IShare $share
362
+     * @throws \Exception
363
+     */
364
+    protected function userCreateChecks(\OCP\Share\IShare $share) {
365
+        // Check if we can share with group members only
366
+        if ($this->shareWithGroupMembersOnly()) {
367
+            $sharedBy = $this->userManager->get($share->getSharedBy());
368
+            $sharedWith = $this->userManager->get($share->getSharedWith());
369
+            // Verify we can share with this user
370
+            $groups = array_intersect(
371
+                    $this->groupManager->getUserGroupIds($sharedBy),
372
+                    $this->groupManager->getUserGroupIds($sharedWith)
373
+            );
374
+            if (empty($groups)) {
375
+                throw new \Exception('Only sharing with group members is allowed');
376
+            }
377
+        }
378
+
379
+        /*
380 380
 		 * TODO: Could be costly, fix
381 381
 		 *
382 382
 		 * Also this is not what we want in the future.. then we want to squash identical shares.
383 383
 		 */
384
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_USER);
385
-		$existingShares = $provider->getSharesByPath($share->getNode());
386
-		foreach($existingShares as $existingShare) {
387
-			// Ignore if it is the same share
388
-			try {
389
-				if ($existingShare->getFullId() === $share->getFullId()) {
390
-					continue;
391
-				}
392
-			} catch (\UnexpectedValueException $e) {
393
-				//Shares are not identical
394
-			}
395
-
396
-			// Identical share already existst
397
-			if ($existingShare->getSharedWith() === $share->getSharedWith()) {
398
-				throw new \Exception('Path already shared with this user');
399
-			}
400
-
401
-			// The share is already shared with this user via a group share
402
-			if ($existingShare->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
403
-				$group = $this->groupManager->get($existingShare->getSharedWith());
404
-				if (!is_null($group)) {
405
-					$user = $this->userManager->get($share->getSharedWith());
406
-
407
-					if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
408
-						throw new \Exception('Path already shared with this user');
409
-					}
410
-				}
411
-			}
412
-		}
413
-	}
414
-
415
-	/**
416
-	 * Check for pre share requirements for group shares
417
-	 *
418
-	 * @param \OCP\Share\IShare $share
419
-	 * @throws \Exception
420
-	 */
421
-	protected function groupCreateChecks(\OCP\Share\IShare $share) {
422
-		// Verify group shares are allowed
423
-		if (!$this->allowGroupSharing()) {
424
-			throw new \Exception('Group sharing is now allowed');
425
-		}
426
-
427
-		// Verify if the user can share with this group
428
-		if ($this->shareWithGroupMembersOnly()) {
429
-			$sharedBy = $this->userManager->get($share->getSharedBy());
430
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
431
-			if (is_null($sharedWith) || !$sharedWith->inGroup($sharedBy)) {
432
-				throw new \Exception('Only sharing within your own groups is allowed');
433
-			}
434
-		}
435
-
436
-		/*
384
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_USER);
385
+        $existingShares = $provider->getSharesByPath($share->getNode());
386
+        foreach($existingShares as $existingShare) {
387
+            // Ignore if it is the same share
388
+            try {
389
+                if ($existingShare->getFullId() === $share->getFullId()) {
390
+                    continue;
391
+                }
392
+            } catch (\UnexpectedValueException $e) {
393
+                //Shares are not identical
394
+            }
395
+
396
+            // Identical share already existst
397
+            if ($existingShare->getSharedWith() === $share->getSharedWith()) {
398
+                throw new \Exception('Path already shared with this user');
399
+            }
400
+
401
+            // The share is already shared with this user via a group share
402
+            if ($existingShare->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
403
+                $group = $this->groupManager->get($existingShare->getSharedWith());
404
+                if (!is_null($group)) {
405
+                    $user = $this->userManager->get($share->getSharedWith());
406
+
407
+                    if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
408
+                        throw new \Exception('Path already shared with this user');
409
+                    }
410
+                }
411
+            }
412
+        }
413
+    }
414
+
415
+    /**
416
+     * Check for pre share requirements for group shares
417
+     *
418
+     * @param \OCP\Share\IShare $share
419
+     * @throws \Exception
420
+     */
421
+    protected function groupCreateChecks(\OCP\Share\IShare $share) {
422
+        // Verify group shares are allowed
423
+        if (!$this->allowGroupSharing()) {
424
+            throw new \Exception('Group sharing is now allowed');
425
+        }
426
+
427
+        // Verify if the user can share with this group
428
+        if ($this->shareWithGroupMembersOnly()) {
429
+            $sharedBy = $this->userManager->get($share->getSharedBy());
430
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
431
+            if (is_null($sharedWith) || !$sharedWith->inGroup($sharedBy)) {
432
+                throw new \Exception('Only sharing within your own groups is allowed');
433
+            }
434
+        }
435
+
436
+        /*
437 437
 		 * TODO: Could be costly, fix
438 438
 		 *
439 439
 		 * Also this is not what we want in the future.. then we want to squash identical shares.
440 440
 		 */
441
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
442
-		$existingShares = $provider->getSharesByPath($share->getNode());
443
-		foreach($existingShares as $existingShare) {
444
-			try {
445
-				if ($existingShare->getFullId() === $share->getFullId()) {
446
-					continue;
447
-				}
448
-			} catch (\UnexpectedValueException $e) {
449
-				//It is a new share so just continue
450
-			}
451
-
452
-			if ($existingShare->getSharedWith() === $share->getSharedWith()) {
453
-				throw new \Exception('Path already shared with this group');
454
-			}
455
-		}
456
-	}
457
-
458
-	/**
459
-	 * Check for pre share requirements for link shares
460
-	 *
461
-	 * @param \OCP\Share\IShare $share
462
-	 * @throws \Exception
463
-	 */
464
-	protected function linkCreateChecks(\OCP\Share\IShare $share) {
465
-		// Are link shares allowed?
466
-		if (!$this->shareApiAllowLinks()) {
467
-			throw new \Exception('Link sharing not allowed');
468
-		}
469
-
470
-		// Link shares by definition can't have share permissions
471
-		if ($share->getPermissions() & \OCP\Constants::PERMISSION_SHARE) {
472
-			throw new \InvalidArgumentException('Link shares can\'t have reshare permissions');
473
-		}
474
-
475
-		// Check if public upload is allowed
476
-		if (!$this->shareApiLinkAllowPublicUpload() &&
477
-			($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE))) {
478
-			throw new \InvalidArgumentException('Public upload not allowed');
479
-		}
480
-	}
481
-
482
-	/**
483
-	 * To make sure we don't get invisible link shares we set the parent
484
-	 * of a link if it is a reshare. This is a quick word around
485
-	 * until we can properly display multiple link shares in the UI
486
-	 *
487
-	 * See: https://github.com/owncloud/core/issues/22295
488
-	 *
489
-	 * FIXME: Remove once multiple link shares can be properly displayed
490
-	 *
491
-	 * @param \OCP\Share\IShare $share
492
-	 */
493
-	protected function setLinkParent(\OCP\Share\IShare $share) {
494
-
495
-		// No sense in checking if the method is not there.
496
-		if (method_exists($share, 'setParent')) {
497
-			$storage = $share->getNode()->getStorage();
498
-			if ($storage->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
499
-				/** @var \OCA\Files_Sharing\SharedStorage $storage */
500
-				$share->setParent($storage->getShareId());
501
-			}
502
-		};
503
-	}
504
-
505
-	/**
506
-	 * @param File|Folder $path
507
-	 */
508
-	protected function pathCreateChecks($path) {
509
-		// Make sure that we do not share a path that contains a shared mountpoint
510
-		if ($path instanceof \OCP\Files\Folder) {
511
-			$mounts = $this->mountManager->findIn($path->getPath());
512
-			foreach($mounts as $mount) {
513
-				if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
514
-					throw new \InvalidArgumentException('Path contains files shared with you');
515
-				}
516
-			}
517
-		}
518
-	}
519
-
520
-	/**
521
-	 * Check if the user that is sharing can actually share
522
-	 *
523
-	 * @param \OCP\Share\IShare $share
524
-	 * @throws \Exception
525
-	 */
526
-	protected function canShare(\OCP\Share\IShare $share) {
527
-		if (!$this->shareApiEnabled()) {
528
-			throw new \Exception('The share API is disabled');
529
-		}
530
-
531
-		if ($this->sharingDisabledForUser($share->getSharedBy())) {
532
-			throw new \Exception('You are not allowed to share');
533
-		}
534
-	}
535
-
536
-	/**
537
-	 * Share a path
538
-	 *
539
-	 * @param \OCP\Share\IShare $share
540
-	 * @return Share The share object
541
-	 * @throws \Exception
542
-	 *
543
-	 * TODO: handle link share permissions or check them
544
-	 */
545
-	public function createShare(\OCP\Share\IShare $share) {
546
-		$this->canShare($share);
547
-
548
-		$this->generalCreateChecks($share);
549
-
550
-		// Verify if there are any issues with the path
551
-		$this->pathCreateChecks($share->getNode());
552
-
553
-		/*
441
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
442
+        $existingShares = $provider->getSharesByPath($share->getNode());
443
+        foreach($existingShares as $existingShare) {
444
+            try {
445
+                if ($existingShare->getFullId() === $share->getFullId()) {
446
+                    continue;
447
+                }
448
+            } catch (\UnexpectedValueException $e) {
449
+                //It is a new share so just continue
450
+            }
451
+
452
+            if ($existingShare->getSharedWith() === $share->getSharedWith()) {
453
+                throw new \Exception('Path already shared with this group');
454
+            }
455
+        }
456
+    }
457
+
458
+    /**
459
+     * Check for pre share requirements for link shares
460
+     *
461
+     * @param \OCP\Share\IShare $share
462
+     * @throws \Exception
463
+     */
464
+    protected function linkCreateChecks(\OCP\Share\IShare $share) {
465
+        // Are link shares allowed?
466
+        if (!$this->shareApiAllowLinks()) {
467
+            throw new \Exception('Link sharing not allowed');
468
+        }
469
+
470
+        // Link shares by definition can't have share permissions
471
+        if ($share->getPermissions() & \OCP\Constants::PERMISSION_SHARE) {
472
+            throw new \InvalidArgumentException('Link shares can\'t have reshare permissions');
473
+        }
474
+
475
+        // Check if public upload is allowed
476
+        if (!$this->shareApiLinkAllowPublicUpload() &&
477
+            ($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE))) {
478
+            throw new \InvalidArgumentException('Public upload not allowed');
479
+        }
480
+    }
481
+
482
+    /**
483
+     * To make sure we don't get invisible link shares we set the parent
484
+     * of a link if it is a reshare. This is a quick word around
485
+     * until we can properly display multiple link shares in the UI
486
+     *
487
+     * See: https://github.com/owncloud/core/issues/22295
488
+     *
489
+     * FIXME: Remove once multiple link shares can be properly displayed
490
+     *
491
+     * @param \OCP\Share\IShare $share
492
+     */
493
+    protected function setLinkParent(\OCP\Share\IShare $share) {
494
+
495
+        // No sense in checking if the method is not there.
496
+        if (method_exists($share, 'setParent')) {
497
+            $storage = $share->getNode()->getStorage();
498
+            if ($storage->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
499
+                /** @var \OCA\Files_Sharing\SharedStorage $storage */
500
+                $share->setParent($storage->getShareId());
501
+            }
502
+        };
503
+    }
504
+
505
+    /**
506
+     * @param File|Folder $path
507
+     */
508
+    protected function pathCreateChecks($path) {
509
+        // Make sure that we do not share a path that contains a shared mountpoint
510
+        if ($path instanceof \OCP\Files\Folder) {
511
+            $mounts = $this->mountManager->findIn($path->getPath());
512
+            foreach($mounts as $mount) {
513
+                if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
514
+                    throw new \InvalidArgumentException('Path contains files shared with you');
515
+                }
516
+            }
517
+        }
518
+    }
519
+
520
+    /**
521
+     * Check if the user that is sharing can actually share
522
+     *
523
+     * @param \OCP\Share\IShare $share
524
+     * @throws \Exception
525
+     */
526
+    protected function canShare(\OCP\Share\IShare $share) {
527
+        if (!$this->shareApiEnabled()) {
528
+            throw new \Exception('The share API is disabled');
529
+        }
530
+
531
+        if ($this->sharingDisabledForUser($share->getSharedBy())) {
532
+            throw new \Exception('You are not allowed to share');
533
+        }
534
+    }
535
+
536
+    /**
537
+     * Share a path
538
+     *
539
+     * @param \OCP\Share\IShare $share
540
+     * @return Share The share object
541
+     * @throws \Exception
542
+     *
543
+     * TODO: handle link share permissions or check them
544
+     */
545
+    public function createShare(\OCP\Share\IShare $share) {
546
+        $this->canShare($share);
547
+
548
+        $this->generalCreateChecks($share);
549
+
550
+        // Verify if there are any issues with the path
551
+        $this->pathCreateChecks($share->getNode());
552
+
553
+        /*
554 554
 		 * On creation of a share the owner is always the owner of the path
555 555
 		 * Except for mounted federated shares.
556 556
 		 */
557
-		$storage = $share->getNode()->getStorage();
558
-		if ($storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
559
-			$parent = $share->getNode()->getParent();
560
-			while($parent->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
561
-				$parent = $parent->getParent();
562
-			}
563
-			$share->setShareOwner($parent->getOwner()->getUID());
564
-		} else {
565
-			$share->setShareOwner($share->getNode()->getOwner()->getUID());
566
-		}
567
-
568
-		//Verify share type
569
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
570
-			$this->userCreateChecks($share);
571
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
572
-			$this->groupCreateChecks($share);
573
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
574
-			$this->linkCreateChecks($share);
575
-			$this->setLinkParent($share);
576
-
577
-			/*
557
+        $storage = $share->getNode()->getStorage();
558
+        if ($storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
559
+            $parent = $share->getNode()->getParent();
560
+            while($parent->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
561
+                $parent = $parent->getParent();
562
+            }
563
+            $share->setShareOwner($parent->getOwner()->getUID());
564
+        } else {
565
+            $share->setShareOwner($share->getNode()->getOwner()->getUID());
566
+        }
567
+
568
+        //Verify share type
569
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
570
+            $this->userCreateChecks($share);
571
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
572
+            $this->groupCreateChecks($share);
573
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
574
+            $this->linkCreateChecks($share);
575
+            $this->setLinkParent($share);
576
+
577
+            /*
578 578
 			 * For now ignore a set token.
579 579
 			 */
580
-			$share->setToken(
581
-				$this->secureRandom->generate(
582
-					\OC\Share\Constants::TOKEN_LENGTH,
583
-					\OCP\Security\ISecureRandom::CHAR_LOWER.
584
-					\OCP\Security\ISecureRandom::CHAR_UPPER.
585
-					\OCP\Security\ISecureRandom::CHAR_DIGITS
586
-				)
587
-			);
588
-
589
-			//Verify the expiration date
590
-			$this->validateExpirationDate($share);
591
-
592
-			//Verify the password
593
-			$this->verifyPassword($share->getPassword());
594
-
595
-			// If a password is set. Hash it!
596
-			if ($share->getPassword() !== null) {
597
-				$share->setPassword($this->hasher->hash($share->getPassword()));
598
-			}
599
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
600
-			$share->setToken(
601
-				$this->secureRandom->generate(
602
-					\OC\Share\Constants::TOKEN_LENGTH,
603
-					\OCP\Security\ISecureRandom::CHAR_LOWER.
604
-					\OCP\Security\ISecureRandom::CHAR_UPPER.
605
-					\OCP\Security\ISecureRandom::CHAR_DIGITS
606
-				)
607
-			);
608
-		}
609
-
610
-		// Cannot share with the owner
611
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
612
-			$share->getSharedWith() === $share->getShareOwner()) {
613
-			throw new \InvalidArgumentException('Can\'t share with the share owner');
614
-		}
615
-
616
-		// Generate the target
617
-		$target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName();
618
-		$target = \OC\Files\Filesystem::normalizePath($target);
619
-		$share->setTarget($target);
620
-
621
-		// Pre share hook
622
-		$run = true;
623
-		$error = '';
624
-		$preHookData = [
625
-			'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
626
-			'itemSource' => $share->getNode()->getId(),
627
-			'shareType' => $share->getShareType(),
628
-			'uidOwner' => $share->getSharedBy(),
629
-			'permissions' => $share->getPermissions(),
630
-			'fileSource' => $share->getNode()->getId(),
631
-			'expiration' => $share->getExpirationDate(),
632
-			'token' => $share->getToken(),
633
-			'itemTarget' => $share->getTarget(),
634
-			'shareWith' => $share->getSharedWith(),
635
-			'run' => &$run,
636
-			'error' => &$error,
637
-		];
638
-		\OC_Hook::emit('OCP\Share', 'pre_shared', $preHookData);
639
-
640
-		if ($run === false) {
641
-			throw new \Exception($error);
642
-		}
643
-
644
-		$oldShare = $share;
645
-		$provider = $this->factory->getProviderForType($share->getShareType());
646
-		$share = $provider->create($share);
647
-		//reuse the node we already have
648
-		$share->setNode($oldShare->getNode());
649
-
650
-		// Post share hook
651
-		$postHookData = [
652
-			'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
653
-			'itemSource' => $share->getNode()->getId(),
654
-			'shareType' => $share->getShareType(),
655
-			'uidOwner' => $share->getSharedBy(),
656
-			'permissions' => $share->getPermissions(),
657
-			'fileSource' => $share->getNode()->getId(),
658
-			'expiration' => $share->getExpirationDate(),
659
-			'token' => $share->getToken(),
660
-			'id' => $share->getId(),
661
-			'shareWith' => $share->getSharedWith(),
662
-			'itemTarget' => $share->getTarget(),
663
-			'fileTarget' => $share->getTarget(),
664
-		];
665
-
666
-		\OC_Hook::emit('OCP\Share', 'post_shared', $postHookData);
667
-
668
-		return $share;
669
-	}
670
-
671
-	/**
672
-	 * Update a share
673
-	 *
674
-	 * @param \OCP\Share\IShare $share
675
-	 * @return \OCP\Share\IShare The share object
676
-	 * @throws \InvalidArgumentException
677
-	 */
678
-	public function updateShare(\OCP\Share\IShare $share) {
679
-		$expirationDateUpdated = false;
680
-
681
-		$this->canShare($share);
682
-
683
-		try {
684
-			$originalShare = $this->getShareById($share->getFullId());
685
-		} catch (\UnexpectedValueException $e) {
686
-			throw new \InvalidArgumentException('Share does not have a full id');
687
-		}
688
-
689
-		// We can't change the share type!
690
-		if ($share->getShareType() !== $originalShare->getShareType()) {
691
-			throw new \InvalidArgumentException('Can\'t change share type');
692
-		}
693
-
694
-		// We can only change the recipient on user shares
695
-		if ($share->getSharedWith() !== $originalShare->getSharedWith() &&
696
-		    $share->getShareType() !== \OCP\Share::SHARE_TYPE_USER) {
697
-			throw new \InvalidArgumentException('Can only update recipient on user shares');
698
-		}
699
-
700
-		// Cannot share with the owner
701
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
702
-			$share->getSharedWith() === $share->getShareOwner()) {
703
-			throw new \InvalidArgumentException('Can\'t share with the share owner');
704
-		}
705
-
706
-		$this->generalCreateChecks($share);
707
-
708
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
709
-			$this->userCreateChecks($share);
710
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
711
-			$this->groupCreateChecks($share);
712
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
713
-			$this->linkCreateChecks($share);
714
-
715
-			// Password updated.
716
-			if ($share->getPassword() !== $originalShare->getPassword()) {
717
-				//Verify the password
718
-				$this->verifyPassword($share->getPassword());
719
-
720
-				// If a password is set. Hash it!
721
-				if ($share->getPassword() !== null) {
722
-					$share->setPassword($this->hasher->hash($share->getPassword()));
723
-				}
724
-			}
725
-
726
-			if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
727
-				//Verify the expiration date
728
-				$this->validateExpirationDate($share);
729
-				$expirationDateUpdated = true;
730
-			}
731
-		}
732
-
733
-		$this->pathCreateChecks($share->getNode());
734
-
735
-		// Now update the share!
736
-		$provider = $this->factory->getProviderForType($share->getShareType());
737
-		$share = $provider->update($share);
738
-
739
-		if ($expirationDateUpdated === true) {
740
-			\OC_Hook::emit('OCP\Share', 'post_set_expiration_date', [
741
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
742
-				'itemSource' => $share->getNode()->getId(),
743
-				'date' => $share->getExpirationDate(),
744
-				'uidOwner' => $share->getSharedBy(),
745
-			]);
746
-		}
747
-
748
-		if ($share->getPassword() !== $originalShare->getPassword()) {
749
-			\OC_Hook::emit('OCP\Share', 'post_update_password', [
750
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
751
-				'itemSource' => $share->getNode()->getId(),
752
-				'uidOwner' => $share->getSharedBy(),
753
-				'token' => $share->getToken(),
754
-				'disabled' => is_null($share->getPassword()),
755
-			]);
756
-		}
757
-
758
-		if ($share->getPermissions() !== $originalShare->getPermissions()) {
759
-			if ($this->userManager->userExists($share->getShareOwner())) {
760
-				$userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
761
-			} else {
762
-				$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
763
-			}
764
-			\OC_Hook::emit('OCP\Share', 'post_update_permissions', array(
765
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
766
-				'itemSource' => $share->getNode()->getId(),
767
-				'shareType' => $share->getShareType(),
768
-				'shareWith' => $share->getSharedWith(),
769
-				'uidOwner' => $share->getSharedBy(),
770
-				'permissions' => $share->getPermissions(),
771
-				'path' => $userFolder->getRelativePath($share->getNode()->getPath()),
772
-			));
773
-		}
774
-
775
-		return $share;
776
-	}
777
-
778
-	/**
779
-	 * Delete all the children of this share
780
-	 * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
781
-	 *
782
-	 * @param \OCP\Share\IShare $share
783
-	 * @return \OCP\Share\IShare[] List of deleted shares
784
-	 */
785
-	protected function deleteChildren(\OCP\Share\IShare $share) {
786
-		$deletedShares = [];
787
-
788
-		$provider = $this->factory->getProviderForType($share->getShareType());
789
-
790
-		foreach ($provider->getChildren($share) as $child) {
791
-			$deletedChildren = $this->deleteChildren($child);
792
-			$deletedShares = array_merge($deletedShares, $deletedChildren);
793
-
794
-			$provider->delete($child);
795
-			$deletedShares[] = $child;
796
-		}
797
-
798
-		return $deletedShares;
799
-	}
800
-
801
-	/**
802
-	 * Delete a share
803
-	 *
804
-	 * @param \OCP\Share\IShare $share
805
-	 * @throws ShareNotFound
806
-	 * @throws \InvalidArgumentException
807
-	 */
808
-	public function deleteShare(\OCP\Share\IShare $share) {
809
-
810
-		try {
811
-			$share->getFullId();
812
-		} catch (\UnexpectedValueException $e) {
813
-			throw new \InvalidArgumentException('Share does not have a full id');
814
-		}
815
-
816
-		$event = new GenericEvent($share);
817
-		$this->eventDispatcher->dispatch('OCP\Share::preUnshare', $event);
818
-
819
-		// Get all children and delete them as well
820
-		$deletedShares = $this->deleteChildren($share);
821
-
822
-		// Do the actual delete
823
-		$provider = $this->factory->getProviderForType($share->getShareType());
824
-		$provider->delete($share);
825
-
826
-		// All the deleted shares caused by this delete
827
-		$deletedShares[] = $share;
828
-
829
-		// Emit post hook
830
-		$event->setArgument('deletedShares', $deletedShares);
831
-		$this->eventDispatcher->dispatch('OCP\Share::postUnshare', $event);
832
-	}
833
-
834
-
835
-	/**
836
-	 * Unshare a file as the recipient.
837
-	 * This can be different from a regular delete for example when one of
838
-	 * the users in a groups deletes that share. But the provider should
839
-	 * handle this.
840
-	 *
841
-	 * @param \OCP\Share\IShare $share
842
-	 * @param string $recipientId
843
-	 */
844
-	public function deleteFromSelf(\OCP\Share\IShare $share, $recipientId) {
845
-		list($providerId, ) = $this->splitFullId($share->getFullId());
846
-		$provider = $this->factory->getProvider($providerId);
847
-
848
-		$provider->deleteFromSelf($share, $recipientId);
849
-	}
850
-
851
-	/**
852
-	 * @inheritdoc
853
-	 */
854
-	public function moveShare(\OCP\Share\IShare $share, $recipientId) {
855
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
856
-			throw new \InvalidArgumentException('Can\'t change target of link share');
857
-		}
858
-
859
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER && $share->getSharedWith() !== $recipientId) {
860
-			throw new \InvalidArgumentException('Invalid recipient');
861
-		}
862
-
863
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
864
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
865
-			if (is_null($sharedWith)) {
866
-				throw new \InvalidArgumentException('Group "' . $share->getSharedWith() . '" does not exist');
867
-			}
868
-			$recipient = $this->userManager->get($recipientId);
869
-			if (!$sharedWith->inGroup($recipient)) {
870
-				throw new \InvalidArgumentException('Invalid recipient');
871
-			}
872
-		}
873
-
874
-		list($providerId, ) = $this->splitFullId($share->getFullId());
875
-		$provider = $this->factory->getProvider($providerId);
876
-
877
-		$provider->move($share, $recipientId);
878
-	}
879
-
880
-	public function getSharesInFolder($userId, Folder $node, $reshares = false) {
881
-		$providers = $this->factory->getAllProviders();
882
-
883
-		return array_reduce($providers, function($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
884
-			$newShares = $provider->getSharesInFolder($userId, $node, $reshares);
885
-			foreach ($newShares as $fid => $data) {
886
-				if (!isset($shares[$fid])) {
887
-					$shares[$fid] = [];
888
-				}
889
-
890
-				$shares[$fid] = array_merge($shares[$fid], $data);
891
-			}
892
-			return $shares;
893
-		}, []);
894
-	}
895
-
896
-	/**
897
-	 * @inheritdoc
898
-	 */
899
-	public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) {
900
-		if ($path !== null &&
901
-				!($path instanceof \OCP\Files\File) &&
902
-				!($path instanceof \OCP\Files\Folder)) {
903
-			throw new \InvalidArgumentException('invalid path');
904
-		}
905
-
906
-		try {
907
-			$provider = $this->factory->getProviderForType($shareType);
908
-		} catch (ProviderException $e) {
909
-			return [];
910
-		}
911
-
912
-		$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
913
-
914
-		/*
580
+            $share->setToken(
581
+                $this->secureRandom->generate(
582
+                    \OC\Share\Constants::TOKEN_LENGTH,
583
+                    \OCP\Security\ISecureRandom::CHAR_LOWER.
584
+                    \OCP\Security\ISecureRandom::CHAR_UPPER.
585
+                    \OCP\Security\ISecureRandom::CHAR_DIGITS
586
+                )
587
+            );
588
+
589
+            //Verify the expiration date
590
+            $this->validateExpirationDate($share);
591
+
592
+            //Verify the password
593
+            $this->verifyPassword($share->getPassword());
594
+
595
+            // If a password is set. Hash it!
596
+            if ($share->getPassword() !== null) {
597
+                $share->setPassword($this->hasher->hash($share->getPassword()));
598
+            }
599
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
600
+            $share->setToken(
601
+                $this->secureRandom->generate(
602
+                    \OC\Share\Constants::TOKEN_LENGTH,
603
+                    \OCP\Security\ISecureRandom::CHAR_LOWER.
604
+                    \OCP\Security\ISecureRandom::CHAR_UPPER.
605
+                    \OCP\Security\ISecureRandom::CHAR_DIGITS
606
+                )
607
+            );
608
+        }
609
+
610
+        // Cannot share with the owner
611
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
612
+            $share->getSharedWith() === $share->getShareOwner()) {
613
+            throw new \InvalidArgumentException('Can\'t share with the share owner');
614
+        }
615
+
616
+        // Generate the target
617
+        $target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName();
618
+        $target = \OC\Files\Filesystem::normalizePath($target);
619
+        $share->setTarget($target);
620
+
621
+        // Pre share hook
622
+        $run = true;
623
+        $error = '';
624
+        $preHookData = [
625
+            'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
626
+            'itemSource' => $share->getNode()->getId(),
627
+            'shareType' => $share->getShareType(),
628
+            'uidOwner' => $share->getSharedBy(),
629
+            'permissions' => $share->getPermissions(),
630
+            'fileSource' => $share->getNode()->getId(),
631
+            'expiration' => $share->getExpirationDate(),
632
+            'token' => $share->getToken(),
633
+            'itemTarget' => $share->getTarget(),
634
+            'shareWith' => $share->getSharedWith(),
635
+            'run' => &$run,
636
+            'error' => &$error,
637
+        ];
638
+        \OC_Hook::emit('OCP\Share', 'pre_shared', $preHookData);
639
+
640
+        if ($run === false) {
641
+            throw new \Exception($error);
642
+        }
643
+
644
+        $oldShare = $share;
645
+        $provider = $this->factory->getProviderForType($share->getShareType());
646
+        $share = $provider->create($share);
647
+        //reuse the node we already have
648
+        $share->setNode($oldShare->getNode());
649
+
650
+        // Post share hook
651
+        $postHookData = [
652
+            'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
653
+            'itemSource' => $share->getNode()->getId(),
654
+            'shareType' => $share->getShareType(),
655
+            'uidOwner' => $share->getSharedBy(),
656
+            'permissions' => $share->getPermissions(),
657
+            'fileSource' => $share->getNode()->getId(),
658
+            'expiration' => $share->getExpirationDate(),
659
+            'token' => $share->getToken(),
660
+            'id' => $share->getId(),
661
+            'shareWith' => $share->getSharedWith(),
662
+            'itemTarget' => $share->getTarget(),
663
+            'fileTarget' => $share->getTarget(),
664
+        ];
665
+
666
+        \OC_Hook::emit('OCP\Share', 'post_shared', $postHookData);
667
+
668
+        return $share;
669
+    }
670
+
671
+    /**
672
+     * Update a share
673
+     *
674
+     * @param \OCP\Share\IShare $share
675
+     * @return \OCP\Share\IShare The share object
676
+     * @throws \InvalidArgumentException
677
+     */
678
+    public function updateShare(\OCP\Share\IShare $share) {
679
+        $expirationDateUpdated = false;
680
+
681
+        $this->canShare($share);
682
+
683
+        try {
684
+            $originalShare = $this->getShareById($share->getFullId());
685
+        } catch (\UnexpectedValueException $e) {
686
+            throw new \InvalidArgumentException('Share does not have a full id');
687
+        }
688
+
689
+        // We can't change the share type!
690
+        if ($share->getShareType() !== $originalShare->getShareType()) {
691
+            throw new \InvalidArgumentException('Can\'t change share type');
692
+        }
693
+
694
+        // We can only change the recipient on user shares
695
+        if ($share->getSharedWith() !== $originalShare->getSharedWith() &&
696
+            $share->getShareType() !== \OCP\Share::SHARE_TYPE_USER) {
697
+            throw new \InvalidArgumentException('Can only update recipient on user shares');
698
+        }
699
+
700
+        // Cannot share with the owner
701
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
702
+            $share->getSharedWith() === $share->getShareOwner()) {
703
+            throw new \InvalidArgumentException('Can\'t share with the share owner');
704
+        }
705
+
706
+        $this->generalCreateChecks($share);
707
+
708
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
709
+            $this->userCreateChecks($share);
710
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
711
+            $this->groupCreateChecks($share);
712
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
713
+            $this->linkCreateChecks($share);
714
+
715
+            // Password updated.
716
+            if ($share->getPassword() !== $originalShare->getPassword()) {
717
+                //Verify the password
718
+                $this->verifyPassword($share->getPassword());
719
+
720
+                // If a password is set. Hash it!
721
+                if ($share->getPassword() !== null) {
722
+                    $share->setPassword($this->hasher->hash($share->getPassword()));
723
+                }
724
+            }
725
+
726
+            if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
727
+                //Verify the expiration date
728
+                $this->validateExpirationDate($share);
729
+                $expirationDateUpdated = true;
730
+            }
731
+        }
732
+
733
+        $this->pathCreateChecks($share->getNode());
734
+
735
+        // Now update the share!
736
+        $provider = $this->factory->getProviderForType($share->getShareType());
737
+        $share = $provider->update($share);
738
+
739
+        if ($expirationDateUpdated === true) {
740
+            \OC_Hook::emit('OCP\Share', 'post_set_expiration_date', [
741
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
742
+                'itemSource' => $share->getNode()->getId(),
743
+                'date' => $share->getExpirationDate(),
744
+                'uidOwner' => $share->getSharedBy(),
745
+            ]);
746
+        }
747
+
748
+        if ($share->getPassword() !== $originalShare->getPassword()) {
749
+            \OC_Hook::emit('OCP\Share', 'post_update_password', [
750
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
751
+                'itemSource' => $share->getNode()->getId(),
752
+                'uidOwner' => $share->getSharedBy(),
753
+                'token' => $share->getToken(),
754
+                'disabled' => is_null($share->getPassword()),
755
+            ]);
756
+        }
757
+
758
+        if ($share->getPermissions() !== $originalShare->getPermissions()) {
759
+            if ($this->userManager->userExists($share->getShareOwner())) {
760
+                $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
761
+            } else {
762
+                $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
763
+            }
764
+            \OC_Hook::emit('OCP\Share', 'post_update_permissions', array(
765
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
766
+                'itemSource' => $share->getNode()->getId(),
767
+                'shareType' => $share->getShareType(),
768
+                'shareWith' => $share->getSharedWith(),
769
+                'uidOwner' => $share->getSharedBy(),
770
+                'permissions' => $share->getPermissions(),
771
+                'path' => $userFolder->getRelativePath($share->getNode()->getPath()),
772
+            ));
773
+        }
774
+
775
+        return $share;
776
+    }
777
+
778
+    /**
779
+     * Delete all the children of this share
780
+     * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
781
+     *
782
+     * @param \OCP\Share\IShare $share
783
+     * @return \OCP\Share\IShare[] List of deleted shares
784
+     */
785
+    protected function deleteChildren(\OCP\Share\IShare $share) {
786
+        $deletedShares = [];
787
+
788
+        $provider = $this->factory->getProviderForType($share->getShareType());
789
+
790
+        foreach ($provider->getChildren($share) as $child) {
791
+            $deletedChildren = $this->deleteChildren($child);
792
+            $deletedShares = array_merge($deletedShares, $deletedChildren);
793
+
794
+            $provider->delete($child);
795
+            $deletedShares[] = $child;
796
+        }
797
+
798
+        return $deletedShares;
799
+    }
800
+
801
+    /**
802
+     * Delete a share
803
+     *
804
+     * @param \OCP\Share\IShare $share
805
+     * @throws ShareNotFound
806
+     * @throws \InvalidArgumentException
807
+     */
808
+    public function deleteShare(\OCP\Share\IShare $share) {
809
+
810
+        try {
811
+            $share->getFullId();
812
+        } catch (\UnexpectedValueException $e) {
813
+            throw new \InvalidArgumentException('Share does not have a full id');
814
+        }
815
+
816
+        $event = new GenericEvent($share);
817
+        $this->eventDispatcher->dispatch('OCP\Share::preUnshare', $event);
818
+
819
+        // Get all children and delete them as well
820
+        $deletedShares = $this->deleteChildren($share);
821
+
822
+        // Do the actual delete
823
+        $provider = $this->factory->getProviderForType($share->getShareType());
824
+        $provider->delete($share);
825
+
826
+        // All the deleted shares caused by this delete
827
+        $deletedShares[] = $share;
828
+
829
+        // Emit post hook
830
+        $event->setArgument('deletedShares', $deletedShares);
831
+        $this->eventDispatcher->dispatch('OCP\Share::postUnshare', $event);
832
+    }
833
+
834
+
835
+    /**
836
+     * Unshare a file as the recipient.
837
+     * This can be different from a regular delete for example when one of
838
+     * the users in a groups deletes that share. But the provider should
839
+     * handle this.
840
+     *
841
+     * @param \OCP\Share\IShare $share
842
+     * @param string $recipientId
843
+     */
844
+    public function deleteFromSelf(\OCP\Share\IShare $share, $recipientId) {
845
+        list($providerId, ) = $this->splitFullId($share->getFullId());
846
+        $provider = $this->factory->getProvider($providerId);
847
+
848
+        $provider->deleteFromSelf($share, $recipientId);
849
+    }
850
+
851
+    /**
852
+     * @inheritdoc
853
+     */
854
+    public function moveShare(\OCP\Share\IShare $share, $recipientId) {
855
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
856
+            throw new \InvalidArgumentException('Can\'t change target of link share');
857
+        }
858
+
859
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER && $share->getSharedWith() !== $recipientId) {
860
+            throw new \InvalidArgumentException('Invalid recipient');
861
+        }
862
+
863
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
864
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
865
+            if (is_null($sharedWith)) {
866
+                throw new \InvalidArgumentException('Group "' . $share->getSharedWith() . '" does not exist');
867
+            }
868
+            $recipient = $this->userManager->get($recipientId);
869
+            if (!$sharedWith->inGroup($recipient)) {
870
+                throw new \InvalidArgumentException('Invalid recipient');
871
+            }
872
+        }
873
+
874
+        list($providerId, ) = $this->splitFullId($share->getFullId());
875
+        $provider = $this->factory->getProvider($providerId);
876
+
877
+        $provider->move($share, $recipientId);
878
+    }
879
+
880
+    public function getSharesInFolder($userId, Folder $node, $reshares = false) {
881
+        $providers = $this->factory->getAllProviders();
882
+
883
+        return array_reduce($providers, function($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
884
+            $newShares = $provider->getSharesInFolder($userId, $node, $reshares);
885
+            foreach ($newShares as $fid => $data) {
886
+                if (!isset($shares[$fid])) {
887
+                    $shares[$fid] = [];
888
+                }
889
+
890
+                $shares[$fid] = array_merge($shares[$fid], $data);
891
+            }
892
+            return $shares;
893
+        }, []);
894
+    }
895
+
896
+    /**
897
+     * @inheritdoc
898
+     */
899
+    public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) {
900
+        if ($path !== null &&
901
+                !($path instanceof \OCP\Files\File) &&
902
+                !($path instanceof \OCP\Files\Folder)) {
903
+            throw new \InvalidArgumentException('invalid path');
904
+        }
905
+
906
+        try {
907
+            $provider = $this->factory->getProviderForType($shareType);
908
+        } catch (ProviderException $e) {
909
+            return [];
910
+        }
911
+
912
+        $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
913
+
914
+        /*
915 915
 		 * Work around so we don't return expired shares but still follow
916 916
 		 * proper pagination.
917 917
 		 */
918
-		if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
919
-			$shares2 = [];
920
-			$today = new \DateTime();
921
-
922
-			while(true) {
923
-				$added = 0;
924
-				foreach ($shares as $share) {
925
-					// Check if the share is expired and if so delete it
926
-					if ($share->getExpirationDate() !== null &&
927
-						$share->getExpirationDate() <= $today
928
-					) {
929
-						try {
930
-							$this->deleteShare($share);
931
-						} catch (NotFoundException $e) {
932
-							//Ignore since this basically means the share is deleted
933
-						}
934
-						continue;
935
-					}
936
-					$added++;
937
-					$shares2[] = $share;
938
-
939
-					if (count($shares2) === $limit) {
940
-						break;
941
-					}
942
-				}
943
-
944
-				if (count($shares2) === $limit) {
945
-					break;
946
-				}
947
-
948
-				// If there was no limit on the select we are done
949
-				if ($limit === -1) {
950
-					break;
951
-				}
952
-
953
-				$offset += $added;
954
-
955
-				// Fetch again $limit shares
956
-				$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
957
-
958
-				// No more shares means we are done
959
-				if (empty($shares)) {
960
-					break;
961
-				}
962
-			}
963
-
964
-			$shares = $shares2;
965
-		}
966
-
967
-		return $shares;
968
-	}
969
-
970
-	/**
971
-	 * @inheritdoc
972
-	 */
973
-	public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
974
-		try {
975
-			$provider = $this->factory->getProviderForType($shareType);
976
-		} catch (ProviderException $e) {
977
-			return [];
978
-		}
979
-
980
-		return $provider->getSharedWith($userId, $shareType, $node, $limit, $offset);
981
-	}
982
-
983
-	/**
984
-	 * @inheritdoc
985
-	 */
986
-	public function getShareById($id, $recipient = null) {
987
-		if ($id === null) {
988
-			throw new ShareNotFound();
989
-		}
990
-
991
-		list($providerId, $id) = $this->splitFullId($id);
992
-
993
-		try {
994
-			$provider = $this->factory->getProvider($providerId);
995
-		} catch (ProviderException $e) {
996
-			throw new ShareNotFound();
997
-		}
998
-
999
-		$share = $provider->getShareById($id, $recipient);
1000
-
1001
-		// Validate link shares expiration date
1002
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
1003
-			$share->getExpirationDate() !== null &&
1004
-			$share->getExpirationDate() <= new \DateTime()) {
1005
-			$this->deleteShare($share);
1006
-			throw new ShareNotFound();
1007
-		}
1008
-
1009
-		return $share;
1010
-	}
1011
-
1012
-	/**
1013
-	 * Get all the shares for a given path
1014
-	 *
1015
-	 * @param \OCP\Files\Node $path
1016
-	 * @param int $page
1017
-	 * @param int $perPage
1018
-	 *
1019
-	 * @return Share[]
1020
-	 */
1021
-	public function getSharesByPath(\OCP\Files\Node $path, $page=0, $perPage=50) {
1022
-		return [];
1023
-	}
1024
-
1025
-	/**
1026
-	 * Get the share by token possible with password
1027
-	 *
1028
-	 * @param string $token
1029
-	 * @return Share
1030
-	 *
1031
-	 * @throws ShareNotFound
1032
-	 */
1033
-	public function getShareByToken($token) {
1034
-		$share = null;
1035
-		try {
1036
-			if($this->shareApiAllowLinks()) {
1037
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_LINK);
1038
-				$share = $provider->getShareByToken($token);
1039
-			}
1040
-		} catch (ProviderException $e) {
1041
-		} catch (ShareNotFound $e) {
1042
-		}
1043
-
1044
-
1045
-		// If it is not a link share try to fetch a federated share by token
1046
-		if ($share === null) {
1047
-			try {
1048
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_REMOTE);
1049
-				$share = $provider->getShareByToken($token);
1050
-			} catch (ProviderException $e) {
1051
-			} catch (ShareNotFound $e) {
1052
-			}
1053
-		}
1054
-
1055
-		// If it is not a link share try to fetch a mail share by token
1056
-		if ($share === null && $this->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
1057
-			try {
1058
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_EMAIL);
1059
-				$share = $provider->getShareByToken($token);
1060
-			} catch (ProviderException $e) {
1061
-			} catch (ShareNotFound $e) {
1062
-			}
1063
-		}
1064
-
1065
-		if ($share === null) {
1066
-			throw new ShareNotFound();
1067
-		}
1068
-
1069
-		if ($share->getExpirationDate() !== null &&
1070
-			$share->getExpirationDate() <= new \DateTime()) {
1071
-			$this->deleteShare($share);
1072
-			throw new ShareNotFound();
1073
-		}
1074
-
1075
-		/*
918
+        if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
919
+            $shares2 = [];
920
+            $today = new \DateTime();
921
+
922
+            while(true) {
923
+                $added = 0;
924
+                foreach ($shares as $share) {
925
+                    // Check if the share is expired and if so delete it
926
+                    if ($share->getExpirationDate() !== null &&
927
+                        $share->getExpirationDate() <= $today
928
+                    ) {
929
+                        try {
930
+                            $this->deleteShare($share);
931
+                        } catch (NotFoundException $e) {
932
+                            //Ignore since this basically means the share is deleted
933
+                        }
934
+                        continue;
935
+                    }
936
+                    $added++;
937
+                    $shares2[] = $share;
938
+
939
+                    if (count($shares2) === $limit) {
940
+                        break;
941
+                    }
942
+                }
943
+
944
+                if (count($shares2) === $limit) {
945
+                    break;
946
+                }
947
+
948
+                // If there was no limit on the select we are done
949
+                if ($limit === -1) {
950
+                    break;
951
+                }
952
+
953
+                $offset += $added;
954
+
955
+                // Fetch again $limit shares
956
+                $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
957
+
958
+                // No more shares means we are done
959
+                if (empty($shares)) {
960
+                    break;
961
+                }
962
+            }
963
+
964
+            $shares = $shares2;
965
+        }
966
+
967
+        return $shares;
968
+    }
969
+
970
+    /**
971
+     * @inheritdoc
972
+     */
973
+    public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
974
+        try {
975
+            $provider = $this->factory->getProviderForType($shareType);
976
+        } catch (ProviderException $e) {
977
+            return [];
978
+        }
979
+
980
+        return $provider->getSharedWith($userId, $shareType, $node, $limit, $offset);
981
+    }
982
+
983
+    /**
984
+     * @inheritdoc
985
+     */
986
+    public function getShareById($id, $recipient = null) {
987
+        if ($id === null) {
988
+            throw new ShareNotFound();
989
+        }
990
+
991
+        list($providerId, $id) = $this->splitFullId($id);
992
+
993
+        try {
994
+            $provider = $this->factory->getProvider($providerId);
995
+        } catch (ProviderException $e) {
996
+            throw new ShareNotFound();
997
+        }
998
+
999
+        $share = $provider->getShareById($id, $recipient);
1000
+
1001
+        // Validate link shares expiration date
1002
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
1003
+            $share->getExpirationDate() !== null &&
1004
+            $share->getExpirationDate() <= new \DateTime()) {
1005
+            $this->deleteShare($share);
1006
+            throw new ShareNotFound();
1007
+        }
1008
+
1009
+        return $share;
1010
+    }
1011
+
1012
+    /**
1013
+     * Get all the shares for a given path
1014
+     *
1015
+     * @param \OCP\Files\Node $path
1016
+     * @param int $page
1017
+     * @param int $perPage
1018
+     *
1019
+     * @return Share[]
1020
+     */
1021
+    public function getSharesByPath(\OCP\Files\Node $path, $page=0, $perPage=50) {
1022
+        return [];
1023
+    }
1024
+
1025
+    /**
1026
+     * Get the share by token possible with password
1027
+     *
1028
+     * @param string $token
1029
+     * @return Share
1030
+     *
1031
+     * @throws ShareNotFound
1032
+     */
1033
+    public function getShareByToken($token) {
1034
+        $share = null;
1035
+        try {
1036
+            if($this->shareApiAllowLinks()) {
1037
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_LINK);
1038
+                $share = $provider->getShareByToken($token);
1039
+            }
1040
+        } catch (ProviderException $e) {
1041
+        } catch (ShareNotFound $e) {
1042
+        }
1043
+
1044
+
1045
+        // If it is not a link share try to fetch a federated share by token
1046
+        if ($share === null) {
1047
+            try {
1048
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_REMOTE);
1049
+                $share = $provider->getShareByToken($token);
1050
+            } catch (ProviderException $e) {
1051
+            } catch (ShareNotFound $e) {
1052
+            }
1053
+        }
1054
+
1055
+        // If it is not a link share try to fetch a mail share by token
1056
+        if ($share === null && $this->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
1057
+            try {
1058
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_EMAIL);
1059
+                $share = $provider->getShareByToken($token);
1060
+            } catch (ProviderException $e) {
1061
+            } catch (ShareNotFound $e) {
1062
+            }
1063
+        }
1064
+
1065
+        if ($share === null) {
1066
+            throw new ShareNotFound();
1067
+        }
1068
+
1069
+        if ($share->getExpirationDate() !== null &&
1070
+            $share->getExpirationDate() <= new \DateTime()) {
1071
+            $this->deleteShare($share);
1072
+            throw new ShareNotFound();
1073
+        }
1074
+
1075
+        /*
1076 1076
 		 * Reduce the permissions for link shares if public upload is not enabled
1077 1077
 		 */
1078
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
1079
-			!$this->shareApiLinkAllowPublicUpload()) {
1080
-			$share->setPermissions($share->getPermissions() & ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE));
1081
-		}
1082
-
1083
-		return $share;
1084
-	}
1085
-
1086
-	/**
1087
-	 * Verify the password of a public share
1088
-	 *
1089
-	 * @param \OCP\Share\IShare $share
1090
-	 * @param string $password
1091
-	 * @return bool
1092
-	 */
1093
-	public function checkPassword(\OCP\Share\IShare $share, $password) {
1094
-		if ($share->getShareType() !== \OCP\Share::SHARE_TYPE_LINK) {
1095
-			//TODO maybe exception?
1096
-			return false;
1097
-		}
1098
-
1099
-		if ($password === null || $share->getPassword() === null) {
1100
-			return false;
1101
-		}
1102
-
1103
-		$newHash = '';
1104
-		if (!$this->hasher->verify($password, $share->getPassword(), $newHash)) {
1105
-			return false;
1106
-		}
1107
-
1108
-		if (!empty($newHash)) {
1109
-			$share->setPassword($newHash);
1110
-			$provider = $this->factory->getProviderForType($share->getShareType());
1111
-			$provider->update($share);
1112
-		}
1113
-
1114
-		return true;
1115
-	}
1116
-
1117
-	/**
1118
-	 * @inheritdoc
1119
-	 */
1120
-	public function userDeleted($uid) {
1121
-		$types = [\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE, \OCP\Share::SHARE_TYPE_EMAIL];
1122
-
1123
-		foreach ($types as $type) {
1124
-			try {
1125
-				$provider = $this->factory->getProviderForType($type);
1126
-			} catch (ProviderException $e) {
1127
-				continue;
1128
-			}
1129
-			$provider->userDeleted($uid, $type);
1130
-		}
1131
-	}
1132
-
1133
-	/**
1134
-	 * @inheritdoc
1135
-	 */
1136
-	public function groupDeleted($gid) {
1137
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1138
-		$provider->groupDeleted($gid);
1139
-	}
1140
-
1141
-	/**
1142
-	 * @inheritdoc
1143
-	 */
1144
-	public function userDeletedFromGroup($uid, $gid) {
1145
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1146
-		$provider->userDeletedFromGroup($uid, $gid);
1147
-	}
1148
-
1149
-	/**
1150
-	 * Get access list to a path. This means
1151
-	 * all the users and groups that can access a given path.
1152
-	 *
1153
-	 * Consider:
1154
-	 * -root
1155
-	 * |-folder1
1156
-	 *  |-folder2
1157
-	 *   |-fileA
1158
-	 *
1159
-	 * fileA is shared with user1
1160
-	 * folder2 is shared with group2
1161
-	 * folder1 is shared with user2
1162
-	 *
1163
-	 * Then the access list will to '/folder1/folder2/fileA' is:
1164
-	 * [
1165
-	 * 	'users' => ['user1', 'user2'],
1166
-	 *  'groups' => ['group2']
1167
-	 * ]
1168
-	 *
1169
-	 * This is required for encryption
1170
-	 *
1171
-	 * @param \OCP\Files\Node $path
1172
-	 */
1173
-	public function getAccessList(\OCP\Files\Node $path) {
1174
-	}
1175
-
1176
-	/**
1177
-	 * Create a new share
1178
-	 * @return \OCP\Share\IShare;
1179
-	 */
1180
-	public function newShare() {
1181
-		return new \OC\Share20\Share($this->rootFolder, $this->userManager);
1182
-	}
1183
-
1184
-	/**
1185
-	 * Is the share API enabled
1186
-	 *
1187
-	 * @return bool
1188
-	 */
1189
-	public function shareApiEnabled() {
1190
-		return $this->config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes';
1191
-	}
1192
-
1193
-	/**
1194
-	 * Is public link sharing enabled
1195
-	 *
1196
-	 * @return bool
1197
-	 */
1198
-	public function shareApiAllowLinks() {
1199
-		return $this->config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes';
1200
-	}
1201
-
1202
-	/**
1203
-	 * Is password on public link requires
1204
-	 *
1205
-	 * @return bool
1206
-	 */
1207
-	public function shareApiLinkEnforcePassword() {
1208
-		return $this->config->getAppValue('core', 'shareapi_enforce_links_password', 'no') === 'yes';
1209
-	}
1210
-
1211
-	/**
1212
-	 * Is default expire date enabled
1213
-	 *
1214
-	 * @return bool
1215
-	 */
1216
-	public function shareApiLinkDefaultExpireDate() {
1217
-		return $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes';
1218
-	}
1219
-
1220
-	/**
1221
-	 * Is default expire date enforced
1222
-	 *`
1223
-	 * @return bool
1224
-	 */
1225
-	public function shareApiLinkDefaultExpireDateEnforced() {
1226
-		return $this->shareApiLinkDefaultExpireDate() &&
1227
-			$this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes';
1228
-	}
1229
-
1230
-	/**
1231
-	 * Number of default expire days
1232
-	 *shareApiLinkAllowPublicUpload
1233
-	 * @return int
1234
-	 */
1235
-	public function shareApiLinkDefaultExpireDays() {
1236
-		return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1237
-	}
1238
-
1239
-	/**
1240
-	 * Allow public upload on link shares
1241
-	 *
1242
-	 * @return bool
1243
-	 */
1244
-	public function shareApiLinkAllowPublicUpload() {
1245
-		return $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') === 'yes';
1246
-	}
1247
-
1248
-	/**
1249
-	 * check if user can only share with group members
1250
-	 * @return bool
1251
-	 */
1252
-	public function shareWithGroupMembersOnly() {
1253
-		return $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
1254
-	}
1255
-
1256
-	/**
1257
-	 * Check if users can share with groups
1258
-	 * @return bool
1259
-	 */
1260
-	public function allowGroupSharing() {
1261
-		return $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes';
1262
-	}
1263
-
1264
-	/**
1265
-	 * Copied from \OC_Util::isSharingDisabledForUser
1266
-	 *
1267
-	 * TODO: Deprecate fuction from OC_Util
1268
-	 *
1269
-	 * @param string $userId
1270
-	 * @return bool
1271
-	 */
1272
-	public function sharingDisabledForUser($userId) {
1273
-		if ($userId === null) {
1274
-			return false;
1275
-		}
1276
-
1277
-		if (isset($this->sharingDisabledForUsersCache[$userId])) {
1278
-			return $this->sharingDisabledForUsersCache[$userId];
1279
-		}
1280
-
1281
-		if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
1282
-			$groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1283
-			$excludedGroups = json_decode($groupsList);
1284
-			if (is_null($excludedGroups)) {
1285
-				$excludedGroups = explode(',', $groupsList);
1286
-				$newValue = json_encode($excludedGroups);
1287
-				$this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
1288
-			}
1289
-			$user = $this->userManager->get($userId);
1290
-			$usersGroups = $this->groupManager->getUserGroupIds($user);
1291
-			if (!empty($usersGroups)) {
1292
-				$remainingGroups = array_diff($usersGroups, $excludedGroups);
1293
-				// if the user is only in groups which are disabled for sharing then
1294
-				// sharing is also disabled for the user
1295
-				if (empty($remainingGroups)) {
1296
-					$this->sharingDisabledForUsersCache[$userId] = true;
1297
-					return true;
1298
-				}
1299
-			}
1300
-		}
1301
-
1302
-		$this->sharingDisabledForUsersCache[$userId] = false;
1303
-		return false;
1304
-	}
1305
-
1306
-	/**
1307
-	 * @inheritdoc
1308
-	 */
1309
-	public function outgoingServer2ServerSharesAllowed() {
1310
-		return $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes';
1311
-	}
1312
-
1313
-	/**
1314
-	 * @inheritdoc
1315
-	 */
1316
-	public function shareProviderExists($shareType) {
1317
-		try {
1318
-			$this->factory->getProviderForType($shareType);
1319
-		} catch (ProviderException $e) {
1320
-			return false;
1321
-		}
1322
-
1323
-		return true;
1324
-	}
1078
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
1079
+            !$this->shareApiLinkAllowPublicUpload()) {
1080
+            $share->setPermissions($share->getPermissions() & ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE));
1081
+        }
1082
+
1083
+        return $share;
1084
+    }
1085
+
1086
+    /**
1087
+     * Verify the password of a public share
1088
+     *
1089
+     * @param \OCP\Share\IShare $share
1090
+     * @param string $password
1091
+     * @return bool
1092
+     */
1093
+    public function checkPassword(\OCP\Share\IShare $share, $password) {
1094
+        if ($share->getShareType() !== \OCP\Share::SHARE_TYPE_LINK) {
1095
+            //TODO maybe exception?
1096
+            return false;
1097
+        }
1098
+
1099
+        if ($password === null || $share->getPassword() === null) {
1100
+            return false;
1101
+        }
1102
+
1103
+        $newHash = '';
1104
+        if (!$this->hasher->verify($password, $share->getPassword(), $newHash)) {
1105
+            return false;
1106
+        }
1107
+
1108
+        if (!empty($newHash)) {
1109
+            $share->setPassword($newHash);
1110
+            $provider = $this->factory->getProviderForType($share->getShareType());
1111
+            $provider->update($share);
1112
+        }
1113
+
1114
+        return true;
1115
+    }
1116
+
1117
+    /**
1118
+     * @inheritdoc
1119
+     */
1120
+    public function userDeleted($uid) {
1121
+        $types = [\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE, \OCP\Share::SHARE_TYPE_EMAIL];
1122
+
1123
+        foreach ($types as $type) {
1124
+            try {
1125
+                $provider = $this->factory->getProviderForType($type);
1126
+            } catch (ProviderException $e) {
1127
+                continue;
1128
+            }
1129
+            $provider->userDeleted($uid, $type);
1130
+        }
1131
+    }
1132
+
1133
+    /**
1134
+     * @inheritdoc
1135
+     */
1136
+    public function groupDeleted($gid) {
1137
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1138
+        $provider->groupDeleted($gid);
1139
+    }
1140
+
1141
+    /**
1142
+     * @inheritdoc
1143
+     */
1144
+    public function userDeletedFromGroup($uid, $gid) {
1145
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1146
+        $provider->userDeletedFromGroup($uid, $gid);
1147
+    }
1148
+
1149
+    /**
1150
+     * Get access list to a path. This means
1151
+     * all the users and groups that can access a given path.
1152
+     *
1153
+     * Consider:
1154
+     * -root
1155
+     * |-folder1
1156
+     *  |-folder2
1157
+     *   |-fileA
1158
+     *
1159
+     * fileA is shared with user1
1160
+     * folder2 is shared with group2
1161
+     * folder1 is shared with user2
1162
+     *
1163
+     * Then the access list will to '/folder1/folder2/fileA' is:
1164
+     * [
1165
+     * 	'users' => ['user1', 'user2'],
1166
+     *  'groups' => ['group2']
1167
+     * ]
1168
+     *
1169
+     * This is required for encryption
1170
+     *
1171
+     * @param \OCP\Files\Node $path
1172
+     */
1173
+    public function getAccessList(\OCP\Files\Node $path) {
1174
+    }
1175
+
1176
+    /**
1177
+     * Create a new share
1178
+     * @return \OCP\Share\IShare;
1179
+     */
1180
+    public function newShare() {
1181
+        return new \OC\Share20\Share($this->rootFolder, $this->userManager);
1182
+    }
1183
+
1184
+    /**
1185
+     * Is the share API enabled
1186
+     *
1187
+     * @return bool
1188
+     */
1189
+    public function shareApiEnabled() {
1190
+        return $this->config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes';
1191
+    }
1192
+
1193
+    /**
1194
+     * Is public link sharing enabled
1195
+     *
1196
+     * @return bool
1197
+     */
1198
+    public function shareApiAllowLinks() {
1199
+        return $this->config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes';
1200
+    }
1201
+
1202
+    /**
1203
+     * Is password on public link requires
1204
+     *
1205
+     * @return bool
1206
+     */
1207
+    public function shareApiLinkEnforcePassword() {
1208
+        return $this->config->getAppValue('core', 'shareapi_enforce_links_password', 'no') === 'yes';
1209
+    }
1210
+
1211
+    /**
1212
+     * Is default expire date enabled
1213
+     *
1214
+     * @return bool
1215
+     */
1216
+    public function shareApiLinkDefaultExpireDate() {
1217
+        return $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes';
1218
+    }
1219
+
1220
+    /**
1221
+     * Is default expire date enforced
1222
+     *`
1223
+     * @return bool
1224
+     */
1225
+    public function shareApiLinkDefaultExpireDateEnforced() {
1226
+        return $this->shareApiLinkDefaultExpireDate() &&
1227
+            $this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes';
1228
+    }
1229
+
1230
+    /**
1231
+     * Number of default expire days
1232
+     *shareApiLinkAllowPublicUpload
1233
+     * @return int
1234
+     */
1235
+    public function shareApiLinkDefaultExpireDays() {
1236
+        return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1237
+    }
1238
+
1239
+    /**
1240
+     * Allow public upload on link shares
1241
+     *
1242
+     * @return bool
1243
+     */
1244
+    public function shareApiLinkAllowPublicUpload() {
1245
+        return $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') === 'yes';
1246
+    }
1247
+
1248
+    /**
1249
+     * check if user can only share with group members
1250
+     * @return bool
1251
+     */
1252
+    public function shareWithGroupMembersOnly() {
1253
+        return $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
1254
+    }
1255
+
1256
+    /**
1257
+     * Check if users can share with groups
1258
+     * @return bool
1259
+     */
1260
+    public function allowGroupSharing() {
1261
+        return $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes';
1262
+    }
1263
+
1264
+    /**
1265
+     * Copied from \OC_Util::isSharingDisabledForUser
1266
+     *
1267
+     * TODO: Deprecate fuction from OC_Util
1268
+     *
1269
+     * @param string $userId
1270
+     * @return bool
1271
+     */
1272
+    public function sharingDisabledForUser($userId) {
1273
+        if ($userId === null) {
1274
+            return false;
1275
+        }
1276
+
1277
+        if (isset($this->sharingDisabledForUsersCache[$userId])) {
1278
+            return $this->sharingDisabledForUsersCache[$userId];
1279
+        }
1280
+
1281
+        if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
1282
+            $groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1283
+            $excludedGroups = json_decode($groupsList);
1284
+            if (is_null($excludedGroups)) {
1285
+                $excludedGroups = explode(',', $groupsList);
1286
+                $newValue = json_encode($excludedGroups);
1287
+                $this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
1288
+            }
1289
+            $user = $this->userManager->get($userId);
1290
+            $usersGroups = $this->groupManager->getUserGroupIds($user);
1291
+            if (!empty($usersGroups)) {
1292
+                $remainingGroups = array_diff($usersGroups, $excludedGroups);
1293
+                // if the user is only in groups which are disabled for sharing then
1294
+                // sharing is also disabled for the user
1295
+                if (empty($remainingGroups)) {
1296
+                    $this->sharingDisabledForUsersCache[$userId] = true;
1297
+                    return true;
1298
+                }
1299
+            }
1300
+        }
1301
+
1302
+        $this->sharingDisabledForUsersCache[$userId] = false;
1303
+        return false;
1304
+    }
1305
+
1306
+    /**
1307
+     * @inheritdoc
1308
+     */
1309
+    public function outgoingServer2ServerSharesAllowed() {
1310
+        return $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes';
1311
+    }
1312
+
1313
+    /**
1314
+     * @inheritdoc
1315
+     */
1316
+    public function shareProviderExists($shareType) {
1317
+        try {
1318
+            $this->factory->getProviderForType($shareType);
1319
+        } catch (ProviderException $e) {
1320
+            return false;
1321
+        }
1322
+
1323
+        return true;
1324
+    }
1325 1325
 
1326 1326
 }
Please login to merge, or discard this patch.