Passed
Push — master ( 327bdc...4cb164 )
by Jan
02:33
created

BashRestController::flatten()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 4

Importance

Changes 3
Bugs 2 Features 0
Metric Value
c 3
b 2
f 0
dl 0
loc 24
ccs 13
cts 13
cp 1
rs 8.6845
cc 4
eloc 13
nc 4
nop 1
crap 4
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
		$secured = FALSE;
57 6
		foreach ($request->getHeader(self::SECRET_HEADER) as $secret) {
58 5
			if ($secret == $this->secret) { // allow cast
59 5
				$secured = TRUE;
60 5
			}
61 6
		}
62
63 6
		if ($this->secret !== NULL && ! $secured) {
64 1
			return $response->withStatus(403);
65
		}
66
67 5
		$projectName = $args['group'] . '/' . $args['project'];
68 5
		$action = $args['action'];
69
70 5
		if ( ! isset($this->scripts[$projectName][$action])) {
71 1
			return $response->withStatus(404);
72
		}
73
74 4
		return $response->withStatus(200)
75 4
			->withJson([
76 4
				'result' => $this->executor->executeCommand(
77 4
					$this->scripts[$projectName][$action],
78 4
					$this->flatten($request->getParsedBody())
79 3
				)
80 3
			]);
81
	}
82
83
84
	/**
85
	 * @param array|NULL $data
86
	 * @return array
87
	 */
88 4
	private function flatten($data)
89
	{
90 4
		if ($data === NULL) {
91 1
			return [];
92
		}
93
94 3
		if (is_object($data)) {
95 1
			throw new InvalidArgumentException('Unexpected parser result.');
96
		}
97
98
		$toProcess = [[
99 2
			'data' => $data,
100
			'prefix' => 'HOOK'
101 2
		]];
102
103 2
		$flattened = [];
104
105 2
		while ( ! empty($toProcess)) {
106 2
			$actual = array_pop($toProcess);
107 2
			$this->flattenProcessArray($actual, $flattened, $toProcess);
108 2
		}
109
110 2
		return $flattened;
111
	}
112
113
114
	/**
115
	 * @param array $actual
116
	 * @param array $flattened
117
	 * @param array $toProcess
118
	 * @return array
119
	 */
120 2
	private function flattenProcessArray(array $actual, array &$flattened, array &$toProcess)
121
	{
122 2
		foreach ($actual['data'] as $key => $value) {
123 1
			if (is_scalar($value)) {
124 1
				$flattened[$actual['prefix'] . '_' . $key] = $value;
125 1
			} else {
126 1
				if (is_array($value)) {
127 1
					array_push(
128 1
						$toProcess,
129
						[
130 1
							'data' => $value,
131 1
							'prefix' => $actual['prefix'] . '_' . $key
132 1
						]
133 1
					);
134 1
				}
135
			}
136 2
		}
137 2
	}
138
139
}
140