Completed
Pull Request — master (#6515)
by Joas
17:19
created
core/Controller/LostController.php 1 patch
Indentation   +309 added lines, -309 removed lines patch added patch discarded remove patch
@@ -55,313 +55,313 @@
 block discarded – undo
55 55
  */
56 56
 class LostController extends Controller {
57 57
 
58
-	/** @var IURLGenerator */
59
-	protected $urlGenerator;
60
-	/** @var IUserManager */
61
-	protected $userManager;
62
-	/** @var Defaults */
63
-	protected $defaults;
64
-	/** @var IL10N */
65
-	protected $l10n;
66
-	/** @var string */
67
-	protected $from;
68
-	/** @var IManager */
69
-	protected $encryptionManager;
70
-	/** @var IConfig */
71
-	protected $config;
72
-	/** @var ISecureRandom */
73
-	protected $secureRandom;
74
-	/** @var IMailer */
75
-	protected $mailer;
76
-	/** @var ITimeFactory */
77
-	protected $timeFactory;
78
-	/** @var ICrypto */
79
-	protected $crypto;
80
-
81
-	/**
82
-	 * @param string $appName
83
-	 * @param IRequest $request
84
-	 * @param IURLGenerator $urlGenerator
85
-	 * @param IUserManager $userManager
86
-	 * @param Defaults $defaults
87
-	 * @param IL10N $l10n
88
-	 * @param IConfig $config
89
-	 * @param ISecureRandom $secureRandom
90
-	 * @param string $defaultMailAddress
91
-	 * @param IManager $encryptionManager
92
-	 * @param IMailer $mailer
93
-	 * @param ITimeFactory $timeFactory
94
-	 * @param ICrypto $crypto
95
-	 */
96
-	public function __construct($appName,
97
-								IRequest $request,
98
-								IURLGenerator $urlGenerator,
99
-								IUserManager $userManager,
100
-								Defaults $defaults,
101
-								IL10N $l10n,
102
-								IConfig $config,
103
-								ISecureRandom $secureRandom,
104
-								$defaultMailAddress,
105
-								IManager $encryptionManager,
106
-								IMailer $mailer,
107
-								ITimeFactory $timeFactory,
108
-								ICrypto $crypto) {
109
-		parent::__construct($appName, $request);
110
-		$this->urlGenerator = $urlGenerator;
111
-		$this->userManager = $userManager;
112
-		$this->defaults = $defaults;
113
-		$this->l10n = $l10n;
114
-		$this->secureRandom = $secureRandom;
115
-		$this->from = $defaultMailAddress;
116
-		$this->encryptionManager = $encryptionManager;
117
-		$this->config = $config;
118
-		$this->mailer = $mailer;
119
-		$this->timeFactory = $timeFactory;
120
-		$this->crypto = $crypto;
121
-	}
122
-
123
-	/**
124
-	 * Someone wants to reset their password:
125
-	 *
126
-	 * @PublicPage
127
-	 * @NoCSRFRequired
128
-	 *
129
-	 * @param string $token
130
-	 * @param string $userId
131
-	 * @return TemplateResponse
132
-	 */
133
-	public function resetform($token, $userId) {
134
-		if ($this->config->getSystemValue('lost_password_link', '') !== '') {
135
-			return new TemplateResponse('core', 'error', [
136
-					'errors' => [['error' => $this->l10n->t('Password reset is disabled')]]
137
-				],
138
-				'guest'
139
-			);
140
-		}
141
-
142
-		try {
143
-			$this->checkPasswordResetToken($token, $userId);
144
-		} catch (\Exception $e) {
145
-			return new TemplateResponse(
146
-				'core', 'error', [
147
-					"errors" => array(array("error" => $e->getMessage()))
148
-				],
149
-				'guest'
150
-			);
151
-		}
152
-
153
-		return new TemplateResponse(
154
-			'core',
155
-			'lostpassword/resetpassword',
156
-			array(
157
-				'link' => $this->urlGenerator->linkToRouteAbsolute('core.lost.setPassword', array('userId' => $userId, 'token' => $token)),
158
-			),
159
-			'guest'
160
-		);
161
-	}
162
-
163
-	/**
164
-	 * @param string $token
165
-	 * @param string $userId
166
-	 * @throws \Exception
167
-	 */
168
-	protected function checkPasswordResetToken($token, $userId) {
169
-		$user = $this->userManager->get($userId);
170
-		if($user === null || !$user->isEnabled()) {
171
-			throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
172
-		}
173
-
174
-		try {
175
-			$encryptedToken = $this->config->getUserValue($userId, 'core', 'lostpassword', null);
176
-			$mailAddress = !is_null($user->getEMailAddress()) ? $user->getEMailAddress() : '';
177
-			$decryptedToken = $this->crypto->decrypt($encryptedToken, $mailAddress.$this->config->getSystemValue('secret'));
178
-		} catch (\Exception $e) {
179
-			throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
180
-		}
181
-
182
-		$splittedToken = explode(':', $decryptedToken);
183
-		if(count($splittedToken) !== 2) {
184
-			throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
185
-		}
186
-
187
-		if ($splittedToken[0] < ($this->timeFactory->getTime() - 60*60*12) ||
188
-			$user->getLastLogin() > $splittedToken[0]) {
189
-			throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is expired'));
190
-		}
191
-
192
-		if (!hash_equals($splittedToken[1], $token)) {
193
-			throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
194
-		}
195
-	}
196
-
197
-	/**
198
-	 * @param $message
199
-	 * @param array $additional
200
-	 * @return array
201
-	 */
202
-	private function error($message, array $additional=array()) {
203
-		return array_merge(array('status' => 'error', 'msg' => $message), $additional);
204
-	}
205
-
206
-	/**
207
-	 * @return array
208
-	 */
209
-	private function success() {
210
-		return array('status'=>'success');
211
-	}
212
-
213
-	/**
214
-	 * @PublicPage
215
-	 * @BruteForceProtection(action=passwordResetEmail)
216
-	 * @AnonRateThrottle(limit=10, period=300)
217
-	 *
218
-	 * @param string $user
219
-	 * @return JSONResponse
220
-	 */
221
-	public function email($user){
222
-		if ($this->config->getSystemValue('lost_password_link', '') !== '') {
223
-			return new JSONResponse($this->error($this->l10n->t('Password reset is disabled')));
224
-		}
225
-
226
-		// FIXME: use HTTP error codes
227
-		try {
228
-			$this->sendEmail($user);
229
-		} catch (\Exception $e){
230
-			$response = new JSONResponse($this->error($e->getMessage()));
231
-			$response->throttle();
232
-			return $response;
233
-		}
234
-
235
-		$response = new JSONResponse($this->success());
236
-		$response->throttle();
237
-		return $response;
238
-	}
239
-
240
-	/**
241
-	 * @PublicPage
242
-	 * @param string $token
243
-	 * @param string $userId
244
-	 * @param string $password
245
-	 * @param boolean $proceed
246
-	 * @return array
247
-	 */
248
-	public function setPassword($token, $userId, $password, $proceed) {
249
-		if ($this->config->getSystemValue('lost_password_link', '') !== '') {
250
-			return $this->error($this->l10n->t('Password reset is disabled'));
251
-		}
252
-
253
-		if ($this->encryptionManager->isEnabled() && !$proceed) {
254
-			return $this->error('', array('encryption' => true));
255
-		}
256
-
257
-		try {
258
-			$this->checkPasswordResetToken($token, $userId);
259
-			$user = $this->userManager->get($userId);
260
-
261
-			\OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'pre_passwordReset', array('uid' => $userId, 'password' => $password));
262
-
263
-			if (!$user->setPassword($password)) {
264
-				throw new \Exception();
265
-			}
266
-
267
-			\OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'post_passwordReset', array('uid' => $userId, 'password' => $password));
268
-
269
-			$this->config->deleteUserValue($userId, 'core', 'lostpassword');
270
-			@\OC::$server->getUserSession()->unsetMagicInCookie();
271
-		} catch (\Exception $e){
272
-			return $this->error($e->getMessage());
273
-		}
274
-
275
-		return $this->success();
276
-	}
277
-
278
-	/**
279
-	 * @param string $input
280
-	 * @throws \Exception
281
-	 */
282
-	protected function sendEmail($input) {
283
-		$user = $this->findUserByIdOrMail($input);
284
-		$email = $user->getEMailAddress();
285
-
286
-		if (empty($email)) {
287
-			throw new \Exception(
288
-				$this->l10n->t('Could not send reset email because there is no email address for this username. Please contact your administrator.')
289
-			);
290
-		}
291
-
292
-		// Generate the token. It is stored encrypted in the database with the
293
-		// secret being the users' email address appended with the system secret.
294
-		// This makes the token automatically invalidate once the user changes
295
-		// their email address.
296
-		$token = $this->secureRandom->generate(
297
-			21,
298
-			ISecureRandom::CHAR_DIGITS.
299
-			ISecureRandom::CHAR_LOWER.
300
-			ISecureRandom::CHAR_UPPER
301
-		);
302
-		$tokenValue = $this->timeFactory->getTime() .':'. $token;
303
-		$encryptedValue = $this->crypto->encrypt($tokenValue, $email . $this->config->getSystemValue('secret'));
304
-		$this->config->setUserValue($user->getUID(), 'core', 'lostpassword', $encryptedValue);
305
-
306
-		$link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', array('userId' => $user->getUID(), 'token' => $token));
307
-
308
-		$emailTemplate = $this->mailer->createEMailTemplate('core.ResetPassword', [
309
-			'link' => $link,
310
-		]);
311
-
312
-		$emailTemplate->setSubject($this->l10n->t('%s password reset', [$this->defaults->getName()]));
313
-		$emailTemplate->addHeader();
314
-		$emailTemplate->addHeading($this->l10n->t('Password reset'));
315
-
316
-		$emailTemplate->addBodyText(
317
-			$this->l10n->t('Click the following button to reset your password. If you have not requested the password reset, then ignore this email.'),
318
-			$this->l10n->t('Click the following link to reset your password. If you have not requested the password reset, then ignore this email.')
319
-		);
320
-
321
-		$emailTemplate->addBodyButton(
322
-			$this->l10n->t('Reset your password'),
323
-			$link,
324
-			false
325
-		);
326
-		$emailTemplate->addFooter();
327
-
328
-		try {
329
-			$message = $this->mailer->createMessage();
330
-			$message->setTo([$email => $user->getUID()]);
331
-			$message->setFrom([$this->from => $this->defaults->getName()]);
332
-			$message->setTemplate($emailTemplate);
333
-			$this->mailer->send($message);
334
-		} catch (\Exception $e) {
335
-			throw new \Exception($this->l10n->t(
336
-				'Couldn\'t send reset email. Please contact your administrator.'
337
-			));
338
-		}
339
-	}
340
-
341
-	/**
342
-	 * @param string $input
343
-	 * @return IUser
344
-	 * @throws \InvalidArgumentException
345
-	 */
346
-	protected function findUserByIdOrMail($input) {
347
-		$user = $this->userManager->get($input);
348
-		if ($user instanceof IUser) {
349
-			if (!$user->isEnabled()) {
350
-				throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
351
-			}
352
-
353
-			return $user;
354
-		}
355
-		$users = $this->userManager->getByEmail($input);
356
-		if (count($users) === 1) {
357
-			$user = $users[0];
358
-			if (!$user->isEnabled()) {
359
-				throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
360
-			}
361
-
362
-			return $user;
363
-		}
364
-
365
-		throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
366
-	}
58
+    /** @var IURLGenerator */
59
+    protected $urlGenerator;
60
+    /** @var IUserManager */
61
+    protected $userManager;
62
+    /** @var Defaults */
63
+    protected $defaults;
64
+    /** @var IL10N */
65
+    protected $l10n;
66
+    /** @var string */
67
+    protected $from;
68
+    /** @var IManager */
69
+    protected $encryptionManager;
70
+    /** @var IConfig */
71
+    protected $config;
72
+    /** @var ISecureRandom */
73
+    protected $secureRandom;
74
+    /** @var IMailer */
75
+    protected $mailer;
76
+    /** @var ITimeFactory */
77
+    protected $timeFactory;
78
+    /** @var ICrypto */
79
+    protected $crypto;
80
+
81
+    /**
82
+     * @param string $appName
83
+     * @param IRequest $request
84
+     * @param IURLGenerator $urlGenerator
85
+     * @param IUserManager $userManager
86
+     * @param Defaults $defaults
87
+     * @param IL10N $l10n
88
+     * @param IConfig $config
89
+     * @param ISecureRandom $secureRandom
90
+     * @param string $defaultMailAddress
91
+     * @param IManager $encryptionManager
92
+     * @param IMailer $mailer
93
+     * @param ITimeFactory $timeFactory
94
+     * @param ICrypto $crypto
95
+     */
96
+    public function __construct($appName,
97
+                                IRequest $request,
98
+                                IURLGenerator $urlGenerator,
99
+                                IUserManager $userManager,
100
+                                Defaults $defaults,
101
+                                IL10N $l10n,
102
+                                IConfig $config,
103
+                                ISecureRandom $secureRandom,
104
+                                $defaultMailAddress,
105
+                                IManager $encryptionManager,
106
+                                IMailer $mailer,
107
+                                ITimeFactory $timeFactory,
108
+                                ICrypto $crypto) {
109
+        parent::__construct($appName, $request);
110
+        $this->urlGenerator = $urlGenerator;
111
+        $this->userManager = $userManager;
112
+        $this->defaults = $defaults;
113
+        $this->l10n = $l10n;
114
+        $this->secureRandom = $secureRandom;
115
+        $this->from = $defaultMailAddress;
116
+        $this->encryptionManager = $encryptionManager;
117
+        $this->config = $config;
118
+        $this->mailer = $mailer;
119
+        $this->timeFactory = $timeFactory;
120
+        $this->crypto = $crypto;
121
+    }
122
+
123
+    /**
124
+     * Someone wants to reset their password:
125
+     *
126
+     * @PublicPage
127
+     * @NoCSRFRequired
128
+     *
129
+     * @param string $token
130
+     * @param string $userId
131
+     * @return TemplateResponse
132
+     */
133
+    public function resetform($token, $userId) {
134
+        if ($this->config->getSystemValue('lost_password_link', '') !== '') {
135
+            return new TemplateResponse('core', 'error', [
136
+                    'errors' => [['error' => $this->l10n->t('Password reset is disabled')]]
137
+                ],
138
+                'guest'
139
+            );
140
+        }
141
+
142
+        try {
143
+            $this->checkPasswordResetToken($token, $userId);
144
+        } catch (\Exception $e) {
145
+            return new TemplateResponse(
146
+                'core', 'error', [
147
+                    "errors" => array(array("error" => $e->getMessage()))
148
+                ],
149
+                'guest'
150
+            );
151
+        }
152
+
153
+        return new TemplateResponse(
154
+            'core',
155
+            'lostpassword/resetpassword',
156
+            array(
157
+                'link' => $this->urlGenerator->linkToRouteAbsolute('core.lost.setPassword', array('userId' => $userId, 'token' => $token)),
158
+            ),
159
+            'guest'
160
+        );
161
+    }
162
+
163
+    /**
164
+     * @param string $token
165
+     * @param string $userId
166
+     * @throws \Exception
167
+     */
168
+    protected function checkPasswordResetToken($token, $userId) {
169
+        $user = $this->userManager->get($userId);
170
+        if($user === null || !$user->isEnabled()) {
171
+            throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
172
+        }
173
+
174
+        try {
175
+            $encryptedToken = $this->config->getUserValue($userId, 'core', 'lostpassword', null);
176
+            $mailAddress = !is_null($user->getEMailAddress()) ? $user->getEMailAddress() : '';
177
+            $decryptedToken = $this->crypto->decrypt($encryptedToken, $mailAddress.$this->config->getSystemValue('secret'));
178
+        } catch (\Exception $e) {
179
+            throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
180
+        }
181
+
182
+        $splittedToken = explode(':', $decryptedToken);
183
+        if(count($splittedToken) !== 2) {
184
+            throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
185
+        }
186
+
187
+        if ($splittedToken[0] < ($this->timeFactory->getTime() - 60*60*12) ||
188
+            $user->getLastLogin() > $splittedToken[0]) {
189
+            throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is expired'));
190
+        }
191
+
192
+        if (!hash_equals($splittedToken[1], $token)) {
193
+            throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
194
+        }
195
+    }
196
+
197
+    /**
198
+     * @param $message
199
+     * @param array $additional
200
+     * @return array
201
+     */
202
+    private function error($message, array $additional=array()) {
203
+        return array_merge(array('status' => 'error', 'msg' => $message), $additional);
204
+    }
205
+
206
+    /**
207
+     * @return array
208
+     */
209
+    private function success() {
210
+        return array('status'=>'success');
211
+    }
212
+
213
+    /**
214
+     * @PublicPage
215
+     * @BruteForceProtection(action=passwordResetEmail)
216
+     * @AnonRateThrottle(limit=10, period=300)
217
+     *
218
+     * @param string $user
219
+     * @return JSONResponse
220
+     */
221
+    public function email($user){
222
+        if ($this->config->getSystemValue('lost_password_link', '') !== '') {
223
+            return new JSONResponse($this->error($this->l10n->t('Password reset is disabled')));
224
+        }
225
+
226
+        // FIXME: use HTTP error codes
227
+        try {
228
+            $this->sendEmail($user);
229
+        } catch (\Exception $e){
230
+            $response = new JSONResponse($this->error($e->getMessage()));
231
+            $response->throttle();
232
+            return $response;
233
+        }
234
+
235
+        $response = new JSONResponse($this->success());
236
+        $response->throttle();
237
+        return $response;
238
+    }
239
+
240
+    /**
241
+     * @PublicPage
242
+     * @param string $token
243
+     * @param string $userId
244
+     * @param string $password
245
+     * @param boolean $proceed
246
+     * @return array
247
+     */
248
+    public function setPassword($token, $userId, $password, $proceed) {
249
+        if ($this->config->getSystemValue('lost_password_link', '') !== '') {
250
+            return $this->error($this->l10n->t('Password reset is disabled'));
251
+        }
252
+
253
+        if ($this->encryptionManager->isEnabled() && !$proceed) {
254
+            return $this->error('', array('encryption' => true));
255
+        }
256
+
257
+        try {
258
+            $this->checkPasswordResetToken($token, $userId);
259
+            $user = $this->userManager->get($userId);
260
+
261
+            \OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'pre_passwordReset', array('uid' => $userId, 'password' => $password));
262
+
263
+            if (!$user->setPassword($password)) {
264
+                throw new \Exception();
265
+            }
266
+
267
+            \OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'post_passwordReset', array('uid' => $userId, 'password' => $password));
268
+
269
+            $this->config->deleteUserValue($userId, 'core', 'lostpassword');
270
+            @\OC::$server->getUserSession()->unsetMagicInCookie();
271
+        } catch (\Exception $e){
272
+            return $this->error($e->getMessage());
273
+        }
274
+
275
+        return $this->success();
276
+    }
277
+
278
+    /**
279
+     * @param string $input
280
+     * @throws \Exception
281
+     */
282
+    protected function sendEmail($input) {
283
+        $user = $this->findUserByIdOrMail($input);
284
+        $email = $user->getEMailAddress();
285
+
286
+        if (empty($email)) {
287
+            throw new \Exception(
288
+                $this->l10n->t('Could not send reset email because there is no email address for this username. Please contact your administrator.')
289
+            );
290
+        }
291
+
292
+        // Generate the token. It is stored encrypted in the database with the
293
+        // secret being the users' email address appended with the system secret.
294
+        // This makes the token automatically invalidate once the user changes
295
+        // their email address.
296
+        $token = $this->secureRandom->generate(
297
+            21,
298
+            ISecureRandom::CHAR_DIGITS.
299
+            ISecureRandom::CHAR_LOWER.
300
+            ISecureRandom::CHAR_UPPER
301
+        );
302
+        $tokenValue = $this->timeFactory->getTime() .':'. $token;
303
+        $encryptedValue = $this->crypto->encrypt($tokenValue, $email . $this->config->getSystemValue('secret'));
304
+        $this->config->setUserValue($user->getUID(), 'core', 'lostpassword', $encryptedValue);
305
+
306
+        $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', array('userId' => $user->getUID(), 'token' => $token));
307
+
308
+        $emailTemplate = $this->mailer->createEMailTemplate('core.ResetPassword', [
309
+            'link' => $link,
310
+        ]);
311
+
312
+        $emailTemplate->setSubject($this->l10n->t('%s password reset', [$this->defaults->getName()]));
313
+        $emailTemplate->addHeader();
314
+        $emailTemplate->addHeading($this->l10n->t('Password reset'));
315
+
316
+        $emailTemplate->addBodyText(
317
+            $this->l10n->t('Click the following button to reset your password. If you have not requested the password reset, then ignore this email.'),
318
+            $this->l10n->t('Click the following link to reset your password. If you have not requested the password reset, then ignore this email.')
319
+        );
320
+
321
+        $emailTemplate->addBodyButton(
322
+            $this->l10n->t('Reset your password'),
323
+            $link,
324
+            false
325
+        );
326
+        $emailTemplate->addFooter();
327
+
328
+        try {
329
+            $message = $this->mailer->createMessage();
330
+            $message->setTo([$email => $user->getUID()]);
331
+            $message->setFrom([$this->from => $this->defaults->getName()]);
332
+            $message->setTemplate($emailTemplate);
333
+            $this->mailer->send($message);
334
+        } catch (\Exception $e) {
335
+            throw new \Exception($this->l10n->t(
336
+                'Couldn\'t send reset email. Please contact your administrator.'
337
+            ));
338
+        }
339
+    }
340
+
341
+    /**
342
+     * @param string $input
343
+     * @return IUser
344
+     * @throws \InvalidArgumentException
345
+     */
346
+    protected function findUserByIdOrMail($input) {
347
+        $user = $this->userManager->get($input);
348
+        if ($user instanceof IUser) {
349
+            if (!$user->isEnabled()) {
350
+                throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
351
+            }
352
+
353
+            return $user;
354
+        }
355
+        $users = $this->userManager->getByEmail($input);
356
+        if (count($users) === 1) {
357
+            $user = $users[0];
358
+            if (!$user->isEnabled()) {
359
+                throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
360
+            }
361
+
362
+            return $user;
363
+        }
364
+
365
+        throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
366
+    }
367 367
 }
Please login to merge, or discard this patch.
apps/sharebymail/lib/ShareByMailProvider.php 2 patches
Indentation   +1013 added lines, -1013 removed lines patch added patch discarded remove patch
@@ -53,1031 +53,1031 @@
 block discarded – undo
53 53
  */
