IndexController   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 168
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 9
dl 0
loc 168
ccs 0
cts 112
cp 0
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A showLogin() 0 15 3
A ajaxAction() 0 30 2
A getEndpoint() 0 11 2
A __construct() 0 11 2
A dispatch() 0 51 4
A isLoggedIn() 0 15 4
1
<?php
2
3
/**
4
 * @author Victor Dubiniuk <[email protected]>
5
 *
6
 * @copyright Copyright (c) 2015, ownCloud, Inc.
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 Owncloud\Updater\Controller;
24
25
use Owncloud\Updater\Utils\Checkpoint;
26
use Owncloud\Updater\Utils\ConfigReader;
27
use Pimple\Container;
28
use Owncloud\Updater\Formatter\HtmlOutputFormatter;
29
use Owncloud\Updater\Http\Request;
30
use League\Plates\Engine;
31
use League\Plates\Extension\Asset;
32
use League\Plates\Extension\URI;
33
use Symfony\Component\Console\Output\BufferedOutput;
34
use Symfony\Component\Console\Input\StringInput;
35
36
/**
37
 * Class IndexController
38
 *
39
 * @package Owncloud\Updater\Controller
40
 */
41
class IndexController {
42
43
	/** @var Container */
44
	protected $container;
45
46
	/** @var Request */
47
	protected $request;
48
49
	/** @var string $command */
50
	protected $command;
51
52
	/**
53
	 * @param Container $container
54
	 * @param Request|null $request
55
	 */
56
	public function __construct(Container $container,
57
								Request $request = null) {
58
		$this->container = $container;
59
		if (is_null($request)){
60
			$this->request = new Request(['post' => $_POST, 'headers' => $_SERVER]);
61
		} else {
62
			$this->request = $request;
63
		}
64
65
		$this->command = $this->request->postParameter('command');
66
	}
67
68
	/**
69
	 * @return string
70
	 */
71
	public function dispatch() {
72
		/** @var ConfigReader $configReader */
73
		$configReader = $this->container['utils.configReader'];
0 ignored issues
show
Unused Code introduced by
$configReader 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...
74
75
		// strip index.php and query string (if any) to get a real base url
76
		$baseUrl = preg_replace('/(index\.php.*|\?.*)$/', '', $_SERVER['REQUEST_URI']);
77
		$templates = new Engine(CURRENT_DIR . '/src/Resources/views/');
78
		$templates->loadExtension(new Asset(CURRENT_DIR . '/pub/', false));
79
		$templates->loadExtension(new URI($baseUrl));
80
		
81
		// Check if the user is logged-in
82
		if(!$this->isLoggedIn()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->isLoggedIn() of type null|boolean is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
83
			return $this->showLogin($templates);
84
		}
85
		
86
		try {
87
			$fullEndpoint = $this->getEndpoint();
88
			$this->container['application']->setEndpoint($fullEndpoint);
89
			$this->container['application']->setAuthToken($this->request->header('X_Updater_Auth'));
90
			$this->container['application']->initConfig();
91
			$this->container['application']->assertOwnCloudFound();
92
		} catch (\Exception $e){
93
			$content = $templates->render(
94
				'partials/error',
95
				[
96
					'title' => 'Updater',
97
					'version' => $this->container['application']->getVersion(),
98
					'error' => $e->getMessage()
99
				]
100
			);
101
			return $content;
102
		}
103
		
104
		if (is_null($this->command)){
105
			/** @var Checkpoint $checkpoint */
106
			$checkpoint = $this->container['utils.checkpoint'];
107
			$checkpoints = $checkpoint->getAll();
108
			$content = $templates->render(
109
					'partials/inner',
110
					[
111
						'title' => 'Updater',
112
						'version' => $this->container['application']->getVersion(),
113
						'checkpoints' => $checkpoints
114
					]
115
			);
116
		} else {
117
			header('Content-Type: application/json');
118
			$content = json_encode($this->ajaxAction(), JSON_UNESCAPED_SLASHES);
119
		}
120
		return $content;
121
	}
122
123
	/**
124
	 * @return bool
125
	 */
126
	protected function isLoggedIn() {
127
		/** @var ConfigReader $configReader */
128
		$locator = $this->container['utils.locator'];
129
		$storedSecret = $locator->getSecretFromConfig();
130
		if ($storedSecret === '') {
131
			die('updater.secret is undefined in config/config.php. Either browse the admin settings in your ownCloud and click "Open updater" or define a strong secret using <pre>php -r \'echo password_hash("MyStrongSecretDoUseYourOwn!", PASSWORD_DEFAULT)."\n";\'</pre> and set this in the config.php.');
132
		}
133
		$sentAuthHeader = ($this->request->header('X_Updater_Auth') !== null) ? $this->request->header('X_Updater_Auth') : '';
134
135
		if(password_verify($sentAuthHeader, $storedSecret)) {
136
			return true;
137
		}
138
139
		return false;
140
	}
141
142
	/**
143
	 * @param Engine $templates
144
	 * @return string
145
	 */
146
	public function showLogin(Engine $templates) {
147
		// If it is a request with invalid token just return "false" so that we can catch this
148
		$token = ($this->request->header('X_Updater_Auth') !== null) ? $this->request->header('X_Updater_Auth') : '';
149
		if($token !== '') {
150
			return 'false';
151
		}
152
153
		$content = $templates->render(
154
			'partials/login',
155
			[
156
				'title' => 'Login Required',
157
			]
158
		);
159
		return $content;
160
	}
161
162
	/**
163
	 * @return array
164
	 */
165
	public function ajaxAction() {
166
		$application = $this->container['application'];
167
168
		$input = new StringInput($this->command);
169
		$input->setInteractive(false);
170
171
		$output = new BufferedOutput();
172
		$formatter = $output->getFormatter();
173
		$formatter->setDecorated(true);
174
		$output->setFormatter(new HtmlOutputFormatter($formatter));
175
176
		$application->setAutoExit(false);
177
178
		// Some commands dump things out instead of returning a value
179
		ob_start();
180
		$errorCode = $application->run($input, $output);
181
		if (!$result = $output->fetch()){
182
			$result = ob_get_contents(); // If empty, replace it by the catched output
183
		}
184
		ob_end_clean();
185
		$result = nl2br($result);
186
		$result = preg_replace('|<br />\r.*<br />(\r.*?)<br />|', '$1<br />', $result);
187
188
		return [
189
			'input' => $this->command,
190
			'output' => $result,
191
			'environment' => '',
192
			'error_code' => $errorCode
193
		];
194
	}
195
	
196
	protected function getEndpoint(){
197
		$endpoint = preg_replace('/(updater\/|updater\/index.php)$/', '', $this->request->getRequestUri());
198
		$fullEndpoint = sprintf(
199
			'%s://%s%sindex.php/occ/',
200
			$this->request->getServerProtocol(),
201
			$this->request->getHost(),
202
			$endpoint !== '' ? $endpoint : '/'
203
		);
204
		
205
		return $fullEndpoint;
206
	}
207
208
}
209