GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

SSH   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 294
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 100%

Importance

Changes 4
Bugs 1 Features 2
Metric Value
wmc 21
lcom 1
cbo 0
dl 0
loc 294
ccs 64
cts 64
cp 1
rs 10
c 4
b 1
f 2

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A setPort() 0 4 1
A getPort() 0 4 1
A setKeyFile() 0 13 1
A getKeyFile() 0 4 1
B prepareCommand() 0 29 4
A execute() 0 13 2
A execCommand() 0 6 1
A getCommand() 0 4 1
A setExecutable() 0 14 1
A getExecutable() 0 4 1
A getCommandParts() 0 4 1
A addCommandPart() 0 4 1
A getArguments() 0 4 1
A addArgument() 0 5 2
A reset() 0 5 1
1
<?php
2
/**
3
 * This file is part of the Gerrie package.
4
 *
5
 * (c) Andreas Grunwald <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Gerrie\Component\Connection;
12
13
class SSH
14
{
15
16
    /**
17
     * SSH Key file for authentification
18
     *
19
     * @var string
20
     */
21
    protected $keyFile = '';
22
23
    /**
24
     * SSH port
25
     *
26
     * @var int
27
     */
28
    protected $port = 0;
29
30
    /**
31
     * SSH commands.
32
     *
33
     * In command "ssh example.com ls-projects --format 'JSON' --description" reflects "ls-projects" a command part.
34
     *
35
     * @var array
36
     */
37
    protected $commandParts = [];
38
39
    /**
40
     * SSH arguments.
41
     *
42
     * In command "ssh example.com ls-projects --format 'JSON' --description" reflects "--format 'JSON"
43
     * and "--description" the argument parts.
44
     *
45
     * @var array
46
     */
47
    protected $arguments = [];
48
49
    /**
50
     * SSH executable
51
     *
52
     * @var string
53
     */
54
    protected $executable = '';
55
56
    /**
57
     * @param $executable
58
     * @param array $config
59
     */
60 21
    public function __construct($executable, array $config)
61
    {
62 21
        $this->setExecutable($executable);
63 21
        $this->setKeyFile($config['KeyFile']);
64 21
        $this->setPort($config['Port']);
65 21
    }
66
67
    /**
68
     * Sets the SSH port
69
     *
70
     * @param int $port Port number
71
     * @return void
72
     */
73 14
    public function setPort($port)
74
    {
75 14
        $this->port = intval($port);
76 14
    }
77
78
    /**
79
     * Gets the SSH port for commands
80
     *
81
     * @return int
82
     */
83 8
    public function getPort()
84
    {
85 8
        return $this->port;
86
    }
87
88
    /**
89
     * Sets the private key file
90
     * e.g. ~/.ssh/id_rsa
91
     *
92
     * @param string $keyFile Path to private key file
93
     * @return void
94
     */
95 14
    public function setKeyFile($keyFile)
96
    {
97
        /*
98
         * TODO Implement a kind of existence check of SSH key
99
        if (file_exists($keyFile) === false) {
100
            $exceptionMessage = 'SSH keyfile "%s" does not exists.';
101
            $exceptionMessage = sprintf($exceptionMessage, $keyFile);
102
            throw new \RuntimeException($exceptionMessage, 1415536217);
103
        }
104
        */
105
106 14
        $this->keyFile = $keyFile;
107 14
    }
108
109
    /**
110
     * Gets the path of the private key file
111
     *
112
     * @return string
113
     */
114 7
    public function getKeyFile()
115
    {
116 7
        return $this->keyFile;
117
    }
118
119
    /**
120
     * Prepares and builds the full command.
121
     * All properties, like ssh key, port, command and agruments will be considered
122
     *
123
     * @return string
124
     */
125 6
    protected function prepareCommand()
126
    {
127 6
        $command = $this->getExecutable() . ' ';
128
129 6
        $keyFile = $this->getKeyFile();
130
        // @todo add file_exists($keyFile) === true
131
        // At the moment this is not working, because i don`t know a PHP function to resolve ~/.ssh/private_key_file
132
        // https://twitter.com/andygrunwald/status/315413070904184832
133
        // Further more, $keyFile can`t be escaped with escapeshellarg(),
134
        // because after this the command is not working anymore
135 6
        if ($keyFile) {
136 1
            $command .= '-i ' . $keyFile . ' ';
137 1
        }
138
139 6
        $port = $this->getPort();
140 6
        if ($port > 0) {
141 1
            $command .= '-p ' . $port . ' ';
142 1
        }
143
144 6
        $command .= implode(' ', $this->getCommandParts()) . ' ';
145 6
        $command .= implode(' ', $this->getArguments());
146
147 6
        $command = trim($command);
148 6
        if ($command) {
149 5
            $command .= ' 2>&1';
150 5
        }
151
152 6
        return $command;
153
    }