54 54
 class ShareByMailProvider implements IShareProvider {
55 55
 
56
-	/** @var  IDBConnection */
57
-	private $dbConnection;
58
-
59
-	/** @var ILogger */
60
-	private $logger;
61
-
62
-	/** @var ISecureRandom */
63
-	private $secureRandom;
64
-
65
-	/** @var IUserManager */
66
-	private $userManager;
67
-
68
-	/** @var IRootFolder */
69
-	private $rootFolder;
70
-
71
-	/** @var IL10N */
72
-	private $l;
73
-
74
-	/** @var IMailer */
75
-	private $mailer;
76
-
77
-	/** @var IURLGenerator */
78
-	private $urlGenerator;
79
-
80
-	/** @var IManager  */
81
-	private $activityManager;
82
-
83
-	/** @var SettingsManager */
84
-	private $settingsManager;
85
-
86
-	/** @var Defaults */
87
-	private $defaults;
88
-
89
-	/** @var IHasher */
90
-	private $hasher;
91
-
92
-	/** @var  CapabilitiesManager */
93
-	private $capabilitiesManager;
94
-
95
-	/**
96
-	 * Return the identifier of this provider.
97
-	 *
98
-	 * @return string Containing only [a-zA-Z0-9]
99
-	 */
100
-	public function identifier() {
101
-		return 'ocMailShare';
102
-	}
103
-
104
-	/**
105
-	 * DefaultShareProvider constructor.
106
-	 *
107
-	 * @param IDBConnection $connection
108
-	 * @param ISecureRandom $secureRandom
109
-	 * @param IUserManager $userManager
110
-	 * @param IRootFolder $rootFolder
111
-	 * @param IL10N $l
112
-	 * @param ILogger $logger
113
-	 * @param IMailer $mailer
114
-	 * @param IURLGenerator $urlGenerator
115
-	 * @param IManager $activityManager
116
-	 * @param SettingsManager $settingsManager
117
-	 * @param Defaults $defaults
118
-	 * @param IHasher $hasher
119
-	 * @param CapabilitiesManager $capabilitiesManager
120
-	 */
121
-	public function __construct(
122
-		IDBConnection $connection,
123
-		ISecureRandom $secureRandom,
124
-		IUserManager $userManager,
125
-		IRootFolder $rootFolder,
126
-		IL10N $l,
127
-		ILogger $logger,
128
-		IMailer $mailer,
129
-		IURLGenerator $urlGenerator,
130
-		IManager $activityManager,
131
-		SettingsManager $settingsManager,
132
-		Defaults $defaults,
133
-		IHasher $hasher,
134
-		CapabilitiesManager $capabilitiesManager
135
-	) {
136
-		$this->dbConnection = $connection;
137
-		$this->secureRandom = $secureRandom;
138
-		$this->userManager = $userManager;
139
-		$this->rootFolder = $rootFolder;
140
-		$this->l = $l;
141
-		$this->logger = $logger;
142
-		$this->mailer = $mailer;
143
-		$this->urlGenerator = $urlGenerator;
144
-		$this->activityManager = $activityManager;
145
-		$this->settingsManager = $settingsManager;
146
-		$this->defaults = $defaults;
147
-		$this->hasher = $hasher;
148
-		$this->capabilitiesManager = $capabilitiesManager;
149
-	}
150
-
151
-	/**
152
-	 * Share a path
153
-	 *
154
-	 * @param IShare $share
155
-	 * @return IShare The share object
156
-	 * @throws ShareNotFound
157
-	 * @throws \Exception
158
-	 */
159
-	public function create(IShare $share) {
160
-
161
-		$shareWith = $share->getSharedWith();
162
-		/*
56
+    /** @var  IDBConnection */
57
+    private $dbConnection;
58
+
59
+    /** @var ILogger */
60
+    private $logger;
61
+
62
+    /** @var ISecureRandom */
63
+    private $secureRandom;
64
+
65
+    /** @var IUserManager */
66
+    private $userManager;
67
+
68
+    /** @var IRootFolder */
69
+    private $rootFolder;
70
+
71
+    /** @var IL10N */
72
+    private $l;
73
+
74
+    /** @var IMailer */
75
+    private $mailer;
76
+
77
+    /** @var IURLGenerator */
78
+    private $urlGenerator;
79
+
80
+    /** @var IManager  */
81
+    private $activityManager;
82
+
83
+    /** @var SettingsManager */
84
+    private $settingsManager;
85
+
86
+    /** @var Defaults */
87
+    private $defaults;
88
+
89
+    /** @var IHasher */
90
+    private $hasher;
91
+
92
+    /** @var  CapabilitiesManager */
93
+    private $capabilitiesManager;
94
+
95
+    /**
96
+     * Return the identifier of this provider.
97
+     *
98
+     * @return string Containing only [a-zA-Z0-9]
99
+     */
100
+    public function identifier() {
101
+        return 'ocMailShare';
102
+    }
103
+
104
+    /**
105
+     * DefaultShareProvider constructor.
106
+     *
107
+     * @param IDBConnection $connection
108
+     * @param ISecureRandom $secureRandom
109
+     * @param IUserManager $userManager
110
+     * @param IRootFolder $rootFolder
111
+     * @param IL10N $l
112
+     * @param ILogger $logger
113
+     * @param IMailer $mailer
114
+     * @param IURLGenerator $urlGenerator
115
+     * @param IManager $activityManager
116
+     * @param SettingsManager $settingsManager
117
+     * @param Defaults $defaults
118
+     * @param IHasher $hasher
119
+     * @param CapabilitiesManager $capabilitiesManager
120
+     */
121
+    public function __construct(
122
+        IDBConnection $connection,
123
+        ISecureRandom $secureRandom,
124
+        IUserManager $userManager,
125
+        IRootFolder $rootFolder,
126
+        IL10N $l,
127
+        ILogger $logger,
128
+        IMailer $mailer,
129
+        IURLGenerator $urlGenerator,
130
+        IManager $activityManager,
131
+        SettingsManager $settingsManager,
132
+        Defaults $defaults,
133
+        IHasher $hasher,
134
+        CapabilitiesManager $capabilitiesManager
135
+    ) {
136
+        $this->dbConnection = $connection;
137
+        $this->secureRandom = $secureRandom;
138
+        $this->userManager = $userManager;
139
+        $this->rootFolder = $rootFolder;
140
+        $this->l = $l;
141
+        $this->logger = $logger;
142
+        $this->mailer = $mailer;
143
+        $this->urlGenerator = $urlGenerator;
144
+        $this->activityManager = $activityManager;
145
+        $this->settingsManager = $settingsManager;
146
+        $this->defaults = $defaults;
147
+        $this->hasher = $hasher;
148
+        $this->capabilitiesManager = $capabilitiesManager;
149
+    }
150
+
151
+    /**
152
+     * Share a path
153
+     *
154
+     * @param IShare $share
155
+     * @return IShare The share object
156
+     * @throws ShareNotFound
157
+     * @throws \Exception
158
+     */
159
+    public function create(IShare $share) {
160
+
161
+        $shareWith = $share->getSharedWith();
162
+        /*
163 163
 		 * Check if file is not already shared with the remote user
164 164
 		 */
165
-		$alreadyShared = $this->getSharedWith($shareWith, \OCP\Share::SHARE_TYPE_EMAIL, $share->getNode(), 1, 0);
166
-		if (!empty($alreadyShared)) {
167
-			$message = 'Sharing %s failed, this item is already shared with %s';
168
-			$message_t = $this->l->t('Sharing %s failed, this item is already shared with %s', array($share->getNode()->getName(), $shareWith));
169
-			$this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
170
-			throw new \Exception($message_t);
171
-		}
172
-
173
-		// if the admin enforces a password for all mail shares we create a
174
-		// random password and send it to the recipient
175
-		$password = '';
176
-		$passwordEnforced = $this->settingsManager->enforcePasswordProtection();
177
-		if ($passwordEnforced) {
178
-			$password = $this->autoGeneratePassword($share);
179
-		}
180
-
181
-		$shareId = $this->createMailShare($share);
182
-		$send = $this->sendPassword($share, $password);
183
-		if ($passwordEnforced && $send === false) {
184
-			$this->sendPasswordToOwner($share, $password);
185
-		}
186
-
187
-		$this->createShareActivity($share);
188
-		$data = $this->getRawShare($shareId);
189
-
190
-		return $this->createShareObject($data);
191
-
192
-	}
193
-
194
-	/**
195
-	 * auto generate password in case of password enforcement on mail shares
196
-	 *
197
-	 * @param IShare $share
198
-	 * @return string
199
-	 * @throws \Exception
200
-	 */
201
-	protected function autoGeneratePassword($share) {
202
-		$initiatorUser = $this->userManager->get($share->getSharedBy());
203
-		$initiatorEMailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
204
-		$allowPasswordByMail = $this->settingsManager->sendPasswordByMail();
205
-
206
-		if ($initiatorEMailAddress === null && !$allowPasswordByMail) {
207
-			throw new \Exception(
208
-				$this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
209
-			);
210
-		}
211
-
212
-		$passwordPolicy = $this->getPasswordPolicy();
213
-		$passwordCharset = ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS;
214
-		$passwordLength = 8;
215
-		if (!empty($passwordPolicy)) {
216
-			$passwordLength = (int)$passwordPolicy['minLength'] > 0 ? (int)$passwordPolicy['minLength'] : $passwordLength;
217
-			$passwordCharset .= $passwordPolicy['enforceSpecialCharacters'] ? ISecureRandom::CHAR_SYMBOLS : '';
218
-		}
219
-
220
-		$password = $this->secureRandom->generate($passwordLength, $passwordCharset);
221
-
222
-		$share->setPassword($this->hasher->hash($password));
223
-
224
-		return $password;
225
-	}
226
-
227
-	/**
228
-	 * get password policy
229
-	 *
230
-	 * @return array
231
-	 */
232
-	protected function getPasswordPolicy() {
233
-		$capabilities = $this->capabilitiesManager->getCapabilities();
234
-		if (isset($capabilities['password_policy'])) {
235
-			return $capabilities['password_policy'];
236
-		}
237
-
238
-		return [];
239
-	}
240
-
241
-	/**
242
-	 * create activity if a file/folder was shared by mail
243
-	 *
244
-	 * @param IShare $share
245
-	 */
246
-	protected function createShareActivity(IShare $share) {
247
-
248
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
249
-
250
-		$this->publishActivity(
251
-			Activity::SUBJECT_SHARED_EMAIL_SELF,
252
-			[$userFolder->getRelativePath($share->getNode()->getPath()), $share->getSharedWith()],
253
-			$share->getSharedBy(),
254
-			$share->getNode()->getId(),
255
-			$userFolder->getRelativePath($share->getNode()->getPath())
256
-		);
257
-
258
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
259
-			$ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
260
-			$fileId = $share->getNode()->getId();
261
-			$nodes = $ownerFolder->getById($fileId);
262
-			$ownerPath = $nodes[0]->getPath();
263
-			$this->publishActivity(
264
-				Activity::SUBJECT_SHARED_EMAIL_BY,
265
-				[$ownerFolder->getRelativePath($ownerPath), $share->getSharedWith(), $share->getSharedBy()],
266
-				$share->getShareOwner(),
267
-				$fileId,
268
-				$ownerFolder->getRelativePath($ownerPath)
269
-			);
270
-		}
271
-
272
-	}
273
-
274
-	/**
275
-	 * create activity if a file/folder was shared by mail
276
-	 *
277
-	 * @param IShare $share
278
-	 * @param string $sharedWith
279
-	 * @param bool $sendToSelf
280
-	 */
281
-	protected function createPasswordSendActivity(IShare $share, $sharedWith, $sendToSelf) {
282
-
283
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
284
-
285
-		if ($sendToSelf) {
286
-			$this->publishActivity(
287
-				Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND_SELF,
288
-				[$userFolder->getRelativePath($share->getNode()->getPath())],
289
-				$share->getSharedBy(),
290
-				$share->getNode()->getId(),
291
-				$userFolder->getRelativePath($share->getNode()->getPath())
292
-			);
293
-		} else {
294
-			$this->publishActivity(
295
-				Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND,
296
-				[$userFolder->getRelativePath($share->getNode()->getPath()), $sharedWith],
297
-				$share->getSharedBy(),
298
-				$share->getNode()->getId(),
299
-				$userFolder->getRelativePath($share->getNode()->getPath())
300
-			);
301
-		}
302
-	}
303
-
304
-
305
-	/**
306
-	 * publish activity if a file/folder was shared by mail
307
-	 *
308
-	 * @param $subject
309
-	 * @param $parameters
310
-	 * @param $affectedUser
311
-	 * @param $fileId
312
-	 * @param $filePath
313
-	 */
314
-	protected function publishActivity($subject, $parameters, $affectedUser, $fileId, $filePath) {
315
-		$event = $this->activityManager->generateEvent();
316
-		$event->setApp('sharebymail')
317
-			->setType('shared')
318
-			->setSubject($subject, $parameters)
319
-			->setAffectedUser($affectedUser)
320
-			->setObject('files', $fileId, $filePath);
321
-		$this->activityManager->publish($event);
322
-
323
-	}
324
-
325
-	/**
326
-	 * @param IShare $share
327
-	 * @return int
328
-	 * @throws \Exception
329
-	 */
330
-	protected function createMailShare(IShare $share) {
331
-		$share->setToken($this->generateToken());
332
-		$shareId = $this->addShareToDB(
333
-			$share->getNodeId(),
334
-			$share->getNodeType(),
335
-			$share->getSharedWith(),
336
-			$share->getSharedBy(),
337
-			$share->getShareOwner(),
338
-			$share->getPermissions(),
339
-			$share->getToken(),
340
-			$share->getPassword()
341
-		);
342
-
343
-		try {
344
-			$link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
345
-				['token' => $share->getToken()]);
346
-			$this->sendMailNotification(
347
-				$share->getNode()->getName(),
348
-				$link,
349
-				$share->getSharedBy(),
350
-				$share->getSharedWith(),
351
-				$share->getExpirationDate()
352
-			);
353
-		} catch (HintException $hintException) {
354
-			$this->logger->error('Failed to send share by mail: ' . $hintException->getMessage());
355
-			$this->removeShareFromTable($shareId);
356
-			throw $hintException;
357
-		} catch (\Exception $e) {
358
-			$this->logger->error('Failed to send share by email: ' . $e->getMessage());
359
-			$this->removeShareFromTable($shareId);
360
-			throw new HintException('Failed to send share by mail',
361
-				$this->l->t('Failed to send share by email'));
362
-		}
363
-
364
-		return $shareId;
365
-
366
-	}
367
-
368
-	/**
369
-	 * @param string $filename
370
-	 * @param string $link
371
-	 * @param string $initiator
372
-	 * @param string $shareWith
373
-	 * @param \DateTime|null $expiration
374
-	 * @throws \Exception If mail couldn't be sent
375
-	 */
376
-	protected function sendMailNotification($filename,
377
-											$link,
378
-											$initiator,
379
-											$shareWith,
380
-											\DateTime $expiration = null) {
381
-		$initiatorUser = $this->userManager->get($initiator);
382
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
383
-		$message = $this->mailer->createMessage();
384
-
385
-		$emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientNotification', [
386
-			'filename' => $filename,
387
-			'link' => $link,
388
-			'initiator' => $initiatorDisplayName,
389
-			'expiration' => $expiration,
390
-			'shareWith' => $shareWith,
391
-		]);
392
-
393
-		$emailTemplate->setSubject($this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename)));
394
-		$emailTemplate->addHeader();
395
-		$emailTemplate->addHeading($this->l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
396
-		$text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
397
-
398
-		$emailTemplate->addBodyText(
399
-			$text . ' ' . $this->l->t('Click the button below to open it.'),
400
-			$text
401
-		);
402
-		$emailTemplate->addBodyButton(
403
-			$this->l->t('Open »%s«', [$filename]),
404
-			$link
405
-		);
406
-
407
-		$message->setTo([$shareWith]);
408
-
409
-		// The "From" contains the sharers name
410
-		$instanceName = $this->defaults->getName();
411
-		$senderName = $this->l->t(
412
-			'%s via %s',
413
-			[
414
-				$initiatorDisplayName,
415
-				$instanceName
416
-			]
417
-		);
418
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
419
-
420
-		// The "Reply-To" is set to the sharer if an mail address is configured
421
-		// also the default footer contains a "Do not reply" which needs to be adjusted.
422
-		$initiatorEmail = $initiatorUser->getEMailAddress();
423
-		if($initiatorEmail !== null) {
424
-			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
425
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
426
-		} else {
427
-			$emailTemplate->addFooter();
428
-		}
429
-
430
-		$message->setTemplate($emailTemplate);
431
-		$this->mailer->send($message);
432
-	}
433
-
434
-	/**
435
-	 * send password to recipient of a mail share
436
-	 *
437
-	 * @param IShare $share
438
-	 * @param string $password
439
-	 * @return bool
440
-	 */
441
-	protected function sendPassword(IShare $share, $password) {
442
-
443
-		$filename = $share->getNode()->getName();
444
-		$initiator = $share->getSharedBy();
445
-		$shareWith = $share->getSharedWith();
446
-
447
-		if ($password === '' || $this->settingsManager->sendPasswordByMail() === false) {
448
-			return false;
449
-		}
450
-
451
-		$initiatorUser = $this->userManager->get($initiator);
452
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
453
-		$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
454
-
455
-		$plainBodyPart = $this->l->t("%s shared »%s« with you.\nYou should have already received a separate mail with a link to access it.\n", [$initiatorDisplayName, $filename]);
456
-		$htmlBodyPart = $this->l->t('%s shared »%s« with you. You should have already received a separate mail with a link to access it.', [$initiatorDisplayName, $filename]);
457
-
458
-		$message = $this->mailer->createMessage();
459
-
460
-		$emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientPasswordNotification', [
461
-			'filename' => $filename,
462
-			'password' => $password,
463
-			'initiator' => $initiatorDisplayName,
464
-			'initiatorEmail' => $initiatorEmailAddress,
465
-			'shareWith' => $shareWith,
466
-		]);
467
-
468
-		$emailTemplate->setSubject($this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]));
469
-		$emailTemplate->addHeader();
470
-		$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
471
-		$emailTemplate->addBodyText($htmlBodyPart, $plainBodyPart);
472
-		$emailTemplate->addBodyText($this->l->t('It is protected with the following password: %s', [$password]));
473
-
474
-		// The "From" contains the sharers name
475
-		$instanceName = $this->defaults->getName();
476
-		$senderName = $this->l->t(
477
-			'%s via %s',
478
-			[
479
-				$initiatorDisplayName,
480
-				$instanceName
481
-			]
482
-		);
483
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
484
-		if ($initiatorEmailAddress !== null) {
485
-			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
486
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
487
-		} else {
488
-			$emailTemplate->addFooter();
489
-		}
490
-
491
-		$message->setTo([$shareWith]);
492
-		$message->setTemplate($emailTemplate);
493
-		$this->mailer->send($message);
494
-
495
-		$this->createPasswordSendActivity($share, $shareWith, false);
496
-
497
-		return true;
498
-	}
499
-
500
-	/**
501
-	 * send auto generated password to the owner. This happens if the admin enforces
502
-	 * a password for mail shares and forbid to send the password by mail to the recipient
503
-	 *
504
-	 * @param IShare $share
505
-	 * @param string $password
506
-	 * @return bool
507
-	 * @throws \Exception
508
-	 */
509
-	protected function sendPasswordToOwner(IShare $share, $password) {
510
-
511
-		$filename = $share->getNode()->getName();
512
-		$initiator = $this->userManager->get($share->getSharedBy());
513
-		$initiatorEMailAddress = ($initiator instanceof IUser) ? $initiator->getEMailAddress() : null;
514
-		$initiatorDisplayName = ($initiator instanceof IUser) ? $initiator->getDisplayName() : $share->getSharedBy();
515
-		$shareWith = $share->getSharedWith();
516
-
517
-		if ($initiatorEMailAddress === null) {
518
-			throw new \Exception(
519
-				$this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
520
-			);
521
-		}
522
-
523
-		$bodyPart = $this->l->t("You just shared »%s« with %s. The share was already send to the recipient. Due to the security policies defined by the administrator of %s each share needs to be protected by password and it is not allowed to send the password directly to the recipient. Therefore you need to forward the password manually to the recipient.", [$filename, $shareWith, $this->defaults->getName()]);
524
-
525
-		$message = $this->mailer->createMessage();
526
-		$emailTemplate = $this->mailer->createEMailTemplate('sharebymail.OwnerPasswordNotification', [
527
-			'filename' => $filename,
528
-			'password' => $password,
529
-			'initiator' => $initiatorDisplayName,
530
-			'initiatorEmail' => $initiatorEMailAddress,
531
-			'shareWith' => $shareWith,
532
-		]);
533
-
534
-		$emailTemplate->setSubject($this->l->t('Password to access »%s« shared with %s', [$filename, $shareWith]));
535
-		$emailTemplate->addHeader();
536
-		$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
537
-		$emailTemplate->addBodyText($bodyPart);
538
-		$emailTemplate->addBodyText($this->l->t('This is the password: %s', [$password]));
539
-		$emailTemplate->addBodyText($this->l->t('You can choose a different password at any time in the share dialog.'));
540
-		$emailTemplate->addFooter();
541
-
542
-		if ($initiatorEMailAddress) {
543
-			$message->setFrom([$initiatorEMailAddress => $initiatorDisplayName]);
544
-		}
545
-		$message->setTo([$initiatorEMailAddress => $initiatorDisplayName]);
546
-		$message->setTemplate($emailTemplate);
547
-		$this->mailer->send($message);
548
-
549
-		$this->createPasswordSendActivity($share, $shareWith, true);
550
-
551
-		return true;
552
-	}
553
-
554
-	/**
555
-	 * generate share token
556
-	 *
557
-	 * @return string
558
-	 */
559
-	protected function generateToken($size = 15) {
560
-		$token = $this->secureRandom->generate($size, ISecureRandom::CHAR_HUMAN_READABLE);
561
-		return $token;
562
-	}
563
-
564
-	/**
565
-	 * Get all children of this share
566
-	 *
567
-	 * @param IShare $parent
568
-	 * @return IShare[]
569
-	 */
570
-	public function getChildren(IShare $parent) {
571
-		$children = [];
572
-
573
-		$qb = $this->dbConnection->getQueryBuilder();
574
-		$qb->select('*')
575
-			->from('share')
576
-			->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
577
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
578
-			->orderBy('id');
579
-
580
-		$cursor = $qb->execute();
581
-		while($data = $cursor->fetch()) {
582
-			$children[] = $this->createShareObject($data);
583
-		}
584
-		$cursor->closeCursor();
585
-
586
-		return $children;
587
-	}
588
-
589
-	/**
590
-	 * add share to the database and return the ID
591
-	 *
592
-	 * @param int $itemSource
593
-	 * @param string $itemType
594
-	 * @param string $shareWith
595
-	 * @param string $sharedBy
596
-	 * @param string $uidOwner
597
-	 * @param int $permissions
598
-	 * @param string $token
599
-	 * @return int
600
-	 */
601
-	protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password) {
602
-		$qb = $this->dbConnection->getQueryBuilder();
603
-		$qb->insert('share')
604
-			->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
605
-			->setValue('item_type', $qb->createNamedParameter($itemType))
606
-			->setValue('item_source', $qb->createNamedParameter($itemSource))
607
-			->setValue('file_source', $qb->createNamedParameter($itemSource))
608
-			->setValue('share_with', $qb->createNamedParameter($shareWith))
609
-			->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
610
-			->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
611
-			->setValue('permissions', $qb->createNamedParameter($permissions))
612
-			->setValue('token', $qb->createNamedParameter($token))
613
-			->setValue('password', $qb->createNamedParameter($password))
614
-			->setValue('stime', $qb->createNamedParameter(time()));
615
-
616
-		/*
165
+        $alreadyShared = $this->getSharedWith($shareWith, \OCP\Share::SHARE_TYPE_EMAIL, $share->getNode(), 1, 0);
166
+        if (!empty($alreadyShared)) {
167
+            $message = 'Sharing %s failed, this item is already shared with %s';
168
+            $message_t = $this->l->t('Sharing %s failed, this item is already shared with %s', array($share->getNode()->getName(), $shareWith));
169
+            $this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
170
+            throw new \Exception($message_t);
171
+        }
172
+
173
+        // if the admin enforces a password for all mail shares we create a
174
+        // random password and send it to the recipient
175
+        $password = '';
176
+        $passwordEnforced = $this->settingsManager->enforcePasswordProtection();
177
+        if ($passwordEnforced) {
178
+            $password = $this->autoGeneratePassword($share);
179
+        }
180
+
181
+        $shareId = $this->createMailShare($share);
182
+        $send = $this->sendPassword($share, $password);
183
+        if ($passwordEnforced && $send === false) {
184
+            $this->sendPasswordToOwner($share, $password);
185
+        }
186
+
187
+        $this->createShareActivity($share);
188
+        $data = $this->getRawShare($shareId);
189
+
190
+        return $this->createShareObject($data);
191
+
192
+    }
193
+
194
+    /**
195
+     * auto generate password in case of password enforcement on mail shares
196
+     *
197
+     * @param IShare $share
198
+     * @return string
199
+     * @throws \Exception
200
+     */
201
+    protected function autoGeneratePassword($share) {
202
+        $initiatorUser = $this->userManager->get($share->getSharedBy());
203
+        $initiatorEMailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
204
+        $allowPasswordByMail = $this->settingsManager->sendPasswordByMail();
205
+
206
+        if ($initiatorEMailAddress === null && !$allowPasswordByMail) {
207
+            throw new \Exception(
208
+                $this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
209
+            );
210
+        }
211
+
212
+        $passwordPolicy = $this->getPasswordPolicy();
213
+        $passwordCharset = ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS;
214
+        $passwordLength = 8;
215
+        if (!empty($passwordPolicy)) {
216
+            $passwordLength = (int)$passwordPolicy['minLength'] > 0 ? (int)$passwordPolicy['minLength'] : $passwordLength;
217
+            $passwordCharset .= $passwordPolicy['enforceSpecialCharacters'] ? ISecureRandom::CHAR_SYMBOLS : '';
218
+        }
219
+
220
+        $password = $this->secureRandom->generate($passwordLength, $passwordCharset);
221
+
222
+        $share->setPassword($this->hasher->hash($password));
223
+
224
+        return $password;
225
+    }
226
+
227
+    /**
228
+     * get password policy
229
+     *
230
+     * @return array
231
+     */
232
+    protected function getPasswordPolicy() {
233
+        $capabilities = $this->capabilitiesManager->getCapabilities();
234
+        if (isset($capabilities['password_policy'])) {
235
+            return $capabilities['password_policy'];
236
+        }
237
+
238
+        return [];
239
+    }
240
+
241
+    /**
242
+     * create activity if a file/folder was shared by mail
243
+     *
244
+     * @param IShare $share
245
+     */
246
+    protected function createShareActivity(IShare $share) {
247
+
248
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
249
+
250
+        $this->publishActivity(
251
+            Activity::SUBJECT_SHARED_EMAIL_SELF,
252
+            [$userFolder->getRelativePath($share->getNode()->getPath()), $share->getSharedWith()],
253
+            $share->getSharedBy(),
254
+            $share->getNode()->getId(),
255
+            $userFolder->getRelativePath($share->getNode()->getPath())
256
+        );
257
+
258
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
259
+            $ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
260
+            $fileId = $share->getNode()->getId();
261
+            $nodes = $ownerFolder->getById($fileId);
262
+            $ownerPath = $nodes[0]->getPath();
263
+            $this->publishActivity(
264
+                Activity::SUBJECT_SHARED_EMAIL_BY,
265
+                [$ownerFolder->getRelativePath($ownerPath), $share->getSharedWith(), $share->getSharedBy()],
266
+                $share->getShareOwner(),
267
+                $fileId,
268
+                $ownerFolder->getRelativePath($ownerPath)
269
+            );
270
+        }
271
+
272
+    }
273
+
274
+    /**
275
+     * create activity if a file/folder was shared by mail
276
+     *
277
+     * @param IShare $share
278
+     * @param string $sharedWith
279
+     * @param bool $sendToSelf
280
+     */
281
+    protected function createPasswordSendActivity(IShare $share, $sharedWith, $sendToSelf) {
282
+
283
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
284
+
285
+        if ($sendToSelf) {
286
+            $this->publishActivity(
287
+                Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND_SELF,
288
+                [$userFolder->getRelativePath($share->getNode()->getPath())],
289
+                $share->getSharedBy(),
290
+                $share->getNode()->getId(),
291
+                $userFolder->getRelativePath($share->getNode()->getPath())
292
+            );
293
+        } else {
294
+            $this->publishActivity(
295
+                Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND,
296
+                [$userFolder->getRelativePath($share->getNode()->getPath()), $sharedWith],
297
+                $share->getSharedBy(),
298
+                $share->getNode()->getId(),
299
+                $userFolder->getRelativePath($share->getNode()->getPath())
300
+            );
301
+        }
302
+    }
303
+
304
+
305
+    /**
306
+     * publish activity if a file/folder was shared by mail
307
+     *
308
+     * @param $subject
309
+     * @param $parameters
310
+     * @param $affectedUser
311
+     * @param $fileId
312
+     * @param $filePath
313
+     */
314
+    protected function publishActivity($subject, $parameters, $affectedUser, $fileId, $filePath) {
315
+        $event = $this->activityManager->generateEvent();
316
+        $event->setApp('sharebymail')
317
+            ->setType('shared')
318
+            ->setSubject($subject, $parameters)
319
+            ->setAffectedUser($affectedUser)
320
+            ->setObject('files', $fileId, $filePath);
321
+        $this->activityManager->publish($event);
322
+
323
+    }
324
+
325
+    /**
326
+     * @param IShare $share
327
+     * @return int
328
+     * @throws \Exception
329
+     */
330
+    protected function createMailShare(IShare $share) {
331
+        $share->setToken($this->generateToken());
332
+        $shareId = $this->addShareToDB(
333
+            $share->getNodeId(),
334
+            $share->getNodeType(),
335
+            $share->getSharedWith(),
336
+            $share->getSharedBy(),
337
+            $share->getShareOwner(),
338
+            $share->getPermissions(),
339
+            $share->getToken(),
340
+            $share->getPassword()
341
+        );
342
+
343
+        try {
344
+            $link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
345
+                ['token' => $share->getToken()]);
346
+            $this->sendMailNotification(
347
+                $share->getNode()->getName(),
348
+                $link,
349
+                $share->getSharedBy(),
350
+                $share->getSharedWith(),
351
+                $share->getExpirationDate()
352
+            );
353
+        } catch (HintException $hintException) {
354
+            $this->logger->error('Failed to send share by mail: ' . $hintException->getMessage());
355
+            $this->removeShareFromTable($shareId);
356
+            throw $hintException;
357
+        } catch (\Exception $e) {
358
+            $this->logger->error('Failed to send share by email: ' . $e->getMessage());
359
+            $this->removeShareFromTable($shareId);
360
+            throw new HintException('Failed to send share by mail',
361
+                $this->l->t('Failed to send share by email'));
362
+        }
363
+
364
+        return $shareId;
365
+
366
+    }
367
+
368
+    /**
369
+     * @param string $filename
370
+     * @param string $link
371
+     * @param string $initiator
372
+     * @param string $shareWith
373
+     * @param \DateTime|null $expiration
374
+     * @throws \Exception If mail couldn't be sent
375
+     */
376
+    protected function sendMailNotification($filename,
377
+                                            $link,
378
+                                            $initiator,
379
+                                            $shareWith,
380
+                                            \DateTime $expiration = null) {
381
+        $initiatorUser = $this->userManager->get($initiator);
382
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
383
+        $message = $this->mailer->createMessage();
384
+
385
+        $emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientNotification', [
386
+            'filename' => $filename,
387
+            'link' => $link,
388
+            'initiator' => $initiatorDisplayName,
389
+            'expiration' => $expiration,
390
+            'shareWith' => $shareWith,
391
+        ]);
392
+
393
+        $emailTemplate->setSubject($this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename)));
394
+        $emailTemplate->addHeader();
395
+        $emailTemplate->addHeading($this->l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
396
+        $text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
397
+
398
+        $emailTemplate->addBodyText(
399
+            $text . ' ' . $this->l->t('Click the button below to open it.'),
400
+            $text
401
+        );
402
+        $emailTemplate->addBodyButton(
403
+            $this->l->t('Open »%s«', [$filename]),
404
+            $link
405
+        );
406
+
407
+        $message->setTo([$shareWith]);
408
+
409
+        // The "From" contains the sharers name
410
+        $instanceName = $this->defaults->getName();
411
+        $senderName = $this->l->t(
412
+            '%s via %s',
413
+            [
414
+                $initiatorDisplayName,
415
+                $instanceName
416
+            ]
417
+        );
418
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
419
+
420
+        // The "Reply-To" is set to the sharer if an mail address is configured
421
+        // also the default footer contains a "Do not reply" which needs to be adjusted.
422
+        $initiatorEmail = $initiatorUser->getEMailAddress();
423
+        if($initiatorEmail !== null) {
424
+            $message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
425
+            $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
426
+        } else {
427
+            $emailTemplate->addFooter();
428
+        }
429
+
430
+        $message->setTemplate($emailTemplate);
431
+        $this->mailer->send($message);
432
+    }
433
+
434
+    /**
435
+     * send password to recipient of a mail share
436
+     *
437
+     * @param IShare $share
438
+     * @param string $password
439
+     * @return bool
440
+     */
441
+    protected function sendPassword(IShare $share, $password) {
442
+
443
+        $filename = $share->getNode()->getName();
444
+        $initiator = $share->getSharedBy();
445
+        $shareWith = $share->getSharedWith();
446
+
447
+        if ($password === '' || $this->settingsManager->sendPasswordByMail() === false) {
448
+            return false;
449
+        }
450
+
451
+        $initiatorUser = $this->userManager->get($initiator);
452
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
453
+        $initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
454
+
455
+        $plainBodyPart = $this->l->t("%s shared »%s« with you.\nYou should have already received a separate mail with a link to access it.\n", [$initiatorDisplayName, $filename]);
456
+        $htmlBodyPart = $this->l->t('%s shared »%s« with you. You should have already received a separate mail with a link to access it.', [$initiatorDisplayName, $filename]);
457
+
458
+        $message = $this->mailer->createMessage();
459
+
460
+        $emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientPasswordNotification', [
461
+            'filename' => $filename,
462
+            'password' => $password,
463
+            'initiator' => $initiatorDisplayName,
464
+            'initiatorEmail' => $initiatorEmailAddress,
465
+            'shareWith' => $shareWith,
466
+        ]);
467
+
468
+        $emailTemplate->setSubject($this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]));
469
+        $emailTemplate->addHeader();
470
+        $emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
471
+        $emailTemplate->addBodyText($htmlBodyPart, $plainBodyPart);
472
+        $emailTemplate->addBodyText($this->l->t('It is protected with the following password: %s', [$password]));
473
+
474
+        // The "From" contains the sharers name
475
+        $instanceName = $this->defaults->getName();
476
+        $senderName = $this->l->t(
477
+            '%s via %s',
478
+            [
479
+                $initiatorDisplayName,
480
+                $instanceName
481
+            ]
482
+        );
483
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
484
+        if ($initiatorEmailAddress !== null) {
485
+            $message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
486
+            $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
487
+        } else {
488
+            $emailTemplate->addFooter();
489
+        }
490
+
491
+        $message->setTo([$shareWith]);
492
+        $message->setTemplate($emailTemplate);
493
+        $this->mailer->send($message);
494
+
495
+        $this->createPasswordSendActivity($share, $shareWith, false);
496
+
497
+        return true;
498
+    }
499
+
500
+    /**
501
+     * send auto generated password to the owner. This happens if the admin enforces
502
+     * a password for mail shares and forbid to send the password by mail to the recipient
503
+     *
504
+     * @param IShare $share
505
+     * @param string $password
506
+     * @return bool
507
+     * @throws \Exception
508
+     */
509
+    protected function sendPasswordToOwner(IShare $share, $password) {
510
+
511
+        $filename = $share->getNode()->getName();
512
+        $initiator = $this->userManager->get($share->getSharedBy());
513
+        $initiatorEMailAddress = ($initiator instanceof IUser) ? $initiator->getEMailAddress() : null;
514
+        $initiatorDisplayName = ($initiator instanceof IUser) ? $initiator->getDisplayName() : $share->getSharedBy();
515
+        $shareWith = $share->getSharedWith();
516
+
517
+        if ($initiatorEMailAddress === null) {
518
+            throw new \Exception(
519
+                $this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
520
+            );
521
+        }
522
+
523
+        $bodyPart = $this->l->t("You just shared »%s« with %s. The share was already send to the recipient. Due to the security policies defined by the administrator of %s each share needs to be protected by password and it is not allowed to send the password directly to the recipient. Therefore you need to forward the password manually to the recipient.", [$filename, $shareWith, $this->defaults->getName()]);
524
+
525
+        $message = $this->mailer->createMessage();
526
+        $emailTemplate = $this->mailer->createEMailTemplate('sharebymail.OwnerPasswordNotification', [
527
+            'filename' => $filename,
528
+            'password' => $password,
529
+            'initiator' => $initiatorDisplayName,
530
+            'initiatorEmail' => $initiatorEMailAddress,
531
+            'shareWith' => $shareWith,
532
+        ]);
533
+
534
+        $emailTemplate->setSubject($this->l->t('Password to access »%s« shared with %s', [$filename, $shareWith]));
535
+        $emailTemplate->addHeader();
536
+        $emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
537
+        $emailTemplate->addBodyText($bodyPart);
538
+        $emailTemplate->addBodyText($this->l->t('This is the password: %s', [$password]));
539
+        $emailTemplate->addBodyText($this->l->t('You can choose a different password at any time in the share dialog.'));
540
+        $emailTemplate->addFooter();
541
+
542
+        if ($initiatorEMailAddress) {
543
+            $message->setFrom([$initiatorEMailAddress => $initiatorDisplayName]);
544
+        }
545
+        $message->setTo([$initiatorEMailAddress => $initiatorDisplayName]);
546
+        $message->setTemplate($emailTemplate);
547
+        $this->mailer->send($message);
548
+
549
+        $this->createPasswordSendActivity($share, $shareWith, true);
550
+
551
+        return true;
552
+    }
553
+
554
+    /**
555
+     * generate share token
556
+     *
557
+     * @return string
558
+     */
559
+    protected function generateToken($size = 15) {
560
+        $token = $this->secureRandom->generate($size, ISecureRandom::CHAR_HUMAN_READABLE);
561
+        return $token;
562
+    }
563
+
564
+    /**
565
+     * Get all children of this share
566
+     *
567
+     * @param IShare $parent
568
+     * @return IShare[]
569
+     */
570
+    public function getChildren(IShare $parent) {
571
+        $children = [];
572
+
573
+        $qb = $this->dbConnection->getQueryBuilder();
574
+        $qb->select('*')
575
+            ->from('share')
576
+            ->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
577
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
578
+            ->orderBy('id');
579
+
580
+        $cursor = $qb->execute();
581
+        while($data = $cursor->fetch()) {
582
+            $children[] = $this->createShareObject($data);
583
+        }
584
+        $cursor->closeCursor();
585
+
586
+        return $children;
587
+    }
588
+
589
+    /**
590
+     * add share to the database and return the ID
591
+     *
592
+     * @param int $itemSource
593
+     * @param string $itemType
594
+     * @param string $shareWith
595
+     * @param string $sharedBy
596
+     * @param string $uidOwner
597
+     * @param int $permissions
598
+     * @param string $token
599
+     * @return int
600
+     */
601
+    protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password) {
602
+        $qb = $this->dbConnection->getQueryBuilder();
603
+        $qb->insert('share')
604
+            ->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
605
+            ->setValue('item_type', $qb->createNamedParameter($itemType))
606
+            ->setValue('item_source', $qb->createNamedParameter($itemSource))
607
+            ->setValue('file_source', $qb->createNamedParameter($itemSource))
608
+            ->setValue('share_with', $qb->createNamedParameter($shareWith))
609
+            ->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
610
+            ->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
611
+            ->setValue('permissions', $qb->createNamedParameter($permissions))
612
+            ->setValue('token', $qb->createNamedParameter($token))
613
+            ->setValue('password', $qb->createNamedParameter($password))
614
+            ->setValue('stime', $qb->createNamedParameter(time()));
615
+
616
+        /*
617 617
 		 * Added to fix https://github.com/owncloud/core/issues/22215
618 618
 		 * Can be removed once we get rid of ajax/share.php
619 619
 		 */
620
-		$qb->setValue('file_target', $qb->createNamedParameter(''));
620
+        $qb->setValue('file_target', $qb->createNamedParameter(''));
621 621
 
622
-		$qb->execute();
623
-		$id = $qb->getLastInsertId();
622
+        $qb->execute();
623
+        $id = $qb->getLastInsertId();
624 624
 
625
-		return (int)$id;
626
-	}
625
+        return (int)$id;
626
+    }
627 627
 
