Passed
Push — master ( 4cb164...4fcf6f )
by Jan
03:04
created

BashRestController::isHandled()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 2
crap 1
1
<?php
2
3
/**
4
 * This file is part of Lekarna.cz (http://www.lekarna.cz/)
5
 *
6
 * Copyright (c) 2014 Pears Health Cyber, s.r.o. (http://pearshealthcyber.cz)
7
 *
8
 * For the full copyright and license information, please view
9
 * the file LICENSE that was distributed with this source code.
10
 */
11
12
namespace App;
13
14
use Interop\Container\ContainerInterface;
15
use InvalidArgumentException;
16
use Slim\Http\Request;
17
use Slim\Http\Response;
18
19
20
final class BashRestController
21
{
22
23
	const SECRET_HEADER = 'X-Secret';
24
25
	/**
26
	 * @var Executor
27
	 */
28
	private $executor;
29
30
	/**
31
	 * @var string
32
	 */
33
	private $secret;
34
35
	/**
36
	 * @var array
37
	 */
38
	private $scripts;
39
40 6
	public function __construct(ContainerInterface $ci, Executor $executor)
41
	{
42 6
		$this->executor = $executor;
43 6
		$this->secret = (string) $ci->get('settings')['secret'];
44 6
		$this->scripts = (array) $ci->get('bashREST');
45 6
	}
46
47
48
	/**
49
	 * @param Request $request
50
	 * @param Response $response
51
	 * @param array $args
52
	 * @return Response
53
	 */
54 6
	public function __invoke(Request $request, Response $response, array $args)
55
	{
56 6
		if ( ! $this->isSecured($request)) {
57 1
			return $response->withStatus(403);
58
		}
59
60 5
		$projectName = $args['group'] . '/' . $args['project'];
61 5
		$action = $args['action'];
62
63 5
		if ( ! $this->isHandled($projectName, $action)) {
64 1
			return $response->withStatus(404);
65
		}
66
67 4
		return $response->withStatus(200)
68 4
			->withJson($this->handle($request, $projectName, $action));
69
	}
70
71
72
	/**
73
	 * @param Request $request
74
	 * @return bool
75
	 */
76 6 View Code Duplication
	private function isSecured(Request $request)
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...
77
	{
78 6
		$secured = FALSE;
79 6
		foreach ($request->getHeader(self::SECRET_HEADER) as $secret) {
80 5
			if ($secret == $this->secret) { // allow cast
81 5
				$secured = TRUE;
82 5
			}
83 6
		}
84
85 6
		return $this->secret === NULL || $secured;
86
	}
87
88
89
	/**
90
	 * @param array|NULL $data
91
	 * @return array
92
	 */
93 4
	private function flatten($data)
94
	{
95 4
		if ($data === NULL) {
96 1
			return [];
97
		}
98
99 3
		if (is_object($data)) {
100 1
			throw new InvalidArgumentException('Unexpected parser result.');
101
		}
102
103
		$toProcess = [[
104 2
			'data' => $data,
105
			'prefix' => 'HOOK'
106 2
		]];
107
108 2
		$flattened = [];
109
110 2
		while ( ! empty($toProcess)) {
111 2
			$actual = array_pop($toProcess);
112 2
			$this->flattenProcessArray($actual, $flattened, $toProcess);
113 2
		}
114
115 2
		return $flattened;
116
	}
117
118
119
	/**
120
	 * @param string $projectName
121
	 * @param string $action
122
	 * @return bool
123
	 */
124 5
	private function isHandled($projectName, $action)
125
	{
126 5
		return isset($this->scripts[$projectName][$action]);
127
	}
128
129
130
	/**
131
	 * @param array $actual
132
	 * @param array $flattened
133
	 * @param array $toProcess
134
	 * @return array
135
	 */
136 2
	private function flattenProcessArray(array $actual, array &$flattened, array &$toProcess)
137
	{
138 2
		foreach ($actual['data'] as $key => $value) {
139 1
			if (is_scalar($value)) {
140 1
				$flattened[$actual['prefix'] . '_' . $key] = $value;
141 1
			} else {
142 1
				if (is_array($value)) {
143 1
					array_push(
144 1
						$toProcess,
145
						[
146 1
							'data' => $value,
147 1
							'prefix' => $actual['prefix'] . '_' . $key
148 1
						]
149 1
					);
150 1
				}
151
			}
152 2
		}
153 2
	}
154
155
156
	/**
157
	 * @param Request $request
158
	 * @param string $projectName
159
	 * @param string $action
160
	 * @return array
161
	 */
162 4
	private function handle(Request $request, $projectName, $action)
163
	{
164
		return [
165 4
			'result' => $this->executor->executeCommand(
166 4
				$this->scripts[$projectName][$action],
167 4
				$this->flatten($request->getParsedBody())
168 3
			)
169 3
		];
170
	}
171
172
}
173