Completed
Push — master ( 91d8a4...77e6a8 )
by smiley
02:53
created

CLIRunner::getPubkeyById()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
/**
3
 * Class CLIRunner
4
 *
5
 * @filesource   CLIRunner.php
6
 * @created      01.04.2016
7
 * @package      chillerlan\Threema
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2016 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\Threema;
14
15
use chillerlan\Threema\Crypto\CryptoInterface;
16
use ReflectionClass;
17
use ReflectionMethod;
18
19
/**
20
 *
21
 */
22
class CLIRunner implements CLIRunnerInterface{
23
24
	/**
25
	 * @var array
26
	 */
27
	const COMMANDS = [
28
		// local
29
		'keypair'      => 'getKeypair',
30
		'hash_email'   => 'hashEmail',
31
		'hash_phone'   => 'hashPhone',
32
#		'encrypt'      => '',
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
33
#		'decrypt'      => '',
34
		// network
35
		'credits'      => 'checkCredits',
36
		'check'        => 'checkCapabilities',
37
		'idbyemail'    => 'getIdByEmail',
38
		'idbyphone'    => 'getIdByPhone',
39
		'pubkeybyid'   => 'getPubkeyById',
40
#		'send'         => '',
0 ignored issues
show
Unused Code Comprehensibility introduced by
52% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
41
#		'sende2e'      => '',
42
#		'sendimage'    => '',
43
#		'sendfile'     => '',
44
#		'receive'      => '',
45
	];
46
47
	/**
48
	 * @var \chillerlan\Threema\Crypto\CryptoInterface
49
	 */
50
	protected $cryptoInterface;
51
52
	/**
53
	 * @var \chillerlan\Threema\GatewayOptions
54
	 */
55
	protected $gatewayOptions;
56
57
	/**
58
	 * @var \chillerlan\Threema\Gateway
59
	 */
60
	protected $threemaGateway;
61
62
	/**
63
	 * @var \ReflectionClass
64
	 */
65
	protected $reflection;
66
67
	/**
68
	 * @var array[\ReflectionMethod]
69
	 */
70
	private   $CLIRunnerInterfaceMap;
71
72
	/**
73
	 * CLIRunner constructor.
74
	 *
75
	 * @param \chillerlan\Threema\Crypto\CryptoInterface $cryptoInterface
76
	 * @param \chillerlan\Threema\GatewayOptions         $gatewayOptions
77
	 */
78
	public function __construct(CryptoInterface $cryptoInterface, GatewayOptions $gatewayOptions){
79
		$this->cryptoInterface = $cryptoInterface;
80
		$this->gatewayOptions  = $gatewayOptions;
81
		$this->threemaGateway  = new Gateway($this->cryptoInterface, $gatewayOptions);
82
		$this->reflection      = new ReflectionClass(CLIRunnerInterface::class);
83
84
		foreach($this->reflection ->getMethods() as $method){
85
			$this->CLIRunnerInterfaceMap[$method->name] = $method;
86
		}
87
	}
88
89
	/**
90
	 * @inheritdoc
91
	 */
92
	public function run(array $arguments):string{
93
		/** @noinspection PhpUnusedLocalVariableInspection */
94
		$scriptName = basename(array_shift($arguments));
0 ignored issues
show
Unused Code introduced by
$scriptName is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
95
		$command    = strtolower(array_shift($arguments));
96
97
		if(array_key_exists($command, self::COMMANDS) && array_key_exists(self::COMMANDS[$command], $this->CLIRunnerInterfaceMap)){
98
			try{
99
				$method = $this->CLIRunnerInterfaceMap[self::COMMANDS[$command]];
100
				$method = new ReflectionMethod($this, $method->name);
101
102
				// @todo: check method arguments
103
				return $this->log2cli($method->invokeArgs($this, $arguments));
104
			}
105
			catch(GatewayException $gatewayException){
106
				return $this->log2cli('ERROR: '.$gatewayException->getMessage());
107
			}
108
		}
109
110
		return $this->log2cli($this->help());
111
	}
112
113
	/**
114
	 * output a string, wrap at 100 chars
115
	 *
116
	 * @param string $string string to output
117
	 *
118
	 * @return string
119
	 */
120
	protected function log2cli(string $string):string{
121
		return PHP_EOL.wordwrap($string, 78, PHP_EOL).PHP_EOL;
122
	}
123
124
	/**
125
	 * @return string
126
	 * @codeCoverageIgnore
127
	 */
128
	protected function readStdIn(){
129
		$stdin = fopen('php://stdin', 'r');
130
		$lines = [];
131
132
		while($line = trim(fgets($stdin))){
133
134
			if(strlen($line) === 0 || $line === "\n"){
135
				continue;
136
			}
137
138
			$lines[] = $line;
139
		}
140
141
		return implode("\n", $lines);
142
	}
143
144
	/**
145
	 * @inheritdoc
146
	 */
147
	public function help():string{
148
		// return info in case no command was found
149
		$help  = 'Threema Gateway CLI tool.'.PHP_EOL;
150
		$help .= 'Crypto: '.$this->threemaGateway->cryptoVersion().PHP_EOL.PHP_EOL;
151
152
		foreach(self::COMMANDS as $command => $method){
153
			$comment = $this->reflection->getMethod($method)->getDocComment();
154
			$comment = str_replace(["\t", ' *'], '', substr($comment, 3, -2));
155
156
			$params  = explode('@', $comment);
157
			$comment = trim(array_shift($params));
158
159
			$paramNames = [];
160
			$paramDoc = [];
161
			$returnDoc = '';
162
			if(count($params) > 0){
163
				foreach($params as $p){
164
					$p = explode(' ', $p, 2);
165
					if(isset($p[1])){
166
						if($p[0] === 'param'){
167
							$p = (explode(' ', trim($p[1]), 3));
168
							$name =  '<'.trim($p[1], ' $').'>';
169
							$paramNames[] = $name;
170
							$doc = isset($p[2]) ? $name.' '.trim($p[2]) : $name;
171
							$paramDoc[] = $doc;
172
						}
173
						else if($p[0] === 'return'){
174
							$p = explode(' ', trim($p[1]), 2);
175
							$returnDoc .= isset($p[1]) ? trim($p[1]) : '';
176
						}
177
					}
178
179
				}
180
			}
181
182
			$help .= PHP_EOL.'threema.php '.$command.' '.implode(' ', $paramNames).PHP_EOL;
183
			$help .= str_repeat('-', strlen($command)+12).PHP_EOL;
184
			$help .= PHP_EOL.$comment.PHP_EOL;
185
			$help .= PHP_EOL.implode(PHP_EOL, $paramDoc).PHP_EOL;
186
			$help .= PHP_EOL.'Returns: '.$returnDoc.PHP_EOL.PHP_EOL;
187
		}
188
189
		return $help;
190
	}
191
192
	/**
193
	 * @inheritdoc
194
	 */
195
	public function getKeypair(string $privateKeyFile = null, string $publicKeyFile = null):string{
196
		$keypair = $this->cryptoInterface->getKeypair();
197
		$message = '';
198
199 View Code Duplication
		if(is_dir(dirname($privateKeyFile))){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
200
			file_put_contents($privateKeyFile, $keypair->privateKey);
201
			$message .= 'Private key saved to: '.$privateKeyFile.PHP_EOL;
202
		}
203
204 View Code Duplication
		if(is_dir(dirname($publicKeyFile))){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
205
			file_put_contents($publicKeyFile, $keypair->publicKey);
206
			$message .= 'Public key saved to: '.$publicKeyFile.PHP_EOL;
207
		}
208
209
		return $message.PHP_EOL.'private:'.$keypair->privateKey.PHP_EOL.'public:'.$keypair->publicKey;
210
	}
211
212
	/**
213
	 * @inheritdoc
214
	 */
215
	public function hashEmail(string $email):string{
216
		return $this->cryptoInterface->hmac_hash($email, GatewayInterface::HMAC_KEY_EMAIL_BIN);
217
	}
218
219
	/**
220
	 * @inheritdoc
221
	 */
222
	public function hashPhone(string $phoneNo):string{
223
		return $this->cryptoInterface->hmac_hash($phoneNo, GatewayInterface::HMAC_KEY_PHONE_BIN);
224
	}
225
226
	/**
227
	 * @inheritdoc
228
	 */
229
	public function checkCredits():string{
230
		return $this->threemaGateway->checkCredits();
231
	}
232
233
	/**
234
	 * @inheritdoc
235
	 */
236
	public function checkCapabilities(string $threemaID):string{
237
		return implode(',', $this->threemaGateway->checkCapabilities($threemaID));
238
	}
239
240
	/**
241
	 * @inheritdoc
242
	 */
243
	public function getIdByEmail(string $email):string{
244
		return $this->threemaGateway->getIdByEmailHash($this->hashEmail($email));
245
	}
246
247
	/**
248
	 * @inheritdoc
249
	 */
250
	public function getIdByPhone(string $phoneNo):string{
251
		return $this->threemaGateway->getIdByPhoneHash($this->hashPhone($phoneNo));
252
	}
253
254
	/**
255
	 * @inheritdoc
256
	 */
257
	public function getPubkeyById(string $threemaID):string{
258
		return $this->threemaGateway->getPublicKey($threemaID);
259
	}
260
261
}
262