628
-	/**
629
-	 * Update a share
630
-	 *
631
-	 * @param IShare $share
632
-	 * @param string|null $plainTextPassword
633
-	 * @return IShare The share object
634
-	 */
635
-	public function update(IShare $share, $plainTextPassword = null) {
628
+    /**
629
+     * Update a share
630
+     *
631
+     * @param IShare $share
632
+     * @param string|null $plainTextPassword
633
+     * @return IShare The share object
634
+     */
635
+    public function update(IShare $share, $plainTextPassword = null) {
636 636
 
637
-		$originalShare = $this->getShareById($share->getId());
637
+        $originalShare = $this->getShareById($share->getId());
638 638
 
639
-		// a real password was given
640
-		$validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
639
+        // a real password was given
640
+        $validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
641 641
 
642
-		if($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
643
-			$this->sendPassword($share, $plainTextPassword);
644
-		}
645
-		/*
642
+        if($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
643
+            $this->sendPassword($share, $plainTextPassword);
644
+        }
645
+        /*
646 646
 		 * We allow updating the permissions and password of mail shares
647 647
 		 */
648
-		$qb = $this->dbConnection->getQueryBuilder();
649
-		$qb->update('share')
650
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
651
-			->set('permissions', $qb->createNamedParameter($share->getPermissions()))
652
-			->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
653
-			->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
654
-			->set('password', $qb->createNamedParameter($share->getPassword()))
655
-			->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
656
-			->execute();
657
-
658
-		return $share;
659
-	}
660
-
661
-	/**
662
-	 * @inheritdoc
663
-	 */
664
-	public function move(IShare $share, $recipient) {
665
-		/**
666
-		 * nothing to do here, mail shares are only outgoing shares
667
-		 */
668
-		return $share;
669
-	}
670
-
671
-	/**
672
-	 * Delete a share (owner unShares the file)
673
-	 *
674
-	 * @param IShare $share
675
-	 */
676
-	public function delete(IShare $share) {
677
-		$this->removeShareFromTable($share->getId());
678
-	}
679
-
680
-	/**
681
-	 * @inheritdoc
682
-	 */
683
-	public function deleteFromSelf(IShare $share, $recipient) {
684
-		// nothing to do here, mail shares are only outgoing shares
685
-		return;
686
-	}
687
-
688
-	/**
689
-	 * @inheritdoc
690
-	 */
691
-	public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
692
-		$qb = $this->dbConnection->getQueryBuilder();
693
-		$qb->select('*')
694
-			->from('share');
695
-
696
-		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
697
-
698
-		/**
699
-		 * Reshares for this user are shares where they are the owner.
700
-		 */
701
-		if ($reshares === false) {
702
-			//Special case for old shares created via the web UI
703
-			$or1 = $qb->expr()->andX(
704
-				$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
705
-				$qb->expr()->isNull('uid_initiator')
706
-			);
707
-
708
-			$qb->andWhere(
709
-				$qb->expr()->orX(
710
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
711
-					$or1
712
-				)
713
-			);
714
-		} else {
715
-			$qb->andWhere(
716
-				$qb->expr()->orX(
717
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
718
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
719
-				)
720
-			);
721
-		}
722
-
723
-		if ($node !== null) {
724
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
725
-		}
726
-
727
-		if ($limit !== -1) {
728
-			$qb->setMaxResults($limit);
729
-		}
730
-
731
-		$qb->setFirstResult($offset);
732
-		$qb->orderBy('id');
733
-
734
-		$cursor = $qb->execute();
735
-		$shares = [];
736
-		while($data = $cursor->fetch()) {
737
-			$shares[] = $this->createShareObject($data);
738
-		}
739
-		$cursor->closeCursor();
740
-
741
-		return $shares;
742
-	}
743
-
744
-	/**
745
-	 * @inheritdoc
746
-	 */
747
-	public function getShareById($id, $recipientId = null) {
748
-		$qb = $this->dbConnection->getQueryBuilder();
749
-
750
-		$qb->select('*')
751
-			->from('share')
752
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
753
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
754
-
755
-		$cursor = $qb->execute();
756
-		$data = $cursor->fetch();
757
-		$cursor->closeCursor();
758
-
759
-		if ($data === false) {
760
-			throw new ShareNotFound();
761
-		}
762
-
763
-		try {
764
-			$share = $this->createShareObject($data);
765
-		} catch (InvalidShare $e) {
766
-			throw new ShareNotFound();
767
-		}
768
-
769
-		return $share;
770
-	}
771
-
772
-	/**
773
-	 * Get shares for a given path
774
-	 *
775
-	 * @param \OCP\Files\Node $path
776
-	 * @return IShare[]
777
-	 */
778
-	public function getSharesByPath(Node $path) {
779
-		$qb = $this->dbConnection->getQueryBuilder();
780
-
781
-		$cursor = $qb->select('*')
782
-			->from('share')
783
-			->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
784
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
785
-			->execute();
786
-
787
-		$shares = [];
788
-		while($data = $cursor->fetch()) {
789
-			$shares[] = $this->createShareObject($data);
790
-		}
791
-		$cursor->closeCursor();
792
-
793
-		return $shares;
794
-	}
795
-
796
-	/**
797
-	 * @inheritdoc
798
-	 */
799
-	public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
800
-		/** @var IShare[] $shares */
801
-		$shares = [];
802
-
803
-		//Get shares directly with this user
804
-		$qb = $this->dbConnection->getQueryBuilder();
805
-		$qb->select('*')
806
-			->from('share');
807
-
808
-		// Order by id
809
-		$qb->orderBy('id');
810
-
811
-		// Set limit and offset
812
-		if ($limit !== -1) {
813
-			$qb->setMaxResults($limit);
814
-		}
815
-		$qb->setFirstResult($offset);
816
-
817
-		$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
818
-		$qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
819
-
820
-		// Filter by node if provided
821
-		if ($node !== null) {
822
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
823
-		}
824
-
825
-		$cursor = $qb->execute();
826
-
827
-		while($data = $cursor->fetch()) {
828
-			$shares[] = $this->createShareObject($data);
829
-		}
830
-		$cursor->closeCursor();
831
-
832
-
833
-		return $shares;
834
-	}
835
-
836
-	/**
837
-	 * Get a share by token
838
-	 *
839
-	 * @param string $token
840
-	 * @return IShare
841
-	 * @throws ShareNotFound
842
-	 */
843
-	public function getShareByToken($token) {
844
-		$qb = $this->dbConnection->getQueryBuilder();
845
-
846
-		$cursor = $qb->select('*')
847
-			->from('share')
848
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
849
-			->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
850
-			->execute();
851
-
852
-		$data = $cursor->fetch();
853
-
854
-		if ($data === false) {
855
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
856
-		}
857
-
858
-		try {
859
-			$share = $this->createShareObject($data);
860
-		} catch (InvalidShare $e) {
861
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
862
-		}
863
-
864
-		return $share;
865
-	}
866
-
867
-	/**
868
-	 * remove share from table
869
-	 *
870
-	 * @param string $shareId
871
-	 */
872
-	protected function removeShareFromTable($shareId) {
873
-		$qb = $this->dbConnection->getQueryBuilder();
874
-		$qb->delete('share')
875
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
876
-		$qb->execute();
877
-	}
878
-
879
-	/**
880
-	 * Create a share object from an database row
881
-	 *
882
-	 * @param array $data
883
-	 * @return IShare
884
-	 * @throws InvalidShare
885
-	 * @throws ShareNotFound
886
-	 */
887
-	protected function createShareObject($data) {
888
-
889
-		$share = new Share($this->rootFolder, $this->userManager);
890
-		$share->setId((int)$data['id'])
891
-			->setShareType((int)$data['share_type'])
892
-			->setPermissions((int)$data['permissions'])
893
-			->setTarget($data['file_target'])
894
-			->setMailSend((bool)$data['mail_send'])
895
-			->setToken($data['token']);
896
-
897
-		$shareTime = new \DateTime();
898
-		$shareTime->setTimestamp((int)$data['stime']);
899
-		$share->setShareTime($shareTime);
900
-		$share->setSharedWith($data['share_with']);
901
-		$share->setPassword($data['password']);
902
-
903
-		if ($data['uid_initiator'] !== null) {
904
-			$share->setShareOwner($data['uid_owner']);
905
-			$share->setSharedBy($data['uid_initiator']);
906
-		} else {
907
-			//OLD SHARE
908
-			$share->setSharedBy($data['uid_owner']);
909
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
910
-
911
-			$owner = $path->getOwner();
912
-			$share->setShareOwner($owner->getUID());
913
-		}
914
-
915
-		if ($data['expiration'] !== null) {
916
-			$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
917
-			if ($expiration !== false) {
918
-				$share->setExpirationDate($expiration);
919
-			}
920
-		}
921
-
922
-		$share->setNodeId((int)$data['file_source']);
923
-		$share->setNodeType($data['item_type']);
924
-
925
-		$share->setProviderId($this->identifier());
926
-
927
-		return $share;
928
-	}
929
-
930
-	/**
931
-	 * Get the node with file $id for $user
932
-	 *
933
-	 * @param string $userId
934
-	 * @param int $id
935
-	 * @return \OCP\Files\File|\OCP\Files\Folder
936
-	 * @throws InvalidShare
937
-	 */
938
-	private function getNode($userId, $id) {
939
-		try {
940
-			$userFolder = $this->rootFolder->getUserFolder($userId);
941
-		} catch (NoUserException $e) {
942
-			throw new InvalidShare();
943
-		}
944
-
945
-		$nodes = $userFolder->getById($id);
946
-
947
-		if (empty($nodes)) {
948
-			throw new InvalidShare();
949
-		}
950
-
951
-		return $nodes[0];
952
-	}
953
-
954
-	/**
955
-	 * A user is deleted from the system
956
-	 * So clean up the relevant shares.
957
-	 *
958
-	 * @param string $uid
959
-	 * @param int $shareType
960
-	 */
961
-	public function userDeleted($uid, $shareType) {
962
-		$qb = $this->dbConnection->getQueryBuilder();
963
-
964
-		$qb->delete('share')
965
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
966
-			->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
967
-			->execute();
968
-	}
969
-
970
-	/**
971
-	 * This provider does not support group shares
972
-	 *
973
-	 * @param string $gid
974
-	 */
975
-	public function groupDeleted($gid) {
976
-		return;
977
-	}
978
-
979
-	/**
980
-	 * This provider does not support group shares
981
-	 *
982
-	 * @param string $uid
983
-	 * @param string $gid
984
-	 */
985
-	public function userDeletedFromGroup($uid, $gid) {
986
-		return;
987
-	}
988
-
989
-	/**
990
-	 * get database row of a give share
991
-	 *
992
-	 * @param $id
993
-	 * @return array
994
-	 * @throws ShareNotFound
995
-	 */
996
-	protected function getRawShare($id) {
997
-
998
-		// Now fetch the inserted share and create a complete share object
999
-		$qb = $this->dbConnection->getQueryBuilder();
1000
-		$qb->select('*')
1001
-			->from('share')
1002
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
1003
-
1004
-		$cursor = $qb->execute();
1005
-		$data = $cursor->fetch();
1006
-		$cursor->closeCursor();
1007
-
1008
-		if ($data === false) {
1009
-			throw new ShareNotFound;
1010
-		}
1011
-
1012
-		return $data;
1013
-	}
1014
-
1015
-	public function getSharesInFolder($userId, Folder $node, $reshares) {
1016
-		$qb = $this->dbConnection->getQueryBuilder();
1017
-		$qb->select('*')
1018
-			->from('share', 's')
1019
-			->andWhere($qb->expr()->orX(
1020
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1021
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1022
-			))
1023
-			->andWhere(
1024
-				$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
1025
-			);
1026
-
1027
-		/**
1028
-		 * Reshares for this user are shares where they are the owner.
1029
-		 */
1030
-		if ($reshares === false) {
1031
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
1032
-		} else {
1033
-			$qb->andWhere(
1034
-				$qb->expr()->orX(
1035
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
1036
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
1037
-				)
1038
-			);
1039
-		}
1040
-
1041
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1042
-		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1043
-
1044
-		$qb->orderBy('id');
1045
-
1046
-		$cursor = $qb->execute();
1047
-		$shares = [];
1048
-		while ($data = $cursor->fetch()) {
1049
-			$shares[$data['fileid']][] = $this->createShareObject($data);
1050
-		}
1051
-		$cursor->closeCursor();
1052
-
1053
-		return $shares;
1054
-	}
1055
-
1056
-	/**
1057
-	 * @inheritdoc
1058
-	 */
1059
-	public function getAccessList($nodes, $currentAccess) {
1060
-		$ids = [];
1061
-		foreach ($nodes as $node) {
1062
-			$ids[] = $node->getId();
1063
-		}
1064
-
1065
-		$qb = $this->dbConnection->getQueryBuilder();
1066
-		$qb->select('share_with')
1067
-			->from('share')
1068
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
1069
-			->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1070
-			->andWhere($qb->expr()->orX(
1071
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1072
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1073
-			))
1074
-			->setMaxResults(1);
1075
-		$cursor = $qb->execute();
1076
-
1077
-		$mail = $cursor->fetch() !== false;
1078
-		$cursor->closeCursor();
1079
-
1080
-		return ['public' => $mail];
1081
-	}
648
+        $qb = $this->dbConnection->getQueryBuilder();
649
+        $qb->update('share')
650
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
651
+            ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
652
+            ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
653
+            ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
654
+            ->set('password', $qb->createNamedParameter($share->getPassword()))
655
+            ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
656
+            ->execute();
657
+
658
+        return $share;
659
+    }
660
+
661
+    /**
662
+     * @inheritdoc
663
+     */
664
+    public function move(IShare $share, $recipient) {
665
+        /**
666
+         * nothing to do here, mail shares are only outgoing shares
667
+         */
668
+        return $share;
669
+    }
670
+
671
+    /**
672
+     * Delete a share (owner unShares the file)
673
+     *
674
+     * @param IShare $share
675
+     */
676
+    public function delete(IShare $share) {
677
+        $this->removeShareFromTable($share->getId());
678
+    }
679
+
680
+    /**
681
+     * @inheritdoc
682
+     */
683
+    public function deleteFromSelf(IShare $share, $recipient) {
684
+        // nothing to do here, mail shares are only outgoing shares
685
+        return;
686
+    }
687
+
688
+    /**
689
+     * @inheritdoc
690
+     */
691
+    public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
692
+        $qb = $this->dbConnection->getQueryBuilder();
693
+        $qb->select('*')
694
+            ->from('share');
695
+
696
+        $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
697
+
698
+        /**
699
+         * Reshares for this user are shares where they are the owner.
700
+         */
701
+        if ($reshares === false) {
702
+            //Special case for old shares created via the web UI
703
+            $or1 = $qb->expr()->andX(
704
+                $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
705
+                $qb->expr()->isNull('uid_initiator')
706
+            );
707
+
708
+            $qb->andWhere(
709
+                $qb->expr()->orX(
710
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
711
+                    $or1
712
+                )
713
+            );
714
+        } else {
715
+            $qb->andWhere(
716
+                $qb->expr()->orX(
717
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
718
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
719
+                )
720
+            );
721
+        }
722
+
723
+        if ($node !== null) {
724
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
725
+        }
726
+
727
+        if ($limit !== -1) {
728
+            $qb->setMaxResults($limit);
729
+        }
730
+
731
+        $qb->setFirstResult($offset);
732
+        $qb->orderBy('id');
733
+
734
+        $cursor = $qb->execute();
735
+        $shares = [];
736
+        while($data = $cursor->fetch()) {
737
+            $shares[] = $this->createShareObject($data);
738
+        }
739
+        $cursor->closeCursor();
740
+
741
+        return $shares;
742
+    }
743
+
744
+    /**
745
+     * @inheritdoc
746
+     */
747
+    public function getShareById($id, $recipientId = null) {
748
+        $qb = $this->dbConnection->getQueryBuilder();
749
+
750
+        $qb->select('*')
751
+            ->from('share')
752
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
753
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
754
+
755
+        $cursor = $qb->execute();
756
+        $data = $cursor->fetch();
757
+        $cursor->closeCursor();
758
+
759
+        if ($data === false) {
760
+            throw new ShareNotFound();
761
+        }
762
+
763
+        try {
764
+            $share = $this->createShareObject($data);
765
+        } catch (InvalidShare $e) {
766
+            throw new ShareNotFound();
767
+        }
768
+
769
+        return $share;
770
+    }
771
+
772
+    /**
773
+     * Get shares for a given path
774
+     *
775
+     * @param \OCP\Files\Node $path
776
+     * @return IShare[]
777
+     */
778
+    public function getSharesByPath(Node $path) {
779
+        $qb = $this->dbConnection->getQueryBuilder();
780
+
781
+        $cursor = $qb->select('*')
782
+            ->from('share')
783
+            ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
784
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
785
+            ->execute();
786
+
787
+        $shares = [];
788
+        while($data = $cursor->fetch()) {
789
+            $shares[] = $this->createShareObject($data);
790
+        }
791
+        $cursor->closeCursor();
792
+
793
+        return $shares;
794
+    }
795
+
796
+    /**
797
+     * @inheritdoc
798
+     */
799
+    public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
800
+        /** @var IShare[] $shares */
801
+        $shares = [];
802
+
803
+        //Get shares directly with this user
804
+        $qb = $this->dbConnection->getQueryBuilder();
805
+        $qb->select('*')
806
+            ->from('share');
807
+
808
+        // Order by id
809
+        $qb->orderBy('id');
810
+
811
+        // Set limit and offset
812
+        if ($limit !== -1) {
813
+            $qb->setMaxResults($limit);
814
+        }
815
+        $qb->setFirstResult($offset);
816
+
817
+        $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
818
+        $qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
819
+
820
+        // Filter by node if provided
821
+        if ($node !== null) {
822
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
823
+        }
824
+
825
+        $cursor = $qb->execute();
826
+
827
+        while($data = $cursor->fetch()) {
828
+            $shares[] = $this->createShareObject($data);
829
+        }
830
+        $cursor->closeCursor();
831
+
832
+
833
+        return $shares;
834
+    }
835
+
836
+    /**
837
+     * Get a share by token
838
+     *
839
+     * @param string $token
840
+     * @return IShare
841
+     * @throws ShareNotFound
842
+     */
843
+    public function getShareByToken($token) {
844
+        $qb = $this->dbConnection->getQueryBuilder();
845
+
846
+        $cursor = $qb->select('*')
847
+            ->from('share')
848
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
849
+            ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
850
+            ->execute();
851
+
852
+        $data = $cursor->fetch();
853
+
854
+        if ($data === false) {
855
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
856
+        }
857
+
858
+        try {
859
+            $share = $this->createShareObject($data);
860
+        } catch (InvalidShare $e) {
861
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
862
+        }
863
+
864
+        return $share;
865
+    }
866
+
867
+    /**
868
+     * remove share from table
869
+     *
870
+     * @param string $shareId
871
+     */
872
+    protected function removeShareFromTable($shareId) {
873
+        $qb = $this->dbConnection->getQueryBuilder();
874
+        $qb->delete('share')
875
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
876
+        $qb->execute();
877
+    }
878
+
879
+    /**
880
+     * Create a share object from an database row
881
+     *
882
+     * @param array $data
883
+     * @return IShare
884
+     * @throws InvalidShare
885
+     * @throws ShareNotFound
886
+     */
887
+    protected function createShareObject($data) {
888
+
889
+        $share = new Share($this->rootFolder, $this->userManager);
890
+        $share->setId((int)$data['id'])
891
+            ->setShareType((int)$data['share_type'])
892
+            ->setPermissions((int)$data['permissions'])
893
+            ->setTarget($data['file_target'])
894
+            ->setMailSend((bool)$data['mail_send'])
895
+            ->setToken($data['token']);
896
+
897
+        $shareTime = new \DateTime();
898
+        $shareTime->setTimestamp((int)$data['stime']);
899
+        $share->setShareTime($shareTime);
900
+        $share->setSharedWith($data['share_with']);
901
+        $share->setPassword($data['password']);
902
+
903
+        if ($data['uid_initiator'] !== null) {
904
+            $share->setShareOwner($data['uid_owner']);
905
+            $share->setSharedBy($data['uid_initiator']);
906
+        } else {
907
+            //OLD SHARE
908
+            $share->setSharedBy($data['uid_owner']);
909
+            $path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
910
+
911
+            $owner = $path->getOwner();
912
+            $share->setShareOwner($owner->getUID());
913
+        }
914
+
915
+        if ($data['expiration'] !== null) {
916
+            $expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
917
+            if ($expiration !== false) {
918
+                $share->setExpirationDate($expiration);
919
+            }
920
+        }
921
+
922
+        $share->setNodeId((int)$data['file_source']);
923
+        $share->setNodeType($data['item_type']);
924
+
925
+        $share->setProviderId($this->identifier());
926
+
927
+        return $share;
928
+    }
929
+
930
+    /**
931
+     * Get the node with file $id for $user
932
+     *
933
+     * @param string $userId
934
+     * @param int $id
935
+     * @return \OCP\Files\File|\OCP\Files\Folder
936
+     * @throws InvalidShare
937
+     */
938
+    private function getNode($userId, $id) {
939
+        try {
940
+            $userFolder = $this->rootFolder->getUserFolder($userId);
941
+        } catch (NoUserException $e) {
942
+            throw new InvalidShare();
943
+        }
944
+
945
+        $nodes = $userFolder->getById($id);
946
+
947
+        if (empty($nodes)) {
948
+            throw new InvalidShare();
949
+        }
950
+
951
+        return $nodes[0];
952
+    }
953
+
954
+    /**
955
+     * A user is deleted from the system
956
+     * So clean up the relevant shares.
957
+     *
958
+     * @param string $uid
959
+     * @param int $shareType
960
+     */
961
+    public function userDeleted($uid, $shareType) {
962
+        $qb = $this->dbConnection->getQueryBuilder();
963
+
964
+        $qb->delete('share')
965
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
966
+            ->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
967
+            ->execute();
968
+    }
969
+
970
+    /**
971
+     * This provider does not support group shares
972
+     *
973
+     * @param string $gid
974
+     */
975
+    public function groupDeleted($gid) {
976
+        return;
977
+    }
978
+
979
+    /**
980
+     * This provider does not support group shares
981
+     *
982
+     * @param string $uid
983
+     * @param string $gid
984
+     */
985
+    public function userDeletedFromGroup($uid, $gid) {
986
+        return;
987
+    }
988
+
989
+    /**
990
+     * get database row of a give share
991
+     *
992
+     * @param $id
993
+     * @return array
994
+     * @throws ShareNotFound
995
+     */
996
+    protected function getRawShare($id) {
997
+
998
+        // Now fetch the inserted share and create a complete share object
999
+        $qb = $this->dbConnection->getQueryBuilder();
1000
+        $qb->select('*')
1001
+            ->from('share')
1002
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
1003
+
1004
+        $cursor = $qb->execute();
1005
+        $data = $cursor->fetch();
1006
+        $cursor->closeCursor();
1007
+
1008
+        if ($data === false) {
1009
+            throw new ShareNotFound;
1010
+        }
1011
+
1012
+        return $data;
1013
+    }
1014
+
1015
+    public function getSharesInFolder($userId, Folder $node, $reshares) {
1016
+        $qb = $this->dbConnection->getQueryBuilder();
1017
+        $qb->select('*')
1018
+            ->from('share', 's')
1019
+            ->andWhere($qb->expr()->orX(
1020
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1021
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1022
+            ))
1023
+            ->andWhere(
1024
+                $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
1025
+            );
1026
+
1027
+        /**
1028
+         * Reshares for this user are shares where they are the owner.
1029
+         */
1030
+        if ($reshares === false) {
1031
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
1032
+        } else {
1033
+            $qb->andWhere(
1034
+                $qb->expr()->orX(
1035
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
1036
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
1037
+                )
1038
+            );
1039
+        }
1040
+
1041
+        $qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1042
+        $qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1043
+
1044
+        $qb->orderBy('id');
1045
+
1046
+        $cursor = $qb->execute();
1047
+        $shares = [];
1048
+        while ($data = $cursor->fetch()) {
1049
+            $shares[$data['fileid']][] = $this->createShareObject($data);
1050
+        }
1051
+        $cursor->closeCursor();
1052
+
1053
+        return $shares;
1054
+    }
1055
+
1056
+    /**
1057
+     * @inheritdoc
1058
+     */
1059
+    public function getAccessList($nodes, $currentAccess) {
1060
+        $ids = [];
1061
+        foreach ($nodes as $node) {
1062
+            $ids[] = $node->getId();
1063
+        }
1064
+
1065
+        $qb = $this->dbConnection->getQueryBuilder();
1066
+        $qb->select('share_with')
1067
+            ->from('share')
1068
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
1069
+            ->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1070
+            ->andWhere($qb->expr()->orX(
1071
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1072
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1073
+            ))
1074
+            ->setMaxResults(1);
1075
+        $cursor = $qb->execute();
1076
+
1077
+        $mail = $cursor->fetch() !== false;
1078
+        $cursor->closeCursor();
1079
+
1080
+        return ['public' => $mail];
1081
+    }
1082 1082
 
1083 1083
 }
Please login to merge, or discard this patch.
Spacing   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -210,10 +210,10 @@  discard block
 block discarded – undo
210 210
 		}
211 211
 
212 212
 		$passwordPolicy = $this->getPasswordPolicy();
213
-		$passwordCharset = ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS;
213
+		$passwordCharset = ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_DIGITS;
214 214
 		$passwordLength = 8;
215 215
 		if (!empty($passwordPolicy)) {
216
-			$passwordLength = (int)$passwordPolicy['minLength'] > 0 ? (int)$passwordPolicy['minLength'] : $passwordLength;
216
+			$passwordLength = (int) $passwordPolicy['minLength'] > 0 ? (int) $passwordPolicy['minLength'] : $passwordLength;
217 217
 			$passwordCharset .= $passwordPolicy['enforceSpecialCharacters'] ? ISecureRandom::CHAR_SYMBOLS : '';
218 218
 		}
219 219
 
@@ -351,11 +351,11 @@  discard block
 block discarded – undo
351 351
 				$share->getExpirationDate()
352 352
 			);
