This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * This file is part of the teamneusta/hosts project. |
||
4 | * Copyright (c) 2017 neusta GmbH | Ein team neusta Unternehmen |
||
5 | * For the full copyright and license information, please view the LICENSE file that was distributed with this source code. |
||
6 | * @license http://www.opensource.org/licenses/mit-license.html MIT License |
||
7 | * |
||
8 | */ |
||
9 | |||
10 | namespace TeamNeusta\Hosts\Services\Provider; |
||
11 | |||
12 | use TeamNeusta\Hosts\Exception\HostAlreadySetException; |
||
13 | |||
14 | /** |
||
15 | * Class Filesystem |
||
16 | * |
||
17 | * @package TeamNeusta\Hosts\Services\Provider |
||
18 | */ |
||
19 | class Filesystem |
||
20 | { |
||
21 | /** |
||
22 | * configuration file name. |
||
23 | */ |
||
24 | const CONFIGURATION_FILE_NAME = '.hosts'; |
||
25 | |||
26 | /** |
||
27 | * @var \Symfony\Component\Filesystem\Filesystem |
||
28 | */ |
||
29 | protected $fs; |
||
30 | |||
31 | /** |
||
32 | * @var File |
||
33 | */ |
||
34 | protected $file; |
||
35 | |||
36 | /** |
||
37 | * Determines if currently adding new Data to avoid setting scope. |
||
38 | * Scope will only be added if not updating. |
||
39 | * |
||
40 | * @var bool |
||
41 | */ |
||
42 | private $_isUpdate = false; |
||
43 | |||
44 | /** |
||
45 | * Minimal Configuration used to save and connect. |
||
46 | * |
||
47 | * @var array |
||
48 | */ |
||
49 | private $_defaultConfig = [ |
||
50 | 'name' => '', |
||
51 | 'host' => '', |
||
52 | 'user' => '', |
||
53 | 'port' => 22 |
||
54 | ]; |
||
55 | |||
56 | /** |
||
57 | * Filesystem constructor. |
||
58 | * @codeCoverageIgnore |
||
59 | * |
||
60 | * @param \Symfony\Component\Filesystem\Filesystem $fs |
||
61 | * @param File $file |
||
62 | */ |
||
63 | public function __construct( |
||
64 | \Symfony\Component\Filesystem\Filesystem $fs = null, |
||
65 | File $file = null |
||
66 | ) |
||
67 | { |
||
68 | $this->fs = $fs ?? new \Symfony\Component\Filesystem\Filesystem(); |
||
69 | $this->file = $file ?? new File(); |
||
70 | } |
||
71 | |||
72 | /** |
||
73 | * Retrieve home dir. |
||
74 | * |
||
75 | * @return null|string |
||
76 | */ |
||
77 | 9 | public function getHomeDir() |
|
78 | { |
||
79 | // Cannot use _SERVER superglobal since that's empty during UnitUnishTestCase |
||
80 | // getenv('HOME') isn't set on Windows and generates a Notice. |
||
81 | 9 | $home = getenv('HOME'); |
|
82 | 9 | if (!empty($home)) { |
|
83 | // home should never end with a trailing slash. |
||
84 | 8 | $home = rtrim($home, '/'); |
|
85 | 1 | } elseif (!empty($_SERVER['HOMEDRIVE']) && !empty($_SERVER['HOMEPATH'])) { |
|
86 | // home on windows |
||
87 | 1 | $home = $_SERVER['HOMEDRIVE'] . $_SERVER['HOMEPATH']; |
|
88 | // If HOMEPATH is a root directory the path can end with a slash. Make sure |
||
89 | // that doesn't happen. |
||
90 | 1 | $home = rtrim($home, '\\/'); |
|
91 | } |
||
92 | 9 | return empty($home) ? NULL : $home; |
|
93 | } |
||
94 | |||
95 | /** |
||
96 | * Retrieve local configuration. |
||
97 | * |
||
98 | * @return bool|array |
||
99 | */ |
||
100 | 3 | public function getLocalConfiguration() : array |
|
101 | { |
||
102 | 3 | $fileName = $this->getFilename(self::getHomeDir()); |
|
103 | 3 | $config = $this->getConfigurationFile($fileName); |
|
104 | 3 | $config = $this->addScope($config, 'local'); |
|
105 | 3 | return $config; |
|
106 | } |
||
107 | |||
108 | /** |
||
109 | * Retrieve project configuration. |
||
110 | * |
||
111 | * @return bool|array |
||
112 | */ |
||
113 | 2 | public function getProjectConfiguration() : array |
|
114 | { |
||
115 | 2 | $filename = $this->getFilename(); |
|
116 | 2 | $config = $this->getConfigurationFile($filename, false); |
|
117 | 2 | $config = $this->addScope($config, 'project'); |
|
118 | 2 | return $config; |
|
119 | } |
||
120 | |||
121 | /** |
||
122 | * Retrieve local configuration. |
||
123 | * |
||
124 | * @return bool|array |
||
125 | */ |
||
126 | 2 | public function getGlobalConfiguration() : array |
|
127 | { |
||
128 | 2 | $fileName = $this->getGlobalUrlFromConfig(); |
|
129 | 2 | $config = []; |
|
130 | 2 | if ($fileName !== false) { |
|
131 | 2 | $config = $this->getConfigurationFile($fileName, false); |
|
132 | 2 | $config = $this->addScope($config, 'global'); |
|
133 | } |
||
134 | 2 | return $config; |
|
135 | } |
||
136 | |||
137 | /** |
||
138 | * @param $fileName |
||
139 | * @param bool $createIfNotExist |
||
140 | * @return array|bool|mixed|null |
||
141 | * @throws \IOException |
||
142 | */ |
||
143 | 13 | public function getConfigurationFile($fileName, $createIfNotExist = true) |
|
144 | { |
||
145 | 13 | if (!$this->fs->exists($fileName) && $createIfNotExist) { |
|
146 | try { |
||
147 | // generate a empty array for local configuration |
||
148 | 4 | $defaults = ['hosts' => []]; |
|
149 | 4 | $this->fs->dumpFile($fileName, json_encode($defaults)); |
|
150 | 1 | } catch (\Exception $e) { |
|
151 | 1 | throw new \IOException($e->getMessage()); |
|
152 | } |
||
153 | } |
||
154 | 12 | $config = json_decode($this->file->getContents($fileName), true); |
|
155 | 12 | if (is_null($config)) { |
|
156 | 1 | $config = false; |
|
157 | 1 | return $config; |
|
158 | } |
||
159 | 11 | return $config; |
|
160 | } |
||
161 | |||
162 | /** |
||
163 | * Adds Host to configuration file. |
||
164 | * |
||
165 | * @param $hostConfig |
||
166 | * @param string $scope |
||
167 | * @throws \Exception |
||
168 | */ |
||
169 | 3 | public function addHostToConfiguration($hostConfig, $scope = 'local') |
|
170 | { |
||
171 | try { |
||
172 | 3 | $this->_isUpdate = true; |
|
173 | switch ($scope) { |
||
174 | 3 | case 'project': |
|
0 ignored issues
–
show
|
|||
175 | 1 | $fileName = $this->getFilename(); |
|
176 | 1 | $config = $this->getProjectConfiguration(); |
|
177 | 1 | break; |
|
178 | default: |
||
179 | 2 | $fileName = $this->getFilename(self::getHomeDir()); |
|
180 | 2 | $config = $this->getLocalConfiguration(); |
|
181 | 2 | break; |
|
182 | } |
||
183 | 3 | $config['hosts'][] = array_merge($this->_defaultConfig, $hostConfig); |
|
184 | 3 | $this->fs->dumpFile($fileName, json_encode($config)); |
|
185 | 2 | $this->_isUpdate = false; |
|
186 | 1 | } catch (\Exception $e) { |
|
187 | 1 | throw new \Exception($e->getMessage()); |
|
188 | 2 | } finally { |
|
189 | 3 | $this->_isUpdate = false; |
|
190 | } |
||
191 | 2 | } |
|
192 | |||
193 | /** |
||
194 | * @param $hostUrl |
||
195 | * @param bool $override |
||
196 | * |
||
197 | * @throws HostAlreadySetException |
||
198 | */ |
||
199 | 3 | public function setGlobalHostsUrl($hostUrl, $override = false) |
|
200 | { |
||
201 | 3 | $fileName = $this->getFilename(self::getHomeDir()); |
|
202 | 3 | $config = $this->getConfigurationFile($fileName); |
|
203 | |||
204 | 3 | if (isset($config['hosts_url']) && $override) { |
|
205 | 1 | $config['hosts_url'] = $hostUrl; |
|
206 | 2 | } elseif (isset($config['hosts_url'])) { |
|
207 | 1 | throw new HostAlreadySetException($config['hosts_url']); |
|
208 | } else { |
||
209 | 1 | $config['hosts_url'] = $hostUrl; |
|
210 | } |
||
211 | 2 | $this->fs->dumpFile($fileName, json_encode($config)); |
|
212 | 2 | } |
|
213 | |||
214 | /** |
||
215 | * Get Filename with given location. |
||
216 | * |
||
217 | * @param string $baseDir |
||
218 | * @return string |
||
219 | */ |
||
220 | 10 | public function getFilename($baseDir = '.') : string |
|
221 | { |
||
222 | 10 | $fileName = $baseDir . DIRECTORY_SEPARATOR . self::CONFIGURATION_FILE_NAME; |
|
223 | 10 | return $fileName; |
|
224 | } |
||
225 | |||
226 | /** |
||
227 | * Add scope to each entry in config. |
||
228 | * |
||
229 | * @param $config |
||
230 | * @param $scope |
||
231 | * |
||
232 | * @return mixed |
||
233 | */ |
||
234 | 9 | public function addScope($config, $scope) : array |
|
235 | { |
||
236 | // do not add Scope during update. Scope will always be set when reading configuration. |
||
237 | 9 | if (!$this->_isUpdate && is_array($config) && isset($config['hosts'])) { |
|
238 | 3 | foreach ($config['hosts'] as $key => $entry) { |
|
239 | 3 | $config['hosts'][$key]['scope'] = $scope; |
|
240 | } |
||
241 | } |
||
242 | 9 | if (!is_array($config)) { |
|
243 | 1 | $config = ['hosts' => []]; |
|
244 | } |
||
245 | 9 | return $config; |
|
246 | } |
||
247 | |||
248 | /** |
||
249 | * Get global URL from config. |
||
250 | * |
||
251 | * @return bool | string |
||
252 | */ |
||
253 | 2 | private function getGlobalUrlFromConfig() : string |
|
254 | { |
||
255 | 2 | $fileName = $this->getFilename(self::getHomeDir()); |
|
256 | 2 | $config = $this->getConfigurationFile($fileName, false); |
|
257 | |||
258 | 2 | $hostUrl = false; |
|
259 | 2 | if (isset($config['hosts_url'])) { |
|
260 | 1 | $hostUrl = $config['hosts_url']; |
|
261 | } |
||
262 | |||
263 | 2 | return $hostUrl; |
|
264 | } |
||
265 | } |
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next
break
.There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.