154
155
    /**
156
     * Executes the built command.
157
     * Returns the output of the command.
158
     *
159
     * @param bool $implodeReturnValue True if the output of the executed command will be imploded. False otherwise
160
     * @return array|string
161
     */
162 2
    public function execute($implodeReturnValue = true)
163
    {
164 2
        $data = [];
165 2
        $command = $this->getCommand();
166
167 2
        $data = $this->execCommand($command, $data);
168
169 2
        if ($implodeReturnValue === false) {
170 1
            return $data;
171
        }
172
173 1
        return implode('', $data);
174
    }
175
176
    /**
177
     * Wrapped exec()-call.
178
     * This makes unit testing possible.
179
     *
180
     * @param string $command The command to execute
181
     * @param array $data Array where the result will be stored
182
     * @return array
183
     */
184 2
    private function execCommand($command, array $data)
185
    {
186 2
        exec($command, $data);
187
188 2
        return $data;
189
    }
190
191
    /**
192
     * Returns the full command, which will be executed.
193
     *
194
     * @return string
195
     */
196 6
    public function getCommand()
197
    {
198 6
        return $this->prepareCommand();
199
    }
200
201
    /**
202
     * Sets the path of the SSH executable
203
     *
204
     * @param string $executable Path to the executable
205
     * @return void
206
     * @throws \Exception
207
     */
208 14
    public function setExecutable($executable)
209
    {
210
        /*
211
         * TODO This executable check works not as expected :( Fix this
212
         * is_executable('ssh') => false
213
         * is_executable('/usr/bin/ssh') => true
214
         *
215
        if (is_executable($executable) === false) {
216
            throw new \Exception('SSH executable is not executable!', 1364032483);
217
        }
218
        */
219
220 14
        $this->executable = $executable;
221 14
    }
222
223
    /**
224
     * Gets the path of the SSH executable
225
     *
226
     * @return string
227
     */
228 7
    public function getExecutable()
229
    {
230 7
        return $this->executable;
231
    }
232
233
    /**
234
     * Gets all command parts
235
     *
236
     * @see $this->addCommandPart()
237
     *
238
     * @return array
239
     */
240 8
    public function getCommandParts()
241
    {
242 8
        return $this->commandParts;
243
    }
244
245
    /**
246
     * Adds a command part to the command.
247
     *
248
     * e.g.
249
     *        Command: ./console gerrie:export
250
     *                 => "gerrie:export" is a command part
251
     *
252
     *        Command: git merge
253
     *                 => "merge" is a command part
254
     *
255
     * @param string $commandPart The command part
256
     * @return void
257
     */
258 5
    public function addCommandPart($commandPart)
259
    {
260 5
        $this->commandParts[] = ($commandPart);
261 5
    }
262
263
    /**
264
     * Gets all command arguments
265
     *
266
     * @see $this->addArgument()
267
     *
268
     * @return array
269
     */
270 8
    public function getArguments()
271
    {
272 8
        return $this->arguments;
273
    }
274
275
    /**
276
     * Adds a new argument to the SSH command.
277
     *
278
     * e.g.
279
     *        --help        => $agrument = '--help', $value = '', $glue = ''
280
     *        --foo=bar    => $agrument = '--foo', $value = 'bar', $glue = '='
281
     *        --foo bar    => $agrument = '--foo', $value = 'bar', $glue = ''
282
     *
283
     * @param string $argument Name of argument
284
     * @param string $value Value of argument
285
     * @param string $glue Concat value of $argument and $value
286
     * @return void
287
     */
288 7
    public function addArgument($argument, $value, $glue)
289
    {
290 7
        $escapedValue = (($value) ? escapeshellarg($value) : '');
291 7
        $this->arguments[] = $argument . $glue . $escapedValue;
292 7
    }
293
294
    /**
295
     * Resets all command specific parts.
296
     * This can be used to fire many ssh commands with one ssh object.
297
     * Just reset() all the seetings before a new command is setted up.
298
     *
299
     * @return void
300
     */
301 1
    public function reset()
302
    {
303 1
        $this->commandParts = [];
304 1
        $this->arguments = [];
305
    }
306
}