353 353
 		} catch (HintException $hintException) {
354
-			$this->logger->error('Failed to send share by mail: ' . $hintException->getMessage());
354
+			$this->logger->error('Failed to send share by mail: '.$hintException->getMessage());
355 355
 			$this->removeShareFromTable($shareId);
356 356
 			throw $hintException;
357 357
 		} catch (\Exception $e) {
358
-			$this->logger->error('Failed to send share by email: ' . $e->getMessage());
358
+			$this->logger->error('Failed to send share by email: '.$e->getMessage());
359 359
 			$this->removeShareFromTable($shareId);
360 360
 			throw new HintException('Failed to send share by mail',
361 361
 				$this->l->t('Failed to send share by email'));
@@ -396,7 +396,7 @@  discard block
 block discarded – undo
396 396
 		$text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
397 397
 
398 398
 		$emailTemplate->addBodyText(
399
-			$text . ' ' . $this->l->t('Click the button below to open it.'),
399
+			$text.' '.$this->l->t('Click the button below to open it.'),
400 400
 			$text
401 401
 		);
402 402
 		$emailTemplate->addBodyButton(
@@ -420,9 +420,9 @@  discard block
 block discarded – undo
420 420
 		// The "Reply-To" is set to the sharer if an mail address is configured
421 421
 		// also the default footer contains a "Do not reply" which needs to be adjusted.
422 422
 		$initiatorEmail = $initiatorUser->getEMailAddress();
423
-		if($initiatorEmail !== null) {
423
+		if ($initiatorEmail !== null) {
424 424
 			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
425
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
425
+			$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
426 426
 		} else {
427 427
 			$emailTemplate->addFooter();
428 428
 		}
@@ -483,7 +483,7 @@  discard block
 block discarded – undo
483 483
 		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
484 484
 		if ($initiatorEmailAddress !== null) {
485 485
 			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
486
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
486
+			$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
487 487
 		} else {
488 488
 			$emailTemplate->addFooter();
489 489
 		}
@@ -578,7 +578,7 @@  discard block
 block discarded – undo
578 578
 			->orderBy('id');
579 579
 
580 580
 		$cursor = $qb->execute();
581
-		while($data = $cursor->fetch()) {
581
+		while ($data = $cursor->fetch()) {
582 582
 			$children[] = $this->createShareObject($data);
583 583
 		}
584 584
 		$cursor->closeCursor();
@@ -622,7 +622,7 @@  discard block
 block discarded – undo
622 622
 		$qb->execute();
623 623
 		$id = $qb->getLastInsertId();
624 624
 
625
-		return (int)$id;
625
+		return (int) $id;
626 626
 	}
627 627
 
628 628
 	/**
@@ -639,7 +639,7 @@  discard block
 block discarded – undo
639 639
 		// a real password was given
640 640
 		$validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
641 641
 
642
-		if($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
642
+		if ($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
643 643
 			$this->sendPassword($share, $plainTextPassword);
644 644
 		}
645 645
 		/*
@@ -733,7 +733,7 @@  discard block
 block discarded – undo
733 733
 
734 734
 		$cursor = $qb->execute();
735 735
 		$shares = [];
736
-		while($data = $cursor->fetch()) {
736
+		while ($data = $cursor->fetch()) {
737 737
 			$shares[] = $this->createShareObject($data);
738 738
 		}
739 739
 		$cursor->closeCursor();
@@ -785,7 +785,7 @@  discard block
 block discarded – undo
785 785
 			->execute();
786 786
 
787 787
 		$shares = [];
788
-		while($data = $cursor->fetch()) {
788
+		while ($data = $cursor->fetch()) {
789 789
 			$shares[] = $this->createShareObject($data);
790 790
 		}
791 791
 		$cursor->closeCursor();
@@ -824,7 +824,7 @@  discard block
 block discarded – undo
824 824
 
825 825
 		$cursor = $qb->execute();
826 826
 
827
-		while($data = $cursor->fetch()) {
827
+		while ($data = $cursor->fetch()) {
828 828
 			$shares[] = $this->createShareObject($data);
829 829
 		}
830 830
 		$cursor->closeCursor();
@@ -887,15 +887,15 @@  discard block
 block discarded – undo
887 887
 	protected function createShareObject($data) {
888 888
 
889 889
 		$share = new Share($this->rootFolder, $this->userManager);
890
-		$share->setId((int)$data['id'])
891
-			->setShareType((int)$data['share_type'])
892
-			->setPermissions((int)$data['permissions'])
890
+		$share->setId((int) $data['id'])
891
+			->setShareType((int) $data['share_type'])
892
+			->setPermissions((int) $data['permissions'])
893 893
 			->setTarget($data['file_target'])
894
-			->setMailSend((bool)$data['mail_send'])
894
+			->setMailSend((bool) $data['mail_send'])
895 895
 			->setToken($data['token']);
896 896
 
897 897
 		$shareTime = new \DateTime();
898
-		$shareTime->setTimestamp((int)$data['stime']);
898
+		$shareTime->setTimestamp((int) $data['stime']);
899 899
 		$share->setShareTime($shareTime);
900 900
 		$share->setSharedWith($data['share_with']);
901 901
 		$share->setPassword($data['password']);
@@ -906,7 +906,7 @@  discard block
 block discarded – undo
906 906
 		} else {
907 907
 			//OLD SHARE
908 908
 			$share->setSharedBy($data['uid_owner']);
909
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
909
+			$path = $this->getNode($share->getSharedBy(), (int) $data['file_source']);
910 910
 
911 911
 			$owner = $path->getOwner();
912 912
 			$share->setShareOwner($owner->getUID());
@@ -919,7 +919,7 @@  discard block
 block discarded – undo
919 919
 			}
920 920
 		}
921 921
 
922
-		$share->setNodeId((int)$data['file_source']);
922
+		$share->setNodeId((int) $data['file_source']);
923 923
 		$share->setNodeType($data['item_type']);
924 924
 
925 925
 		$share->setProviderId($this->identifier());
@@ -1038,7 +1038,7 @@  discard block
 block discarded – undo
1038 1038
 			);
1039 1039
 		}
1040 1040
 
1041
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1041
+		$qb->innerJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1042 1042
 		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1043 1043
 
1044 1044
 		$qb->orderBy('id');
Please login to merge, or discard this patch.
settings/Controller/MailSettingsController.php 1 patch
Indentation   +133 added lines, -133 removed lines patch added patch discarded remove patch
@@ -39,138 +39,138 @@
 block discarded – undo
39 39
  */
40 40
 class MailSettingsController extends Controller {
41 41
 
42
-	/** @var IL10N */
43
-	private $l10n;
44
-	/** @var IConfig */
45
-	private $config;
46
-	/** @var IUserSession */
47
-	private $userSession;
48
-	/** @var IMailer */
49
-	private $mailer;
50
-	/** @var string */
51
-	private $defaultMailAddress;
52
-
53
-	/**
54
-	 * @param string $appName
55
-	 * @param IRequest $request
56
-	 * @param IL10N $l10n
57
-	 * @param IConfig $config
58
-	 * @param IUserSession $userSession
59
-	 * @param IMailer $mailer
60
-	 * @param string $fromMailAddress
61
-	 */
62
-	public function __construct($appName,
63
-								IRequest $request,
64
-								IL10N $l10n,
65
-								IConfig $config,
66
-								IUserSession $userSession,
67
-								IMailer $mailer,
68
-								$fromMailAddress) {
69
-		parent::__construct($appName, $request);
70
-		$this->l10n = $l10n;
71
-		$this->config = $config;
72
-		$this->userSession = $userSession;
73
-		$this->mailer = $mailer;
74
-		$this->defaultMailAddress = $fromMailAddress;
75
-	}
76
-
77
-	/**
78
-	 * Sets the email settings
79
-	 *
80
-	 * @PasswordConfirmationRequired
81
-	 *
82
-	 * @param string $mail_domain
83
-	 * @param string $mail_from_address
84
-	 * @param string $mail_smtpmode
85
-	 * @param string $mail_smtpsecure
86
-	 * @param string $mail_smtphost
87
-	 * @param string $mail_smtpauthtype
88
-	 * @param int $mail_smtpauth
89
-	 * @param string $mail_smtpport
90
-	 * @return DataResponse
91
-	 */
92
-	public function setMailSettings($mail_domain,
93
-									$mail_from_address,
94
-									$mail_smtpmode,
95
-									$mail_smtpsecure,
96
-									$mail_smtphost,
97
-									$mail_smtpauthtype,
98
-									$mail_smtpauth,
99
-									$mail_smtpport) {
100
-
101
-		$params = get_defined_vars();
102
-		$configs = [];
103
-		foreach($params as $key => $value) {
104
-			$configs[$key] = (empty($value)) ? null : $value;
105
-		}
106
-
107
-		// Delete passwords from config in case no auth is specified
108
-		if ($params['mail_smtpauth'] !== 1) {
109
-			$configs['mail_smtpname'] = null;
110
-			$configs['mail_smtppassword'] = null;
111
-		}
112
-
113
-		$this->config->setSystemValues($configs);
114
-
115
-		return new DataResponse();
116
-	}
117
-
118
-	/**
119
-	 * Store the credentials used for SMTP in the config
120
-	 *
121
-	 * @PasswordConfirmationRequired
122
-	 *
123
-	 * @param string $mail_smtpname
124
-	 * @param string $mail_smtppassword
125
-	 * @return DataResponse
126
-	 */
127
-	public function storeCredentials($mail_smtpname, $mail_smtppassword) {
128
-		if ($mail_smtppassword === '********') {
129
-			return new DataResponse($this->l10n->t('Invalid SMTP password.'), Http::STATUS_BAD_REQUEST);
130
-		}
131
-
132
-		$this->config->setSystemValues([
133
-			'mail_smtpname'		=> $mail_smtpname,
134
-			'mail_smtppassword'	=> $mail_smtppassword,
135
-		]);
136
-
137
-		return new DataResponse();
138
-	}
139
-
140
-	/**
141
-	 * Send a mail to test the settings
142
-	 * @return DataResponse
143
-	 */
144
-	public function sendTestMail() {
145
-		$email = $this->config->getUserValue($this->userSession->getUser()->getUID(), $this->appName, 'email', '');
146
-		if (!empty($email)) {
147
-			try {
148
-				$displayName = $this->userSession->getUser()->getDisplayName();
149
-
150
-				$template = $this->mailer->createEMailTemplate('settings.TestEmail', [
151
-					'displayname' => $displayName,
152
-				]);
153
-
154
-				$template->setSubject($this->l10n->t('Email setting test'));
155
-				$template->addHeader();
156
-				$template->addHeading($this->l10n->t('Well done, %s!', [$displayName]));
157
-				$template->addBodyText($this->l10n->t('If you received this email, the email configuration seems to be correct.'));
158
-				$template->addFooter();
159
-
160
-				$message = $this->mailer->createMessage();
161
-				$message->setTo([$email => $displayName]);
162
-				$message->setTemplate($template);
163
-				$errors = $this->mailer->send($message);
164
-				if (!empty($errors)) {
165
-					throw new \RuntimeException($this->l10n->t('Email could not be sent. Check your mail server log'));
166
-				}
167
-				return new DataResponse();
168
-			} catch (\Exception $e) {
169
-				return new DataResponse($this->l10n->t('A problem occurred while sending the email. Please revise your settings. (Error: %s)', [$e->getMessage()]), Http::STATUS_BAD_REQUEST);
170
-			}
171
-		}
172
-
173
-		return new DataResponse($this->l10n->t('You need to set your user email before being able to send test emails.'), Http::STATUS_BAD_REQUEST);
174
-	}
42
+    /** @var IL10N */
43
+    private $l10n;
44
+    /** @var IConfig */
45
+    private $config;
46
+    /** @var IUserSession */
47
+    private $userSession;
48
+    /** @var IMailer */
49
+    private $mailer;
50
+    /** @var string */
51
+    private $defaultMailAddress;
52
+
53
+    /**
54
+     * @param string $appName
55
+     * @param IRequest $request
56
+     * @param IL10N $l10n
57
+     * @param IConfig $config
58
+     * @param IUserSession $userSession
59
+     * @param IMailer $mailer
60
+     * @param string $fromMailAddress
61
+     */
62
+    public function __construct($appName,
63
+                                IRequest $request,
64
+                                IL10N $l10n,
65
+                                IConfig $config,
66
+                                IUserSession $userSession,
67
+                                IMailer $mailer,
68
+                                $fromMailAddress) {
69
+        parent::__construct($appName, $request);
70
+        $this->l10n = $l10n;
71
+        $this->config = $config;
72
+        $this->userSession = $userSession;
73
+        $this->mailer = $mailer;
74
+        $this->defaultMailAddress = $fromMailAddress;
75
+    }
76
+
77
+    /**
78
+     * Sets the email settings
79
+     *
80
+     * @PasswordConfirmationRequired
81
+     *
82
+     * @param string $mail_domain
83
+     * @param string $mail_from_address
84
+     * @param string $mail_smtpmode
85
+     * @param string $mail_smtpsecure
86
+     * @param string $mail_smtphost
87
+     * @param string $mail_smtpauthtype
88
+     * @param int $mail_smtpauth
89
+     * @param string $mail_smtpport
90
+     * @return DataResponse
91
+     */
92
+    public function setMailSettings($mail_domain,
93
+                                    $mail_from_address,
94
+                                    $mail_smtpmode,
95
+                                    $mail_smtpsecure,
96
+                                    $mail_smtphost,
97
+                                    $mail_smtpauthtype,
98
+                                    $mail_smtpauth,
99
+                                    $mail_smtpport) {
100
+
101
+        $params = get_defined_vars();
102
+        $configs = [];
103
+        foreach($params as $key => $value) {
104
+            $configs[$key] = (empty($value)) ? null : $value;
105
+        }
106
+
107
+        // Delete passwords from config in case no auth is specified
108
+        if ($params['mail_smtpauth'] !== 1) {
109
+            $configs['mail_smtpname'] = null;
110
+            $configs['mail_smtppassword'] = null;
111
+        }
112
+
113
+        $this->config->setSystemValues($configs);
114
+
115
+        return new DataResponse();
116
+    }
117
+
118
+    /**
119
+     * Store the credentials used for SMTP in the config
120
+     *
121
+     * @PasswordConfirmationRequired
122
+     *
123
+     * @param string $mail_smtpname
124
+     * @param string $mail_smtppassword
125
+     * @return DataResponse
126
+     */
127
+    public function storeCredentials($mail_smtpname, $mail_smtppassword) {
128
+        if ($mail_smtppassword === '********') {
129
+            return new DataResponse($this->l10n->t('Invalid SMTP password.'), Http::STATUS_BAD_REQUEST);
130
+        }
131
+
132
+        $this->config->setSystemValues([
133
+            'mail_smtpname'		=> $mail_smtpname,
134
+            'mail_smtppassword'	=> $mail_smtppassword,
135
+        ]);
136
+
137
+        return new DataResponse();
138
+    }
139
+
140
+    /**
141
+     * Send a mail to test the settings
142
+     * @return DataResponse
143
+     */
144
+    public function sendTestMail() {
145
+        $email = $this->config->getUserValue($this->userSession->getUser()->getUID(), $this->appName, 'email', '');
146
+        if (!empty($email)) {
147
+            try {
148
+                $displayName = $this->userSession->getUser()->getDisplayName();
149
+
150
+                $template = $this->mailer->createEMailTemplate('settings.TestEmail', [
151
+                    'displayname' => $displayName,
152
+                ]);
153
+
154
+                $template->setSubject($this->l10n->t('Email setting test'));
155
+                $template->addHeader();
156
+                $template->addHeading($this->l10n->t('Well done, %s!', [$displayName]));
157
+                $template->addBodyText($this->l10n->t('If you received this email, the email configuration seems to be correct.'));
158
+                $template->addFooter();
159
+
160
+                $message = $this->mailer->createMessage();
161
+                $message->setTo([$email => $displayName]);
162
+                $message->setTemplate($template);
163
+                $errors = $this->mailer->send($message);
164
+                if (!empty($errors)) {
165
+                    throw new \RuntimeException($this->l10n->t('Email could not be sent. Check your mail server log'));
166
+                }
167
+                return new DataResponse();
168
+            } catch (\Exception $e) {
169
+                return new DataResponse($this->l10n->t('A problem occurred while sending the email. Please revise your settings. (Error: %s)', [$e->getMessage()]), Http::STATUS_BAD_REQUEST);
170
+            }
171
+        }
172
+
173
+        return new DataResponse($this->l10n->t('You need to set your user email before being able to send test emails.'), Http::STATUS_BAD_REQUEST);
174
+    }
175 175
 
176 176
 }
Please login to merge, or discard this patch.
settings/Mailer/NewUserMailHelper.php 1 patch
Indentation   +124 added lines, -124 removed lines patch added patch discarded remove patch
@@ -33,135 +33,135 @@
 block discarded – undo
33 33
 use OCP\Security\ISecureRandom;
34 34
 
35 35
 class NewUserMailHelper {
36
-	/** @var Defaults */
37
-	private $themingDefaults;
38
-	/** @var IURLGenerator */
39
-	private $urlGenerator;
40
-	/** @var IL10N */
41
-	private $l10n;
42
-	/** @var IMailer */
43
-	private $mailer;
44
-	/** @var ISecureRandom */
45
-	private $secureRandom;
46
-	/** @var ITimeFactory */
47
-	private $timeFactory;
48
-	/** @var IConfig */
49
-	private $config;
50
-	/** @var ICrypto */
51
-	private $crypto;
52
-	/** @var string */
53
-	private $fromAddress;
36
+    /** @var Defaults */
37
+    private $themingDefaults;
38
+    /** @var IURLGenerator */
39
+    private $urlGenerator;
40
+    /** @var IL10N */
41
+    private $l10n;
42
+    /** @var IMailer */
43
+    private $mailer;
44
+    /** @var ISecureRandom */
45
+    private $secureRandom;
46
+    /** @var ITimeFactory */
47
+    private $timeFactory;
48
+    /** @var IConfig */
49
+    private $config;
50
+    /** @var ICrypto */
51
+    private $crypto;
52
+    /** @var string */
53
+    private $fromAddress;
54 54
 
55
-	/**
56
-	 * @param Defaults $themingDefaults
57
-	 * @param IURLGenerator $urlGenerator
58
-	 * @param IL10N $l10n
59
-	 * @param IMailer $mailer
60
-	 * @param ISecureRandom $secureRandom
61
-	 * @param ITimeFactory $timeFactory
62
-	 * @param IConfig $config
63
-	 * @param ICrypto $crypto
64
-	 * @param string $fromAddress
65
-	 */
66
-	public function __construct(Defaults $themingDefaults,
67
-								IURLGenerator $urlGenerator,
68
-								IL10N $l10n,
69
-								IMailer $mailer,
70
-								ISecureRandom $secureRandom,
71
-								ITimeFactory $timeFactory,
72
-								IConfig $config,
73
-								ICrypto $crypto,
74
-								$fromAddress) {
75
-		$this->themingDefaults = $themingDefaults;
76
-		$this->urlGenerator = $urlGenerator;
77
-		$this->l10n = $l10n;
78
-		$this->mailer = $mailer;
79
-		$this->secureRandom = $secureRandom;
80
-		$this->timeFactory = $timeFactory;
81
-		$this->config = $config;
82
-		$this->crypto = $crypto;
83
-		$this->fromAddress = $fromAddress;
84
-	}
55
+    /**
56
+     * @param Defaults $themingDefaults
57
+     * @param IURLGenerator $urlGenerator
58
+     * @param IL10N $l10n
59
+     * @param IMailer $mailer
60
+     * @param ISecureRandom $secureRandom
61
+     * @param ITimeFactory $timeFactory
62
+     * @param IConfig $config
63
+     * @param ICrypto $crypto
64
+     * @param string $fromAddress
65
+     */
66
+    public function __construct(Defaults $themingDefaults,
67
+                                IURLGenerator $urlGenerator,
68
+                                IL10N $l10n,
69
+                                IMailer $mailer,
70
+                                ISecureRandom $secureRandom,
71
+                                ITimeFactory $timeFactory,
72
+                                IConfig $config,
73
+                                ICrypto $crypto,
74
+                                $fromAddress) {
75
+        $this->themingDefaults = $themingDefaults;
76
+        $this->urlGenerator = $urlGenerator;
77
+        $this->l10n = $l10n;
78
+        $this->mailer = $mailer;
79
+        $this->secureRandom = $secureRandom;
80
+        $this->timeFactory = $timeFactory;
81
+        $this->config = $config;
82
+        $this->crypto = $crypto;
83
+        $this->fromAddress = $fromAddress;
84
+    }
85 85
 
86
-	/**
87
-	 * Set the IL10N object
88
-	 *
89
-	 * @param IL10N $l10n
90
-	 */
91
-	public function setL10N(IL10N $l10n) {
92
-		$this->l10n = $l10n;
93
-	}
86
+    /**
87
+     * Set the IL10N object
88
+     *
89
+     * @param IL10N $l10n
90
+     */
91
+    public function setL10N(IL10N $l10n) {
92
+        $this->l10n = $l10n;
93
+    }
94 94
 
95
-	/**
96
-	 * @param IUser $user
97
-	 * @param bool $generatePasswordResetToken
98
-	 * @return IEMailTemplate
99
-	 */
100
-	public function generateTemplate(IUser $user, $generatePasswordResetToken = false) {
101
-		if ($generatePasswordResetToken) {
102
-			$token = $this->secureRandom->generate(
103
-				21,
104
-				ISecureRandom::CHAR_DIGITS .
105
-				ISecureRandom::CHAR_LOWER .
106
-				ISecureRandom::CHAR_UPPER
107
-			);
108
-			$tokenValue = $this->timeFactory->getTime() . ':' . $token;
109
-			$mailAddress = (null !== $user->getEMailAddress()) ? $user->getEMailAddress() : '';
110
-			$encryptedValue = $this->crypto->encrypt($tokenValue, $mailAddress . $this->config->getSystemValue('secret'));
111
-			$this->config->setUserValue($user->getUID(), 'core', 'lostpassword', $encryptedValue);
112
-			$link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', ['userId' => $user->getUID(), 'token' => $token]);
113
-		} else {
114
-			$link = $this->urlGenerator->getAbsoluteURL('/');
115
-		}
116
-		$displayName = $user->getDisplayName();
117
-		$userId = $user->getUID();
95
+    /**
96
+     * @param IUser $user
97
+     * @param bool $generatePasswordResetToken
98
+     * @return IEMailTemplate
99
+     */
100
+    public function generateTemplate(IUser $user, $generatePasswordResetToken = false) {
101
+        if ($generatePasswordResetToken) {
102
+            $token = $this->secureRandom->generate(
103
+                21,
104
+                ISecureRandom::CHAR_DIGITS .
105
+                ISecureRandom::CHAR_LOWER .
106
+                ISecureRandom::CHAR_UPPER
107
+            );
108
+            $tokenValue = $this->timeFactory->getTime() . ':' . $token;
109
+            $mailAddress = (null !== $user->getEMailAddress()) ? $user->getEMailAddress() : '';
110
+            $encryptedValue = $this->crypto->encrypt($tokenValue, $mailAddress . $this->config->getSystemValue('secret'));
111
+            $this->config->setUserValue($user->getUID(), 'core', 'lostpassword', $encryptedValue);
112
+            $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', ['userId' => $user->getUID(), 'token' => $token]);
113
+        } else {
114
+            $link = $this->urlGenerator->getAbsoluteURL('/');
115
+        }
116
+        $displayName = $user->getDisplayName();
117
+        $userId = $user->getUID();
118 118
 
119
-		$emailTemplate = $this->mailer->createEMailTemplate('settings.Welcome', [
120
-			'link' => $link,
121
-			'displayname' => $displayName,
122
-			'userid' => $userId,
123
-			'instancename' => $this->themingDefaults->getName(),
124
-			'resetTokenGenerated' => $generatePasswordResetToken,
125
-		]);
119
+        $emailTemplate = $this->mailer->createEMailTemplate('settings.Welcome', [
120
+            'link' => $link,
121
+            'displayname' => $displayName,
122
+            'userid' => $userId,
123
+            'instancename' => $this->themingDefaults->getName(),
124
+            'resetTokenGenerated' => $generatePasswordResetToken,
125
+        ]);
126 126
 
127
-		$emailTemplate->setSubject($this->l10n->t('Your %s account was created', [$this->themingDefaults->getName()]));
128
-		$emailTemplate->addHeader();
129
-		if ($displayName === $userId) {
130
-			$emailTemplate->addHeading($this->l10n->t('Welcome aboard'));
131
-		} else {
132
-			$emailTemplate->addHeading($this->l10n->t('Welcome aboard %s', [$displayName]));
133
-		}
134
-		$emailTemplate->addBodyText($this->l10n->t('You now have an %s account, you can add, protect, and share your data.', [$this->themingDefaults->getName()]));
135
-		$emailTemplate->addBodyText($this->l10n->t('Your username is: %s', [$userId]));
136
-		if ($generatePasswordResetToken) {
137
-			$leftButtonText = $this->l10n->t('Set your password');
138
-		} else {
139
-			$leftButtonText = $this->l10n->t('Go to %s', [$this->themingDefaults->getName()]);
140
-		}
141
-		$emailTemplate->addBodyButtonGroup(
142
-			$leftButtonText,
143
-			$link,
144
-			$this->l10n->t('Install Client'),
145
-			'https://nextcloud.com/install/#install-clients'
146
-		);
147
-		$emailTemplate->addFooter();
127
+        $emailTemplate->setSubject($this->l10n->t('Your %s account was created', [$this->themingDefaults->getName()]));
128
+        $emailTemplate->addHeader();
129
+        if ($displayName === $userId) {
130
+            $emailTemplate->addHeading($this->l10n->t('Welcome aboard'));
131
+        } else {
132
+            $emailTemplate->addHeading($this->l10n->t('Welcome aboard %s', [$displayName]));
133
+        }
134
+        $emailTemplate->addBodyText($this->l10n->t('You now have an %s account, you can add, protect, and share your data.', [$this->themingDefaults->getName()]));
135
+        $emailTemplate->addBodyText($this->l10n->t('Your username is: %s', [$userId]));
136
+        if ($generatePasswordResetToken) {
137
+            $leftButtonText = $this->l10n->t('Set your password');
138
+        } else {
139
+            $leftButtonText = $this->l10n->t('Go to %s', [$this->themingDefaults->getName()]);
140
+        }
141
+        $emailTemplate->addBodyButtonGroup(
142
+            $leftButtonText,
143
+            $link,
144
+            $this->l10n->t('Install Client'),
145
+            'https://nextcloud.com/install/#install-clients'
146
+        );
147
+        $emailTemplate->addFooter();
148 148
 
149
-		return $emailTemplate;
150
-	}
149
+        return $emailTemplate;
150
+    }
151 151
 
152
-	/**
153
-	 * Sends a welcome mail to $user
154
-	 *
155
-	 * @param IUser $user
156
-	 * @param IEmailTemplate $emailTemplate
157
-	 * @throws \Exception If mail could not be sent
158
-	 */
159
-	public function sendMail(IUser $user,
160
-							 IEMailTemplate $emailTemplate) {
161
-		$message = $this->mailer->createMessage();
162
-		$message->setTo([$user->getEMailAddress() => $user->getDisplayName()]);
163
-		$message->setFrom([$this->fromAddress => $this->themingDefaults->getName()]);
164
-		$message->setTemplate($emailTemplate);
165
-		$this->mailer->send($message);
166
-	}
152
+    /**
153
+     * Sends a welcome mail to $user
154
+     *
155
+     * @param IUser $user
156
+     * @param IEmailTemplate $emailTemplate
157
+     * @throws \Exception If mail could not be sent
158
+     */
159
+    public function sendMail(IUser $user,
160
+                                IEMailTemplate $emailTemplate) {
161
+        $message = $this->mailer->createMessage();
162
+        $message->setTo([$user->getEMailAddress() => $user->getDisplayName()]);
163
+        $message->setFrom([$this->fromAddress => $this->themingDefaults->getName()]);
164
+        $message->setTemplate($emailTemplate);
165
+        $this->mailer->send($message);
166
+    }
167 167
 }
Please login to merge, or discard this patch.
settings/Hooks.php 2 patches
Indentation   +175 added lines, -175 removed lines patch added patch discarded remove patch
@@ -34,179 +34,179 @@
 block discarded – undo
34 34
 
35 35
 class Hooks {
36 36
 
37
-	/** @var IActivityManager */
38
-	protected $activityManager;
39
-	/** @var IUserManager */
40
-	protected $userManager;
41
-	/** @var IUserSession */
42
-	protected $userSession;
43
-	/** @var IURLGenerator */
44
-	protected $urlGenerator;
45
-	/** @var IMailer */
46
-	protected $mailer;
47
-	/** @var IConfig */
48
-	protected $config;
49
-	/** @var IFactory */
50
-	protected $languageFactory;
51
-	/** @var IL10N */
52
-	protected $l;
53
-
54
-	public function __construct(IActivityManager $activityManager,
55
-								IUserManager $userManager,
56
-								IUserSession $userSession,
57
-								IURLGenerator $urlGenerator,
58
-								IMailer $mailer,
59
-								IConfig $config,
60
-								IFactory $languageFactory,
61
-								IL10N $l) {
62
-		$this->activityManager = $activityManager;
63
-		$this->userManager = $userManager;
64
-		$this->userSession = $userSession;
65
-		$this->urlGenerator = $urlGenerator;
66
-		$this->mailer = $mailer;
67
-		$this->config = $config;
68
-		$this->languageFactory = $languageFactory;
69
-		$this->l = $l;
70
-	}
71
-
72
-	/**
73
-	 * @param string $uid
74
-	 * @throws \InvalidArgumentException
75
-	 * @throws \BadMethodCallException
76
-	 * @throws \Exception
77
-	 */
78
-	public function onChangePassword($uid) {
79
-		$user = $this->userManager->get($uid);
80
-
81
-		if (!$user instanceof IUser || $user->getLastLogin() === 0) {
82
-			// User didn't login, so don't create activities and emails.
83
-			return;
84
-		}
85
-
86
-		$event = $this->activityManager->generateEvent();
87
-		$event->setApp('settings')
88
-			->setType('personal_settings')
89
-			->setAffectedUser($user->getUID());
90
-
91
-		$instanceUrl = $this->urlGenerator->getAbsoluteURL('/');
92
-
93
-		$actor = $this->userSession->getUser();
94
-		if ($actor instanceof IUser) {
95
-			if ($actor->getUID() !== $user->getUID()) {
96
-				$this->l = $this->languageFactory->get(
97
-					'settings',
98
-					$this->config->getUserValue(
99
-						$user->getUID(), 'core', 'lang',
100
-						$this->config->getSystemValue('default_language', 'en')
101
-					)
102
-				);
103
-
104
-				$text = $this->l->t('%1$s changed your password on %2$s.', [$actor->getDisplayName(), $instanceUrl]);
105
-				$event->setAuthor($actor->getUID())
106
-					->setSubject(Provider::PASSWORD_CHANGED_BY, [$actor->getUID()]);
107
-			} else {
108
-				$text = $this->l->t('Your password on %s was changed.', [$instanceUrl]);
109
-				$event->setAuthor($actor->getUID())
110
-					->setSubject(Provider::PASSWORD_CHANGED_SELF);
111
-			}
112
-		} else {
113
-			$text = $this->l->t('Your password on %s was reset by an administrator.', [$instanceUrl]);
114
-			$event->setSubject(Provider::PASSWORD_RESET);
115
-		}
116
-
117
-		$this->activityManager->publish($event);
118
-
119
-		if ($user->getEMailAddress() !== null) {
120
-			$template = $this->mailer->createEMailTemplate('settings.PasswordChanged', [
121
-				'displayname' => $user->getDisplayName(),
122
-				'emailAddress' => $user->getEMailAddress(),
123
-				'instanceUrl' => $instanceUrl,
124
-			]);
125
-
126
-			$template->setSubject($this->l->t('Password for %1$s changed on %2$s', [$user->getDisplayName(), $instanceUrl]));
127
-			$template->addHeader();
128
-			$template->addHeading($this->l->t('Password changed for %s', [$user->getDisplayName()]), false);
129
-			$template->addBodyText($text . ' ' . $this->l->t('If you did not request this, please contact an administrator.'));
130
-			$template->addFooter();
131
-
132
-
133
-			$message = $this->mailer->createMessage();
134
-			$message->setTo([$user->getEMailAddress() => $user->getDisplayName()]);
135
-			$message->setTemplate($template);
136
-			$this->mailer->send($message);
137
-		}
138
-	}
139
-
140
-	/**
141
-	 * @param IUser $user
142
-	 * @param string|null $oldMailAddress
143
-	 * @throws \InvalidArgumentException
144
-	 * @throws \BadMethodCallException
145
-	 */
146
-	public function onChangeEmail(IUser $user, $oldMailAddress) {
147
-
148
-		if ($oldMailAddress === $user->getEMailAddress() ||
149
-			$user->getLastLogin() === 0) {
150
-			// Email didn't really change or user didn't login,
151
-			// so don't create activities and emails.
152
-			return;
153
-		}
154
-
155
-		$event = $this->activityManager->generateEvent();
156
-		$event->setApp('settings')
157
-			->setType('personal_settings')
158
-			->setAffectedUser($user->getUID());
159
-
160
-		$instanceUrl = $this->urlGenerator->getAbsoluteURL('/');
161
-
162
-		$actor = $this->userSession->getUser();
163
-		if ($actor instanceof IUser) {
164
-			if ($actor->getUID() !== $user->getUID()) {
165
-				$this->l = $this->languageFactory->get(
166
-					'settings',
167
-					$this->config->getUserValue(
168
-						$user->getUID(), 'core', 'lang',
169
-						$this->config->getSystemValue('default_language', 'en')
170
-					)
171
-				);
172
-
173
-				$text = $this->l->t('%1$s changed your email address on %2$s.', [$actor->getDisplayName(), $instanceUrl]);
174
-				$event->setAuthor($actor->getUID())
175
-					->setSubject(Provider::EMAIL_CHANGED_BY, [$actor->getUID()]);
176
-			} else {
177
-				$text = $this->l->t('Your email address on %s was changed.', [$instanceUrl]);
178
-				$event->setAuthor($actor->getUID())
179
-					->setSubject(Provider::EMAIL_CHANGED_SELF);
180
-			}
181
-		} else {
182
-			$text = $this->l->t('Your email address on %s was changed by an administrator.', [$instanceUrl]);
183
-			$event->setSubject(Provider::EMAIL_CHANGED);
184
-		}
185
-		$this->activityManager->publish($event);
186
-
187
-
188
-		if ($oldMailAddress !== null) {
189
-			$template = $this->mailer->createEMailTemplate('settings.EmailChanged', [
190
-				'displayname' => $user->getDisplayName(),
191
-				'newEMailAddress' => $user->getEMailAddress(),
192
-				'oldEMailAddress' => $oldMailAddress,
193
-				'instanceUrl' => $instanceUrl,
194
-			]);
195
-
196
-			$template->setSubject($this->l->t('Email address for %1$s changed on %2$s', [$user->getDisplayName(), $instanceUrl]));
197
-			$template->addHeader();
198
-			$template->addHeading($this->l->t('Email address changed for %s', [$user->getDisplayName()]), false);
199
-			$template->addBodyText($text . ' ' . $this->l->t('If you did not request this, please contact an administrator.'));
200
-			if ($user->getEMailAddress()) {
201
-				$template->addBodyText($this->l->t('The new email address is %s', [$user->getEMailAddress()]));
202
-			}
203
-			$template->addFooter();
204
-
205
-
206
-			$message = $this->mailer->createMessage();
207
-			$message->setTo([$oldMailAddress => $user->getDisplayName()]);
208
-			$message->setTemplate($template);
209
-			$this->mailer->send($message);
210
-		}
211
-	}
37
+    /** @var IActivityManager */
38
+    protected $activityManager;
39
+    /** @var IUserManager */
40
+    protected $userManager;
41
+    /** @var IUserSession */
42
+    protected $userSession;
43
+    /** @var IURLGenerator */
44
+    protected $urlGenerator;
45
+    /** @var IMailer */
46
+    protected $mailer;
47
+    /** @var IConfig */
48
+    protected $config;
49
+    /** @var IFactory */
50
+    protected $languageFactory;
51
+    /** @var IL10N */
52
+    protected $l;
53
+
54
+    public function __construct(IActivityManager $activityManager,
55
+                                IUserManager $userManager,
56
+                                IUserSession $userSession,
57
+                                IURLGenerator $urlGenerator,
58
+                                IMailer $mailer,
59
+                                IConfig $config,
60
+                                IFactory $languageFactory,
61
+                                IL10N $l) {
62
+        $this->activityManager = $activityManager;
63
+        $this->userManager = $userManager;
64
+        $this->userSession = $userSession;
65
+        $this->urlGenerator = $urlGenerator;
66
+        $this->mailer = $mailer;
67
+        $this->config = $config;
68
+        $this->languageFactory = $languageFactory;
69
+        $this->l = $l;
70
+    }
71
+
72
+    /**
73
+     * @param string $uid
74
+     * @throws \InvalidArgumentException
75
+     * @throws \BadMethodCallException
76
+     * @throws \Exception
77
+     */
78
+    public function onChangePassword($uid) {
79
+        $user = $this->userManager->get($uid);
80
+
81
+        if (!$user instanceof IUser || $user->getLastLogin() === 0) {
82
+            // User didn't login, so don't create activities and emails.
83
+            return;
84
+        }
85
+
86
+        $event = $this->activityManager->generateEvent();
87
+        $event->setApp('settings')
88
+            ->setType('personal_settings')
89
+            ->setAffectedUser($user->getUID());
90
+
91
+        $instanceUrl = $this->urlGenerator->getAbsoluteURL('/');
92
+
93
+        $actor = $this->userSession->getUser();
94
+        if ($actor instanceof IUser) {
95
+            if ($actor->getUID() !== $user->getUID()) {
96
+                $this->l = $this->languageFactory->get(
97
+                    'settings',
98
+                    $this->config->getUserValue(
99
+                        $user->getUID(), 'core', 'lang',
100
+                        $this->config->getSystemValue('default_language', 'en')
101
+                    )
102
+                );
103
+
104
+                $text = $this->l->t('%1$s changed your password on %2$s.', [$actor->getDisplayName(), $instanceUrl]);
105
+                $event->setAuthor($actor->getUID())
106
+                    ->setSubject(Provider::PASSWORD_CHANGED_BY, [$actor->getUID()]);
107
+            } else {
108
+                $text = $this->l->t('Your password on %s was changed.', [$instanceUrl]);
109
+                $event->setAuthor($actor->getUID())
110
+                    ->setSubject(Provider::PASSWORD_CHANGED_SELF);
111
+            }
112
+        } else {
113
+            $text = $this->l->t('Your password on %s was reset by an administrator.', [$instanceUrl]);
114
+            $event->setSubject(Provider::PASSWORD_RESET);
115
+        }
116
+
117
+        $this->activityManager->publish($event);
118
+
119
+        if ($user->getEMailAddress() !== null) {
120
+            $template = $this->mailer->createEMailTemplate('settings.PasswordChanged', [
121
+                'displayname' => $user->getDisplayName(),
122
+                'emailAddress' => $user->getEMailAddress(),
123
+                'instanceUrl' => $instanceUrl,
124
+            ]);
125
+
126
+            $template->setSubject($this->l->t('Password for %1$s changed on %2$s', [$user->getDisplayName(), $instanceUrl]));
127
+            $template->addHeader();
128
+            $template->addHeading($this->l->t('Password changed for %s', [$user->getDisplayName()]), false);
129
+            $template->addBodyText($text . ' ' . $this->l->t('If you did not request this, please contact an administrator.'));
130
+            $template->addFooter();
131
+
132
+
133
+            $message = $this->mailer->createMessage();
134
+            $message->setTo([$user->getEMailAddress() => $user->getDisplayName()]);
135
+            $message->setTemplate($template);
136
+            $this->mailer->send($message);
137
+        }
138
+    }
139
+
140
+    /**
141
+     * @param IUser $user
142
+     * @param string|null $oldMailAddress
143
+     * @throws \InvalidArgumentException
144
+     * @throws \BadMethodCallException
145
+     */
146
+    public function onChangeEmail(IUser $user, $oldMailAddress) {
147
+
148
+        if ($oldMailAddress === $user->getEMailAddress() ||
149
+            $user->getLastLogin() === 0) {
150
+            // Email didn't really change or user didn't login,
151
+            // so don't create activities and emails.
152
+            return;
153
+        }
154
+
155
+        $event = $this->activityManager->generateEvent();
156
+        $event->setApp('settings')
157
+            ->setType('personal_settings')
158
+            ->setAffectedUser($user->getUID());
159
+
160
+        $instanceUrl = $this->urlGenerator->getAbsoluteURL('/');
161
+
162
+        $actor = $this->userSession->getUser();
163
+        if ($actor instanceof IUser) {
164
+            if ($actor->getUID() !== $user->getUID()) {
165
+                $this->l = $this->languageFactory->get(
166
+                    'settings',
167
+                    $this->config->getUserValue(
168
+                        $user->getUID(), 'core', 'lang',
169
+                        $this->config->getSystemValue('default_language', 'en')
170
+                    )
171
+                );
172
+
173
+                $text = $this->l->t('%1$s changed your email address on %2$s.', [$actor->getDisplayName(), $instanceUrl]);
174
+                $event->setAuthor($actor->getUID())
175
+                    ->setSubject(Provider::EMAIL_CHANGED_BY, [$actor->getUID()]);
176
+            } else {
177
+                $text = $this->l->t('Your email address on %s was changed.', [$instanceUrl]);
178
+                $event->setAuthor($actor->getUID())
179
+                    ->setSubject(Provider::EMAIL_CHANGED_SELF);
180
+            }
181
+        } else {
182
+            $text = $this->l->t('Your email address on %s was changed by an administrator.', [$instanceUrl]);
183
+            $event->setSubject(Provider::EMAIL_CHANGED);
184
+        }
185
+        $this->activityManager->publish($event);
186
+
187
+
188
+        if ($oldMailAddress !== null) {
189
+            $template = $this->mailer->createEMailTemplate('settings.EmailChanged', [
190
+                'displayname' => $user->getDisplayName(),
191
+                'newEMailAddress' => $user->getEMailAddress(),
192
+                'oldEMailAddress' => $oldMailAddress,
193
+                'instanceUrl' => $instanceUrl,
194
+            ]);
195
+
196
+            $template->setSubject($this->l->t('Email address for %1$s changed on %2$s', [$user->getDisplayName(), $instanceUrl]));
197
+            $template->addHeader();
198
+            $template->addHeading($this->l->t('Email address changed for %s', [$user->getDisplayName()]), false);
199
+            $template->addBodyText($text . ' ' . $this->l->t('If you did not request this, please contact an administrator.'));
200
+            if ($user->getEMailAddress()) {
201
+                $template->addBodyText($this->l->t('The new email address is %s', [$user->getEMailAddress()]));
202
+            }
203
+            $template->addFooter();
204
+
205
+
206
+            $message = $this->mailer->createMessage();
207
+            $message->setTo([$oldMailAddress => $user->getDisplayName()]);
208
+            $message->setTemplate($template);
209
+            $this->mailer->send($message);
210
+        }
211
+    }
212 212
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -126,7 +126,7 @@  discard block
 block discarded – undo
126 126
 			$template->setSubject($this->l->t('Password for %1$s changed on %2$s', [$user->getDisplayName(), $instanceUrl]));
127 127
 			$template->addHeader();
128 128
 			$template->addHeading($this->l->t('Password changed for %s', [$user->getDisplayName()]), false);
129
-			$template->addBodyText($text . ' ' . $this->l->t('If you did not request this, please contact an administrator.'));
129
+			$template->addBodyText($text.' '.$this->l->t('If you did not request this, please contact an administrator.'));
130 130
 			$template->addFooter();
131 131
 
132 132
 
@@ -196,7 +196,7 @@  discard block
 block discarded – undo
196 196
 			$template->setSubject($this->l->t('Email address for %1$s changed on %2$s', [$user->getDisplayName(), $instanceUrl]));
197 197
 			$template->addHeader();
198 198
 			$template->addHeading($this->l->t('Email address changed for %s', [$user->getDisplayName()]), false);
199
-			$template->addBodyText($text . ' ' . $this->l->t('If you did not request this, please contact an administrator.'));
199
+			$template->addBodyText($text.' '.$this->l->t('If you did not request this, please contact an administrator.'));
200 200
 			if ($user->getEMailAddress()) {
201 201
 				$template->addBodyText($this->l->t('The new email address is %s', [$user->getEMailAddress()]));
202 202
 			}
Please login to merge, or discard this patch.
lib/private/Share20/Manager.php 1 patch
Indentation   +1454 added lines, -1454 removed lines patch added patch discarded remove patch
@@ -60,1482 +60,1482 @@
 block discarded – undo
60 60
  */
61 61
 class Manager implements IManager {
62 62
 
63
-	/** @var IProviderFactory */
64
-	private $factory;
65
-	/** @var ILogger */
66
-	private $logger;
67
-	/** @var IConfig */
68
-	private $config;
69
-	/** @var ISecureRandom */
70
-	private $secureRandom;
71
-	/** @var IHasher */
72
-	private $hasher;
73
-	/** @var IMountManager */
74
-	private $mountManager;
75
-	/** @var IGroupManager */
76
-	private $groupManager;
77
-	/** @var IL10N */
78
-	private $l;
79
-	/** @var IFactory */
80
-	private $l10nFactory;
81
-	/** @var IUserManager */
82
-	private $userManager;
83
-	/** @var IRootFolder */
84
-	private $rootFolder;
85
-	/** @var CappedMemoryCache */
86
-	private $sharingDisabledForUsersCache;
87
-	/** @var EventDispatcher */
88
-	private $eventDispatcher;
89
-	/** @var LegacyHooks */
90
-	private $legacyHooks;
91
-	/** @var IMailer */
92
-	private $mailer;
93
-	/** @var IURLGenerator */
94
-	private $urlGenerator;
95
-	/** @var \OC_Defaults */
96
-	private $defaults;
97
-
98
-
99
-	/**
100
-	 * Manager constructor.
101
-	 *
102
-	 * @param ILogger $logger
103
-	 * @param IConfig $config
104
-	 * @param ISecureRandom $secureRandom
105
-	 * @param IHasher $hasher
106
-	 * @param IMountManager $mountManager
107
-	 * @param IGroupManager $groupManager
108
-	 * @param IL10N $l
109
-	 * @param IFactory $l10nFactory
110
-	 * @param IProviderFactory $factory
111
-	 * @param IUserManager $userManager
112
-	 * @param IRootFolder $rootFolder
113
-	 * @param EventDispatcher $eventDispatcher
114
-	 * @param IMailer $mailer
115
-	 * @param IURLGenerator $urlGenerator
116
-	 * @param \OC_Defaults $defaults
117
-	 */
118
-	public function __construct(
119
-			ILogger $logger,
120
-			IConfig $config,
121
-			ISecureRandom $secureRandom,
122
-			IHasher $hasher,
123
-			IMountManager $mountManager,
124
-			IGroupManager $groupManager,
125
-			IL10N $l,
126
-			IFactory $l10nFactory,
127
-			IProviderFactory $factory,
128
-			IUserManager $userManager,
129
-			IRootFolder $rootFolder,
130
-			EventDispatcher $eventDispatcher,
131
-			IMailer $mailer,
132
-			IURLGenerator $urlGenerator,
133
-			\OC_Defaults $defaults
134
-	) {
135
-		$this->logger = $logger;
136
-		$this->config = $config;
137
-		$this->secureRandom = $secureRandom;
138
-		$this->hasher = $hasher;
139
-		$this->mountManager = $mountManager;
140
-		$this->groupManager = $groupManager;
141
-		$this->l = $l;
142
-		$this->l10nFactory = $l10nFactory;
143
-		$this->factory = $factory;
144
-		$this->userManager = $userManager;
145
-		$this->rootFolder = $rootFolder;
146
-		$this->eventDispatcher = $eventDispatcher;
147
-		$this->sharingDisabledForUsersCache = new CappedMemoryCache();
148
-		$this->legacyHooks = new LegacyHooks($this->eventDispatcher);
149
-		$this->mailer = $mailer;
150
-		$this->urlGenerator = $urlGenerator;
151
-		$this->defaults = $defaults;
152
-	}
153
-
154
-	/**
155
-	 * Convert from a full share id to a tuple (providerId, shareId)
156
-	 *
157
-	 * @param string $id
158
-	 * @return string[]
159
-	 */
160
-	private function splitFullId($id) {
161
-		return explode(':', $id, 2);
162
-	}
163
-
164
-	/**
165
-	 * Verify if a password meets all requirements
166
-	 *
167
-	 * @param string $password
168
-	 * @throws \Exception
169
-	 */
170
-	protected function verifyPassword($password) {
171
-		if ($password === null) {
172
-			// No password is set, check if this is allowed.
173
-			if ($this->shareApiLinkEnforcePassword()) {
174
-				throw new \InvalidArgumentException('Passwords are enforced for link shares');
175
-			}
176
-
177
-			return;
178
-		}
179
-
180
-		// Let others verify the password
181
-		try {
182
-			$event = new GenericEvent($password);
183
-			$this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
184
-		} catch (HintException $e) {
185
-			throw new \Exception($e->getHint());
186
-		}
187
-	}
188
-
189
-	/**
190
-	 * Check for generic requirements before creating a share
191
-	 *
192
-	 * @param \OCP\Share\IShare $share
193
-	 * @throws \InvalidArgumentException
194
-	 * @throws GenericShareException
195
-	 *
196
-	 * @suppress PhanUndeclaredClassMethod
197
-	 */
198
-	protected function generalCreateChecks(\OCP\Share\IShare $share) {
199
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
200
-			// We expect a valid user as sharedWith for user shares
201
-			if (!$this->userManager->userExists($share->getSharedWith())) {
202
-				throw new \InvalidArgumentException('SharedWith is not a valid user');
203
-			}
204
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
205
-			// We expect a valid group as sharedWith for group shares
206
-			if (!$this->groupManager->groupExists($share->getSharedWith())) {
207
-				throw new \InvalidArgumentException('SharedWith is not a valid group');
208
-			}
209
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
210
-			if ($share->getSharedWith() !== null) {
211
-				throw new \InvalidArgumentException('SharedWith should be empty');
212
-			}
213
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
214
-			if ($share->getSharedWith() === null) {
215
-				throw new \InvalidArgumentException('SharedWith should not be empty');
216
-			}
217
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
218
-			if ($share->getSharedWith() === null) {
219
-				throw new \InvalidArgumentException('SharedWith should not be empty');
220
-			}
221
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
222
-			$circle = \OCA\Circles\Api\v1\Circles::detailsCircle($share->getSharedWith());
223
-			if ($circle === null) {
224
-				throw new \InvalidArgumentException('SharedWith is not a valid circle');
225
-			}
226
-		} else {
227
-			// We can't handle other types yet
228
-			throw new \InvalidArgumentException('unknown share type');
229
-		}
230
-
231
-		// Verify the initiator of the share is set
232
-		if ($share->getSharedBy() === null) {
233
-			throw new \InvalidArgumentException('SharedBy should be set');
234
-		}
235
-
236
-		// Cannot share with yourself
237
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
238
-			$share->getSharedWith() === $share->getSharedBy()) {
239
-			throw new \InvalidArgumentException('Can’t share with yourself');
240
-		}
241
-
242
-		// The path should be set
243
-		if ($share->getNode() === null) {
244
-			throw new \InvalidArgumentException('Path should be set');
245
-		}
246
-
247
-		// And it should be a file or a folder
248
-		if (!($share->getNode() instanceof \OCP\Files\File) &&
249
-				!($share->getNode() instanceof \OCP\Files\Folder)) {
250
-			throw new \InvalidArgumentException('Path should be either a file or a folder');
251
-		}
252
-
253
-		// And you can't share your rootfolder
254
-		if ($this->userManager->userExists($share->getSharedBy())) {
255
-			$sharedPath = $this->rootFolder->getUserFolder($share->getSharedBy())->getPath();
256
-		} else {
257
-			$sharedPath = $this->rootFolder->getUserFolder($share->getShareOwner())->getPath();
258
-		}
259
-		if ($sharedPath === $share->getNode()->getPath()) {
260
-			throw new \InvalidArgumentException('You can’t share your root folder');
261
-		}
262
-
263
-		// Check if we actually have share permissions
264
-		if (!$share->getNode()->isShareable()) {
265
-			$message_t = $this->l->t('You are not allowed to share %s', [$share->getNode()->getPath()]);
266
-			throw new GenericShareException($message_t, $message_t, 404);
267
-		}
268
-
269
-		// Permissions should be set
270
-		if ($share->getPermissions() === null) {
271
-			throw new \InvalidArgumentException('A share requires permissions');
272
-		}
273
-
274
-		/*
63
+    /** @var IProviderFactory */
64
+    private $factory;
65
+    /** @var ILogger */
66
+    private $logger;
67
+    /** @var IConfig */
68
+    private $config;
69
+    /** @var ISecureRandom */
70
+    private $secureRandom;
71
+    /** @var IHasher */
72
+    private $hasher;
73
+    /** @var IMountManager */
74
+    private $mountManager;
75
+    /** @var IGroupManager */
76
+    private $groupManager;
77
+    /** @var IL10N */
78
+    private $l;
79
+    /** @var IFactory */
80
+    private $l10nFactory;
81
+    /** @var IUserManager */
82
+    private $userManager;
83
+    /** @var IRootFolder */
84
+    private $rootFolder;
85
+    /** @var CappedMemoryCache */
86
+    private $sharingDisabledForUsersCache;
87
+    /** @var EventDispatcher */
88
+    private $eventDispatcher;
89
+    /** @var LegacyHooks */
90
+    private $legacyHooks;
91
+    /** @var IMailer */
92
+    private $mailer;
93
+    /** @var IURLGenerator */
94
+    private $urlGenerator;
95
+    /** @var \OC_Defaults */
96
+    private $defaults;
97
+
98
+
99
+    /**
100
+     * Manager constructor.
101
+     *
102
+     * @param ILogger $logger
103
+     * @param IConfig $config
104
+     * @param ISecureRandom $secureRandom
105
+     * @param IHasher $hasher
106
+     * @param IMountManager $mountManager
107
+     * @param IGroupManager $groupManager
108
+     * @param IL10N $l
109
+     * @param IFactory $l10nFactory
110
+     * @param IProviderFactory $factory
111
+     * @param IUserManager $userManager
112
+     * @param IRootFolder $rootFolder
113
+     * @param EventDispatcher $eventDispatcher
114
+     * @param IMailer $mailer
115
+     * @param IURLGenerator $urlGenerator
116
+     * @param \OC_Defaults $defaults
117
+     */
118
+    public function __construct(
119
+            ILogger $logger,
120
+            IConfig $config,
121
+            ISecureRandom $secureRandom,
122
+            IHasher $hasher,
123
+            IMountManager $mountManager,
124
+            IGroupManager $groupManager,
125
+            IL10N $l,
126
+            IFactory $l10nFactory,
127
+            IProviderFactory $factory,
128
+            IUserManager $userManager,
129
+            IRootFolder $rootFolder,
130
+            EventDispatcher $eventDispatcher,
131
+            IMailer $mailer,
132
+            IURLGenerator $urlGenerator,
133
+            \OC_Defaults $defaults
134
+    ) {
135
+        $this->logger = $logger;
136
+        $this->config = $config;
137
+        $this->secureRandom = $secureRandom;
138
+        $this->hasher = $hasher;
139
+        $this->mountManager = $mountManager;
140
+        $this->groupManager = $groupManager;
141
+        $this->l = $l;
142
+        $this->l10nFactory = $l10nFactory;
143
+        $this->factory = $factory;
144
+        $this->userManager = $userManager;
145
+        $this->rootFolder = $rootFolder;
146
+        $this->eventDispatcher = $eventDispatcher;
147
+        $this->sharingDisabledForUsersCache = new CappedMemoryCache();
148
+        $this->legacyHooks = new LegacyHooks($this->eventDispatcher);
149
+        $this->mailer = $mailer;
150
+        $this->urlGenerator = $urlGenerator;
151
+        $this->defaults = $defaults;
152
+    }
153
+
154
+    /**
155
+     * Convert from a full share id to a tuple (providerId, shareId)
156
+     *
157
+     * @param string $id
158
+     * @return string[]
159
+     */
160
+    private function splitFullId($id) {
161
+        return explode(':', $id, 2);
162
+    }
163
+
164
+    /**
165
+     * Verify if a password meets all requirements
166
+     *
167
+     * @param string $password
168
+     * @throws \Exception
169
+     */
170
+    protected function verifyPassword($password) {
171
+        if ($password === null) {
172
+            // No password is set, check if this is allowed.
173
+            if ($this->shareApiLinkEnforcePassword()) {
174
+                throw new \InvalidArgumentException('Passwords are enforced for link shares');
175
+            }
176
+
177
+            return;
178
+        }
179
+
180
+        // Let others verify the password
181
+        try {
182
+            $event = new GenericEvent($password);
183
+            $this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
184
+        } catch (HintException $e) {
185
+            throw new \Exception($e->getHint());
186
+        }
187
+    }
188
+
189
+    /**
190
+     * Check for generic requirements before creating a share
191
+     *
192
+     * @param \OCP\Share\IShare $share
193
+     * @throws \InvalidArgumentException
194
+     * @throws GenericShareException
195
+     *
196
+     * @suppress PhanUndeclaredClassMethod
197
+     */
198
+    protected function generalCreateChecks(\OCP\Share\IShare $share) {
199
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
200
+            // We expect a valid user as sharedWith for user shares
201
+            if (!$this->userManager->userExists($share->getSharedWith())) {
202
+                throw new \InvalidArgumentException('SharedWith is not a valid user');
203
+            }
204
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
205
+            // We expect a valid group as sharedWith for group shares
206
+            if (!$this->groupManager->groupExists($share->getSharedWith())) {
207
+                throw new \InvalidArgumentException('SharedWith is not a valid group');
208
+            }
209
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
210
+            if ($share->getSharedWith() !== null) {
211
+                throw new \InvalidArgumentException('SharedWith should be empty');
212
+            }
213
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
214
+            if ($share->getSharedWith() === null) {
215
+                throw new \InvalidArgumentException('SharedWith should not be empty');
216
+            }
217
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
218
+            if ($share->getSharedWith() === null) {
219
+                throw new \InvalidArgumentException('SharedWith should not be empty');
220
+            }
221
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
222
+            $circle = \OCA\Circles\Api\v1\Circles::detailsCircle($share->getSharedWith());
223
+            if ($circle === null) {
224
+                throw new \InvalidArgumentException('SharedWith is not a valid circle');
225
+            }
226
+        } else {
227
+            // We can't handle other types yet
228
+            throw new \InvalidArgumentException('unknown share type');
229
+        }
230
+
231
+        // Verify the initiator of the share is set
232
+        if ($share->getSharedBy() === null) {
233
+            throw new \InvalidArgumentException('SharedBy should be set');
234
+        }
235
+
236
+        // Cannot share with yourself
237
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
238
+            $share->getSharedWith() === $share->getSharedBy()) {
239
+            throw new \InvalidArgumentException('Can’t share with yourself');
240
+        }
241
+
242
+        // The path should be set
243
+        if ($share->getNode() === null) {
244
+            throw new \InvalidArgumentException('Path should be set');
245
+        }
246
+
247
+        // And it should be a file or a folder
248
+        if (!($share->getNode() instanceof \OCP\Files\File) &&
249
+                !($share->getNode() instanceof \OCP\Files\Folder)) {
250
+            throw new \InvalidArgumentException('Path should be either a file or a folder');
251
+        }
252
+
253
+        // And you can't share your rootfolder
254
+        if ($this->userManager->userExists($share->getSharedBy())) {
255
+            $sharedPath = $this->rootFolder->getUserFolder($share->getSharedBy())->getPath();
256
+        } else {
257
+            $sharedPath = $this->rootFolder->getUserFolder($share->getShareOwner())->getPath();
258
+        }
259
+        if ($sharedPath === $share->getNode()->getPath()) {
260
+            throw new \InvalidArgumentException('You can’t share your root folder');
261
+        }
262
+
263
+        // Check if we actually have share permissions
264
+        if (!$share->getNode()->isShareable()) {
265
+            $message_t = $this->l->t('You are not allowed to share %s', [$share->getNode()->getPath()]);
266
+            throw new GenericShareException($message_t, $message_t, 404);
267
+        }
268
+
269
+        // Permissions should be set
270
+        if ($share->getPermissions() === null) {
271
+            throw new \InvalidArgumentException('A share requires permissions');
272
+        }
273
+
274
+        /*
275 275
 		 * Quick fix for #23536
276 276
 		 * Non moveable mount points do not have update and delete permissions
277 277
 		 * while we 'most likely' do have that on the storage.
278 278
 		 */
279
-		$permissions = $share->getNode()->getPermissions();
280
-		$mount = $share->getNode()->getMountPoint();
281
-		if (!($mount instanceof MoveableMount)) {
282
-			$permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
283
-		}
284
-
285
-		// Check that we do not share with more permissions than we have
286
-		if ($share->getPermissions() & ~$permissions) {
287
-			$message_t = $this->l->t('Can’t increase permissions of %s', [$share->getNode()->getPath()]);
288
-			throw new GenericShareException($message_t, $message_t, 404);
289
-		}
290
-
291
-
292
-		// Check that read permissions are always set
293
-		// Link shares are allowed to have no read permissions to allow upload to hidden folders
294
-		$noReadPermissionRequired = $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK
295
-			|| $share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL;
296
-		if (!$noReadPermissionRequired &&
297
-			($share->getPermissions() & \OCP\Constants::PERMISSION_READ) === 0) {
298
-			throw new \InvalidArgumentException('Shares need at least read permissions');
299
-		}
300
-
301
-		if ($share->getNode() instanceof \OCP\Files\File) {
302
-			if ($share->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
303
-				$message_t = $this->l->t('Files can’t be shared with delete permissions');
304
-				throw new GenericShareException($message_t);
305
-			}
306
-			if ($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE) {
307
-				$message_t = $this->l->t('Files can’t be shared with create permissions');
308
-				throw new GenericShareException($message_t);
309
-			}
310
-		}
311
-	}
312
-
313
-	/**
314
-	 * Validate if the expiration date fits the system settings
315
-	 *
316
-	 * @param \OCP\Share\IShare $share The share to validate the expiration date of
317
-	 * @return \OCP\Share\IShare The modified share object
318
-	 * @throws GenericShareException
319
-	 * @throws \InvalidArgumentException
320
-	 * @throws \Exception
321
-	 */
322
-	protected function validateExpirationDate(\OCP\Share\IShare $share) {
323
-
324
-		$expirationDate = $share->getExpirationDate();
325
-
326
-		if ($expirationDate !== null) {
327
-			//Make sure the expiration date is a date
328
-			$expirationDate->setTime(0, 0, 0);
329
-
330
-			$date = new \DateTime();
331
-			$date->setTime(0, 0, 0);
332
-			if ($date >= $expirationDate) {
333
-				$message = $this->l->t('Expiration date is in the past');
334
-				throw new GenericShareException($message, $message, 404);
335
-			}
336
-		}
337
-
338
-		// If expiredate is empty set a default one if there is a default
339
-		$fullId = null;
340
-		try {
341
-			$fullId = $share->getFullId();
342
-		} catch (\UnexpectedValueException $e) {
343
-			// This is a new share
344
-		}
345
-
346
-		if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
347
-			$expirationDate = new \DateTime();
348
-			$expirationDate->setTime(0,0,0);
349
-			$expirationDate->add(new \DateInterval('P'.$this->shareApiLinkDefaultExpireDays().'D'));
350
-		}
351
-
352
-		// If we enforce the expiration date check that is does not exceed
353
-		if ($this->shareApiLinkDefaultExpireDateEnforced()) {
354
-			if ($expirationDate === null) {
355
-				throw new \InvalidArgumentException('Expiration date is enforced');
356
-			}
357
-
358
-			$date = new \DateTime();
359
-			$date->setTime(0, 0, 0);
360
-			$date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
361
-			if ($date < $expirationDate) {
362
-				$message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
363
-				throw new GenericShareException($message, $message, 404);
364
-			}
365
-		}
366
-
367
-		$accepted = true;
368
-		$message = '';
369
-		\OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
370
-			'expirationDate' => &$expirationDate,
371
-			'accepted' => &$accepted,
372
-			'message' => &$message,
373
-			'passwordSet' => $share->getPassword() !== null,
374
-		]);
375
-
376
-		if (!$accepted) {
377
-			throw new \Exception($message);
378
-		}
379
-
380
-		$share->setExpirationDate($expirationDate);
381
-
382
-		return $share;
383
-	}
384
-
385
-	/**
386
-	 * Check for pre share requirements for user shares
387
-	 *
388
-	 * @param \OCP\Share\IShare $share
389
-	 * @throws \Exception
390
-	 */
391
-	protected function userCreateChecks(\OCP\Share\IShare $share) {
392
-		// Check if we can share with group members only
393
-		if ($this->shareWithGroupMembersOnly()) {
394
-			$sharedBy = $this->userManager->get($share->getSharedBy());
395
-			$sharedWith = $this->userManager->get($share->getSharedWith());
396
-			// Verify we can share with this user
397
-			$groups = array_intersect(
398
-					$this->groupManager->getUserGroupIds($sharedBy),
399
-					$this->groupManager->getUserGroupIds($sharedWith)
400
-			);
401
-			if (empty($groups)) {
402
-				throw new \Exception('Sharing is only allowed with group members');
403
-			}
404
-		}
405
-
406
-		/*
279
+        $permissions = $share->getNode()->getPermissions();
280
+        $mount = $share->getNode()->getMountPoint();
281
+        if (!($mount instanceof MoveableMount)) {
282
+            $permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
283
+        }
284
+
285
+        // Check that we do not share with more permissions than we have
286
+        if ($share->getPermissions() & ~$permissions) {
287
+            $message_t = $this->l->t('Can’t increase permissions of %s', [$share->getNode()->getPath()]);
288
+            throw new GenericShareException($message_t, $message_t, 404);
289
+        }
290
+
291
+
292
+        // Check that read permissions are always set
293
+        // Link shares are allowed to have no read permissions to allow upload to hidden folders
294
+        $noReadPermissionRequired = $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK
295
+            || $share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL;
296
+        if (!$noReadPermissionRequired &&
297
+            ($share->getPermissions() & \OCP\Constants::PERMISSION_READ) === 0) {
298
+            throw new \InvalidArgumentException('Shares need at least read permissions');
299
+        }
300
+
301
+        if ($share->getNode() instanceof \OCP\Files\File) {
302
+            if ($share->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
303
+                $message_t = $this->l->t('Files can’t be shared with delete permissions');
304
+                throw new GenericShareException($message_t);
305
+            }
306
+            if ($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE) {
307
+                $message_t = $this->l->t('Files can’t be shared with create permissions');
308
+                throw new GenericShareException($message_t);
309
+            }
310
+        }
311
+    }
312
+
313
+    /**
314
+     * Validate if the expiration date fits the system settings
315
+     *
316
+     * @param \OCP\Share\IShare $share The share to validate the expiration date of
317
+     * @return \OCP\Share\IShare The modified share object
318
+     * @throws GenericShareException
319
+     * @throws \InvalidArgumentException
320
+     * @throws \Exception
321
+     */
322
+    protected function validateExpirationDate(\OCP\Share\IShare $share) {
323
+
324
+        $expirationDate = $share->getExpirationDate();
325
+
326
+        if ($expirationDate !== null) {
327
+            //Make sure the expiration date is a date
328
+            $expirationDate->setTime(0, 0, 0);
329
+
330
+            $date = new \DateTime();
331
+            $date->setTime(0, 0, 0);
332
+            if ($date >= $expirationDate) {
333
+                $message = $this->l->t('Expiration date is in the past');
334
+                throw new GenericShareException($message, $message, 404);
335
+            }
336
+        }
337
+
338
+        // If expiredate is empty set a default one if there is a default
339
+        $fullId = null;
340
+        try {
341
+            $fullId = $share->getFullId();
342
+        } catch (\UnexpectedValueException $e) {
343
+            // This is a new share
344
+        }
345
+
346
+        if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
347
+            $expirationDate = new \DateTime();
348
+            $expirationDate->setTime(0,0,0);
349
+            $expirationDate->add(new \DateInterval('P'.$this->shareApiLinkDefaultExpireDays().'D'));
350
+        }
351
+
352
+        // If we enforce the expiration date check that is does not exceed
353
+        if ($this->shareApiLinkDefaultExpireDateEnforced()) {
354
+            if ($expirationDate === null) {
355
+                throw new \InvalidArgumentException('Expiration date is enforced');
356
+            }
357
+
358
+            $date = new \DateTime();
359
+            $date->setTime(0, 0, 0);
360
+            $date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
361
+            if ($date < $expirationDate) {
362
+                $message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
363
+                throw new GenericShareException($message, $message, 404);
364
+            }
365
+        }
366
+
367
+        $accepted = true;
368
+        $message = '';
369
+        \OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
370
+            'expirationDate' => &$expirationDate,
371
+            'accepted' => &$accepted,
372
+            'message' => &$message,
373
+            'passwordSet' => $share->getPassword() !== null,
374
+        ]);
375
+
376
+        if (!$accepted) {
377
+            throw new \Exception($message);
378
+        }
379
+
380
+        $share->setExpirationDate($expirationDate);
381
+
382
+        return $share;
383
+    }
384
+
385
+    /**
386
+     * Check for pre share requirements for user shares
387
+     *
388
+     * @param \OCP\Share\IShare $share
389
+     * @throws \Exception
390
+     */
391
+    protected function userCreateChecks(\OCP\Share\IShare $share) {
392
+        // Check if we can share with group members only
393
+        if ($this->shareWithGroupMembersOnly()) {
394
+            $sharedBy = $this->userManager->get($share->getSharedBy());
395
+            $sharedWith = $this->userManager->get($share->getSharedWith());
396
+            // Verify we can share with this user
397
+            $groups = array_intersect(
398
+                    $this->groupManager->getUserGroupIds($sharedBy),
399
+                    $this->groupManager->getUserGroupIds($sharedWith)
400
+            );
401
+            if (empty($groups)) {
402
+                throw new \Exception('Sharing is only allowed with group members');
403
+            }
404
+        }
405
+
406
+        /*
407 407
 		 * TODO: Could be costly, fix
408 408
 		 *
409 409
 		 * Also this is not what we want in the future.. then we want to squash identical shares.
410 410
 		 */
411
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_USER);
412
-		$existingShares = $provider->getSharesByPath($share->getNode());
413
-		foreach($existingShares as $existingShare) {
414
-			// Ignore if it is the same share
415
-			try {
416
-				if ($existingShare->getFullId() === $share->getFullId()) {
417
-					continue;
418
-				}
419
-			} catch (\UnexpectedValueException $e) {
420
-				//Shares are not identical
421
-			}
422
-
423
-			// Identical share already existst
424
-			if ($existingShare->getSharedWith() === $share->getSharedWith()) {
425
-				throw new \Exception('Path is already shared with this user');
426
-			}
427
-
428
-			// The share is already shared with this user via a group share
429
-			if ($existingShare->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
430
-				$group = $this->groupManager->get($existingShare->getSharedWith());
431
-				if (!is_null($group)) {
432
-					$user = $this->userManager->get($share->getSharedWith());
433
-
434
-					if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
435
-						throw new \Exception('Path is already shared with this user');
436
-					}
437
-				}
438
-			}
439
-		}
440
-	}
441
-
442
-	/**
443
-	 * Check for pre share requirements for group shares
444
-	 *
445
-	 * @param \OCP\Share\IShare $share
446
-	 * @throws \Exception
447
-	 */
448
-	protected function groupCreateChecks(\OCP\Share\IShare $share) {
449
-		// Verify group shares are allowed
450
-		if (!$this->allowGroupSharing()) {
451
-			throw new \Exception('Group sharing is now allowed');
452
-		}
453
-
454
-		// Verify if the user can share with this group
455
-		if ($this->shareWithGroupMembersOnly()) {
456
-			$sharedBy = $this->userManager->get($share->getSharedBy());
457
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
458
-			if (is_null($sharedWith) || !$sharedWith->inGroup($sharedBy)) {
459
-				throw new \Exception('Sharing is only allowed within your own groups');
460
-			}
461
-		}
462
-
463
-		/*
411
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_USER);
412
+        $existingShares = $provider->getSharesByPath($share->getNode());
413
+        foreach($existingShares as $existingShare) {
414
+            // Ignore if it is the same share
415
+            try {
416
+                if ($existingShare->getFullId() === $share->getFullId()) {
417
+                    continue;
418
+                }
419
+            } catch (\UnexpectedValueException $e) {
420
+                //Shares are not identical
421
+            }
422
+
423
+            // Identical share already existst
424
+            if ($existingShare->getSharedWith() === $share->getSharedWith()) {
425
+                throw new \Exception('Path is already shared with this user');
426
+            }
427
+
428
+            // The share is already shared with this user via a group share
429
+            if ($existingShare->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
430
+                $group = $this->groupManager->get($existingShare->getSharedWith());
431
+                if (!is_null($group)) {
432
+                    $user = $this->userManager->get($share->getSharedWith());
433
+
434
+                    if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
435
+                        throw new \Exception('Path is already shared with this user');
436
+                    }
437
+                }
438
+            }
439
+        }
440
+    }
441
+
442
+    /**
443
+     * Check for pre share requirements for group shares
444
+     *
445
+     * @param \OCP\Share\IShare $share
446
+     * @throws \Exception
447
+     */
448
+    protected function groupCreateChecks(\OCP\Share\IShare $share) {
449
+        // Verify group shares are allowed
450
+        if (!$this->allowGroupSharing()) {
451
+            throw new \Exception('Group sharing is now allowed');
452
+        }
453
+
454
+        // Verify if the user can share with this group
455
+        if ($this->shareWithGroupMembersOnly()) {
456
+            $sharedBy = $this->userManager->get($share->getSharedBy());
457
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
458
+            if (is_null($sharedWith) || !$sharedWith->inGroup($sharedBy)) {
459
+                throw new \Exception('Sharing is only allowed within your own groups');
460
+            }
461
+        }
462
+
463
+        /*
464 464
 		 * TODO: Could be costly, fix
465 465
 		 *
466 466
 		 * Also this is not what we want in the future.. then we want to squash identical shares.
467 467
 		 */
468
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
469
-		$existingShares = $provider->getSharesByPath($share->getNode());
470
-		foreach($existingShares as $existingShare) {
471
-			try {
472
-				if ($existingShare->getFullId() === $share->getFullId()) {
473
-					continue;
474
-				}
475
-			} catch (\UnexpectedValueException $e) {
476
-				//It is a new share so just continue
477
-			}
478
-
479
-			if ($existingShare->getSharedWith() === $share->getSharedWith()) {
480
-				throw new \Exception('Path is already shared with this group');
481
-			}
482
-		}
483
-	}
484
-
485
-	/**
486
-	 * Check for pre share requirements for link shares
487
-	 *
488
-	 * @param \OCP\Share\IShare $share
489
-	 * @throws \Exception
490
-	 */
491
-	protected function linkCreateChecks(\OCP\Share\IShare $share) {
492
-		// Are link shares allowed?
493
-		if (!$this->shareApiAllowLinks()) {
494
-			throw new \Exception('Link sharing is not allowed');
495
-		}
496
-
497
-		// Link shares by definition can't have share permissions
498
-		if ($share->getPermissions() & \OCP\Constants::PERMISSION_SHARE) {
499
-			throw new \InvalidArgumentException('Link shares can’t have reshare permissions');
500
-		}
501
-
502
-		// Check if public upload is allowed
503
-		if (!$this->shareApiLinkAllowPublicUpload() &&
504
-			($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE))) {
505
-			throw new \InvalidArgumentException('Public upload is not allowed');
506
-		}
507
-	}
508
-
509
-	/**
510
-	 * To make sure we don't get invisible link shares we set the parent
511
-	 * of a link if it is a reshare. This is a quick word around
512
-	 * until we can properly display multiple link shares in the UI
513
-	 *
514
-	 * See: https://github.com/owncloud/core/issues/22295
515
-	 *
516
-	 * FIXME: Remove once multiple link shares can be properly displayed
517
-	 *
518
-	 * @param \OCP\Share\IShare $share
519
-	 */
520
-	protected function setLinkParent(\OCP\Share\IShare $share) {
521
-
522
-		// No sense in checking if the method is not there.
523
-		if (method_exists($share, 'setParent')) {
524
-			$storage = $share->getNode()->getStorage();
525
-			if ($storage->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
526
-				/** @var \OCA\Files_Sharing\SharedStorage $storage */
527
-				$share->setParent($storage->getShareId());
528
-			}
529
-		};
530
-	}
531
-
532
-	/**
533
-	 * @param File|Folder $path
534
-	 */
535
-	protected function pathCreateChecks($path) {
536
-		// Make sure that we do not share a path that contains a shared mountpoint
537
-		if ($path instanceof \OCP\Files\Folder) {
538
-			$mounts = $this->mountManager->findIn($path->getPath());
539
-			foreach($mounts as $mount) {
540
-				if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
541
-					throw new \InvalidArgumentException('Path contains files shared with you');
542
-				}
543
-			}
544
-		}
545
-	}
546
-
547
-	/**
548
-	 * Check if the user that is sharing can actually share
549
-	 *
550
-	 * @param \OCP\Share\IShare $share
551
-	 * @throws \Exception
552
-	 */
553
-	protected function canShare(\OCP\Share\IShare $share) {
554
-		if (!$this->shareApiEnabled()) {
555
-			throw new \Exception('Sharing is disabled');
556
-		}
557
-
558
-		if ($this->sharingDisabledForUser($share->getSharedBy())) {
559
-			throw new \Exception('Sharing is disabled for you');
560
-		}
561
-	}
562
-
563
-	/**
564
-	 * Share a path
565
-	 *
566
-	 * @param \OCP\Share\IShare $share
567
-	 * @return Share The share object
568
-	 * @throws \Exception
569
-	 *
570
-	 * TODO: handle link share permissions or check them
571
-	 */
572
-	public function createShare(\OCP\Share\IShare $share) {
573
-		$this->canShare($share);
574
-
575
-		$this->generalCreateChecks($share);
576
-
577
-		// Verify if there are any issues with the path
578
-		$this->pathCreateChecks($share->getNode());
579
-
580
-		/*
468
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
469
+        $existingShares = $provider->getSharesByPath($share->getNode());
470
+        foreach($existingShares as $existingShare) {
471
+            try {
472
+                if ($existingShare->getFullId() === $share->getFullId()) {
473
+                    continue;
474
+                }
475
+            } catch (\UnexpectedValueException $e) {
476
+                //It is a new share so just continue
477
+            }
478
+
479
+            if ($existingShare->getSharedWith() === $share->getSharedWith()) {
480
+                throw new \Exception('Path is already shared with this group');
481
+            }
482
+        }
483
+    }
484
+
485
+    /**
486
+     * Check for pre share requirements for link shares
487
+     *
488
+     * @param \OCP\Share\IShare $share
489
+     * @throws \Exception
490
+     */
491
+    protected function linkCreateChecks(\OCP\Share\IShare $share) {
492
+        // Are link shares allowed?
493
+        if (!$this->shareApiAllowLinks()) {
494
+            throw new \Exception('Link sharing is not allowed');
495
+        }
496
+
497
+        // Link shares by definition can't have share permissions
498
+        if ($share->getPermissions() & \OCP\Constants::PERMISSION_SHARE) {
499
+            throw new \InvalidArgumentException('Link shares can’t have reshare permissions');
500
+        }
501
+
502
+        // Check if public upload is allowed
503
+        if (!$this->shareApiLinkAllowPublicUpload() &&
504
+            ($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE))) {
505
+            throw new \InvalidArgumentException('Public upload is not allowed');
506
+        }
507
+    }
508
+
509
+    /**
510
+     * To make sure we don't get invisible link shares we set the parent
511
+     * of a link if it is a reshare. This is a quick word around
512
+     * until we can properly display multiple link shares in the UI
513
+     *
514
+     * See: https://github.com/owncloud/core/issues/22295
515
+     *
516
+     * FIXME: Remove once multiple link shares can be properly displayed
517
+     *
518
+     * @param \OCP\Share\IShare $share
519
+     */
520
+    protected function setLinkParent(\OCP\Share\IShare $share) {
521
+
522
+        // No sense in checking if the method is not there.
523
+        if (method_exists($share, 'setParent')) {
524
+            $storage = $share->getNode()->getStorage();
525
+            if ($storage->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
526
+                /** @var \OCA\Files_Sharing\SharedStorage $storage */
527
+                $share->setParent($storage->getShareId());
528
+            }
529
+        };
530
+    }
531
+
532
+    /**
533
+     * @param File|Folder $path
534
+     */
535
+    protected function pathCreateChecks($path) {
536
+        // Make sure that we do not share a path that contains a shared mountpoint
537
+        if ($path instanceof \OCP\Files\Folder) {
538
+            $mounts = $this->mountManager->findIn($path->getPath());
539
+            foreach($mounts as $mount) {
540
+                if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
541
+                    throw new \InvalidArgumentException('Path contains files shared with you');
542
+                }
543
+            }
544
+        }
545
+    }
546
+
547
+    /**
548
+     * Check if the user that is sharing can actually share
549
+     *
550
+     * @param \OCP\Share\IShare $share
551
+     * @throws \Exception
552
+     */
553
+    protected function canShare(\OCP\Share\IShare $share) {
554
+        if (!$this->shareApiEnabled()) {
555
+            throw new \Exception('Sharing is disabled');
556
+        }
557
+
558
+        if ($this->sharingDisabledForUser($share->getSharedBy())) {
559
+            throw new \Exception('Sharing is disabled for you');
560
+        }
561
+    }
562
+
563
+    /**
564
+     * Share a path
565
+     *
566
+     * @param \OCP\Share\IShare $share
567
+     * @return Share The share object
568
+     * @throws \Exception
569
+     *
570
+     * TODO: handle link share permissions or check them
571
+     */
572
+    public function createShare(\OCP\Share\IShare $share) {
573
+        $this->canShare($share);
574
+
575
+        $this->generalCreateChecks($share);
576
+
577
+        // Verify if there are any issues with the path
578
+        $this->pathCreateChecks($share->getNode());
579
+
580
+        /*
581 581
 		 * On creation of a share the owner is always the owner of the path
582 582
 		 * Except for mounted federated shares.
583 583
 		 */
584
-		$storage = $share->getNode()->getStorage();
585
-		if ($storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
586
-			$parent = $share->getNode()->getParent();
587
-			while($parent->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
588
-				$parent = $parent->getParent();
589
-			}
590
-			$share->setShareOwner($parent->getOwner()->getUID());
591
-		} else {
592
-			$share->setShareOwner($share->getNode()->getOwner()->getUID());
593
-		}
594
-
595
-		//Verify share type
596
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
597
-			$this->userCreateChecks($share);
598
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
599
-			$this->groupCreateChecks($share);
600
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
601
-			$this->linkCreateChecks($share);
602
-			$this->setLinkParent($share);
603
-
604
-			/*
584
+        $storage = $share->getNode()->getStorage();
585
+        if ($storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
586
+            $parent = $share->getNode()->getParent();
587
+            while($parent->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
588
+                $parent = $parent->getParent();
589
+            }
590
+            $share->setShareOwner($parent->getOwner()->getUID());
591
+        } else {
592
+            $share->setShareOwner($share->getNode()->getOwner()->getUID());
593
+        }
594
+
595
+        //Verify share type
596
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
597
+            $this->userCreateChecks($share);
598
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
599
+            $this->groupCreateChecks($share);
600
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
601
+            $this->linkCreateChecks($share);
602
+            $this->setLinkParent($share);
603
+
604
+            /*
605 605
 			 * For now ignore a set token.
606 606
 			 */
607
-			$share->setToken(
608
-				$this->secureRandom->generate(
609
-					\OC\Share\Constants::TOKEN_LENGTH,
610
-					\OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
611
-				)
612
-			);
613
-
614
-			//Verify the expiration date
615
-			$this->validateExpirationDate($share);
616
-
617
-			//Verify the password
618
-			$this->verifyPassword($share->getPassword());
619
-
620
-			// If a password is set. Hash it!
621
-			if ($share->getPassword() !== null) {
622
-				$share->setPassword($this->hasher->hash($share->getPassword()));
623
-			}
624
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
625
-			$share->setToken(
626
-				$this->secureRandom->generate(
627
-					\OC\Share\Constants::TOKEN_LENGTH,
628
-					\OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
629
-				)
630
-			);
631
-		}
632
-
633
-		// Cannot share with the owner
634
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
635
-			$share->getSharedWith() === $share->getShareOwner()) {
636
-			throw new \InvalidArgumentException('Can’t share with the share owner');
637
-		}
638
-
639
-		// Generate the target
640
-		$target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName();
641
-		$target = \OC\Files\Filesystem::normalizePath($target);
642
-		$share->setTarget($target);
643
-
644
-		// Pre share event
645
-		$event = new GenericEvent($share);
646
-		$a = $this->eventDispatcher->dispatch('OCP\Share::preShare', $event);
647
-		if ($event->isPropagationStopped() && $event->hasArgument('error')) {
648
-			throw new \Exception($event->getArgument('error'));
649
-		}
650
-
651
-		$oldShare = $share;
652
-		$provider = $this->factory->getProviderForType($share->getShareType());
653
-		$share = $provider->create($share);
654
-		//reuse the node we already have
655
-		$share->setNode($oldShare->getNode());
656
-
657
-		// Post share event
658
-		$event = new GenericEvent($share);
659
-		$this->eventDispatcher->dispatch('OCP\Share::postShare', $event);
660
-
661
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
662
-			$user = $this->userManager->get($share->getSharedWith());
663
-			if ($user !== null) {
664
-				$emailAddress = $user->getEMailAddress();
665
-				if ($emailAddress !== null && $emailAddress !== '') {
666
-					$userLang = $this->config->getUserValue($share->getSharedWith(), 'core', 'lang', null);
667
-					$l = $this->l10nFactory->get('lib', $userLang);
668
-					$this->sendMailNotification(
669
-						$l,
670
-						$share->getNode()->getName(),
671
-						$this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', [ 'fileid' => $share->getNode()->getId() ]),
672
-						$share->getSharedBy(),
673
-						$emailAddress,
674
-						$share->getExpirationDate()
675
-					);
676
-					$this->logger->debug('Send share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
677
-				} else {
678
-					$this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
679
-				}
680
-			} else {
681
-				$this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
682
-			}
683
-		}
684
-
685
-		return $share;
686
-	}
687
-
688
-	/**
689
-	 * @param IL10N $l Language of the recipient
690
-	 * @param string $filename file/folder name
691
-	 * @param string $link link to the file/folder
692
-	 * @param string $initiator user ID of share sender
693
-	 * @param string $shareWith email address of share receiver
694
-	 * @param \DateTime|null $expiration
695
-	 * @throws \Exception If mail couldn't be sent
696
-	 */
697
-	protected function sendMailNotification(IL10N $l,
698
-											$filename,
699
-											$link,
700
-											$initiator,
701
-											$shareWith,
702
-											\DateTime $expiration = null) {
703
-		$initiatorUser = $this->userManager->get($initiator);
704
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
705
-
706
-		$message = $this->mailer->createMessage();
707
-
708
-		$emailTemplate = $this->mailer->createEMailTemplate('files_sharing.RecipientNotification', [
709
-			'filename' => $filename,
710
-			'link' => $link,
711
-			'initiator' => $initiatorDisplayName,
712
-			'expiration' => $expiration,
713
-			'shareWith' => $shareWith,
714
-		]);
715
-
716
-		$emailTemplate->setSubject($l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename)));
717
-		$emailTemplate->addHeader();
718
-		$emailTemplate->addHeading($l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
719
-		$text = $l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
720
-
721
-		$emailTemplate->addBodyText(
722
-			$text . ' ' . $l->t('Click the button below to open it.'),
723
-			$text
724
-		);
725
-		$emailTemplate->addBodyButton(
726
-			$l->t('Open »%s«', [$filename]),
727
-			$link
728
-		);
729
-
730
-		$message->setTo([$shareWith]);
731
-
732
-		// The "From" contains the sharers name
733
-		$instanceName = $this->defaults->getName();
734
-		$senderName = $l->t(
735
-			'%s via %s',
736
-			[
737
-				$initiatorDisplayName,
738
-				$instanceName
739
-			]
740
-		);
741
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
742
-
743
-		// The "Reply-To" is set to the sharer if an mail address is configured
744
-		// also the default footer contains a "Do not reply" which needs to be adjusted.
745
-		$initiatorEmail = $initiatorUser->getEMailAddress();
746
-		if($initiatorEmail !== null) {
747
-			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
748
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
749
-		} else {
750
-			$emailTemplate->addFooter();
751
-		}
752
-
753
-		$message->setTemplate($emailTemplate);
754
-		$this->mailer->send($message);
755
-	}
756
-
757
-	/**
758
-	 * Update a share
759
-	 *
760
-	 * @param \OCP\Share\IShare $share
761
-	 * @return \OCP\Share\IShare The share object
762
-	 * @throws \InvalidArgumentException
763
-	 */
764
-	public function updateShare(\OCP\Share\IShare $share) {
765
-		$expirationDateUpdated = false;
766
-
767
-		$this->canShare($share);
768
-
769
-		try {
770
-			$originalShare = $this->getShareById($share->getFullId());
771
-		} catch (\UnexpectedValueException $e) {
772
-			throw new \InvalidArgumentException('Share does not have a full id');
773
-		}
774
-
775
-		// We can't change the share type!
776
-		if ($share->getShareType() !== $originalShare->getShareType()) {
777
-			throw new \InvalidArgumentException('Can’t change share type');
778
-		}
779
-
780
-		// We can only change the recipient on user shares
781
-		if ($share->getSharedWith() !== $originalShare->getSharedWith() &&
782
-		    $share->getShareType() !== \OCP\Share::SHARE_TYPE_USER) {
783
-			throw new \InvalidArgumentException('Can only update recipient on user shares');
784
-		}
785
-
786
-		// Cannot share with the owner
787
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
788
-			$share->getSharedWith() === $share->getShareOwner()) {
789
-			throw new \InvalidArgumentException('Can’t share with the share owner');
790
-		}
791
-
792
-		$this->generalCreateChecks($share);
793
-
794
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
795
-			$this->userCreateChecks($share);
796
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
797
-			$this->groupCreateChecks($share);
798
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
799
-			$this->linkCreateChecks($share);
800
-
801
-			$this->updateSharePasswordIfNeeded($share, $originalShare);
802
-
803
-			if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
804
-				//Verify the expiration date
805
-				$this->validateExpirationDate($share);
806
-				$expirationDateUpdated = true;
807
-			}
808
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
809
-			$plainTextPassword = $share->getPassword();
810
-			if (!$this->updateSharePasswordIfNeeded($share, $originalShare)) {
811
-				$plainTextPassword = null;
812
-			}
813
-		}
814
-
815
-		$this->pathCreateChecks($share->getNode());
816
-
817
-		// Now update the share!
818
-		$provider = $this->factory->getProviderForType($share->getShareType());
819
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
820
-			$share = $provider->update($share, $plainTextPassword);
821
-		} else {
822
-			$share = $provider->update($share);
823
-		}
824
-
825
-		if ($expirationDateUpdated === true) {
826
-			\OC_Hook::emit('OCP\Share', 'post_set_expiration_date', [
827
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
828
-				'itemSource' => $share->getNode()->getId(),
829
-				'date' => $share->getExpirationDate(),
830
-				'uidOwner' => $share->getSharedBy(),
831
-			]);
832
-		}
833
-
834
-		if ($share->getPassword() !== $originalShare->getPassword()) {
835
-			\OC_Hook::emit('OCP\Share', 'post_update_password', [
836
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
837
-				'itemSource' => $share->getNode()->getId(),
838
-				'uidOwner' => $share->getSharedBy(),
839
-				'token' => $share->getToken(),
840
-				'disabled' => is_null($share->getPassword()),
841
-			]);
842
-		}
843
-
844
-		if ($share->getPermissions() !== $originalShare->getPermissions()) {
845
-			if ($this->userManager->userExists($share->getShareOwner())) {
846
-				$userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
847
-			} else {
848
-				$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
849
-			}
850
-			\OC_Hook::emit('OCP\Share', 'post_update_permissions', array(
851
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
852
-				'itemSource' => $share->getNode()->getId(),
853
-				'shareType' => $share->getShareType(),
854
-				'shareWith' => $share->getSharedWith(),
855
-				'uidOwner' => $share->getSharedBy(),
856
-				'permissions' => $share->getPermissions(),
857
-				'path' => $userFolder->getRelativePath($share->getNode()->getPath()),
858
-			));
859
-		}
860
-
861
-		return $share;
862
-	}
863
-
864
-	/**
865
-	 * Updates the password of the given share if it is not the same as the
866
-	 * password of the original share.
867
-	 *
868
-	 * @param \OCP\Share\IShare $share the share to update its password.
869
-	 * @param \OCP\Share\IShare $originalShare the original share to compare its
870
-	 *        password with.
871
-	 * @return boolean whether the password was updated or not.
872
-	 */
873
-	private function updateSharePasswordIfNeeded(\OCP\Share\IShare $share, \OCP\Share\IShare $originalShare) {
874
-		// Password updated.
875
-		if ($share->getPassword() !== $originalShare->getPassword()) {
876
-			//Verify the password
877
-			$this->verifyPassword($share->getPassword());
878
-
879
-			// If a password is set. Hash it!
880
-			if ($share->getPassword() !== null) {
881
-				$share->setPassword($this->hasher->hash($share->getPassword()));
882
-
883
-				return true;
884
-			}
885
-		}
886
-
887
-		return false;
888
-	}
889
-
890
-	/**
891
-	 * Delete all the children of this share
892
-	 * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
893
-	 *
894
-	 * @param \OCP\Share\IShare $share
895
-	 * @return \OCP\Share\IShare[] List of deleted shares
896
-	 */
897
-	protected function deleteChildren(\OCP\Share\IShare $share) {
898
-		$deletedShares = [];
899
-
900
-		$provider = $this->factory->getProviderForType($share->getShareType());
901
-
902
-		foreach ($provider->getChildren($share) as $child) {
903
-			$deletedChildren = $this->deleteChildren($child);
904
-			$deletedShares = array_merge($deletedShares, $deletedChildren);
905
-
906
-			$provider->delete($child);
907
-			$deletedShares[] = $child;
908
-		}
909
-
910
-		return $deletedShares;
911
-	}
912
-
913
-	/**
914
-	 * Delete a share
915
-	 *
916
-	 * @param \OCP\Share\IShare $share
917
-	 * @throws ShareNotFound
918
-	 * @throws \InvalidArgumentException
919
-	 */
920
-	public function deleteShare(\OCP\Share\IShare $share) {
921
-
922
-		try {
923
-			$share->getFullId();
924
-		} catch (\UnexpectedValueException $e) {
925
-			throw new \InvalidArgumentException('Share does not have a full id');
926
-		}
927
-
928
-		$event = new GenericEvent($share);
929
-		$this->eventDispatcher->dispatch('OCP\Share::preUnshare', $event);
930
-
931
-		// Get all children and delete them as well
932
-		$deletedShares = $this->deleteChildren($share);
933
-
934
-		// Do the actual delete
935
-		$provider = $this->factory->getProviderForType($share->getShareType());
936
-		$provider->delete($share);
937
-
938
-		// All the deleted shares caused by this delete
939
-		$deletedShares[] = $share;
940
-
941
-		// Emit post hook
942
-		$event->setArgument('deletedShares', $deletedShares);
943
-		$this->eventDispatcher->dispatch('OCP\Share::postUnshare', $event);
944
-	}
945
-
946
-
947
-	/**
948
-	 * Unshare a file as the recipient.
949
-	 * This can be different from a regular delete for example when one of
950
-	 * the users in a groups deletes that share. But the provider should
951
-	 * handle this.
952
-	 *
953
-	 * @param \OCP\Share\IShare $share
954
-	 * @param string $recipientId
955
-	 */
956
-	public function deleteFromSelf(\OCP\Share\IShare $share, $recipientId) {
957
-		list($providerId, ) = $this->splitFullId($share->getFullId());
958
-		$provider = $this->factory->getProvider($providerId);
959
-
960
-		$provider->deleteFromSelf($share, $recipientId);
961
-		$event = new GenericEvent($share);
962
-		$this->eventDispatcher->dispatch('OCP\Share::postUnshareFromSelf', $event);
963
-	}
964
-
965
-	/**
966
-	 * @inheritdoc
967
-	 */
968
-	public function moveShare(\OCP\Share\IShare $share, $recipientId) {
969
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
970
-			throw new \InvalidArgumentException('Can’t change target of link share');
971
-		}
972
-
973
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER && $share->getSharedWith() !== $recipientId) {
974
-			throw new \InvalidArgumentException('Invalid recipient');
975
-		}
976
-
977
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
978
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
979
-			if (is_null($sharedWith)) {
980
-				throw new \InvalidArgumentException('Group "' . $share->getSharedWith() . '" does not exist');
981
-			}
982
-			$recipient = $this->userManager->get($recipientId);
983
-			if (!$sharedWith->inGroup($recipient)) {
984
-				throw new \InvalidArgumentException('Invalid recipient');
985
-			}
986
-		}
987
-
988
-		list($providerId, ) = $this->splitFullId($share->getFullId());
989
-		$provider = $this->factory->getProvider($providerId);
990
-
991
-		$provider->move($share, $recipientId);
992
-	}
993
-
994
-	public function getSharesInFolder($userId, Folder $node, $reshares = false) {
995
-		$providers = $this->factory->getAllProviders();
996
-
997
-		return array_reduce($providers, function($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
998
-			$newShares = $provider->getSharesInFolder($userId, $node, $reshares);
999
-			foreach ($newShares as $fid => $data) {
1000
-				if (!isset($shares[$fid])) {
1001
-					$shares[$fid] = [];
1002
-				}
1003
-
1004
-				$shares[$fid] = array_merge($shares[$fid], $data);
1005
-			}
1006
-			return $shares;
1007
-		}, []);
1008
-	}
1009
-
1010
-	/**
1011
-	 * @inheritdoc
1012
-	 */
1013
-	public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) {
1014
-		if ($path !== null &&
1015
-				!($path instanceof \OCP\Files\File) &&
1016
-				!($path instanceof \OCP\Files\Folder)) {
1017
-			throw new \InvalidArgumentException('invalid path');
1018
-		}
1019
-
1020
-		try {
1021
-			$provider = $this->factory->getProviderForType($shareType);
1022
-		} catch (ProviderException $e) {
1023
-			return [];
1024
-		}
1025
-
1026
-		$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1027
-
1028
-		/*
607
+            $share->setToken(
608
+                $this->secureRandom->generate(
609
+                    \OC\Share\Constants::TOKEN_LENGTH,
610
+                    \OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
611
+                )
612
+            );
613
+
614
+            //Verify the expiration date
615
+            $this->validateExpirationDate($share);
616
+
617
+            //Verify the password
618
+            $this->verifyPassword($share->getPassword());
619
+
620
+            // If a password is set. Hash it!
621
+            if ($share->getPassword() !== null) {
622
+                $share->setPassword($this->hasher->hash($share->getPassword()));
623
+            }
624
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
625
+            $share->setToken(
626
+                $this->secureRandom->generate(
627
+                    \OC\Share\Constants::TOKEN_LENGTH,
628
+                    \OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
629
+                )
630
+            );
631
+        }
632
+
633
+        // Cannot share with the owner
634
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
635
+            $share->getSharedWith() === $share->getShareOwner()) {
636
+            throw new \InvalidArgumentException('Can’t share with the share owner');
637
+        }
638
+
639
+        // Generate the target
640
+        $target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName();
641
+        $target = \OC\Files\Filesystem::normalizePath($target);
642
+        $share->setTarget($target);
643
+
644
+        // Pre share event
645
+        $event = new GenericEvent($share);
646
+        $a = $this->eventDispatcher->dispatch('OCP\Share::preShare', $event);
647
+        if ($event->isPropagationStopped() && $event->hasArgument('error')) {
648
+            throw new \Exception($event->getArgument('error'));
649
+        }
650
+
651
+        $oldShare = $share;
652
+        $provider = $this->factory->getProviderForType($share->getShareType());
653
+        $share = $provider->create($share);
654
+        //reuse the node we already have
655
+        $share->setNode($oldShare->getNode());
656
+
657
+        // Post share event
658
+        $event = new GenericEvent($share);
659
+        $this->eventDispatcher->dispatch('OCP\Share::postShare', $event);
660
+
661
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
662
+            $user = $this->userManager->get($share->getSharedWith());
663
+            if ($user !== null) {
664
+                $emailAddress = $user->getEMailAddress();
665
+                if ($emailAddress !== null && $emailAddress !== '') {
666
+                    $userLang = $this->config->getUserValue($share->getSharedWith(), 'core', 'lang', null);
667
+                    $l = $this->l10nFactory->get('lib', $userLang);
668
+                    $this->sendMailNotification(
669
+                        $l,
670
+                        $share->getNode()->getName(),
671
+                        $this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', [ 'fileid' => $share->getNode()->getId() ]),
672
+                        $share->getSharedBy(),
673
+                        $emailAddress,
674
+                        $share->getExpirationDate()
675
+                    );
676
+                    $this->logger->debug('Send share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
677
+                } else {
678
+                    $this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
679
+                }
680
+            } else {
681
+                $this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
682
+            }
683
+        }
684
+
685
+        return $share;
686
+    }
687
+
688
+    /**
689
+     * @param IL10N $l Language of the recipient
690
+     * @param string $filename file/folder name
691
+     * @param string $link link to the file/folder
692
+     * @param string $initiator user ID of share sender
693
+     * @param string $shareWith email address of share receiver
694
+     * @param \DateTime|null $expiration
695
+     * @throws \Exception If mail couldn't be sent
696
+     */
697
+    protected function sendMailNotification(IL10N $l,
698
+                                            $filename,
699
+                                            $link,
700
+                                            $initiator,
701
+                                            $shareWith,
702
+                                            \DateTime $expiration = null) {
703
+        $initiatorUser = $this->userManager->get($initiator);
704
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
705
+
706
+        $message = $this->mailer->createMessage();
707
+
708
+        $emailTemplate = $this->mailer->createEMailTemplate('files_sharing.RecipientNotification', [
709
+            'filename' => $filename,
710
+            'link' => $link,
711
+            'initiator' => $initiatorDisplayName,
712
+            'expiration' => $expiration,
713
+            'shareWith' => $shareWith,
714
+        ]);
715
+
716
+        $emailTemplate->setSubject($l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename)));
717
+        $emailTemplate->addHeader();
718
+        $emailTemplate->addHeading($l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
719
+        $text = $l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
720
+
721
+        $emailTemplate->addBodyText(
722
+            $text . ' ' . $l->t('Click the button below to open it.'),
723
+            $text
724
+        );
725
+        $emailTemplate->addBodyButton(
726
+            $l->t('Open »%s«', [$filename]),
727
+            $link
728
+        );
729
+
730
+        $message->setTo([$shareWith]);
731
+
732
+        // The "From" contains the sharers name
733
+        $instanceName = $this->defaults->getName();
734
+        $senderName = $l->t(
735
+            '%s via %s',
736
+            [
737
+                $initiatorDisplayName,
738
+                $instanceName
739
+            ]
740
+        );
741
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
742
+
743
+        // The "Reply-To" is set to the sharer if an mail address is configured
744
+        // also the default footer contains a "Do not reply" which needs to be adjusted.
745
+        $initiatorEmail = $initiatorUser->getEMailAddress();
746
+        if($initiatorEmail !== null) {
747
+            $message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
748
+            $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
749
+        } else {
750
+            $emailTemplate->addFooter();
751
+        }
752
+
753
+        $message->setTemplate($emailTemplate);
754
+        $this->mailer->send($message);
755
+    }
756
+
757
+    /**
758
+     * Update a share
759
+     *
760
+     * @param \OCP\Share\IShare $share
761
+     * @return \OCP\Share\IShare The share object
762
+     * @throws \InvalidArgumentException
763
+     */
764
+    public function updateShare(\OCP\Share\IShare $share) {
765
+        $expirationDateUpdated = false;
766
+
767
+        $this->canShare($share);
768
+
769
+        try {
770
+            $originalShare = $this->getShareById($share->getFullId());
771
+        } catch (\UnexpectedValueException $e) {
772
+            throw new \InvalidArgumentException('Share does not have a full id');
773
+        }
774
+
775
+        // We can't change the share type!
776
+        if ($share->getShareType() !== $originalShare->getShareType()) {
777
+            throw new \InvalidArgumentException('Can’t change share type');
778
+        }
779
+
780
+        // We can only change the recipient on user shares
781
+        if ($share->getSharedWith() !== $originalShare->getSharedWith() &&
782
+            $share->getShareType() !== \OCP\Share::SHARE_TYPE_USER) {
783
+            throw new \InvalidArgumentException('Can only update recipient on user shares');
784
+        }
785
+
786
+        // Cannot share with the owner
787
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
788
+            $share->getSharedWith() === $share->getShareOwner()) {
789
+            throw new \InvalidArgumentException('Can’t share with the share owner');
790
+        }
791
+
792
+        $this->generalCreateChecks($share);
793
+
794
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
795
+            $this->userCreateChecks($share);
796
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
797
+            $this->groupCreateChecks($share);
798
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
799
+            $this->linkCreateChecks($share);
800
+
801
+            $this->updateSharePasswordIfNeeded($share, $originalShare);
802
+
803
+            if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
804
+                //Verify the expiration date
805
+                $this->validateExpirationDate($share);
806
+                $expirationDateUpdated = true;
807
+            }
808
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
809
+            $plainTextPassword = $share->getPassword();
810
+            if (!$this->updateSharePasswordIfNeeded($share, $originalShare)) {
811
+                $plainTextPassword = null;
812
+            }
813
+        }
814
+
815
+        $this->pathCreateChecks($share->getNode());
816
+
817
+        // Now update the share!
818
+        $provider = $this->factory->getProviderForType($share->getShareType());
819
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
820
+            $share = $provider->update($share, $plainTextPassword);
821
+        } else {
822
+            $share = $provider->update($share);
823
+        }
824
+
825
+        if ($expirationDateUpdated === true) {
826
+            \OC_Hook::emit('OCP\Share', 'post_set_expiration_date', [
827
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
828
+                'itemSource' => $share->getNode()->getId(),
829
+                'date' => $share->getExpirationDate(),
830
+                'uidOwner' => $share->getSharedBy(),
831
+            ]);
832
+        }
833
+
834
+        if ($share->getPassword() !== $originalShare->getPassword()) {
835
+            \OC_Hook::emit('OCP\Share', 'post_update_password', [
836
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
837
+                'itemSource' => $share->getNode()->getId(),
838
+                'uidOwner' => $share->getSharedBy(),
839
+                'token' => $share->getToken(),
840
+                'disabled' => is_null($share->getPassword()),
841
+            ]);
842
+        }
843
+
844
+        if ($share->getPermissions() !== $originalShare->getPermissions()) {
845
+            if ($this->userManager->userExists($share->getShareOwner())) {
846
+                $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
847
+            } else {
848
+                $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
849
+            }
850
+            \OC_Hook::emit('OCP\Share', 'post_update_permissions', array(
851
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
852
+                'itemSource' => $share->getNode()->getId(),
853
+                'shareType' => $share->getShareType(),
854
+                'shareWith' => $share->getSharedWith(),
855
+                'uidOwner' => $share->getSharedBy(),
856
+                'permissions' => $share->getPermissions(),
857
+                'path' => $userFolder->getRelativePath($share->getNode()->getPath()),
858
+            ));
859
+        }
860
+
861
+        return $share;
862
+    }
863
+
864
+    /**
865
+     * Updates the password of the given share if it is not the same as the
866
+     * password of the original share.
867
+     *
868
+     * @param \OCP\Share\IShare $share the share to update its password.
869
+     * @param \OCP\Share\IShare $originalShare the original share to compare its
870
+     *        password with.
871
+     * @return boolean whether the password was updated or not.
872
+     */
873
+    private function updateSharePasswordIfNeeded(\OCP\Share\IShare $share, \OCP\Share\IShare $originalShare) {
874
+        // Password updated.
875
+        if ($share->getPassword() !== $originalShare->getPassword()) {
876
+            //Verify the password
877
+            $this->verifyPassword($share->getPassword());
878
+
879
+            // If a password is set. Hash it!
880
+            if ($share->getPassword() !== null) {
881
+                $share->setPassword($this->hasher->hash($share->getPassword()));
882
+
883
+                return true;
884
+            }
885
+        }
886
+
887
+        return false;
888
+    }
889
+
890
+    /**
891
+     * Delete all the children of this share
892
+     * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
893
+     *
894
+     * @param \OCP\Share\IShare $share
895
+     * @return \OCP\Share\IShare[] List of deleted shares
896
+     */
897
+    protected function deleteChildren(\OCP\Share\IShare $share) {
898
+        $deletedShares = [];
899
+
900
+        $provider = $this->factory->getProviderForType($share->getShareType());
901
+
902
+        foreach ($provider->getChildren($share) as $child) {
903
+            $deletedChildren = $this->deleteChildren($child);
904
+            $deletedShares = array_merge($deletedShares, $deletedChildren);
905
+
906
+            $provider->delete($child);
907
+            $deletedShares[] = $child;
908
+        }
909
+
910
+        return $deletedShares;
911
+    }
912
+
913
+    /**
914
+     * Delete a share
915
+     *
916
+     * @param \OCP\Share\IShare $share
917
+     * @throws ShareNotFound
918
+     * @throws \InvalidArgumentException
919
+     */
920
+    public function deleteShare(\OCP\Share\IShare $share) {
921
+
922
+        try {
923
+            $share->getFullId();
924
+        } catch (\UnexpectedValueException $e) {
925
+            throw new \InvalidArgumentException('Share does not have a full id');
926
+        }
927
+
928
+        $event = new GenericEvent($share);
929
+        $this->eventDispatcher->dispatch('OCP\Share::preUnshare', $event);
930
+
931
+        // Get all children and delete them as well
932
+        $deletedShares = $this->deleteChildren($share);
933
+
934
+        // Do the actual delete
935
+        $provider = $this->factory->getProviderForType($share->getShareType());
936
+        $provider->delete($share);
937
+
938
+        // All the deleted shares caused by this delete
939
+        $deletedShares[] = $share;
940
+
941
+        // Emit post hook
942
+        $event->setArgument('deletedShares', $deletedShares);
943
+        $this->eventDispatcher->dispatch('OCP\Share::postUnshare', $event);
944
+    }
945
+
946
+
947
+    /**
948
+     * Unshare a file as the recipient.
949
+     * This can be different from a regular delete for example when one of
950
+     * the users in a groups deletes that share. But the provider should
951
+     * handle this.
952
+     *
953
+     * @param \OCP\Share\IShare $share
954
+     * @param string $recipientId
955
+     */
956
+    public function deleteFromSelf(\OCP\Share\IShare $share, $recipientId) {
957
+        list($providerId, ) = $this->splitFullId($share->getFullId());
958
+        $provider = $this->factory->getProvider($providerId);
959
+
960
+        $provider->deleteFromSelf($share, $recipientId);
961
+        $event = new GenericEvent($share);
962
+        $this->eventDispatcher->dispatch('OCP\Share::postUnshareFromSelf', $event);
963
+    }
964
+
965
+    /**
966
+     * @inheritdoc
967
+     */
968
+    public function moveShare(\OCP\Share\IShare $share, $recipientId) {
969
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
970
+            throw new \InvalidArgumentException('Can’t change target of link share');
971
+        }
972
+
973
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER && $share->getSharedWith() !== $recipientId) {
974
+            throw new \InvalidArgumentException('Invalid recipient');
975
+        }
976
+
977
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
978
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
979
+            if (is_null($sharedWith)) {
980
+                throw new \InvalidArgumentException('Group "' . $share->getSharedWith() . '" does not exist');
981
+            }
982
+            $recipient = $this->userManager->get($recipientId);
983
+            if (!$sharedWith->inGroup($recipient)) {
984
+                throw new \InvalidArgumentException('Invalid recipient');
985
+            }
986
+        }
987
+
988
+        list($providerId, ) = $this->splitFullId($share->getFullId());
989
+        $provider = $this->factory->getProvider($providerId);
990
+
991
+        $provider->move($share, $recipientId);
992
+    }
993
+
994
+    public function getSharesInFolder($userId, Folder $node, $reshares = false) {
995
+        $providers = $this->factory->getAllProviders();
996
+
997
+        return array_reduce($providers, function($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
998
+            $newShares = $provider->getSharesInFolder($userId, $node, $reshares);
999
+            foreach ($newShares as $fid => $data) {
1000
+                if (!isset($shares[$fid])) {
1001
+                    $shares[$fid] = [];
1002
+                }
1003
+
1004
+                $shares[$fid] = array_merge($shares[$fid], $data);
1005
+            }
1006
+            return $shares;
1007
+        }, []);
1008
+    }
1009
+
1010
+    /**
1011
+     * @inheritdoc
1012
+     */
1013
+    public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) {
1014
+        if ($path !== null &&
1015
+                !($path instanceof \OCP\Files\File) &&
1016
+                !($path instanceof \OCP\Files\Folder)) {
1017
+            throw new \InvalidArgumentException('invalid path');
1018
+        }
1019
+
1020
+        try {
1021
+            $provider = $this->factory->getProviderForType($shareType);
1022
+        } catch (ProviderException $e) {
1023
+            return [];
1024
+        }
1025
+
1026
+        $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1027
+
1028
+        /*
1029 1029
 		 * Work around so we don't return expired shares but still follow
1030 1030
 		 * proper pagination.
1031 1031
 		 */
1032 1032
 
1033
-		$shares2 = [];
1034
-
1035
-		while(true) {
1036
-			$added = 0;
1037
-			foreach ($shares as $share) {
1038
-
1039
-				try {
1040
-					$this->checkExpireDate($share);
1041
-				} catch (ShareNotFound $e) {
1042
-					//Ignore since this basically means the share is deleted
1043
-					continue;
1044
-				}
1045
-
1046
-				$added++;
1047
-				$shares2[] = $share;
1048
-
1049
-				if (count($shares2) === $limit) {
1050
-					break;
1051
-				}
1052
-			}
1053
-
1054
-			if (count($shares2) === $limit) {
1055
-				break;
1056
-			}
1057
-
1058
-			// If there was no limit on the select we are done
1059
-			if ($limit === -1) {
1060
-				break;
1061
-			}
1062
-
1063
-			$offset += $added;
1064
-
1065
-			// Fetch again $limit shares
1066
-			$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1067
-
1068
-			// No more shares means we are done
1069
-			if (empty($shares)) {
1070
-				break;
1071
-			}
1072
-		}
1073
-
1074
-		$shares = $shares2;
1075
-
1076
-		return $shares;
1077
-	}
1078
-
1079
-	/**
1080
-	 * @inheritdoc
1081
-	 */
1082
-	public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1083
-		try {
1084
-			$provider = $this->factory->getProviderForType($shareType);
1085
-		} catch (ProviderException $e) {
1086
-			return [];
1087
-		}
1088
-
1089
-		$shares = $provider->getSharedWith($userId, $shareType, $node, $limit, $offset);
1090
-
1091
-		// remove all shares which are already expired
1092
-		foreach ($shares as $key => $share) {
1093
-			try {
1094
-				$this->checkExpireDate($share);
1095
-			} catch (ShareNotFound $e) {
1096
-				unset($shares[$key]);
1097
-			}
1098
-		}
1099
-
1100
-		return $shares;
1101
-	}
1102
-
1103
-	/**
1104
-	 * @inheritdoc
1105
-	 */
1106
-	public function getShareById($id, $recipient = null) {
1107
-		if ($id === null) {
1108
-			throw new ShareNotFound();
1109
-		}
1110
-
1111
-		list($providerId, $id) = $this->splitFullId($id);
1112
-
1113
-		try {
1114
-			$provider = $this->factory->getProvider($providerId);
1115
-		} catch (ProviderException $e) {
1116
-			throw new ShareNotFound();
1117
-		}
1118
-
1119
-		$share = $provider->getShareById($id, $recipient);
1120
-
1121
-		$this->checkExpireDate($share);
1122
-
1123
-		return $share;
1124
-	}
1125
-
1126
-	/**
1127
-	 * Get all the shares for a given path
1128
-	 *
1129
-	 * @param \OCP\Files\Node $path
1130
-	 * @param int $page
1131
-	 * @param int $perPage
1132
-	 *
1133
-	 * @return Share[]
1134
-	 */
1135
-	public function getSharesByPath(\OCP\Files\Node $path, $page=0, $perPage=50) {
1136
-		return [];
1137
-	}
1138
-
1139
-	/**
1140
-	 * Get the share by token possible with password
1141
-	 *
1142
-	 * @param string $token
1143
-	 * @return Share
1144
-	 *
1145
-	 * @throws ShareNotFound
1146
-	 */
1147
-	public function getShareByToken($token) {
1148
-		$share = null;
1149
-		try {
1150
-			if($this->shareApiAllowLinks()) {
1151
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_LINK);
1152
-				$share = $provider->getShareByToken($token);
1153
-			}
1154
-		} catch (ProviderException $e) {
1155
-		} catch (ShareNotFound $e) {
1156
-		}
1157
-
1158
-
1159
-		// If it is not a link share try to fetch a federated share by token
1160
-		if ($share === null) {
1161
-			try {
1162
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_REMOTE);
1163
-				$share = $provider->getShareByToken($token);
1164
-			} catch (ProviderException $e) {
1165
-			} catch (ShareNotFound $e) {
1166
-			}
1167
-		}
1168
-
1169
-		// If it is not a link share try to fetch a mail share by token
1170
-		if ($share === null && $this->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
1171
-			try {
1172
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_EMAIL);
1173
-				$share = $provider->getShareByToken($token);
1174
-			} catch (ProviderException $e) {
1175
-			} catch (ShareNotFound $e) {
1176
-			}
1177
-		}
1178
-
1179
-		if ($share === null && $this->shareProviderExists(\OCP\Share::SHARE_TYPE_CIRCLE)) {
1180
-			try {
1181
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_CIRCLE);
1182
-				$share = $provider->getShareByToken($token);
1183
-			} catch (ProviderException $e) {
1184
-			} catch (ShareNotFound $e) {
1185
-			}
1186
-		}
1187
-
1188
-		if ($share === null) {
1189
-			throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1190
-		}
1191
-
1192
-		$this->checkExpireDate($share);
1193
-
1194
-		/*
1033
+        $shares2 = [];
1034
+
1035
+        while(true) {
1036
+            $added = 0;
1037
+            foreach ($shares as $share) {
1038
+
1039
+                try {
1040
+                    $this->checkExpireDate($share);
1041
+                } catch (ShareNotFound $e) {
1042
+                    //Ignore since this basically means the share is deleted
1043
+                    continue;
1044
+                }
1045
+
1046
+                $added++;
1047
+                $shares2[] = $share;
1048
+
1049
+                if (count($shares2) === $limit) {
1050
+                    break;
1051
+                }
1052
+            }
1053
+
1054
+            if (count($shares2) === $limit) {
1055
+                break;
1056
+            }
1057
+
1058
+            // If there was no limit on the select we are done
1059
+            if ($limit === -1) {
1060
+                break;
1061
+            }
1062
+
1063
+            $offset += $added;
1064
+
1065
+            // Fetch again $limit shares
1066
+            $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1067
+
1068
+            // No more shares means we are done
1069
+            if (empty($shares)) {
1070
+                break;
1071
+            }
1072
+        }
1073
+
1074
+        $shares = $shares2;
1075
+
1076
+        return $shares;
1077
+    }
1078
+
1079
+    /**
1080
+     * @inheritdoc
1081
+     */
1082
+    public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1083
+        try {
1084
+            $provider = $this->factory->getProviderForType($shareType);
1085
+        } catch (ProviderException $e) {
1086
+            return [];
1087
+        }
1088
+
1089
+        $shares = $provider->getSharedWith($userId, $shareType, $node, $limit, $offset);
1090
+
1091
+        // remove all shares which are already expired
1092
+        foreach ($shares as $key => $share) {
1093
+            try {
1094
+                $this->checkExpireDate($share);
1095
+            } catch (ShareNotFound $e) {
1096
+                unset($shares[$key]);
1097
+            }
1098
+        }
1099
+
1100
+        return $shares;
1101
+    }
1102
+
1103
+    /**
1104
+     * @inheritdoc
1105
+     */
1106
+    public function getShareById($id, $recipient = null) {
1107
+        if ($id === null) {
1108
+            throw new ShareNotFound();
1109
+        }
1110
+
1111
+        list($providerId, $id) = $this->splitFullId($id);
1112
+
1113
+        try {
1114
+            $provider = $this->factory->getProvider($providerId);
1115
+        } catch (ProviderException $e) {
1116
+            throw new ShareNotFound();
1117
+        }
1118
+
1119
+        $share = $provider->getShareById($id, $recipient);
1120
+
1121
+        $this->checkExpireDate($share);
1122
+
1123
+        return $share;
1124
+    }
1125
+
1126
+    /**
1127
+     * Get all the shares for a given path
1128
+     *
1129
+     * @param \OCP\Files\Node $path
1130
+     * @param int $page
1131
+     * @param int $perPage
1132
+     *
1133
+     * @return Share[]
1134
+     */
1135
+    public function getSharesByPath(\OCP\Files\Node $path, $page=0, $perPage=50) {
1136
+        return [];
1137
+    }
1138
+
1139
+    /**
1140
+     * Get the share by token possible with password
1141
+     *
1142
+     * @param string $token
1143
+     * @return Share
1144
+     *
1145
+     * @throws ShareNotFound
1146
+     */
1147
+    public function getShareByToken($token) {
1148
+        $share = null;
1149
+        try {
1150
+            if($this->shareApiAllowLinks()) {
1151
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_LINK);
1152
+                $share = $provider->getShareByToken($token);
1153
+            }
1154
+        } catch (ProviderException $e) {
1155
+        } catch (ShareNotFound $e) {
1156
+        }
1157
+
1158
+
1159
+        // If it is not a link share try to fetch a federated share by token
1160
+        if ($share === null) {
1161
+            try {
1162
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_REMOTE);
1163
+                $share = $provider->getShareByToken($token);
1164
+            } catch (ProviderException $e) {
1165
+            } catch (ShareNotFound $e) {
1166
+            }
1167
+        }
1168
+
1169
+        // If it is not a link share try to fetch a mail share by token
1170
+        if ($share === null && $this->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
1171
+            try {
1172
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_EMAIL);
1173
+                $share = $provider->getShareByToken($token);
1174
+            } catch (ProviderException $e) {
1175
+            } catch (ShareNotFound $e) {
1176
+            }
1177
+        }
1178
+
1179
+        if ($share === null && $this->shareProviderExists(\OCP\Share::SHARE_TYPE_CIRCLE)) {
1180
+            try {
1181
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_CIRCLE);
1182
+                $share = $provider->getShareByToken($token);
1183
+            } catch (ProviderException $e) {
1184
+            } catch (ShareNotFound $e) {
1185
+            }
1186
+        }
1187
+
1188
+        if ($share === null) {
1189
+            throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1190
+        }
1191
+
1192
+        $this->checkExpireDate($share);
1193
+
1194
+        /*
1195 1195
 		 * Reduce the permissions for link shares if public upload is not enabled
1196 1196
 		 */
