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