Completed
Pull Request — master (#355)
by Victor
02:52
created

IndexController::isLoggedIn()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 3
Bugs 0 Features 1
Metric Value
c 3
b 0
f 1
dl 0
loc 15
ccs 0
cts 12
cp 0
rs 9.2
cc 4
eloc 9
nc 5
nop 0
crap 20
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 League\Plates\Extension\URI;
26
use Owncloud\Updater\Utils\Checkpoint;
27
use Owncloud\Updater\Utils\ConfigReader;
28
use Symfony\Component\Console\Input\StringInput;
29
use Symfony\Component\Console\Output\BufferedOutput;
30
use Owncloud\Updater\Formatter\HtmlOutputFormatter;
31
use Owncloud\Updater\Http\Request;
32
use League\Plates\Engine;
33
use League\Plates\Extension\Asset;
34
35
class IndexController {
36
37
	/** @var \Pimple\Container */
38
	protected $container;
39
40
	/** @var Request */
41
	protected $request;
42
43
	/** @var string $command */
44
	protected $command;
45
46
	/**
47
	 * @param \Pimple\Container $container
48
	 * @param Request|null $request
49
	 */
50
	public function __construct(\Pimple\Container $container,
51
								Request $request = null) {
52
		$this->container = $container;
53
		if (is_null($request)){
54
			$this->request = new Request(['post' => $_POST, 'headers' => $_SERVER]);
55
		} else {
56
			$this->request = $request;
57
		}
58
59
		$this->command = $this->request->postParameter('command');
60
	}
61
62
	public function dispatch() {
63
		// strip index.php and query string (if any) to get a real base url
64
		$baseUrl = preg_replace('/(index\.php.*|\?.*)$/', '', $_SERVER['REQUEST_URI']);
65
		$templates = new Engine(CURRENT_DIR . '/src/Resources/views/');
66
		$templates->loadExtension(new Asset(CURRENT_DIR . '/pub/', false));
67
		$templates->loadExtension(new URI($baseUrl));
68
69
		// Check if the user is logged-in
70
		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...
71
			return $this->showLogin($templates);
72
		}
73
74
		if (is_null($this->command)){
75
			/** @var Checkpoint $checkpoint */
76
			$checkpoint = $this->container['utils.checkpoint'];
77
			$checkpoints = $checkpoint->getAll();
78
			$content = $templates->render(
79
					'partials/inner',
80
					[
81
						'title' => 'Updater',
82
						'version' => $this->container['application']->getVersion(),
83
						'checkpoints' => $checkpoints
84
					]
85
			);
86
		} else {
87
			header('Content-Type: application/json');
88
			$content = json_encode($this->ajaxAction(), JSON_UNESCAPED_SLASHES);
89
		}
90
		return $content;
91
	}
92
93
	protected function isLoggedIn() {
94
		/** @var ConfigReader $configReader */
95
		$locator = $this->container['utils.locator'];
96
		$storedSecret = $locator->getSecretFromConfig();
97
		if($storedSecret === '') {
98
			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.');
99
		}
100
		$sentAuthHeader = ($this->request->header('X_Updater_Auth') !== null) ? $this->request->header('X_Updater_Auth') : '';
101
102
		if(password_verify($sentAuthHeader, $storedSecret)) {
103
			return true;
104
		}
105
106
		return false;
107
	}
108
109
	public function showLogin(Engine $templates) {
110
		// If it is a request with invalid token just return "false" so that we can catch this
111
		$token = ($this->request->header('X_Updater_Auth') !== null) ? $this->request->header('X_Updater_Auth') : '';
112
		if($token !== '') {
113
			return 'false';
114
		}
115
116
		$content = $templates->render(
117
			'partials/login',
118
			[
119
				'title' => 'Login Required',
120
			]
121
		);
122
		return $content;
123
	}
124
125
	public function ajaxAction() {
126
		$application = $this->container['application'];
127
128
		$input = new StringInput($this->command);
129
		$input->setInteractive(false);
130
131
		$output = new BufferedOutput();
132
		$formatter = $output->getFormatter();
133
		$formatter->setDecorated(true);
134
		$output->setFormatter(new HtmlOutputFormatter($formatter));
135
136
		$application->setAutoExit(false);
137
138
		$endpoint = preg_replace('/(updater\/|updater\/index.php)$/', '', $this->request->getRequestUri());
139
		$fullEndpoint = sprintf(
140
			'%s://%s%sindex.php/occ/',
141
			$this->request->getServerProtocol(),
142
			$this->request->getHost(),
143
			$endpoint !== '' ? $endpoint : '/'
144
		);
145
146
		$application->setEndpoint($fullEndpoint);
147
		$application->setAuthToken($this->request->header('X_Updater_Auth'));
148
		// Some commands dump things out instead of returning a value
149
		ob_start();
150
		$errorCode = $application->run($input, $output);
151
		if (!$result = $output->fetch()){
152
			$result = ob_get_contents(); // If empty, replace it by the catched output
153
		}
154
		ob_end_clean();
155
		$result = nl2br($result);
156
		$result = preg_replace('|<br />\r.*<br />(\r.*?)<br />|', '$1<br />', $result);
157
158
		return [
159
			'input' => $this->command,
160
			'output' => $result,
161
			'environment' => '',
162
			'error_code' => $errorCode
163
		];
164
	}
165
166
}
167