Completed
Push — master ( 5a6198...a64e14 )
by Maxence
17s queued 10s
created

FileSharingBroadcaster::generateShare()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.7666
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * Circles - Bring cloud-users closer together.
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2017
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
28
namespace OCA\Circles\Circles;
29
30
use OC;
31
use OC\Share20\Share;
32
use OCA\Circles\AppInfo\Application;
33
use OCA\Circles\Db\TokensRequest;
34
use OCA\Circles\Exceptions\TokenDoesNotExistException;
35
use OCA\Circles\IBroadcaster;
36
use OCA\Circles\Model\Circle;
37
use OCA\Circles\Model\Member;
38
use OCA\Circles\Model\SharingFrame;
39
use OCA\Circles\Service\MiscService;
40
use OCP\AppFramework\QueryException;
41
use OCP\Defaults;
42
use OCP\Files\IRootFolder;
43
use OCP\Files\NotFoundException;
44
use OCP\IL10N;
45
use OCP\ILogger;
46
use OCP\IURLGenerator;
47
use OCP\IUserManager;
48
use OCP\Mail\IMailer;
49
use OCP\Share\Exceptions\IllegalIDChangeException;
50
use OCP\Share\IShare;
51
use OCP\Util;
52
53
54
class FileSharingBroadcaster implements IBroadcaster {
55
56
	/** @var IL10N */
57
	private $l10n = null;
58
59
	/** @var IMailer */
60
	private $mailer;
61
62
	/** @var IRootFolder */
63
	private $rootFolder;
64
65
	/** @var IUserManager */
66
	private $userManager;
67
68
	/** @var ILogger */
69
	private $logger;
70
71
	/** @var Defaults */
72
	private $defaults;
73
74
	/** @var IURLGenerator */
75
	private $urlGenerator;
76
77
	/** @var TokensRequest */
78
	private $tokensRequest;
79
80
	/**
81
	 * {@inheritdoc}
82
	 */
83
	public function init() {
84
		$this->l10n = OC::$server->getL10N(Application::APP_NAME);
85
		$this->mailer = OC::$server->getMailer();
86
		$this->rootFolder = OC::$server->getLazyRootFolder();
87
		$this->userManager = OC::$server->getUserManager();
88
		$this->logger = OC::$server->getLogger();
89
		$this->urlGenerator = OC::$server->getURLGenerator();
90
91
		try {
92
			$this->defaults = OC::$server->query(Defaults::class);
93
			$this->tokensRequest = OC::$server->query(TokensRequest::class);
94
		} catch (QueryException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
Bug introduced by
The class OCP\AppFramework\QueryException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
95
		}
96
	}
97
98
99
	/**
100
	 * {@inheritdoc}
101
	 */
102
	public function end() {
103
	}
104
105
106
	/**
107
	 * {@inheritdoc}
108
	 */
109
	public function createShareToCircle(SharingFrame $frame, Circle $circle) {
110
		if ($frame->is0Circle()) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return !$frame->is0Circle();.
Loading history...
111
			return false;
112
		}
113
114
		return true;
115
	}
116
117
118
	/**
119
	 * {@inheritdoc}
120
	 */
121
	public function deleteShareToCircle(SharingFrame $frame, Circle $circle) {
122
		return true;
123
	}
124
125
126
	/**
127
	 * {@inheritdoc}
128
	 */
129
	public function editShareToCircle(SharingFrame $frame, Circle $circle) {
130
		return true;
131
	}
132
133
134
	/**
135
	 * {@inheritdoc}
136
	 */
137
	public function createShareToMember(SharingFrame $frame, Member $member) {
138
		if (!$frame->is0Circle()) {
139
			return false;
140
		}
141
142
		$payload = $frame->getPayload();
143
		if (!key_exists('share', $payload)) {
144
			return false;
145
		}
146
147
		$share = $this->generateShare($payload['share']);
148
		if ($member->getType() === Member::TYPE_MAIL) {
149
			try {
150
				$circle = $frame->getCircle();
151
				$token = $this->tokensRequest->generateTokenForMember($member, $share->getId());
152
				if ($token !== '') {
153
					$this->sharedByMail($circle, $share, $member->getUserId(), $token);
154
				}
155
			} catch (TokenDoesNotExistException $e) {
156
			} catch (NotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class OCP\Files\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
157
			}
158
		}
159
160
		return true;
161
	}
162
163
164
	/**
165
	 * {@inheritdoc}
166
	 */