1197
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
1198
-			!$this->shareApiLinkAllowPublicUpload()) {
1199
-			$share->setPermissions($share->getPermissions() & ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE));
1200
-		}
1201
-
1202
-		return $share;
1203
-	}
1204
-
1205
-	protected function checkExpireDate($share) {
1206
-		if ($share->getExpirationDate() !== null &&
1207
-			$share->getExpirationDate() <= new \DateTime()) {
1208
-			$this->deleteShare($share);
1209
-			throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1210
-		}
1211
-
1212
-	}
1213
-
1214
-	/**
1215
-	 * Verify the password of a public share
1216
-	 *
1217
-	 * @param \OCP\Share\IShare $share
1218
-	 * @param string $password
1219
-	 * @return bool
1220
-	 */
1221
-	public function checkPassword(\OCP\Share\IShare $share, $password) {
1222
-		$passwordProtected = $share->getShareType() !== \OCP\Share::SHARE_TYPE_LINK
1223
-			|| $share->getShareType() !== \OCP\Share::SHARE_TYPE_EMAIL;
1224
-		if (!$passwordProtected) {
1225
-			//TODO maybe exception?
1226
-			return false;
1227
-		}
1228
-
1229
-		if ($password === null || $share->getPassword() === null) {
1230
-			return false;
1231
-		}
1232
-
1233
-		$newHash = '';
1234
-		if (!$this->hasher->verify($password, $share->getPassword(), $newHash)) {
1235
-			return false;
1236
-		}
1237
-
1238
-		if (!empty($newHash)) {
1239
-			$share->setPassword($newHash);
1240
-			$provider = $this->factory->getProviderForType($share->getShareType());
1241
-			$provider->update($share);
1242
-		}
1243
-
1244
-		return true;
1245
-	}
1246
-
1247
-	/**
1248
-	 * @inheritdoc
1249
-	 */
1250
-	public function userDeleted($uid) {
1251
-		$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];
1252
-
1253
-		foreach ($types as $type) {
1254
-			try {
1255
-				$provider = $this->factory->getProviderForType($type);
1256
-			} catch (ProviderException $e) {
1257
-				continue;
1258
-			}
1259
-			$provider->userDeleted($uid, $type);
1260
-		}
1261
-	}
1262
-
1263
-	/**
1264
-	 * @inheritdoc
1265
-	 */
1266
-	public function groupDeleted($gid) {
1267
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1268
-		$provider->groupDeleted($gid);
1269
-	}
1270
-
1271
-	/**
1272
-	 * @inheritdoc
1273
-	 */
1274
-	public function userDeletedFromGroup($uid, $gid) {
1275
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1276
-		$provider->userDeletedFromGroup($uid, $gid);
1277
-	}
1278
-
1279
-	/**
1280
-	 * Get access list to a path. This means
1281
-	 * all the users that can access a given path.
1282
-	 *
1283
-	 * Consider:
1284
-	 * -root
1285
-	 * |-folder1 (23)
1286
-	 *  |-folder2 (32)
1287
-	 *   |-fileA (42)
1288
-	 *
1289
-	 * fileA is shared with user1 and user1@server1
1290
-	 * folder2 is shared with group2 (user4 is a member of group2)
1291
-	 * folder1 is shared with user2 (renamed to "folder (1)") and user2@server2
1292
-	 *
1293
-	 * Then the access list to '/folder1/folder2/fileA' with $currentAccess is:
1294
-	 * [
1295
-	 *  users  => [
1296
-	 *      'user1' => ['node_id' => 42, 'node_path' => '/fileA'],
1297
-	 *      'user4' => ['node_id' => 32, 'node_path' => '/folder2'],
1298
-	 *      'user2' => ['node_id' => 23, 'node_path' => '/folder (1)'],
1299
-	 *  ],
1300
-	 *  remote => [
1301
-	 *      'user1@server1' => ['node_id' => 42, 'token' => 'SeCr3t'],
1302
-	 *      'user2@server2' => ['node_id' => 23, 'token' => 'FooBaR'],
1303
-	 *  ],
1304
-	 *  public => bool
1305
-	 *  mail => bool
1306
-	 * ]
1307
-	 *
1308
-	 * The access list to '/folder1/folder2/fileA' **without** $currentAccess is:
1309
-	 * [
1310
-	 *  users  => ['user1', 'user2', 'user4'],
1311
-	 *  remote => bool,
1312
-	 *  public => bool
1313
-	 *  mail => bool
1314
-	 * ]
1315
-	 *
1316
-	 * This is required for encryption/activity
1317
-	 *
1318
-	 * @param \OCP\Files\Node $path
1319
-	 * @param bool $recursive Should we check all parent folders as well
1320
-	 * @param bool $currentAccess Should the user have currently access to the file
1321
-	 * @return array
1322
-	 */
1323
-	public function getAccessList(\OCP\Files\Node $path, $recursive = true, $currentAccess = false) {
1324
-		$owner = $path->getOwner()->getUID();
1325
-
1326
-		if ($currentAccess) {
1327
-			$al = ['users' => [], 'remote' => [], 'public' => false];
1328
-		} else {
1329
-			$al = ['users' => [], 'remote' => false, 'public' => false];
1330
-		}
1331
-		if (!$this->userManager->userExists($owner)) {
1332
-			return $al;
1333
-		}
1334
-
1335
-		//Get node for the owner
1336
-		$userFolder = $this->rootFolder->getUserFolder($owner);
1337
-		if ($path->getId() !== $userFolder->getId() && !$userFolder->isSubNode($path)) {
1338
-			$path = $userFolder->getById($path->getId())[0];
1339
-		}
1340
-
1341
-		$providers = $this->factory->getAllProviders();
1342
-
1343
-		/** @var Node[] $nodes */
1344
-		$nodes = [];
1345
-
1346
-
1347
-		if ($currentAccess) {
1348
-			$ownerPath = $path->getPath();
1349
-			$ownerPath = explode('/', $ownerPath, 4);
1350
-			if (count($ownerPath) < 4) {
1351
-				$ownerPath = '';
1352
-			} else {
1353
-				$ownerPath = $ownerPath[3];
1354
-			}
1355
-			$al['users'][$owner] = [
1356
-				'node_id' => $path->getId(),
1357
-				'node_path' => '/' . $ownerPath,
1358
-			];
1359
-		} else {
1360
-			$al['users'][] = $owner;
1361
-		}
1362
-
1363
-		// Collect all the shares
1364
-		while ($path->getPath() !== $userFolder->getPath()) {
1365
-			$nodes[] = $path;
1366
-			if (!$recursive) {
1367
-				break;
1368
-			}
1369
-			$path = $path->getParent();
1370
-		}
1371
-
1372
-		foreach ($providers as $provider) {
1373
-			$tmp = $provider->getAccessList($nodes, $currentAccess);
1374
-
1375
-			foreach ($tmp as $k => $v) {
1376
-				if (isset($al[$k])) {
1377
-					if (is_array($al[$k])) {
1378
-						$al[$k] = array_merge($al[$k], $v);
1379
-					} else {
1380
-						$al[$k] = $al[$k] || $v;
1381
-					}
1382
-				} else {
1383
-					$al[$k] = $v;
1384
-				}
1385
-			}
1386
-		}
1387
-
1388
-		return $al;
1389
-	}
1390
-
1391
-	/**
1392
-	 * Create a new share
1393
-	 * @return \OCP\Share\IShare;
1394
-	 */
1395
-	public function newShare() {
1396
-		return new \OC\Share20\Share($this->rootFolder, $this->userManager);
1397
-	}
1398
-
1399
-	/**
1400
-	 * Is the share API enabled
1401
-	 *
1402
-	 * @return bool
1403
-	 */
1404
-	public function shareApiEnabled() {
1405
-		return $this->config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes';
1406
-	}
1407
-
1408
-	/**
1409
-	 * Is public link sharing enabled
1410
-	 *
1411
-	 * @return bool
1412
-	 */
1413
-	public function shareApiAllowLinks() {
1414
-		return $this->config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes';
1415
-	}
1416
-
1417
-	/**
1418
-	 * Is password on public link requires
1419
-	 *
1420
-	 * @return bool
1421
-	 */
1422
-	public function shareApiLinkEnforcePassword() {
1423
-		return $this->config->getAppValue('core', 'shareapi_enforce_links_password', 'no') === 'yes';
1424
-	}
1425
-
1426
-	/**
1427
-	 * Is default expire date enabled
1428
-	 *
1429
-	 * @return bool
1430
-	 */
1431
-	public function shareApiLinkDefaultExpireDate() {
1432
-		return $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes';
1433
-	}
1434
-
1435
-	/**
1436
-	 * Is default expire date enforced
1437
-	 *`
1438
-	 * @return bool
1439
-	 */
1440
-	public function shareApiLinkDefaultExpireDateEnforced() {
1441
-		return $this->shareApiLinkDefaultExpireDate() &&
1442
-			$this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes';
1443
-	}
1444
-
1445
-	/**
1446
-	 * Number of default expire days
1447
-	 *shareApiLinkAllowPublicUpload
1448
-	 * @return int
1449
-	 */
1450
-	public function shareApiLinkDefaultExpireDays() {
1451
-		return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1452
-	}
1453
-
1454
-	/**
1455
-	 * Allow public upload on link shares
1456
-	 *
1457
-	 * @return bool
1458
-	 */
1459
-	public function shareApiLinkAllowPublicUpload() {
1460
-		return $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') === 'yes';
1461
-	}
1462
-
1463
-	/**
1464
-	 * check if user can only share with group members
1465
-	 * @return bool
1466
-	 */
1467
-	public function shareWithGroupMembersOnly() {
1468
-		return $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
1469
-	}
1470
-
1471
-	/**
1472
-	 * Check if users can share with groups
1473
-	 * @return bool
1474
-	 */
1475
-	public function allowGroupSharing() {
1476
-		return $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes';
1477
-	}
1478
-
1479
-	/**
1480
-	 * Copied from \OC_Util::isSharingDisabledForUser
1481
-	 *
1482
-	 * TODO: Deprecate fuction from OC_Util
1483
-	 *
1484
-	 * @param string $userId
1485
-	 * @return bool
1486
-	 */
1487
-	public function sharingDisabledForUser($userId) {
1488
-		if ($userId === null) {
1489
-			return false;
1490
-		}
1491
-
1492
-		if (isset($this->sharingDisabledForUsersCache[$userId])) {
1493
-			return $this->sharingDisabledForUsersCache[$userId];
1494
-		}
1495
-
1496
-		if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
1497
-			$groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1498
-			$excludedGroups = json_decode($groupsList);
1499
-			if (is_null($excludedGroups)) {
1500
-				$excludedGroups = explode(',', $groupsList);
1501
-				$newValue = json_encode($excludedGroups);
1502
-				$this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
1503
-			}
1504
-			$user = $this->userManager->get($userId);
1505
-			$usersGroups = $this->groupManager->getUserGroupIds($user);
1506
-			if (!empty($usersGroups)) {
1507
-				$remainingGroups = array_diff($usersGroups, $excludedGroups);
1508
-				// if the user is only in groups which are disabled for sharing then
1509
-				// sharing is also disabled for the user
1510
-				if (empty($remainingGroups)) {
1511
-					$this->sharingDisabledForUsersCache[$userId] = true;
1512
-					return true;
1513
-				}
1514
-			}
1515
-		}
1516
-
1517
-		$this->sharingDisabledForUsersCache[$userId] = false;
1518
-		return false;
1519
-	}
1520
-
1521
-	/**
1522
-	 * @inheritdoc
1523
-	 */
1524
-	public function outgoingServer2ServerSharesAllowed() {
1525
-		return $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes';
1526
-	}
1527
-
1528
-	/**
1529
-	 * @inheritdoc
1530
-	 */
1531
-	public function shareProviderExists($shareType) {
1532
-		try {
1533
-			$this->factory->getProviderForType($shareType);
1534
-		} catch (ProviderException $e) {
1535
-			return false;
1536
-		}
1537
-
1538
-		return true;
1539
-	}
1197
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
1198
+            !$this->shareApiLinkAllowPublicUpload()) {
1199
+            $share->setPermissions($share->getPermissions() & ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE));
1200
+        }
1201
+
1202
+        return $share;
1203
+    }
1204
+
1205
+    protected function checkExpireDate($share) {
1206
+        if ($share->getExpirationDate() !== null &&
1207
+            $share->getExpirationDate() <= new \DateTime()) {
1208
+            $this->deleteShare($share);
1209
+            throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1210
+        }
1211
+
1212
+    }
1213
+
1214
+    /**
1215
+     * Verify the password of a public share
1216
+     *
1217
+     * @param \OCP\Share\IShare $share
1218
+     * @param string $password
1219
+     * @return bool
1220
+     */
1221
+    public function checkPassword(\OCP\Share\IShare $share, $password) {
1222
+        $passwordProtected = $share->getShareType() !== \OCP\Share::SHARE_TYPE_LINK
1223
+            || $share->getShareType() !== \OCP\Share::SHARE_TYPE_EMAIL;
1224
+        if (!$passwordProtected) {
1225
+            //TODO maybe exception?
1226
+            return false;
1227
+        }
1228
+
1229
+        if ($password === null || $share->getPassword() === null) {
1230
+            return false;
1231
+        }
1232
+
1233
+        $newHash = '';
1234
+        if (!$this->hasher->verify($password, $share->getPassword(), $newHash)) {
1235
+            return false;
1236
+        }
1237
+
1238
+        if (!empty($newHash)) {
1239
+            $share->setPassword($newHash);
1240
+            $provider = $this->factory->getProviderForType($share->getShareType());
1241
+            $provider->update($share);
1242
+        }
1243
+
1244
+        return true;
1245
+    }
1246
+
1247
+    /**
1248
+     * @inheritdoc
1249
+     */
1250
+    public function userDeleted($uid) {
1251
+        $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];
1252
+
1253
+        foreach ($types as $type) {
1254
+            try {
1255
+                $provider = $this->factory->getProviderForType($type);
1256
+            } catch (ProviderException $e) {
1257
+                continue;
1258
+            }
1259
+            $provider->userDeleted($uid, $type);
1260
+        }
1261
+    }
1262
+
1263
+    /**
1264
+     * @inheritdoc
1265
+     */
1266
+    public function groupDeleted($gid) {
1267
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1268
+        $provider->groupDeleted($gid);
1269
+    }
1270
+
1271
+    /**
1272
+     * @inheritdoc
1273
+     */
1274
+    public function userDeletedFromGroup($uid, $gid) {
1275
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1276
+        $provider->userDeletedFromGroup($uid, $gid);
1277
+    }
1278
+
1279
+    /**
1280
+     * Get access list to a path. This means
1281
+     * all the users that can access a given path.
1282
+     *
1283
+     * Consider:
1284
+     * -root
1285
+     * |-folder1 (23)
1286
+     *  |-folder2 (32)
1287
+     *   |-fileA (42)
1288
+     *
1289
+     * fileA is shared with user1 and user1@server1
1290
+     * folder2 is shared with group2 (user4 is a member of group2)
1291
+     * folder1 is shared with user2 (renamed to "folder (1)") and user2@server2
1292
+     *
1293
+     * Then the access list to '/folder1/folder2/fileA' with $currentAccess is:
1294
+     * [
1295
+     *  users  => [
1296
+     *      'user1' => ['node_id' => 42, 'node_path' => '/fileA'],
1297
+     *      'user4' => ['node_id' => 32, 'node_path' => '/folder2'],
1298
+     *      'user2' => ['node_id' => 23, 'node_path' => '/folder (1)'],
1299
+     *  ],
1300
+     *  remote => [
1301
+     *      'user1@server1' => ['node_id' => 42, 'token' => 'SeCr3t'],
1302
+     *      'user2@server2' => ['node_id' => 23, 'token' => 'FooBaR'],
1303
+     *  ],
1304
+     *  public => bool
1305
+     *  mail => bool
1306
+     * ]
1307
+     *
1308
+     * The access list to '/folder1/folder2/fileA' **without** $currentAccess is:
1309
+     * [
1310
+     *  users  => ['user1', 'user2', 'user4'],
1311
+     *  remote => bool,
1312
+     *  public => bool
1313
+     *  mail => bool
1314
+     * ]
1315
+     *
1316
+     * This is required for encryption/activity
1317
+     *
1318
+     * @param \OCP\Files\Node $path
1319
+     * @param bool $recursive Should we check all parent folders as well
1320
+     * @param bool $currentAccess Should the user have currently access to the file
1321
+     * @return array
1322
+     */
1323
+    public function getAccessList(\OCP\Files\Node $path, $recursive = true, $currentAccess = false) {
1324
+        $owner = $path->getOwner()->getUID();
1325
+
1326
+        if ($currentAccess) {
1327
+            $al = ['users' => [], 'remote' => [], 'public' => false];
1328
+        } else {
1329
+            $al = ['users' => [], 'remote' => false, 'public' => false];
1330
+        }
1331
+        if (!$this->userManager->userExists($owner)) {
1332
+            return $al;
1333
+        }
1334
+
1335
+        //Get node for the owner
1336
+        $userFolder = $this->rootFolder->getUserFolder($owner);
1337
+        if ($path->getId() !== $userFolder->getId() && !$userFolder->isSubNode($path)) {
1338
+            $path = $userFolder->getById($path->getId())[0];
1339
+        }
1340
+
1341
+        $providers = $this->factory->getAllProviders();
1342
+
1343
+        /** @var Node[] $nodes */
1344
+        $nodes = [];
1345
+
1346
+
1347
+        if ($currentAccess) {
1348
+            $ownerPath = $path->getPath();
1349
+            $ownerPath = explode('/', $ownerPath, 4);
1350
+            if (count($ownerPath) < 4) {
1351
+                $ownerPath = '';
1352
+            } else {
1353
+                $ownerPath = $ownerPath[3];
1354
+            }
1355
+            $al['users'][$owner] = [
1356
+                'node_id' => $path->getId(),
1357
+                'node_path' => '/' . $ownerPath,
1358
+            ];
1359
+        } else {
1360
+            $al['users'][] = $owner;
1361
+        }
1362
+
1363
+        // Collect all the shares
1364
+        while ($path->getPath() !== $userFolder->getPath()) {
1365
+            $nodes[] = $path;
1366
+            if (!$recursive) {
1367
+                break;
1368
+            }
1369
+            $path = $path->getParent();
1370
+        }
1371
+
1372
+        foreach ($providers as $provider) {
1373
+            $tmp = $provider->getAccessList($nodes, $currentAccess);
1374
+
1375
+            foreach ($tmp as $k => $v) {
1376
+                if (isset($al[$k])) {
1377
+                    if (is_array($al[$k])) {
1378
+                        $al[$k] = array_merge($al[$k], $v);
1379
+                    } else {
1380
+                        $al[$k] = $al[$k] || $v;
1381
+                    }
1382
+                } else {
1383
+                    $al[$k] = $v;
1384
+                }
1385
+            }
1386
+        }
1387
+
1388
+        return $al;
1389
+    }
1390
+
1391
+    /**
1392
+     * Create a new share
1393
+     * @return \OCP\Share\IShare;
1394
+     */
1395
+    public function newShare() {
1396
+        return new \OC\Share20\Share($this->rootFolder, $this->userManager);
1397
+    }
1398
+
1399
+    /**
1400
+     * Is the share API enabled
1401
+     *
1402
+     * @return bool
1403
+     */
1404
+    public function shareApiEnabled() {
1405
+        return $this->config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes';
1406
+    }
1407
+
1408
+    /**
1409
+     * Is public link sharing enabled
1410
+     *
1411
+     * @return bool
1412
+     */
1413
+    public function shareApiAllowLinks() {
1414
+        return $this->config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes';
1415
+    }
1416
+
1417
+    /**
1418
+     * Is password on public link requires
1419
+     *
1420
+     * @return bool
1421
+     */
1422
+    public function shareApiLinkEnforcePassword() {
1423
+        return $this->config->getAppValue('core', 'shareapi_enforce_links_password', 'no') === 'yes';
1424
+    }
1425
+
1426
+    /**
1427
+     * Is default expire date enabled
1428
+     *
1429
+     * @return bool
1430
+     */
1431
+    public function shareApiLinkDefaultExpireDate() {
1432
+        return $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes';
1433
+    }
1434
+
1435
+    /**
1436
+     * Is default expire date enforced
1437
+     *`
1438
+     * @return bool
1439
+     */
1440
+    public function shareApiLinkDefaultExpireDateEnforced() {
1441
+        return $this->shareApiLinkDefaultExpireDate() &&
1442
+            $this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes';
1443
+    }
1444
+
1445
+    /**
1446
+     * Number of default expire days
1447
+     *shareApiLinkAllowPublicUpload
1448
+     * @return int
1449
+     */
1450
+    public function shareApiLinkDefaultExpireDays() {
1451
+        return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1452
+    }
1453
+
1454
+    /**
1455
+     * Allow public upload on link shares
1456
+     *
1457
+     * @return bool
1458
+     */
1459
+    public function shareApiLinkAllowPublicUpload() {
1460
+        return $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') === 'yes';
1461
+    }
1462
+
1463
+    /**
1464
+     * check if user can only share with group members
1465
+     * @return bool
1466
+     */
1467
+    public function shareWithGroupMembersOnly() {
1468
+        return $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
1469
+    }
1470
+
1471
+    /**
1472
+     * Check if users can share with groups
1473
+     * @return bool
1474
+     */
1475
+    public function allowGroupSharing() {
1476
+        return $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes';
1477
+    }
1478
+
1479
+    /**
1480
+     * Copied from \OC_Util::isSharingDisabledForUser
1481
+     *
1482
+     * TODO: Deprecate fuction from OC_Util
1483
+     *
1484
+     * @param string $userId
1485
+     * @return bool
1486
+     */
1487
+    public function sharingDisabledForUser($userId) {
1488
+        if ($userId === null) {
1489
+            return false;
1490
+        }
1491
+
1492
+        if (isset($this->sharingDisabledForUsersCache[$userId])) {
1493
+            return $this->sharingDisabledForUsersCache[$userId];
1494
+        }
1495
+
1496
+        if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
1497
+            $groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1498
+            $excludedGroups = json_decode($groupsList);
1499
+            if (is_null($excludedGroups)) {
1500
+                $excludedGroups = explode(',', $groupsList);
1501
+                $newValue = json_encode($excludedGroups);
1502
+                $this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
1503
+            }
1504
+            $user = $this->userManager->get($userId);
1505
+            $usersGroups = $this->groupManager->getUserGroupIds($user);
1506
+            if (!empty($usersGroups)) {
1507
+                $remainingGroups = array_diff($usersGroups, $excludedGroups);
1508
+                // if the user is only in groups which are disabled for sharing then
1509
+                // sharing is also disabled for the user
1510
+                if (empty($remainingGroups)) {
1511
+                    $this->sharingDisabledForUsersCache[$userId] = true;
1512
+                    return true;
1513
+                }
1514
+            }
1515
+        }
1516
+
1517
+        $this->sharingDisabledForUsersCache[$userId] = false;
1518
+        return false;
1519
+    }
1520
+
1521
+    /**
1522
+     * @inheritdoc
1523
+     */
1524
+    public function outgoingServer2ServerSharesAllowed() {
1525
+        return $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes';
1526
+    }
1527
+
1528
+    /**
1529
+     * @inheritdoc
1530
+     */
1531
+    public function shareProviderExists($shareType) {
1532
+        try {
1533
+            $this->factory->getProviderForType($shareType);
1534
+        } catch (ProviderException $e) {
1535
+            return false;
1536
+        }
1537
+
1538
+        return true;
1539
+    }
1540 1540
 
