Completed
Pull Request — master (#586)
by Maxence
02:27
created

CirclesReport::obfuscateCircle()   B

Complexity

Conditions 7
Paths 16

Size

Total Lines 35

Duplication

Lines 7
Ratio 20 %

Importance

Changes 0
Metric Value
dl 7
loc 35
rs 8.4266
c 0
b 0
f 0
cc 7
nc 16
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
6
/**
7
 * Circles - Bring cloud-users closer together.
8
 *
9
 * This file is licensed under the Affero General Public License version 3 or
10
 * later. See the COPYING file.
11
 *
12
 * @author Maxence Lange <[email protected]>
13
 * @copyright 2021
14
 * @license GNU AGPL version 3 or any later version
15
 *
16
 * This program is free software: you can redistribute it and/or modify
17
 * it under the terms of the GNU Affero General Public License as
18
 * published by the Free Software Foundation, either version 3 of the
19
 * License, or (at your option) any later version.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 * GNU Affero General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU Affero General Public License
27
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
28
 *
29
 */
30
31
32
namespace OCA\Circles\Command;
33
34
use daita\MySmallPhpTools\Console\Nextcloud\nc22\NC22InteractiveShell;
35
use daita\MySmallPhpTools\Exceptions\InvalidItemException;
36
use daita\MySmallPhpTools\IInteractiveShellClient;
37
use daita\MySmallPhpTools\Model\SimpleDataStore;
38
use daita\MySmallPhpTools\Traits\Nextcloud\nc22\TNC22Deserialize;
39
use daita\MySmallPhpTools\Traits\TArrayTools;
40
use OC\Core\Command\Base;
41
use OCA\Circles\Exceptions\InitiatorNotFoundException;
42
use OCA\Circles\Model\Circle;
43
use OCA\Circles\Model\Federated\RemoteInstance;
44
use OCA\Circles\Model\FederatedUser;
45
use OCA\Circles\Model\Member;
46
use OCA\Circles\Model\Membership;
47
use OCA\Circles\Model\Report;
48
use OCA\Circles\Service\CircleService;
49
use OCA\Circles\Service\ConfigService;
50
use OCA\Circles\Service\FederatedUserService;
51
use OCA\Circles\Service\MemberService;
52
use Symfony\Component\Console\Input\InputInterface;
53
use Symfony\Component\Console\Input\InputOption;
54
use Symfony\Component\Console\Output\ConsoleOutput;
55
use Symfony\Component\Console\Output\OutputInterface;
56
57
58
/**
59
 * Class CirclesReport
60
 *
61
 * @package OCA\Circles\Command
62
 */
63
class CirclesReport extends Base implements IInteractiveShellClient {
64
65
66
	use TNC22Deserialize;
67
	use TArrayTools;
68
69
70
	/** @var FederatedUserService */
71
	private $federatedUserService;
72
73
	/** @var CircleService */
74
	private $circleService;
75
76
	/** @var MemberService */
77
	private $memberService;
78
79
	/** @var ConfigService */
80
	private $configService;
81
82
83
	/** @var OutputInterface */
84
	private $output;
85
86
87
	/**
88
	 * CirclesReport constructor.
89
	 *
90
	 * @param FederatedUserService $federatedUserService
91
	 * @param CircleService $circleService
92
	 * @param MemberService $memberService
93
	 * @param ConfigService $configService
94
	 */
95 View Code Duplication
	public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
96
		FederatedUserService $federatedUserService,
97
		CircleService $circleService,
98
		MemberService $memberService,
99
		ConfigService $configService
100
	) {
101
		parent::__construct();
102
103
		$this->federatedUserService = $federatedUserService;
104
		$this->circleService = $circleService;
105
		$this->memberService = $memberService;
106
		$this->configService = $configService;
107
	}
108
109
110
	/**
111
	 *
112
	 */
113
	protected function configure() {
114
		parent::configure();
115
		$this->setName('circles:report')
116
			 ->setDescription('Read and write obfuscated report')
117
			 ->addOption('local', '', InputOption::VALUE_NONE, 'Use local report')
118
			 ->addOption('read', '', InputOption::VALUE_REQUIRED, 'File containing the report to read', '');
119
	}
120
121
122
	/**
123
	 * @param InputInterface $input
124
	 * @param OutputInterface $output
125
	 *
126
	 * @return int
127
	 * @throws InvalidItemException
128
	 * @throws InitiatorNotFoundException
129
	 */
130
	protected function execute(InputInterface $input, OutputInterface $output): int {
131
		$filename = $input->getOption('read');
132
		$local = $input->getOption('local');
133
		$this->output = $output;
134
135
		$report = null;
136
		if ($filename === '' || $local) {
137
			$report = $this->generateReport();
138
			if (!$local) {
139
				$this->output->writeln(json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
140
141
				return 0;
142
			}
143
		}
144
145
		if ($filename !== '') {
146
			/** @var Report $report */
147
			$data = file_get_contents($filename);
148
			$report = $this->deserialize(json_decode($data, true), Report::class);
149
		}
150
151
		if (!is_null($report)) {
152
			$this->readReport($input, $report);
153
		}
154
155
		return 0;
156
	}
157
158
159
	/**
160
	 * @throws InitiatorNotFoundException
161
	 */
162
	private function generateReport(): Report {
163
		$report = new Report();
164
		$report->setSource($this->configService->getFrontalInstance());
165
		$this->federatedUserService->bypassCurrentUserCondition(true);
166
167
		$raw = $this->circleService->getCircles(
168
			null,
169
			null,
170
			new SimpleDataStore(['includeSystemCircles' => true])
171
		);
172
173
		$circles = [];
174
		foreach ($raw as $circle) {
175
			$circle->getMembers();
176
177
			$circles[] = $this->obfuscateCircle($circle);
178
		}
179
180
		$report->setCircles($circles);
181
182
		return $report;
183
	}
184
185
186
	/**
187
	 * @param InputInterface $input
188
	 * @param Report $report
189
	 */
190
	private function readReport(InputInterface $input, Report $report) {
191
		$output = new ConsoleOutput();
192
		$this->output = $output->section();
193
194
		$interactiveShell = new NC22InteractiveShell($this, $input, $this);
195
		$commands = [
196
			'oui.?Test',
197
			'oui.ok.abcd.1234.#IEntitiesAccounts',
198
			'oui.ok.abcd.2345.#IEntitiesAccounts',
199
			'oui.ok.abcd.4567.#IEntitiesAccounts',
200
			'remoteInstance'
201
		];
202
203
		$interactiveShell->setCommands($commands);
204
		$interactiveShell->run(
205
			'Circles Report [<info>' . $report->getSource() . '</info>]:<comment>%PATH%</comment>$'
206
		);
207
	}
208
209
210
	/**
211
	 * @param string $source
212
	 * @param string $field
213
	 *
214
	 * @return string[]
215
	 */
216
	public function fillCommandList(string $source, string $field): array {
217
		echo $source . ' ' . $field . "\n";
218
219
		return ['abcd', 'abdde', 'erfg'];
220
	}
221
222
223
	/**
224
	 * @param string $command
225
	 */
226
	public function manageCommand(string $command): void {
227
//		echo $command . "\n";
228
	}
229
230
231
	/**
232
	 * @param Circle $circle
233
	 *
234
	 * @return Circle
235
	 */
236
	private function obfuscateCircle(Circle $circle): Circle {
237
		$singleId = $this->obfuscateId($circle->getSingleId());
238
		$circle->setSingleId($singleId)
239
			   ->setName($singleId)
240
			   ->setDisplayName($singleId)
241
			   ->setDescription('')
242
			   ->setCreation(0);
243
244
		if ($circle->hasOwner()) {
245
			$circle->setOwner($this->obfuscateMember($circle->getOwner()));
246
		}
247
248
		if ($circle->hasInitiator()) {
249
			$circle->setInitiator($this->obfuscateMember($circle->getInitiator()));
250
		}
251
252
		if ($circle->hasMembers()) {
253
			$members = [];
254
			foreach ($circle->getMembers() as $member) {
255
				$members[] = $this->obfuscateMember($member);
256
			}
257
			$circle->setMembers($members);
258
		}
259
260 View Code Duplication
		if ($circle->hasMemberships()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
261
			$memberships = [];
262
			foreach ($circle->getMemberships() as $membership) {
263
				$memberships[] = $this->obfuscateMembership($membership);
264
			}
265
			$circle->setMemberships($memberships);
266
		}
267
268
269
		return $circle;
270
	}
271
272
273
	/**
274
	 * @param Member $member
275
	 *
276
	 * @return Member
277
	 */
278
	private function obfuscateMember(Member $member): Member {
279
		$memberId = $this->obfuscateId($member->getId());
280
		$singleId = $this->obfuscateId($member->getSingleId());
281
		$circleId = $this->obfuscateId($member->getCircleId());
282
283
		$member->setSingleId($singleId)
284
			   ->setCircleId($circleId)
285
			   ->setId($memberId)
286
			   ->setUserId($singleId)
287
			   ->setDisplayName($singleId)
288
			   ->setDisplayUpdate(0)
289
			   ->setNote('')
290
			   ->setContactId('')
291
			   ->setContactMeta('')
292
			   ->setJoined(0);
293
294
		if ($member->hasCircle()) {
295
			$member->setCircle($this->obfuscateCircle($member->getCircle()));
296
		}
297
298
		if ($member->hasBasedOn()) {
299
			$member->setBasedOn($this->obfuscateCircle($member->getBasedOn()));
300
		}
301
302
		if ($member->hasInheritedBy()) {
303
			$member->setInheritedBy($this->obfuscateFederatedUser($member->getInheritedBy()));
304
		}
305
306
		if ($member->hasInheritanceFrom()) {
307
			$member->setInheritanceFrom($this->obfuscateMember($member->getInheritanceFrom()));
308
		}
309
310
		if ($member->hasRemoteInstance()) {
311
			$member->setRemoteInstance($this->obfuscateRemoteInstance($member->getRemoteInstance()));
312
		}
313
314 View Code Duplication
		if ($member->hasMemberships()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
315
			$memberships = [];
316
			foreach ($member->getMemberships() as $membership) {
317
				$memberships[] = $this->obfuscateMembership($membership);
318
			}
319
			$member->setMemberships($memberships);
320
		}
321
322
		return $member;
323
	}
324
325
326
	/**
327
	 * @param FederatedUser $federatedUser
328
	 *
329
	 * @return FederatedUser
330
	 */
331
	private function obfuscateFederatedUser(FederatedUser $federatedUser): FederatedUser {
332
		$singleId = $this->obfuscateId($federatedUser->getSingleId());
333
		$federatedUser->setSingleId($singleId)
334
					  ->setUserId($singleId);
335
336
		if ($federatedUser->hasBasedOn()) {
337
			$federatedUser->setBasedOn($this->obfuscateCircle($federatedUser->getBasedOn()));
338
		}
339
340
		if ($federatedUser->hasLink()) {
341
			$federatedUser->setLink($this->obfuscateMembership($federatedUser->getLink()));
342
		}
343
344 View Code Duplication
		if ($federatedUser->hasMemberships()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
345
			$memberships = [];
346
			foreach ($federatedUser->getMemberships() as $membership) {
347
				$memberships[] = $this->obfuscateMembership($membership);
348
			}
349
			$federatedUser->setMemberships($memberships);
350
		}
351
352
		return $federatedUser;
353
	}
354
355
356
	/**
357
	 * @param Membership $membership
358
	 *
359
	 * @return Membership
360
	 */
361
	private function obfuscateMembership(Membership $membership): Membership {
362
		$membership->setSingleId($this->obfuscateId($membership->getSingleId()));
363
		$membership->setCircleId($this->obfuscateId($membership->getCircleId()));
364
		$membership->setInheritanceFirst($this->obfuscateId($membership->getInheritanceFirst()));
365
		$membership->setInheritanceLast($this->obfuscateId($membership->getInheritanceLast()));
366
367
		$path = [];
368
		foreach ($membership->getInheritancePath() as $item) {
369
			$path[] = $this->obfuscateId($item);
370
		}
371
		$membership->setInheritancePath($path);
372
373
		return $membership;
374
	}
375
376
377
	/**
378
	 * @param RemoteInstance $remoteInstance
379
	 *
380
	 * @return RemoteInstance
381
	 */
382
	private function obfuscateRemoteInstance(RemoteInstance $remoteInstance): RemoteInstance {
383
		return $remoteInstance;
384
	}
385
386
387
	/**
388
	 * @param string $id
389
	 *
390
	 * @return string
391
	 */
392
	private function obfuscateId(string $id): string {
393
		return substr($id, 0, 5) . '.' . md5(substr($id, 5));
394
	}
395
396
}
397
398