167
	public function deleteShareToMember(SharingFrame $frame, Member $member) {
168
		return true;
169
	}
170
171
172
	/**
173
	 * {@inheritdoc}
174
	 */
175
	public function editShareToMember(SharingFrame $frame, Member $member) {
176
		return true;
177
	}
178
179
180
	/**
181
	 * recreate the share from the JSON payload.
182
	 *
183
	 * @param array $data
184
	 *
185
	 * @return IShare
0 ignored issues
show
Documentation introduced by
Should the return type not be Share?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
186
	 * @throws IllegalIDChangeException
187
	 */
188
	private function generateShare($data) {
189
		$this->logger->log(0, 'Regenerate shares from payload: ' . json_encode($data));
190
191
		$share = new Share($this->rootFolder, $this->userManager);
192
		$share->setId($data['id']);
193
		$share->setSharedBy($data['sharedBy']);
194
		$share->setSharedWith($data['sharedWith']);
195
		$share->setNodeId($data['nodeId']);
196
		$share->setShareOwner($data['shareOwner']);
197
		$share->setPermissions($data['permissions']);
198
		$share->setToken($data['token']);
199
		$share->setPassword($data['password']);
200
201
		return $share;
202
	}
203
204
205
	/**
206
	 * @param Circle $circle
207
	 * @param IShare $share
208
	 * @param string $email
209
	 * @param string $token
210
	 *
211
	 * @throws NotFoundException
212
	 */
213
	private function sharedByMail(Circle $circle, IShare $share, $email, $token) {
214
		// genelink
215
		$link = $this->urlGenerator->linkToRouteAbsolute(
216
			'circles.Shares.public',
217
			['token' => $token]
218
		);
219
220
		$this->sendMail(
221
			$share->getNode()
222
				  ->getName(), $link,
223
			MiscService::getDisplay($share->getSharedBy(), Member::TYPE_USER),
224
			$circle->getName(), $email
225
		);
226
	}
227
228
229
	/**
230
	 * @param $fileName
231
	 * @param string $link
232
	 * @param string $author
233
	 * @param $circleName
234
	 * @param string $email
235
	 */
236
	protected function sendMail($fileName, $link, $author, $circleName, $email) {
237
		$message = $this->mailer->createMessage();
238
239
		$this->logger->log(
240
			0, "Sending mail to circle '" . $circleName . "': " . $email . ' file: ' . $fileName
241
			   . ' - link: ' . $link
242
		);
243
244
		$subject = $this->l10n->t('%s shared »%s« with you.', [$author, $fileName]);
245
		$text = $this->l10n->t('%s shared »%s« with \'%s\'.', [$author, $fileName, $circleName]);
246
247
		$emailTemplate =
248
			$this->generateEmailTemplate($subject, $text, $fileName, $link, $author, $circleName);
249
250
		$instanceName = $this->defaults->getName();
251
		$senderName = $this->l10n->t('%s on %s', [$author, $instanceName]);
252
253
		$message->setFrom([Util::getDefaultEmailAddress($instanceName) => $senderName]);
254
		$message->setSubject($subject);
255
		$message->setPlainBody($emailTemplate->renderText());
256
		$message->setHtmlBody($emailTemplate->renderHtml());
257
		$message->setTo([$email]);
258
259
		$this->mailer->send($message);
260
	}
261
262
263
	/**
264
	 * @param $subject
265
	 * @param $text
266
	 * @param $fileName
267
	 * @param $link
268
	 * @param string $author
269
	 * @param string $circleName
270
	 *
271
	 * @return \OCP\Mail\IEMailTemplate
272
	 */
273
	private function generateEmailTemplate($subject, $text, $fileName, $link, $author, $circleName
274
	) {
275
276
		$emailTemplate = $this->mailer->createEMailTemplate(
277
			'circles.ShareNotification', [
278
										   'fileName'   => $fileName,
279
										   'fileLink'   => $link,
280
										   'author'     => $author,
281
										   'circleName' => $circleName,
282
									   ]
283
		);
284
285
		$emailTemplate->addHeader();
286
		$emailTemplate->addHeading($subject, false);
287
		$emailTemplate->addBodyText(
288
			htmlspecialchars($text) . '<br>' . htmlspecialchars(
289
				$this->l10n->t('Click the button below to open it.')
290
			), $text
291
		);
292
		$emailTemplate->addBodyButton(
293
			$this->l10n->t('Open »%s«', [htmlspecialchars($fileName)]), $link
294
		);
295
296
		return $emailTemplate;
297
	}
298
}
299