Completed
Pull Request — master (#26700)
by Philipp
08:19
created

apps/files_external/lib/Command/Import.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * @author Joas Schilling <[email protected]>
4
 * @author Robin Appelman <[email protected]>
5
 *
6
 * @copyright Copyright (c) 2016, ownCloud GmbH.
7
 * @license AGPL-3.0
8
 *
9
 * This code is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License, version 3,
11
 * as published by the Free Software Foundation.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License, version 3,
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
20
 *
21
 */
22
23
namespace OCA\Files_External\Command;
24
25
use OC\Core\Command\Base;
26
use OC\User\NoUserException;
27
use OCA\Files_External\Lib\StorageConfig;
28
use OCA\Files_External\Service\BackendService;
29
use OCA\Files_External\Service\GlobalStoragesService;
30
use OCA\Files_External\Service\ImportLegacyStoragesService;
31
use OCA\Files_External\Service\UserStoragesService;
32
use OCP\IUserManager;
33
use OCP\IUserSession;
34
use Symfony\Component\Console\Input\ArrayInput;
35
use Symfony\Component\Console\Input\InputArgument;
36
use Symfony\Component\Console\Input\InputInterface;
37
use Symfony\Component\Console\Input\InputOption;
38
use Symfony\Component\Console\Output\OutputInterface;
39
40
class Import extends Base {
41
	/**
42
	 * @var GlobalStoragesService
43
	 */
44
	private $globalService;
45
46
	/**
47
	 * @var UserStoragesService
48
	 */
49
	private $userService;
50
51
	/**
52
	 * @var IUserSession
53
	 */
54
	private $userSession;
55
56
	/**
57
	 * @var IUserManager
58
	 */
59
	private $userManager;
60
61
	/** @var ImportLegacyStoragesService */
62
	private $importLegacyStorageService;
63
64
	/** @var BackendService */
65
	private $backendService;
66
67
	function __construct(GlobalStoragesService $globalService,
68
						 UserStoragesService $userService,
69
						 IUserSession $userSession,
70
						 IUserManager $userManager,
71
						 ImportLegacyStoragesService $importLegacyStorageService,
72
						 BackendService $backendService
73
	) {
74
		parent::__construct();
75
		$this->globalService = $globalService;
76
		$this->userService = $userService;
77
		$this->userSession = $userSession;
78
		$this->userManager = $userManager;
79
		$this->importLegacyStorageService = $importLegacyStorageService;
80
		$this->backendService = $backendService;
81
	}
82
83 View Code Duplication
	protected function configure() {
84
		$this
85
			->setName('files_external:import')
86
			->setDescription('Import mount configurations')
87
			->addOption(
88
				'user',
89
				null,
90
				InputOption::VALUE_OPTIONAL,
91
				'user to add the mount configurations for, if not set the mount will be added as system mount'
92
			)
93
			->addArgument(
94
				'path',
95
				InputArgument::REQUIRED,
96
				'path to a json file containing the mounts to import, use "-" to read from stdin'
97
			)
98
			->addOption(
99
				'dry',
100
				null,
101
				InputOption::VALUE_NONE,
102
				'Don\'t save the imported mounts, only list the new mounts'
103
			);
104
		parent::configure();
105
	}
106
107
	protected function execute(InputInterface $input, OutputInterface $output) {
108
		$user = $input->getOption('user');
109
		$path = $input->getArgument('path');
110
		if ($path === '-') {
111
			$json = file_get_contents('php://stdin');
112
		} else {
113
			if (!file_exists($path)) {
114
				$output->writeln('<error>File not found: ' . $path . '</error>');
115
				return 1;
116
			}
117
			$json = file_get_contents($path);
118
		}
119
		if (!is_string($json) || strlen($json) < 2) {
120
			$output->writeln('<error>Error while reading json</error>');
121
			return 1;
122
		}
123
		$data = json_decode($json, true);
124
		if (!is_array($data)) {
125
			$output->writeln('<error>Error while parsing json</error>');
126
			return 1;
127
		}
128
129
		$isLegacy = isset($data['user']) || isset($data['group']);
130
		if ($isLegacy) {
131
			$this->importLegacyStorageService->setData($data);
132
			$mounts = $this->importLegacyStorageService->getAllStorages();
133
			foreach ($mounts as $mount) {
134
				if ($mount->getBackendOption('password') === false) {
135
					$output->writeln('<error>Failed to decrypt password</error>');
136
					return 1;
137
				}
138
			}
139
		} else {
140
			if (!isset($data[0])) { //normalize to an array of mounts
141
				$data = [$data];
142
			}
143
			$mounts = array_map([$this, 'parseData'], $data);
144
		}
145
146
		if ($user) {
147
			// ensure applicables are correct for personal mounts
148
			foreach ($mounts as $mount) {
149
				$mount->setApplicableGroups([]);
150
				$mount->setApplicableUsers([$user]);
151
			}
152
		}
153
154
		$storageService = $this->getStorageService($user);
155
156
		$existingMounts = $storageService->getAllStorages();
157
158
		foreach ($mounts as $mount) {
159
			foreach ($existingMounts as $existingMount) {
160
				if (
161
					$existingMount->getMountPoint() === $mount->getMountPoint() &&
162
					$existingMount->getApplicableGroups() === $mount->getApplicableGroups() &&
163
					$existingMount->getApplicableUsers() == $mount->getApplicableUsers() &&
164
					$existingMount->getBackendOptions() == $mount->getBackendOptions()
165
				) {
166
					$output->writeln("<error>Duplicate mount (" . $mount->getMountPoint() . ")</error>");
167
					return 1;
168
				}
169
			}
170
		}
171
172
		if ($input->getOption('dry')) {
173
			if (count($mounts) === 0) {
174
				$output->writeln('<error>No mounts to be imported</error>');
175
				return 1;
176
			}
177
			$listCommand = new ListCommand($this->globalService, $this->userService, $this->userSession, $this->userManager);
178
			$listInput = new ArrayInput([], $listCommand->getDefinition());
179
			$listInput->setOption('output', $input->getOption('output'));
180
			$listInput->setOption('show-password', true);
181
			$listCommand->listMounts($user, $mounts, $listInput, $output);
182
		} else {
183
			foreach ($mounts as $mount) {
184
				$storageService->addStorage($mount);
185
			}
186
		}
187
		return 0;
188
	}
189
190
	private function parseData(array $data) {
191
		$mount = new StorageConfig($data['mount_id']);
192
		$mount->setMountPoint($data['mount_point']);
193
		$mount->setBackend($this->getBackendByClass($data['storage']));
194
		$authBackend = $this->backendService->getAuthMechanism($data['authentication_type']);
195
		$mount->setAuthMechanism($authBackend);
0 ignored issues
show
It seems like $authBackend defined by $this->backendService->g...'authentication_type']) on line 194 can be null; however, OCA\Files_External\Lib\S...fig::setAuthMechanism() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
196
		$mount->setBackendOptions($data['configuration']);
197
		$mount->setMountOptions($data['options']);
198
		$mount->setApplicableUsers(isset($data['applicable_users']) ? $data['applicable_users'] : []);
199
		$mount->setApplicableGroups(isset($data['applicable_groups']) ? $data['applicable_groups'] : []);
200
		return $mount;
201
	}
202
203
	private function getBackendByClass($className) {
204
		$backends = $this->backendService->getBackends();
205
		foreach ($backends as $backend) {
206
			if ($backend->getStorageClass() === $className) {
207
				return $backend;
208
			}
209
		}
210
	}
211
212 View Code Duplication
	protected function getStorageService($userId) {
213
		if (!empty($userId)) {
214
			$user = $this->userManager->get($userId);
215
			if (is_null($user)) {
216
				throw new NoUserException("user $userId not found");
217
			}
218
			$this->userSession->setUser($user);
219
			return $this->userService;
220
		} else {
221
			return $this->globalService;
222
		}
223
	}
224
}
225