Completed
Pull Request — master (#347)
by Maxence
02:20
created

ContactsExistingShares::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php declare(strict_types=1);
2
3
4
/**
5
 * Circles - Bring cloud-users closer together.
6
 *
7
 * This file is licensed under the Affero General Public License version 3 or
8
 * later. See the COPYING file.
9
 *
10
 * @author Maxence Lange <[email protected]>
11
 * @copyright 2020
12
 * @license GNU AGPL version 3 or any later version
13
 *
14
 * This program is free software: you can redistribute it and/or modify
15
 * it under the terms of the GNU Affero General Public License as
16
 * published by the Free Software Foundation, either version 3 of the
17
 * License, or (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU Affero General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Affero General Public License
25
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
26
 *
27
 */
28
29
30
namespace OCA\Circles\Cron;
31
32
33
use daita\MySmallPhpTools\Traits\TArrayTools;
34
use OC\BackgroundJob\TimedJob;
35
use OC\Share20\Share;
36
use OCA\Circles\AppInfo\Application;
37
use OCA\Circles\Circles\FileSharingBroadcaster;
38
use OCA\Circles\Db\CirclesRequest;
39
use OCA\Circles\Db\MembersRequest;
40
use OCA\Circles\Db\SharesRequest;
41
use OCA\Circles\Db\TokensRequest;
42
use OCA\Circles\Exceptions\CircleDoesNotExistException;
43
use OCA\Circles\Exceptions\MemberDoesNotExistException;
44
use OCA\Circles\Exceptions\TokenDoesNotExistException;
45
use OCA\Circles\Model\Member;
46
use OCA\Circles\Model\SharesToken;
47
use OCA\Circles\Service\ConfigService;
48
use OCA\Circles\Service\DavService;
49
use OCA\Circles\Service\MiscService;
50
use OCP\AppFramework\QueryException;
51
use OCP\Files\IRootFolder;
52
use OCP\IUserManager;
53
use OCP\Share\Exceptions\IllegalIDChangeException;
54
use OCP\Share\IShare;
55
56
57
/**
58
 * Class GlobalSync
59
 *
60
 * @package OCA\Cicles\Cron
61
 */
62
class ContactsExistingShares extends TimedJob {
63
64
65
	use TArrayTools;
66
67
68
	/** @var IRootFolder */
69
	private $rootFolder;
70
71
	/** @var IUserManager */
72
	private $userManager;
73
74
	/** @var DavService */
75
	private $davService;
76
77
	/** @var MembersRequest */
78
	private $membersRequest;
79
80
	/** @var CirclesRequest */
81
	private $circlesRequest;
82
83
	/** @var SharesRequest */
84
	private $sharesRequest;
85
86
	/** @var TokensRequest */
87
	private $tokensRequest;
88
89
	/** @var FileSharingBroadcaster */
90
	private $fileSharingBroadcaster;
91
92
	/** @var ConfigService */
93
	private $configService;
94
95
	/** @var MiscService */
96
	private $miscService;
97
98
99
	/**
100
	 * Cache constructor.
101
	 */
102
	public function __construct() {
103
		$this->setInterval(1);
104
	}
105
106
107
	/**
108
	 * @param mixed $argument
109
	 *
110
	 * @throws QueryException
111
	 */
112
	protected function run($argument) {
113
		$app = new Application();
114
		$c = $app->getContainer();
115
116
		$this->davService = $c->query(DavService::class);
117
		$this->rootFolder = $c->query(IRootFolder::class);
118
		$this->userManager = $c->query(IUserManager::class);
119
		$this->membersRequest = $c->query(MembersRequest::class);
120
		$this->circlesRequest = $c->query(CirclesRequest::class);
121
		$this->tokensRequest = $c->query(TokensRequest::class);
122
		$this->sharesRequest = $c->query(SharesRequest::class);
123
		$this->fileSharingBroadcaster = $c->query(FileSharingBroadcaster::class);
124
		$this->configService = $c->query(ConfigService::class);
125
		$this->miscService = $c->query(MiscService::class);
126
127
		if ($this->configService->getAppValue(ConfigService::CIRCLES_CONTACT_BACKEND) !== '1') {
128
			return;
129
		}
130
131
		$this->fileSharingBroadcaster->init();
132
133
		$members = $this->getNewMembers();
0 ignored issues
show
Unused Code introduced by
$members is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
134
	}
135
136
137
	/**
138
	 * @return Member[]
139
	 */
140
	private function getNewMembers(): array {
141
		$knownMembers = $this->membersRequest->forceGetAllRecentContactEdit();
142
143
		$members = [];
144
		foreach ($knownMembers as $member) {
145
			try {
146
				$circle = $this->circlesRequest->forceGetCircle($member->getCircleId());
147
			} catch (CircleDoesNotExistException $e) {
148
				continue;
149
			}
150
151
			try {
152
				$davCard = $this->davService->getDavCardFromMember($member);
153
			} catch (MemberDoesNotExistException $e) {
154
				continue;
155
			}
156
157
			$contactMeta = $member->getContactMeta();
158
			$missingMails = array_diff(
159
				$davCard->getEmails(), $this->getArray('existing_shares.emails', $contactMeta, [])
160
			);
161
			$missingClouds = array_diff(
162
				$davCard->getClouds(), $this->getArray('existing_shares.clouds', $contactMeta, [])
163
			);
164
165
			$owners = $this->membersRequest->forceGetMembers($member->getCircleId(), Member::LEVEL_OWNER);
166
			$owner = $owners[0];
167
168
			// send mail to $missingMails
169
			$allShares = $this->sharesRequest->getSharesForCircle($member->getCircleId());
170
171
			foreach ($missingMails as $recipient) {
172
				$this->fileSharingBroadcaster->sendMailExitingShares(
173
					$allShares, MiscService::getDisplay($owner->getUserId(), Member::TYPE_USER), $member,
174
					$recipient, $circle->getName()
175
				);
176
				$this->updateContactMeta($member, 'emails', $recipient);
177
			}
178
179
			foreach ($missingClouds as $cloudId) {
180
				foreach ($allShares as $item) {
181
					try {
182
						$share = $this->generateShare($item);
183
						$sharesToken =
184
							$this->tokensRequest->generateTokenForMember($member, (int)$share->getId());
185
186
						if ($this->fileSharingBroadcaster->sharedByFederated(
187
							$circle, $share, $cloudId, $sharesToken
188
						)) {
189
							$this->updateContactMeta($member, 'clouds', $cloudId);
190
						}
191
					} catch (IllegalIDChangeException | TokenDoesNotExistException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
192
					}
193
				}
194
			}
195
		}
196
197
		return $members;
198
	}
199
200
201
	/**
202
	 * @param int $id
203
	 * @param SharesToken[] $tokens
204
	 *
205
	 * @return SharesToken
206
	 * @throws TokenDoesNotExistException
207
	 */
208
	private function getSharesTokenById(int $id, array $tokens): SharesToken {
209
		foreach ($tokens as $token) {
210
			if ($token->getShareId() === $id) {
211
				return $token;
212
			}
213
		}
214
215
		throw new TokenDoesNotExistException();
216
	}
217
218
219
	/**
220
	 * @param Member $member
221
	 * @param string $key
222
	 * @param string $value
223
	 */
224
	private function updateContactMeta(Member $member, string $key, string $value) {
225
		$current = $member->getContactMeta();
226
		if (!array_key_exists('existing_shares', $current)) {
227
			$current['existing_shares'] = [];
228
		}
229
230
		if (!array_key_exists($key, $current['existing_shares'])) {
231
			$current['existing_shares'][$key] = [];
232
		}
233
234
		$current['existing_shares'][$key][] = $value;
235
236
		$member->setContactMeta($current);
237
		$this->membersRequest->updateContactMeta($member);
238
	}
239
240
241
	/**
242
	 * @param $data
243
	 *
244
	 * @return IShare
245
	 */
246
	private function generateShare($data): IShare {
247
		$share = new Share($this->rootFolder, $this->userManager);
248
249
		try {
250
			$share->setId($data['id']);
251
		} catch (IllegalIDChangeException $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\Share\Exceptions\IllegalIDChangeException 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...
252
		}
253
		$share->setSharedBy($data['uid_initiator']);
254
		$share->setSharedWith($data['share_with']);
255
		$share->setNodeId($data['file_source']);
256
		$share->setShareOwner($data['uid_owner']);
257
		$share->setPermissions($data['permissions']);
258
		$share->setToken($data['token']);
259
		$share->setPassword($data['password']);
260
261
		return $share;
262
	}
263
264
}
265
266