1541 1541
 }
Please login to merge, or discard this patch.
lib/private/Mail/EMailTemplate.php 1 patch
Indentation   +341 added lines, -341 removed lines patch added patch discarded remove patch
@@ -39,33 +39,33 @@  discard block
 block discarded – undo
39 39
  * @package OC\Mail
40 40
  */
41 41
 class EMailTemplate implements IEMailTemplate {
42
-	/** @var Defaults */
43
-	protected $themingDefaults;
44
-	/** @var IURLGenerator */
45
-	protected $urlGenerator;
46
-	/** @var IL10N */
47
-	protected $l10n;
48
-	/** @var string */
49
-	protected $emailId;
50
-	/** @var array */
51
-	protected $data;
52
-
53
-	/** @var string */
54
-	protected $subject = '';
55
-	/** @var string */
56
-	protected $htmlBody = '';
57
-	/** @var string */
58
-	protected $plainBody = '';
59
-	/** @var bool indicated if the footer is added */
60
-	protected $headerAdded = false;
61
-	/** @var bool indicated if the body is already opened */
62
-	protected $bodyOpened = false;
63
-	/** @var bool indicated if there is a list open in the body */
64
-	protected $bodyListOpened = false;
65
-	/** @var bool indicated if the footer is added */
66
-	protected $footerAdded = false;
67
-
68
-	protected $head = <<<EOF
42
+    /** @var Defaults */
43
+    protected $themingDefaults;
44
+    /** @var IURLGenerator */
45
+    protected $urlGenerator;
46
+    /** @var IL10N */
47
+    protected $l10n;
48
+    /** @var string */
49
+    protected $emailId;
50
+    /** @var array */
51
+    protected $data;
52
+
53
+    /** @var string */
54
+    protected $subject = '';
55
+    /** @var string */
56
+    protected $htmlBody = '';
57
+    /** @var string */
58
+    protected $plainBody = '';
59
+    /** @var bool indicated if the footer is added */
60
+    protected $headerAdded = false;
61
+    /** @var bool indicated if the body is already opened */
62
+    protected $bodyOpened = false;
63
+    /** @var bool indicated if there is a list open in the body */
64
+    protected $bodyListOpened = false;
65
+    /** @var bool indicated if the footer is added */
66
+    protected $footerAdded = false;
67
+
68
+    protected $head = <<<EOF
69 69
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
70 70
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" style="-webkit-font-smoothing:antialiased;background:#f3f3f3!important">
71 71
 <head>
@@ -83,7 +83,7 @@  discard block
 block discarded – undo
83 83
 				<center data-parsed="" style="min-width:580px;width:100%">
84 84
 EOF;
85 85
 
86
-	protected $tail = <<<EOF
86
+    protected $tail = <<<EOF
87 87
 					</center>
88 88
 				</td>
89 89
 			</tr>
@@ -94,7 +94,7 @@  discard block
 block discarded – undo
94 94
 </html>
95 95
 EOF;
96 96
 
97
-	protected $header = <<<EOF
97
+    protected $header = <<<EOF
98 98
 <table align="center" class="wrapper header float-center" style="Margin:0 auto;background:#8a8a8a;background-color:%s;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%%">
99 99
 	<tr style="padding:0;text-align:left;vertical-align:top">
100 100
 		<td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:20px;text-align:left;vertical-align:top;word-wrap:break-word">
@@ -127,7 +127,7 @@  discard block
 block discarded – undo
127 127
 </table>
128 128
 EOF;
129 129
 
130
-	protected $heading = <<<EOF
130
+    protected $heading = <<<EOF
131 131
 <table align="center" class="container main-heading float-center" style="Margin:0 auto;background:0 0!important;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:580px">
132 132
 	<tbody>
133 133
 	<tr style="padding:0;text-align:left;vertical-align:top">
@@ -146,7 +146,7 @@  discard block
 block discarded – undo
146 146
 </table>
147 147
 EOF;
148 148
 
149
-	protected $bodyBegin = <<<EOF
149
+    protected $bodyBegin = <<<EOF
150 150
 <table align="center" class="wrapper content float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
151 151
 	<tr style="padding:0;text-align:left;vertical-align:top">
152 152
 		<td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
@@ -163,7 +163,7 @@  discard block
 block discarded – undo
163 163
 						</table>
164 164
 EOF;
165 165
 
166
-	protected $bodyText = <<<EOF
166
+    protected $bodyText = <<<EOF
167 167
 <table class="row description" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%%">
168 168
 	<tbody>
169 169
 	<tr style="padding:0;text-align:left;vertical-align:top">
@@ -182,7 +182,7 @@  discard block
 block discarded – undo
182 182
 </table>
183 183
 EOF;
184 184
 
185
-	protected $listBegin = <<<EOF
185
+    protected $listBegin = <<<EOF
186 186
 <table class="row description" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%%">
187 187
 	<tbody>
188 188
 	<tr style="padding:0;text-align:left;vertical-align:top">
@@ -190,7 +190,7 @@  discard block
 block discarded – undo
190 190
 			<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
191 191
 EOF;
192 192
 
193
-	protected $listItem = <<<EOF
193
+    protected $listItem = <<<EOF
194 194
 				<tr style="padding:0;text-align:left;vertical-align:top">
195 195
 					<td style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left;width:15px;">
196 196
 						<p class="text-left" style="Margin:0;Margin-bottom:10px;color:#777;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;padding-left:10px;text-align:left">%s</p>
@@ -202,7 +202,7 @@  discard block
 block discarded – undo
202 202
 				</tr>
203 203
 EOF;
204 204
 
205
-	protected $listEnd = <<<EOF
205
+    protected $listEnd = <<<EOF
206 206
 			</table>
207 207
 		</th>
208 208
 	</tr>
@@ -210,7 +210,7 @@  discard block
 block discarded – undo
210 210
 </table>
211 211
 EOF;
212 212
 
213
-	protected $buttonGroup = <<<EOF
213
+    protected $buttonGroup = <<<EOF
214 214
 <table class="spacer" style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
215 215
 	<tbody>
216 216
 	<tr style="padding:0;text-align:left;vertical-align:top">
@@ -263,7 +263,7 @@  discard block
 block discarded – undo
263 263
 </table>
264 264
 EOF;
265 265
 
266
-	protected $button = <<<EOF
266
+    protected $button = <<<EOF
267 267
 <table class="spacer" style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
268 268
 	<tbody>
269 269
 	<tr style="padding:0;text-align:left;vertical-align:top">
@@ -303,7 +303,7 @@  discard block
 block discarded – undo
303 303
 </table>
304 304
 EOF;
305 305
 
306
-	protected $bodyEnd = <<<EOF
306
+    protected $bodyEnd = <<<EOF
307 307
 
308 308
 					</td>
309 309
 				</tr>
@@ -314,7 +314,7 @@  discard block
 block discarded – undo
314 314
 </table>
315 315
 EOF;
316 316
 
317
-	protected $footer = <<<EOF
317
+    protected $footer = <<<EOF
318 318
 <table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%%">
319 319
 	<tbody>
320 320
 	<tr style="padding:0;text-align:left;vertical-align:top">
@@ -340,306 +340,306 @@  discard block
 block discarded – undo
340 340
 </table>
341 341
 EOF;
342 342
 
343
-	/**
344
-	 * @param Defaults $themingDefaults
345
-	 * @param IURLGenerator $urlGenerator
346
-	 * @param IL10N $l10n
347
-	 * @param string $emailId
348
-	 * @param array $data
349
-	 */
350
-	public function __construct(Defaults $themingDefaults,
351
-								IURLGenerator $urlGenerator,
352
-								IL10N $l10n,
353
-								$emailId,
354
-								array $data) {
355
-		$this->themingDefaults = $themingDefaults;
356
-		$this->urlGenerator = $urlGenerator;
357
-		$this->l10n = $l10n;
358
-		$this->htmlBody .= $this->head;
359
-		$this->emailId = $emailId;
360
-		$this->data = $data;
361
-	}
362
-
363
-	/**
364
-	 * Sets the subject of the email
365
-	 *
366
-	 * @param string $subject
367
-	 */
368
-	public function setSubject($subject) {
369
-		$this->subject = $subject;
370
-	}
371
-
372
-	/**
373
-	 * Adds a header to the email
374
-	 */
375
-	public function addHeader() {
376
-		if ($this->headerAdded) {
377
-			return;
378
-		}
379
-		$this->headerAdded = true;
380
-
381
-		$logoUrl = $this->urlGenerator->getAbsoluteURL($this->themingDefaults->getLogo(false));
382
-		$this->htmlBody .= vsprintf($this->header, [$this->themingDefaults->getColorPrimary(), $logoUrl, $this->themingDefaults->getName()]);
383
-	}
384
-
385
-	/**
386
-	 * Adds a heading to the email
387
-	 *
388
-	 * @param string $title
389
-	 * @param string|bool $plainTitle Title that is used in the plain text email
390
-	 *   if empty the $title is used, if false none will be used
391
-	 */
392
-	public function addHeading($title, $plainTitle = '') {
393
-		if ($this->footerAdded) {
394
-			return;
395
-		}
396
-		if ($plainTitle === '') {
397
-			$plainTitle = $title;
398
-		}
399
-
400
-		$this->htmlBody .= vsprintf($this->heading, [htmlspecialchars($title)]);
401
-		if ($plainTitle !== false) {
402
-			$this->plainBody .= $plainTitle . PHP_EOL . PHP_EOL;
403
-		}
404
-	}
405
-
406
-	/**
407
-	 * Open the HTML body when it is not already
408
-	 */
409
-	protected function ensureBodyIsOpened() {
410
-		if ($this->bodyOpened) {
411
-			return;
412
-		}
413
-
414
-		$this->htmlBody .= $this->bodyBegin;
415
-		$this->bodyOpened = true;
416
-	}
417
-
418
-	/**
419
-	 * Adds a paragraph to the body of the email
420
-	 *
421
-	 * @param string $text
422
-	 * @param string|bool $plainText Text that is used in the plain text email
423
-	 *   if empty the $text is used, if false none will be used
424
-	 */
425
-	public function addBodyText($text, $plainText = '') {
426
-		if ($this->footerAdded) {
427
-			return;
428
-		}
429
-		if ($plainText === '') {
430
-			$plainText = $text;
431
-		}
432
-
433
-		$this->ensureBodyIsOpened();
434
-
435
-		$this->htmlBody .= vsprintf($this->bodyText, [htmlspecialchars($text)]);
436
-		if ($plainText !== false) {
437
-			$this->plainBody .= $plainText . PHP_EOL . PHP_EOL;
438
-		}
439
-	}
440
-
441
-	/**
442
-	 * Adds a list item to the body of the email
443
-	 *
444
-	 * @param string $text
445
-	 * @param string $metaInfo
446
-	 * @param string $icon Absolute path, must be 16*16 pixels
447
-	 * @param string $plainText Text that is used in the plain text email
448
-	 *   if empty the $text is used, if false none will be used
449
-	 * @param string $plainMetaInfo Meta info that is used in the plain text email
450
-	 *   if empty the $metaInfo is used, if false none will be used
451
-	 * @since 12.0.0
452
-	 */
453
-	public function addBodyListItem($text, $metaInfo = '', $icon = '', $plainText = '', $plainMetaInfo = '') {
454
-		$this->ensureBodyListOpened();
455
-
456
-		if ($plainText === '') {
457
-			$plainText = $text;
458
-		}
459
-		if ($plainMetaInfo === '') {
460
-			$plainMetaInfo = $metaInfo;
461
-		}
462
-
463
-		$htmlText = htmlspecialchars($text);
464
-		if ($metaInfo) {
465
-			$htmlText = '<em style="color:#777;">' . htmlspecialchars($metaInfo) . '</em><br>' . $htmlText;
466
-		}
467
-		if ($icon !== '') {
468
-			$icon = '<img src="' . htmlspecialchars($icon) . '" alt="&bull;">';
469
-		} else {
470
-			$icon = '&bull;';
471
-		}
472
-		$this->htmlBody .= vsprintf($this->listItem, [$icon, $htmlText]);
473
-		if ($plainText !== false) {
474
-			$this->plainBody .= '  * ' . $plainText;
475
-			if ($plainMetaInfo !== false) {
476
-				$this->plainBody .= ' (' . $plainMetaInfo . ')';
477
-			}
478
-			$this->plainBody .= PHP_EOL;
479
-		}
480
-	}
481
-
482
-	protected function ensureBodyListOpened() {
483
-		if ($this->bodyListOpened) {
484
-			return;
485
-		}
486
-
487
-		$this->ensureBodyIsOpened();
488
-		$this->bodyListOpened = true;
489
-		$this->htmlBody .= $this->listBegin;
490
-	}
491
-
492
-	protected function ensureBodyListClosed() {
493
-		if (!$this->bodyListOpened) {
494
-			return;
495
-		}
496
-
497
-		$this->bodyListOpened = false;
498
-		$this->htmlBody .= $this->listEnd;
499
-	}
500
-
501
-	/**
502
-	 * Adds a button group of two buttons to the body of the email
503
-	 *
504
-	 * @param string $textLeft Text of left button
505
-	 * @param string $urlLeft URL of left button
506
-	 * @param string $textRight Text of right button
507
-	 * @param string $urlRight URL of right button
508
-	 * @param string $plainTextLeft Text of left button that is used in the plain text version - if unset the $textLeft is used
509
-	 * @param string $plainTextRight Text of right button that is used in the plain text version - if unset the $textRight is used
510
-	 */
511
-	public function addBodyButtonGroup($textLeft,
512
-									   $urlLeft,
513
-									   $textRight,
514
-									   $urlRight,
515
-									   $plainTextLeft = '',
516
-									   $plainTextRight = '') {
517
-		if ($this->footerAdded) {
518
-			return;
519
-		}
520
-		if ($plainTextLeft === '') {
521
-			$plainTextLeft = $textLeft;
522
-		}
523
-
524
-		if ($plainTextRight === '') {
525
-			$plainTextRight = $textRight;
526
-		}
527
-
528
-		$this->ensureBodyIsOpened();
529
-		$this->ensureBodyListClosed();
530
-
531
-		$color = $this->themingDefaults->getColorPrimary();
532
-
533
-		$this->htmlBody .= vsprintf($this->buttonGroup, [$color, $color, $urlLeft, $color, htmlspecialchars($textLeft), $urlRight, htmlspecialchars($textRight)]);
534
-		$this->plainBody .= $plainTextLeft . ': ' . $urlLeft . PHP_EOL;
535
-		$this->plainBody .= $plainTextRight . ': ' . $urlRight . PHP_EOL . PHP_EOL;
536
-
537
-	}
538
-
539
-	/**
540
-	 * Adds a button to the body of the email
541
-	 *
542
-	 * @param string $text Text of button
543
-	 * @param string $url URL of button
544
-	 * @param string $plainText Text of button in plain text version
545
-	 * 		if empty the $text is used, if false none will be used
546
-	 *
547
-	 * @since 12.0.0
548
-	 */
549
-	public function addBodyButton($text, $url, $plainText = '') {
550
-		if ($this->footerAdded) {
551
-			return;
552
-		}
553
-
554
-		$this->ensureBodyIsOpened();
555
-		$this->ensureBodyListClosed();
556
-
557
-		if ($plainText === '') {
558
-			$plainText = $text;
559
-		}
560
-
561
-		$color = $this->themingDefaults->getColorPrimary();
562
-		$this->htmlBody .= vsprintf($this->button, [$color, $color, $url, $color, htmlspecialchars($text)]);
563
-
564
-		if ($plainText !== false) {
565
-			$this->plainBody .= $plainText . ': ';
566
-		}
567
-
568
-		$this->plainBody .=  $url . PHP_EOL;
569
-
570
-	}
571
-
572
-	/**
573
-	 * Close the HTML body when it is open
574
-	 */
575
-	protected function ensureBodyIsClosed() {
576
-		if (!$this->bodyOpened) {
577
-			return;
578
-		}
579
-
580
-		$this->ensureBodyListClosed();
581
-
582
-		$this->htmlBody .= $this->bodyEnd;
583
-		$this->bodyOpened = false;
584
-	}
585
-
586
-	/**
587
-	 * Adds a logo and a text to the footer. <br> in the text will be replaced by new lines in the plain text email
588
-	 *
589
-	 * @param string $text If the text is empty the default "Name - Slogan<br>This is an automatically sent email" will be used
590
-	 */
591
-	public function addFooter($text = '') {
592
-		if($text === '') {
593
-			$text = $this->themingDefaults->getName() . ' - ' . $this->themingDefaults->getSlogan() . '<br>' . $this->l10n->t('This is an automatically sent email, please do not reply.');
594
-		}
595
-
596
-		if ($this->footerAdded) {
597
-			return;
598
-		}
599
-		$this->footerAdded = true;
600
-
601
-		$this->ensureBodyIsClosed();
602
-
603
-		$this->htmlBody .= vsprintf($this->footer, [$text]);
604
-		$this->htmlBody .= $this->tail;
605
-		$this->plainBody .= PHP_EOL . '-- ' . PHP_EOL;
606
-		$this->plainBody .= str_replace('<br>', PHP_EOL, $text);
607
-	}
608
-
609
-	/**
610
-	 * Returns the rendered email subject as string
611
-	 *
612
-	 * @return string
613
-	 */
614
-	public function renderSubject() {
615
-		return $this->subject;
616
-	}
617
-
618
-	/**
619
-	 * Returns the rendered HTML email as string
620
-	 *
621
-	 * @return string
622
-	 */
623
-	public function renderHtml() {
624
-		if (!$this->footerAdded) {
625
-			$this->footerAdded = true;
626
-			$this->ensureBodyIsClosed();
627
-			$this->htmlBody .= $this->tail;
628
-		}
629
-		return $this->htmlBody;
630
-	}
631
-
632
-	/**
633
-	 * Returns the rendered plain text email as string
634
-	 *
635
-	 * @return string
636
-	 */
637
-	public function renderText() {
638
-		if (!$this->footerAdded) {
639
-			$this->footerAdded = true;
640
-			$this->ensureBodyIsClosed();
641
-			$this->htmlBody .= $this->tail;
642
-		}
643
-		return $this->plainBody;
644
-	}
343
+    /**
344
+     * @param Defaults $themingDefaults
345
+     * @param IURLGenerator $urlGenerator
346
+     * @param IL10N $l10n
347
+     * @param string $emailId
348
+     * @param array $data
349
+     */
350
+    public function __construct(Defaults $themingDefaults,
351
+                                IURLGenerator $urlGenerator,
352
+                                IL10N $l10n,
353
+                                $emailId,
354
+                                array $data) {
355
+        $this->themingDefaults = $themingDefaults;
356
+        $this->urlGenerator = $urlGenerator;
357
+        $this->l10n = $l10n;
358
+        $this->htmlBody .= $this->head;
359
+        $this->emailId = $emailId;
360
+        $this->data = $data;
361
+    }
362
+
363
+    /**
364
+     * Sets the subject of the email
365
+     *
366
+     * @param string $subject
367
+     */
368
+    public function setSubject($subject) {
369
+        $this->subject = $subject;
370
+    }
371
+
372
+    /**
373
+     * Adds a header to the email
374
+     */
375
+    public function addHeader() {
376
+        if ($this->headerAdded) {
377
+            return;
378
+        }
379
+        $this->headerAdded = true;
380
+
381
+        $logoUrl = $this->urlGenerator->getAbsoluteURL($this->themingDefaults->getLogo(false));
382
+        $this->htmlBody .= vsprintf($this->header, [$this->themingDefaults->getColorPrimary(), $logoUrl, $this->themingDefaults->getName()]);
383
+    }
384
+
385
+    /**
386
+     * Adds a heading to the email
387
+     *
388
+     * @param string $title
389
+     * @param string|bool $plainTitle Title that is used in the plain text email
390
+     *   if empty the $title is used, if false none will be used
391
+     */
392
+    public function addHeading($title, $plainTitle = '') {
393
+        if ($this->footerAdded) {
394
+            return;
395
+        }
396
+        if ($plainTitle === '') {
397
+            $plainTitle = $title;
398
+        }
399
+
400
+        $this->htmlBody .= vsprintf($this->heading, [htmlspecialchars($title)]);
401
+        if ($plainTitle !== false) {
402
+            $this->plainBody .= $plainTitle . PHP_EOL . PHP_EOL;
403
+        }
404
+    }
405
+
406
+    /**
407
+     * Open the HTML body when it is not already
408
+     */
409
+    protected function ensureBodyIsOpened() {
410
+        if ($this->bodyOpened) {
411
+            return;
412
+        }
413
+
414
+        $this->htmlBody .= $this->bodyBegin;
415
+        $this->bodyOpened = true;
416
+    }
417
+
418
+    /**
419
+     * Adds a paragraph to the body of the email
420
+     *
421
+     * @param string $text
422
+     * @param string|bool $plainText Text that is used in the plain text email
423
+     *   if empty the $text is used, if false none will be used
424
+     */
425
+    public function addBodyText($text, $plainText = '') {
426
+        if ($this->footerAdded) {
427
+            return;
428
+        }
429
+        if ($plainText === '') {
430
+            $plainText = $text;
431
+        }
432
+
433
+        $this->ensureBodyIsOpened();
434
+
435
+        $this->htmlBody .= vsprintf($this->bodyText, [htmlspecialchars($text)]);
436
+        if ($plainText !== false) {
437
+            $this->plainBody .= $plainText . PHP_EOL . PHP_EOL;
438
+        }
439
+    }
440
+
441
+    /**
442
+     * Adds a list item to the body of the email
443
+     *
444
+     * @param string $text
445
+     * @param string $metaInfo
446
+     * @param string $icon Absolute path, must be 16*16 pixels
447
+     * @param string $plainText Text that is used in the plain text email
448
+     *   if empty the $text is used, if false none will be used
449
+     * @param string $plainMetaInfo Meta info that is used in the plain text email
450
+     *   if empty the $metaInfo is used, if false none will be used
451
+     * @since 12.0.0
452
+     */
453
+    public function addBodyListItem($text, $metaInfo = '', $icon = '', $plainText = '', $plainMetaInfo = '') {
454
+        $this->ensureBodyListOpened();
455
+
456
+        if ($plainText === '') {
457
+            $plainText = $text;
458
+        }
459
+        if ($plainMetaInfo === '') {
460
+            $plainMetaInfo = $metaInfo;
461
+        }
462
+
463
+        $htmlText = htmlspecialchars($text);
464
+        if ($metaInfo) {
465
+            $htmlText = '<em style="color:#777;">' . htmlspecialchars($metaInfo) . '</em><br>' . $htmlText;
466
+        }
467
+        if ($icon !== '') {
468
+            $icon = '<img src="' . htmlspecialchars($icon) . '" alt="&bull;">';
469
+        } else {
470
+            $icon = '&bull;';
471
+        }
472
+        $this->htmlBody .= vsprintf($this->listItem, [$icon, $htmlText]);
473
+        if ($plainText !== false) {
474
+            $this->plainBody .= '  * ' . $plainText;
475
+            if ($plainMetaInfo !== false) {
476
+                $this->plainBody .= ' (' . $plainMetaInfo . ')';
477
+            }
478
+            $this->plainBody .= PHP_EOL;
479
+        }
480
+    }
481
+
482
+    protected function ensureBodyListOpened() {
483
+        if ($this->bodyListOpened) {
484
+            return;
485
+        }
486
+
487
+        $this->ensureBodyIsOpened();
488
+        $this->bodyListOpened = true;
489
+        $this->htmlBody .= $this->listBegin;
490
+    }
491
+
492
+    protected function ensureBodyListClosed() {
493
+        if (!$this->bodyListOpened) {
494
+            return;
495
+        }
496
+
497
+        $this->bodyListOpened = false;
498
+        $this->htmlBody .= $this->listEnd;
499
+    }
500
+
501
+    /**
502
+     * Adds a button group of two buttons to the body of the email
503
+     *
504
+     * @param string $textLeft Text of left button
505
+     * @param string $urlLeft URL of left button
506
+     * @param string $textRight Text of right button
507
+     * @param string $urlRight URL of right button
508
+     * @param string $plainTextLeft Text of left button that is used in the plain text version - if unset the $textLeft is used
509
+     * @param string $plainTextRight Text of right button that is used in the plain text version - if unset the $textRight is used
510
+     */
511
+    public function addBodyButtonGroup($textLeft,
512
+                                        $urlLeft,
513
+                                        $textRight,
514
+                                        $urlRight,
515
+                                        $plainTextLeft = '',
516
+                                        $plainTextRight = '') {
517
+        if ($this->footerAdded) {
518
+            return;
519
+        }
520
+        if ($plainTextLeft === '') {
521
+            $plainTextLeft = $textLeft;
522
+        }
523
+
524
+        if ($plainTextRight === '') {
525
+            $plainTextRight = $textRight;
526
+        }
527
+
528
+        $this->ensureBodyIsOpened();
529
+        $this->ensureBodyListClosed();
530
+
531
+        $color = $this->themingDefaults->getColorPrimary();
532
+
533
+        $this->htmlBody .= vsprintf($this->buttonGroup, [$color, $color, $urlLeft, $color, htmlspecialchars($textLeft), $urlRight, htmlspecialchars($textRight)]);
534
+        $this->plainBody .= $plainTextLeft . ': ' . $urlLeft . PHP_EOL;
535
+        $this->plainBody .= $plainTextRight . ': ' . $urlRight . PHP_EOL . PHP_EOL;
536
+
537
+    }
538
+
539
+    /**
540
+     * Adds a button to the body of the email
541
+     *
542
+     * @param string $text Text of button
543
+     * @param string $url URL of button
544
+     * @param string $plainText Text of button in plain text version
545
+     * 		if empty the $text is used, if false none will be used
546
+     *
547
+     * @since 12.0.0
548
+     */
549
+    public function addBodyButton($text, $url, $plainText = '') {
550
+        if ($this->footerAdded) {
551
+            return;
552
+        }
553
+
554
+        $this->ensureBodyIsOpened();
555
+        $this->ensureBodyListClosed();
556
+
557
+        if ($plainText === '') {
558
+            $plainText = $text;
559
+        }
560
+
561
+        $color = $this->themingDefaults->getColorPrimary();
562
+        $this->htmlBody .= vsprintf($this->button, [$color, $color, $url, $color, htmlspecialchars($text)]);
563
+
564
+        if ($plainText !== false) {
565
+            $this->plainBody .= $plainText . ': ';
566
+        }
567
+
568
+        $this->plainBody .=  $url . PHP_EOL;
569
+
570
+    }
571
+
572
+    /**
573
+     * Close the HTML body when it is open
574
+     */
575
+    protected function ensureBodyIsClosed() {
576
+        if (!$this->bodyOpened) {
577
+            return;
578
+        }
579
+
580
+        $this->ensureBodyListClosed();
581
+
582
+        $this->htmlBody .= $this->bodyEnd;
583
+        $this->bodyOpened = false;
584
+    }
585
+
586
+    /**
587
+     * Adds a logo and a text to the footer. <br> in the text will be replaced by new lines in the plain text email
588
+     *
589
+     * @param string $text If the text is empty the default "Name - Slogan<br>This is an automatically sent email" will be used
590
+     */
591
+    public function addFooter($text = '') {
592
+        if($text === '') {
593
+            $text = $this->themingDefaults->getName() . ' - ' . $this->themingDefaults->getSlogan() . '<br>' . $this->l10n->t('This is an automatically sent email, please do not reply.');
594
+        }
595
+
596
+        if ($this->footerAdded) {
597
+            return;
598
+        }
599
+        $this->footerAdded = true;
600
+
601
+        $this->ensureBodyIsClosed();
602
+
603
+        $this->htmlBody .= vsprintf($this->footer, [$text]);
604
+        $this->htmlBody .= $this->tail;
605
+        $this->plainBody .= PHP_EOL . '-- ' . PHP_EOL;
606
+        $this->plainBody .= str_replace('<br>', PHP_EOL, $text);
607
+    }
608
+
609
+    /**
610
+     * Returns the rendered email subject as string
611
+     *
612
+     * @return string
613
+     */
614
+    public function renderSubject() {
615
+        return $this->subject;
616
+    }
617
+
618
+    /**
619
+     * Returns the rendered HTML email as string
620
+     *
621
+     * @return string
622
+     */
623
+    public function renderHtml() {
624
+        if (!$this->footerAdded) {
625
+            $this->footerAdded = true;
626
+            $this->ensureBodyIsClosed();
627
+            $this->htmlBody .= $this->tail;
628
+        }
629
+        return $this->htmlBody;
630
+    }
631
+
632
+    /**
633
+     * Returns the rendered plain text email as string
634
+     *
635
+     * @return string
636
+     */
637
+    public function renderText() {
638
+        if (!$this->footerAdded) {
639
+            $this->footerAdded = true;
640
+            $this->ensureBodyIsClosed();
641
+            $this->htmlBody .= $this->tail;
642
+        }
643
+        return $this->plainBody;
644
+    }
645 645
 }
