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

apps/files_external/lib/Command/Verify.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 OCA\Files_External\Lib\Auth\AuthMechanism;
27
use OCA\Files_External\Lib\Backend\Backend;
28
use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException;
29
use OCA\Files_External\Lib\StorageConfig;
30
use OCA\Files_External\NotFoundException;
31
use OCA\Files_External\Service\GlobalStoragesService;
32
use OCP\Files\StorageNotAvailableException;
33
use Symfony\Component\Console\Input\InputArgument;
34
use Symfony\Component\Console\Input\InputInterface;
35
use Symfony\Component\Console\Input\InputOption;
36
use Symfony\Component\Console\Output\OutputInterface;
37
38
class Verify extends Base {
39
	/**
40
	 * @var GlobalStoragesService
41
	 */
42
	protected $globalService;
43
44
	function __construct(GlobalStoragesService $globalService) {
45
		parent::__construct();
46
		$this->globalService = $globalService;
47
	}
48
49
	protected function configure() {
50
		$this
51
			->setName('files_external:verify')
52
			->setDescription('Verify mount configuration')
53
			->addArgument(
54
				'mount_id',
55
				InputArgument::REQUIRED,
56
				'The id of the mount to check'
57
			)->addOption(
58
				'config',
59
				'c',
60
				InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
61
				'Additional config option to set before checking in key=value pairs, required for certain auth backends such as login credentails'
62
			);
63
		parent::configure();
64
	}
65
66
	protected function execute(InputInterface $input, OutputInterface $output) {
67
		$mountId = $input->getArgument('mount_id');
68
		$configInput = $input->getOption('config');
69
70
		try {
71
			$mount = $this->globalService->getStorage($mountId);
72
		} catch (NotFoundException $e) {
73
			$output->writeln('<error>Mount with id "' . $mountId . ' not found, check "occ files_external:list" to get available mounts"</error>');
74
			return 404;
75
		}
76
77
		$this->updateStorageStatus($mount, $configInput, $output);
0 ignored issues
show
It seems like $mount defined by $this->globalService->getStorage($mountId) on line 71 can be null; however, OCA\Files_External\Comma...::updateStorageStatus() 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...
78
79
		$this->writeArrayInOutputFormat($input, $output, [
80
			'status' => StorageNotAvailableException::getStateCodeName($mount->getStatus()),
81
			'code' => $mount->getStatus(),
82
			'message' => $mount->getStatusMessage()
83
		]);
84
	}
85
86
	private function manipulateStorageConfig(StorageConfig $storage) {
87
		/** @var AuthMechanism */
88
		$authMechanism = $storage->getAuthMechanism();
89
		$authMechanism->manipulateStorageConfig($storage);
90
		/** @var Backend */
91
		$backend = $storage->getBackend();
92
		$backend->manipulateStorageConfig($storage);
93
	}
94
95
	private function updateStorageStatus(StorageConfig &$storage, $configInput, OutputInterface $output) {
96
		try {
97
			try {
98
				$this->manipulateStorageConfig($storage);
99
			} catch (InsufficientDataForMeaningfulAnswerException $e) {
100
				if (count($configInput) === 0) { // extra config options might solve the error
101
					throw $e;
102
				}
103
			}
104
105
			foreach ($configInput as $configOption) {
106
				if (!strpos($configOption, '=')) {
107
					$output->writeln('<error>Invalid mount configuration option "' . $configOption . '"</error>');
108
					return;
109
				}
110
				list($key, $value) = explode('=', $configOption, 2);
111
				$storage->setBackendOption($key, $value);
112
			}
113
114
			/** @var Backend */
115
			$backend = $storage->getBackend();
116
			// update status (can be time-consuming)
117
			$storage->setStatus(
118
				\OC_Mount_Config::getBackendStatus(
119
					$backend->getStorageClass(),
120
					$storage->getBackendOptions(),
121
					false
122
				)
123
			);
124
		} catch (InsufficientDataForMeaningfulAnswerException $e) {
125
			$status = $e->getCode() ? $e->getCode() : StorageNotAvailableException::STATUS_INDETERMINATE;
126
			$storage->setStatus(
127
				$status,
128
				$e->getMessage()
129
			);
130
		} catch (StorageNotAvailableException $e) {
131
			$storage->setStatus(
132
				$e->getCode(),
133
				$e->getMessage()
134
			);
135
		} catch (\Exception $e) {
136
			// FIXME: convert storage exceptions to StorageNotAvailableException
137
			$storage->setStatus(
138
				StorageNotAvailableException::STATUS_ERROR,
139
				get_class($e) . ': ' . $e->getMessage()
140
			);
141
		}
142
	}
143
}
144