Please login to merge, or discard this patch.
lib/private/Mail/Message.php 1 patch
Indentation   +202 added lines, -202 removed lines patch added patch discarded remove patch
@@ -33,234 +33,234 @@
 block discarded – undo
33 33
  * @package OC\Mail
34 34
  */
35 35
 class Message implements IMessage {
36
-	/** @var Swift_Message */
37
-	private $swiftMessage;
36
+    /** @var Swift_Message */
37
+    private $swiftMessage;
38 38
 
39
-	/**
40
-	 * @param Swift_Message $swiftMessage
41
-	 */
42
-	public function __construct(Swift_Message $swiftMessage) {
43
-		$this->swiftMessage = $swiftMessage;
44
-	}
39
+    /**
40
+     * @param Swift_Message $swiftMessage
41
+     */
42
+    public function __construct(Swift_Message $swiftMessage) {
43
+        $this->swiftMessage = $swiftMessage;
44
+    }
45 45
 
46
-	/**
47
-	 * SwiftMailer does currently not work with IDN domains, this function therefore converts the domains
48
-	 * FIXME: Remove this once SwiftMailer supports IDN
49
-	 *
50
-	 * @param array $addresses Array of mail addresses, key will get converted
51
-	 * @return array Converted addresses if `idn_to_ascii` exists
52
-	 */
53
-	protected function convertAddresses($addresses) {
54
-		if (!function_exists('idn_to_ascii')) {
55
-			return $addresses;
56
-		}
46
+    /**
47
+     * SwiftMailer does currently not work with IDN domains, this function therefore converts the domains
48
+     * FIXME: Remove this once SwiftMailer supports IDN
49
+     *
50
+     * @param array $addresses Array of mail addresses, key will get converted
51
+     * @return array Converted addresses if `idn_to_ascii` exists
52
+     */
53
+    protected function convertAddresses($addresses) {
54
+        if (!function_exists('idn_to_ascii')) {
55
+            return $addresses;
56
+        }
57 57
 
58
-		$convertedAddresses = array();
58
+        $convertedAddresses = array();
59 59
 
60
-		foreach($addresses as $email => $readableName) {
61
-			if(!is_numeric($email)) {
62
-				list($name, $domain) = explode('@', $email, 2);
63
-				$domain = idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46);
64
-				$convertedAddresses[$name.'@'.$domain] = $readableName;
65
-			} else {
66
-				list($name, $domain) = explode('@', $readableName, 2);
67
-				$domain = idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46);
68
-				$convertedAddresses[$email] = $name.'@'.$domain;
69
-			}
70
-		}
60
+        foreach($addresses as $email => $readableName) {
61
+            if(!is_numeric($email)) {
62
+                list($name, $domain) = explode('@', $email, 2);
63
+                $domain = idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46);
64
+                $convertedAddresses[$name.'@'.$domain] = $readableName;
65
+            } else {
66
+                list($name, $domain) = explode('@', $readableName, 2);
67
+                $domain = idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46);
68
+                $convertedAddresses[$email] = $name.'@'.$domain;
69
+            }
70
+        }
71 71
 
72
-		return $convertedAddresses;
73
-	}
72
+        return $convertedAddresses;
73
+    }
74 74
 
75
-	/**
76
-	 * Set the from address of this message.
77
-	 *
78
-	 * If no "From" address is used \OC\Mail\Mailer will use mail_from_address and mail_domain from config.php
79
-	 *
80
-	 * @param array $addresses Example: array('[email protected]', '[email protected]' => 'A name')
81
-	 * @return $this
82
-	 */
83
-	public function setFrom(array $addresses) {
84
-		$addresses = $this->convertAddresses($addresses);
75
+    /**
76
+     * Set the from address of this message.
77
+     *
78
+     * If no "From" address is used \OC\Mail\Mailer will use mail_from_address and mail_domain from config.php
79
+     *
80
+     * @param array $addresses Example: array('[email protected]', '[email protected]' => 'A name')
81
+     * @return $this
82
+     */
83
+    public function setFrom(array $addresses) {
84
+        $addresses = $this->convertAddresses($addresses);
85 85
 
86
-		$this->swiftMessage->setFrom($addresses);
87
-		return $this;
88
-	}
86
+        $this->swiftMessage->setFrom($addresses);
87
+        return $this;
88
+    }
89 89
 
90
-	/**
91
-	 * Get the from address of this message.
92
-	 *
93
-	 * @return array
94
-	 */
95
-	public function getFrom() {
96
-		return $this->swiftMessage->getFrom();
97
-	}
90
+    /**
91
+     * Get the from address of this message.
92
+     *
93
+     * @return array
94
+     */
95
+    public function getFrom() {
96
+        return $this->swiftMessage->getFrom();
97
+    }
98 98
 
99
-	/**
100
-	 * Set the Reply-To address of this message
101
-	 *
102
-	 * @param array $addresses
103
-	 * @return $this
104
-	 */
105
-	public function setReplyTo(array $addresses) {
106
-		$addresses = $this->convertAddresses($addresses);
99
+    /**
100
+     * Set the Reply-To address of this message
101
+     *
102
+     * @param array $addresses
103
+     * @return $this
104
+     */
105
+    public function setReplyTo(array $addresses) {
106
+        $addresses = $this->convertAddresses($addresses);
107 107
 
108
-		$this->swiftMessage->setReplyTo($addresses);
109
-		return $this;
110
-	}
108
+        $this->swiftMessage->setReplyTo($addresses);
109
+        return $this;
110
+    }
111 111
 
112
-	/**
113
-	 * Returns the Reply-To address of this message
114
-	 *
115
-	 * @return array
116
-	 */
117
-	public function getReplyTo() {
118
-		return $this->swiftMessage->getReplyTo();
119
-	}
112
+    /**
113
+     * Returns the Reply-To address of this message
114
+     *
115
+     * @return array
116
+     */
117
+    public function getReplyTo() {
118
+        return $this->swiftMessage->getReplyTo();
119
+    }
120 120
 
121
-	/**
122
-	 * Set the to addresses of this message.
123
-	 *
124
-	 * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
125
-	 * @return $this
126
-	 */
127
-	public function setTo(array $recipients) {
128
-		$recipients = $this->convertAddresses($recipients);
121
+    /**
122
+     * Set the to addresses of this message.
123
+     *
124
+     * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
125
+     * @return $this
126
+     */
127
+    public function setTo(array $recipients) {
128
+        $recipients = $this->convertAddresses($recipients);
129 129
 
130
-		$this->swiftMessage->setTo($recipients);
131
-		return $this;
132
-	}
130
+        $this->swiftMessage->setTo($recipients);
131
+        return $this;
132
+    }
133 133
 
134
-	/**
135
-	 * Get the to address of this message.
136
-	 *
137
-	 * @return array
138
-	 */
139
-	public function getTo() {
140
-		return $this->swiftMessage->getTo();
141
-	}
134
+    /**
135
+     * Get the to address of this message.
136
+     *
137
+     * @return array
138
+     */
139
+    public function getTo() {
140
+        return $this->swiftMessage->getTo();
141
+    }
142 142
 
143
-	/**
144
-	 * Set the CC recipients of this message.
145
-	 *
146
-	 * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
147
-	 * @return $this
148
-	 */
149
-	public function setCc(array $recipients) {
150
-		$recipients = $this->convertAddresses($recipients);
143
+    /**
144
+     * Set the CC recipients of this message.
145
+     *
146
+     * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
147
+     * @return $this
148
+     */
149
+    public function setCc(array $recipients) {
150
+        $recipients = $this->convertAddresses($recipients);
151 151
 
152
-		$this->swiftMessage->setCc($recipients);
153
-		return $this;
154
-	}
152
+        $this->swiftMessage->setCc($recipients);
153
+        return $this;
154
+    }
155 155
 
156
-	/**
157
-	 * Get the cc address of this message.
158
-	 *
159
-	 * @return array
160
-	 */
161
-	public function getCc() {
162
-		return $this->swiftMessage->getCc();
163
-	}
156
+    /**
157
+     * Get the cc address of this message.
158
+     *
159
+     * @return array
160
+     */
161
+    public function getCc() {
162
+        return $this->swiftMessage->getCc();
163
+    }
164 164
 
165
-	/**
166
-	 * Set the BCC recipients of this message.
167
-	 *
168
-	 * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
169
-	 * @return $this
170
-	 */
171
-	public function setBcc(array $recipients) {
172
-		$recipients = $this->convertAddresses($recipients);
165
+    /**
166
+     * Set the BCC recipients of this message.
167
+     *
168
+     * @param array $recipients Example: array('[email protected]', '[email protected]' => 'A name')
169
+     * @return $this
170
+     */
171
+    public function setBcc(array $recipients) {
172
+        $recipients = $this->convertAddresses($recipients);
173 173
 
174
-		$this->swiftMessage->setBcc($recipients);
175
-		return $this;
176
-	}
174
+        $this->swiftMessage->setBcc($recipients);
175
+        return $this;
176
+    }
177 177
 
178
-	/**
179
-	 * Get the Bcc address of this message.
180
-	 *
181
-	 * @return array
182
-	 */
183
-	public function getBcc() {
184
-		return $this->swiftMessage->getBcc();
185
-	}
178
+    /**
179
+     * Get the Bcc address of this message.
180
+     *
181
+     * @return array
182
+     */
183
+    public function getBcc() {
184
+        return $this->swiftMessage->getBcc();
185
+    }
186 186
 
187
-	/**
188
-	 * Set the subject of this message.
189
-	 *
190
-	 * @param $subject
191
-	 * @return $this
192
-	 */
193
-	public function setSubject($subject) {
194
-		$this->swiftMessage->setSubject($subject);
195
-		return $this;
196
-	}
187
+    /**
188
+     * Set the subject of this message.
189
+     *
190
+     * @param $subject
191
+     * @return $this
192
+     */
193
+    public function setSubject($subject) {
194
+        $this->swiftMessage->setSubject($subject);
195
+        return $this;
196
+    }
197 197
 
198
-	/**
199
-	 * Get the from subject of this message.
200
-	 *
201
-	 * @return string
202
-	 */
203
-	public function getSubject() {
204
-		return $this->swiftMessage->getSubject();
205
-	}
198
+    /**
199
+     * Get the from subject of this message.
200
+     *
201
+     * @return string
202
+     */
203
+    public function getSubject() {
204
+        return $this->swiftMessage->getSubject();
205
+    }
206 206
 
207
-	/**
208
-	 * Set the plain-text body of this message.
209
-	 *
210
-	 * @param string $body
211
-	 * @return $this
212
-	 */
213
-	public function setPlainBody($body) {
214
-		$this->swiftMessage->setBody($body);
215
-		return $this;
216
-	}
207
+    /**
208
+     * Set the plain-text body of this message.
209
+     *
210
+     * @param string $body
211
+     * @return $this
212
+     */
213
+    public function setPlainBody($body) {
214
+        $this->swiftMessage->setBody($body);
215
+        return $this;
216
+    }
217 217
 
218
-	/**
219
-	 * Get the plain body of this message.
220
-	 *
221
-	 * @return string
222
-	 */
223
-	public function getPlainBody() {
224
-		return $this->swiftMessage->getBody();
225
-	}
218
+    /**
219
+     * Get the plain body of this message.
220
+     *
221
+     * @return string
222
+     */
223
+    public function getPlainBody() {
224
+        return $this->swiftMessage->getBody();
225
+    }
226 226
 
227
-	/**
228
-	 * Set the HTML body of this message. Consider also sending a plain-text body instead of only an HTML one.
229
-	 *
230
-	 * @param string $body
231
-	 * @return $this
232
-	 */
233
-	public function setHtmlBody($body) {
234
-		$this->swiftMessage->addPart($body, 'text/html');
235
-		return $this;
236
-	}
227
+    /**
228
+     * Set the HTML body of this message. Consider also sending a plain-text body instead of only an HTML one.
229
+     *
230
+     * @param string $body
231
+     * @return $this
232
+     */
233
+    public function setHtmlBody($body) {
234
+        $this->swiftMessage->addPart($body, 'text/html');
235
+        return $this;
236
+    }
237 237
 
238
-	/**
239
-	 * Get's the underlying SwiftMessage
240
-	 * @return Swift_Message
241
-	 */
242
-	public function getSwiftMessage() {
243
-		return $this->swiftMessage;
244
-	}
238
+    /**
239
+     * Get's the underlying SwiftMessage
240
+     * @return Swift_Message
241
+     */
242
+    public function getSwiftMessage() {
243
+        return $this->swiftMessage;
244
+    }
245 245
 
246
-	/**
247
-	 * @param string $body
248
-	 * @param string $contentType
249
-	 * @return $this
250
-	 */
251
-	public function setBody($body, $contentType) {
252
-		$this->swiftMessage->setBody($body, $contentType);
253
-		return $this;
254
-	}
246
+    /**
247
+     * @param string $body
248
+     * @param string $contentType
249
+     * @return $this
250
+     */
251
+    public function setBody($body, $contentType) {
252
+        $this->swiftMessage->setBody($body, $contentType);
253
+        return $this;
254
+    }
255 255
 
256
-	/**
257
-	 * @param IEMailTemplate $emailTemplate
258
-	 * @return $this
259
-	 */
260
-	public function setTemplate(IEMailTemplate $emailTemplate) {
261
-		$this->setSubject($emailTemplate->renderSubject());
262
-		$this->setPlainBody($emailTemplate->renderText());
263
-		$this->setHtmlBody($emailTemplate->renderHtml());
264
-		return $this;
265
-	}
256
+    /**
257
+     * @param IEMailTemplate $emailTemplate
258
+     * @return $this
259
+     */
260
+    public function setTemplate(IEMailTemplate $emailTemplate) {
261
+        $this->setSubject($emailTemplate->renderSubject());
262
+        $this->setPlainBody($emailTemplate->renderText());
263
+        $this->setHtmlBody($emailTemplate->renderHtml());
264
+        return $this;
265
+    }
266 266
 }
Please login to merge, or discard this patch.
lib/private/Mail/Mailer.php 1 patch
Indentation   +192 added lines, -192 removed lines patch added patch discarded remove patch
@@ -50,220 +50,220 @@
 block discarded – undo
50 50
  * @package OC\Mail
51 51
  */
52 52
 class Mailer implements IMailer {
53
-	/** @var \Swift_SmtpTransport|\Swift_SendmailTransport|\Swift_MailTransport Cached transport */
54
-	private $instance = null;
55
-	/** @var IConfig */
56
-	private $config;
57
-	/** @var ILogger */
58
-	private $logger;
59
-	/** @var Defaults */
60
-	private $defaults;
61
-	/** @var IURLGenerator */
62
-	private $urlGenerator;
63
-	/** @var IL10N */
64
-	private $l10n;
53
+    /** @var \Swift_SmtpTransport|\Swift_SendmailTransport|\Swift_MailTransport Cached transport */
54
+    private $instance = null;
55
+    /** @var IConfig */
56
+    private $config;
57
+    /** @var ILogger */
58
+    private $logger;
59
+    /** @var Defaults */
60
+    private $defaults;
61
+    /** @var IURLGenerator */
62
+    private $urlGenerator;
63
+    /** @var IL10N */
64
+    private $l10n;
65 65
 
66
-	/**
67
-	 * @param IConfig $config
68
-	 * @param ILogger $logger
69
-	 * @param Defaults $defaults
70
-	 * @param IURLGenerator $urlGenerator
71
-	 * @param IL10N $l10n
72
-	 */
73
-	public function __construct(IConfig $config,
74
-						 ILogger $logger,
75
-						 Defaults $defaults,
76
-						 IURLGenerator $urlGenerator,
77
-						 IL10N $l10n) {
78
-		$this->config = $config;
79
-		$this->logger = $logger;
80
-		$this->defaults = $defaults;
81
-		$this->urlGenerator = $urlGenerator;
82
-		$this->l10n = $l10n;
83
-	}
66
+    /**
67
+     * @param IConfig $config
68
+     * @param ILogger $logger
69
+     * @param Defaults $defaults
70
+     * @param IURLGenerator $urlGenerator
71
+     * @param IL10N $l10n
72
+     */
73
+    public function __construct(IConfig $config,
74
+                            ILogger $logger,
75
+                            Defaults $defaults,
76
+                            IURLGenerator $urlGenerator,
77
+                            IL10N $l10n) {
78
+        $this->config = $config;
79
+        $this->logger = $logger;
80
+        $this->defaults = $defaults;
81
+        $this->urlGenerator = $urlGenerator;
82
+        $this->l10n = $l10n;
83
+    }
84 84
 
85
-	/**
86
-	 * Creates a new message object that can be passed to send()
87
-	 *
88
-	 * @return IMessage
89
-	 */
90
-	public function createMessage() {
91
-		return new Message(new \Swift_Message());
92
-	}
85
+    /**
86
+     * Creates a new message object that can be passed to send()
87
+     *
88
+     * @return IMessage
89
+     */
90
+    public function createMessage() {
91
+        return new Message(new \Swift_Message());
92
+    }
93 93
 
94
-	/**
95
-	 * Creates a new email template object
96
-	 *
97
-	 * @param string $emailId
98
-	 * @param array $data
99
-	 * @return IEMailTemplate
100
-	 * @since 12.0.0
101
-	 */
102
-	public function createEMailTemplate($emailId, array $data = []) {
103
-		$class = $this->config->getSystemValue('mail_template_class', '');
94
+    /**
95
+     * Creates a new email template object
96
+     *
97
+     * @param string $emailId
98
+     * @param array $data
99
+     * @return IEMailTemplate
100
+     * @since 12.0.0
101
+     */
102
+    public function createEMailTemplate($emailId, array $data = []) {
103
+        $class = $this->config->getSystemValue('mail_template_class', '');
104 104
 
105
-		if ($class !== '' && class_exists($class) && is_a($class, EMailTemplate::class, true)) {
106
-			return new $class(
107
-				$this->defaults,
108
-				$this->urlGenerator,
109
-				$this->l10n,
110
-				$emailId,
111
-				$data
112
-			);
113
-		}
105
+        if ($class !== '' && class_exists($class) && is_a($class, EMailTemplate::class, true)) {
106
+            return new $class(
107
+                $this->defaults,
108
+                $this->urlGenerator,
109
+                $this->l10n,
110
+                $emailId,
111
+                $data
112
+            );
113
+        }
114 114
 
115
-		return new EMailTemplate(
116
-			$this->defaults,
117
-			$this->urlGenerator,
118
-			$this->l10n,
119
-			$emailId,
120
-			$data
121
-		);
122
-	}
115
+        return new EMailTemplate(
116
+            $this->defaults,
117
+            $this->urlGenerator,
118
+            $this->l10n,
119
+            $emailId,
120
+            $data
121
+        );
122
+    }
123 123
 
124
-	/**
125
-	 * Send the specified message. Also sets the from address to the value defined in config.php
126
-	 * if no-one has been passed.
127
-	 *
128
-	 * @param IMessage|Message $message Message to send
129
-	 * @return string[] Array with failed recipients. Be aware that this depends on the used mail backend and
130
-	 * therefore should be considered
131
-	 * @throws \Exception In case it was not possible to send the message. (for example if an invalid mail address
132
-	 * has been supplied.)
133
-	 */
134
-	public function send(IMessage $message) {
135
-		$debugMode = $this->config->getSystemValue('mail_smtpdebug', false);
124
+    /**
125
+     * Send the specified message. Also sets the from address to the value defined in config.php
126
+     * if no-one has been passed.
127
+     *
128
+     * @param IMessage|Message $message Message to send
129
+     * @return string[] Array with failed recipients. Be aware that this depends on the used mail backend and
130
+     * therefore should be considered
131
+     * @throws \Exception In case it was not possible to send the message. (for example if an invalid mail address
132
+     * has been supplied.)
133
+     */
134
+    public function send(IMessage $message) {
135
+        $debugMode = $this->config->getSystemValue('mail_smtpdebug', false);
136 136
 
137
-		if (empty($message->getFrom())) {
138
-			$message->setFrom([\OCP\Util::getDefaultEmailAddress($this->defaults->getName()) => $this->defaults->getName()]);
139
-		}
137
+        if (empty($message->getFrom())) {
138
+            $message->setFrom([\OCP\Util::getDefaultEmailAddress($this->defaults->getName()) => $this->defaults->getName()]);
139
+        }
140 140
 
141
-		$failedRecipients = [];
141
+        $failedRecipients = [];
142 142
 
143
-		$mailer = $this->getInstance();
143
+        $mailer = $this->getInstance();
144 144
 
145
-		// Enable logger if debug mode is enabled
146
-		if($debugMode) {
147
-			$mailLogger = new \Swift_Plugins_Loggers_ArrayLogger();
148
-			$mailer->registerPlugin(new \Swift_Plugins_LoggerPlugin($mailLogger));
149
-		}
145
+        // Enable logger if debug mode is enabled
146
+        if($debugMode) {
147
+            $mailLogger = new \Swift_Plugins_Loggers_ArrayLogger();
148
+            $mailer->registerPlugin(new \Swift_Plugins_LoggerPlugin($mailLogger));
149
+        }
150 150
 
151
-		$mailer->send($message->getSwiftMessage(), $failedRecipients);
151
+        $mailer->send($message->getSwiftMessage(), $failedRecipients);
152 152
 
153
-		// Debugging logging
154
-		$logMessage = sprintf('Sent mail to "%s" with subject "%s"', print_r($message->getTo(), true), $message->getSubject());
155
-		$this->logger->debug($logMessage, ['app' => 'core']);
156
-		if($debugMode && isset($mailLogger)) {
157
-			$this->logger->debug($mailLogger->dump(), ['app' => 'core']);
158
-		}
153
+        // Debugging logging
154
+        $logMessage = sprintf('Sent mail to "%s" with subject "%s"', print_r($message->getTo(), true), $message->getSubject());
155
+        $this->logger->debug($logMessage, ['app' => 'core']);
156
+        if($debugMode && isset($mailLogger)) {
157
+            $this->logger->debug($mailLogger->dump(), ['app' => 'core']);
158
+        }
159 159
 
160
-		return $failedRecipients;
161
-	}
160
+        return $failedRecipients;
161
+    }
162 162
 
163
-	/**
164
-	 * Checks if an e-mail address is valid
165
-	 *
166
-	 * @param string $email Email address to be validated
167
-	 * @return bool True if the mail address is valid, false otherwise
168
-	 */
169
-	public function validateMailAddress($email) {
170
-		return \Swift_Validate::email($this->convertEmail($email));
171
-	}
163
+    /**
164
+     * Checks if an e-mail address is valid
165
+     *
166
+     * @param string $email Email address to be validated
167
+     * @return bool True if the mail address is valid, false otherwise
168
+     */
169
+    public function validateMailAddress($email) {
170
+        return \Swift_Validate::email($this->convertEmail($email));
171
+    }
172 172
 
173
-	/**
174
-	 * SwiftMailer does currently not work with IDN domains, this function therefore converts the domains
175
-	 *
176
-	 * FIXME: Remove this once SwiftMailer supports IDN
177
-	 *
178
-	 * @param string $email
179
-	 * @return string Converted mail address if `idn_to_ascii` exists
180
-	 */
181
-	protected function convertEmail($email) {
182
-		if (!function_exists('idn_to_ascii') || strpos($email, '@') === false) {
183
-			return $email;
184
-		}
173
+    /**
174
+     * SwiftMailer does currently not work with IDN domains, this function therefore converts the domains
175
+     *
176
+     * FIXME: Remove this once SwiftMailer supports IDN
177
+     *
178
+     * @param string $email
179
+     * @return string Converted mail address if `idn_to_ascii` exists
180
+     */
181
+    protected function convertEmail($email) {
182
+        if (!function_exists('idn_to_ascii') || strpos($email, '@') === false) {
183
+            return $email;
184
+        }
185 185
 
186
-		list($name, $domain) = explode('@', $email, 2);
187
-		$domain = idn_to_ascii($domain, 0,INTL_IDNA_VARIANT_UTS46);
188
-		return $name.'@'.$domain;
189
-	}
186
+        list($name, $domain) = explode('@', $email, 2);
187
+        $domain = idn_to_ascii($domain, 0,INTL_IDNA_VARIANT_UTS46);
188
+        return $name.'@'.$domain;
189
+    }
190 190
 
191
-	/**
192
-	 * Returns whatever transport is configured within the config
193
-	 *
194
-	 * @return \Swift_SmtpTransport|\Swift_SendmailTransport|\Swift_MailTransport
195
-	 */
196
-	protected function getInstance() {
197
-		if (!is_null($this->instance)) {
198
-			return $this->instance;
199
-		}
191
+    /**
192
+     * Returns whatever transport is configured within the config
193
+     *
194
+     * @return \Swift_SmtpTransport|\Swift_SendmailTransport|\Swift_MailTransport
195
+     */
196
+    protected function getInstance() {
197
+        if (!is_null($this->instance)) {
198
+            return $this->instance;
199
+        }
200 200
 
201
-		switch ($this->config->getSystemValue('mail_smtpmode', 'php')) {
202
-			case 'smtp':
203
-				$this->instance = $this->getSmtpInstance();
204
-				break;
205
-			case 'sendmail':
206
-				// FIXME: Move into the return statement but requires proper testing
207
-				//       for SMTP and mail as well. Thus not really doable for a
208
-				//       minor release.
209
-				$this->instance = \Swift_Mailer::newInstance($this->getSendMailInstance());
210
-				break;
211
-			default:
212
-				$this->instance = $this->getMailInstance();
213
-				break;
214
-		}
201
+        switch ($this->config->getSystemValue('mail_smtpmode', 'php')) {
202
+            case 'smtp':
203
+                $this->instance = $this->getSmtpInstance();
204
+                break;
205
+            case 'sendmail':
206
+                // FIXME: Move into the return statement but requires proper testing
207
+                //       for SMTP and mail as well. Thus not really doable for a
208
+                //       minor release.
209
+                $this->instance = \Swift_Mailer::newInstance($this->getSendMailInstance());
210
+                break;
211
+            default:
212
+                $this->instance = $this->getMailInstance();
213
+                break;
214
+        }
215 215
 
216
-		return $this->instance;
217
-	}
216
+        return $this->instance;
217
+    }
218 218
 
219
-	/**
220
-	 * Returns the SMTP transport
221
-	 *
222
-	 * @return \Swift_SmtpTransport
223
-	 */
224
-	protected function getSmtpInstance() {
225
-		$transport = \Swift_SmtpTransport::newInstance();
226
-		$transport->setTimeout($this->config->getSystemValue('mail_smtptimeout', 10));
227
-		$transport->setHost($this->config->getSystemValue('mail_smtphost', '127.0.0.1'));
228
-		$transport->setPort($this->config->getSystemValue('mail_smtpport', 25));
229
-		if ($this->config->getSystemValue('mail_smtpauth', false)) {
230
-			$transport->setUsername($this->config->getSystemValue('mail_smtpname', ''));
231
-			$transport->setPassword($this->config->getSystemValue('mail_smtppassword', ''));
232
-			$transport->setAuthMode($this->config->getSystemValue('mail_smtpauthtype', 'LOGIN'));
233
-		}
234
-		$smtpSecurity = $this->config->getSystemValue('mail_smtpsecure', '');
235
-		if (!empty($smtpSecurity)) {
236
-			$transport->setEncryption($smtpSecurity);
237
-		}
238
-		$transport->start();
239
-		return $transport;
240
-	}
219
+    /**
220
+     * Returns the SMTP transport
221
+     *
222
+     * @return \Swift_SmtpTransport
223
+     */
224
+    protected function getSmtpInstance() {
225
+        $transport = \Swift_SmtpTransport::newInstance();
226
+        $transport->setTimeout($this->config->getSystemValue('mail_smtptimeout', 10));
227
+        $transport->setHost($this->config->getSystemValue('mail_smtphost', '127.0.0.1'));
228
+        $transport->setPort($this->config->getSystemValue('mail_smtpport', 25));
229
+        if ($this->config->getSystemValue('mail_smtpauth', false)) {
230
+            $transport->setUsername($this->config->getSystemValue('mail_smtpname', ''));
231
+            $transport->setPassword($this->config->getSystemValue('mail_smtppassword', ''));
232
+            $transport->setAuthMode($this->config->getSystemValue('mail_smtpauthtype', 'LOGIN'));
233
+        }
234
+        $smtpSecurity = $this->config->getSystemValue('mail_smtpsecure', '');
235
+        if (!empty($smtpSecurity)) {
236
+            $transport->setEncryption($smtpSecurity);
237
+        }
238
+        $transport->start();
239
+        return $transport;
240
+    }
241 241
 
242
-	/**
243
-	 * Returns the sendmail transport
244
-	 *
245
-	 * @return \Swift_SendmailTransport
246
-	 */
247
-	protected function getSendMailInstance() {
248
-		switch ($this->config->getSystemValue('mail_smtpmode', 'php')) {
249
-			case 'qmail':
250
-				$binaryPath = '/var/qmail/bin/sendmail';
251
-				break;
252
-			default:
253
-				$binaryPath = '/usr/sbin/sendmail';
254
-				break;
255
-		}
242
+    /**
243
+     * Returns the sendmail transport
244
+     *
245
+     * @return \Swift_SendmailTransport
246
+     */
247
+    protected function getSendMailInstance() {
248
+        switch ($this->config->getSystemValue('mail_smtpmode', 'php')) {
249
+            case 'qmail':
250
+                $binaryPath = '/var/qmail/bin/sendmail';
251
+                break;
252
+            default:
253
+                $binaryPath = '/usr/sbin/sendmail';
254
+                break;
255
+        }
256 256
 
257
-		return \Swift_SendmailTransport::newInstance($binaryPath . ' -bs');
258
-	}
257
+        return \Swift_SendmailTransport::newInstance($binaryPath . ' -bs');
258
+    }
259 259
 
260
-	/**
261
-	 * Returns the mail transport
262
-	 *
263
-	 * @return \Swift_MailTransport
264
-	 */
265
-	protected function getMailInstance() {
266
-		return \Swift_MailTransport::newInstance();
267
-	}
260
+    /**
261
+     * Returns the mail transport
262
+     *
263
+     * @return \Swift_MailTransport
264
+     */
265
+    protected function getMailInstance() {
266
+        return \Swift_MailTransport::newInstance();
267
+    }
268 268
 
269 269
 }
Please login to merge, or discard this patch.