Skip to content

Commit 852ed19

Browse files
authored
Merge pull request #1 from noplanman/develop
Allow CLI call to skip secret and action validations.
2 parents 55fcd6b + f2b2297 commit 852ed19

File tree

3 files changed

+181
-56
lines changed

3 files changed

+181
-56
lines changed

.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
end_of_line = lf
5+
insert_final_newline = true
6+
charset = utf-8
7+
indent_style = space
8+
indent_size = 4
9+
trim_trailing_whitespace = true

src/BotManager.php

Lines changed: 155 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -33,31 +33,128 @@ class BotManager
3333
*/
3434
public $test_output;
3535

36-
/** vitals */
37-
public $api_key;
36+
/**
37+
* @var string Telegram Bot API key
38+
*/
39+
protected $api_key = '';
40+
41+
/**
42+
* @var string Telegram Bot name
43+
*/
3844
public $botname;
45+
46+
/**
47+
* @var string Secret string to validate calls
48+
*/
3949
public $secret;
4050

41-
public $action;
51+
/**
52+
* @var string Action to be executed
53+
*/
54+
public $action = 'handle';
55+
56+
/**
57+
* @var string URI of the webhook
58+
*/
4259
public $webhook;
60+
61+
/**
62+
* @var string Path to the self-signed certificate
63+
*/
4364
public $selfcrt;
4465

45-
/**
46-
* BotManager constructor that assigns all necessary member variables.
47-
*
48-
* @param array $vars
49-
*
50-
* @throws \Exception
51-
*/
66+
/**
67+
* @var array Array of logger files to set
68+
*/
69+
public $logging;
70+
71+
/**
72+
* @var array List of admins to enable
73+
*/
74+
public $admins;
75+
76+
/**
77+
* @var array MySQL credentials to use
78+
*/
79+
public $mysql;
80+
81+
/**
82+
* @var string Custom download path to set
83+
*/
84+
public $download_path;
85+
86+
/**
87+
* @var string Custom upload path to set
88+
*/
89+
public $upload_path;
90+
91+
/**
92+
* @var array Custom commands paths to set
93+
*/
94+
public $commands_paths;
95+
96+
/**
97+
* @var array List of custom command configs
98+
*/
99+
public $command_configs;
100+
101+
/**
102+
* @var string Botan token to enable botan.io support
103+
*/
104+
public $botan_token;
105+
106+
/**
107+
* @var string Custom raw JSON string to use as input
108+
*/
109+
public $custom_input;
110+
111+
/**
112+
* @var array List of valid actions that can be called
113+
*/
114+
private static $valid_actions = [
115+
'set',
116+
'unset',
117+
'reset',
118+
'handle'
119+
];
120+
121+
/**
122+
* @var array List of valid extra parameters that can be passed
123+
*/
124+
private static $valid_params = [
125+
'api_key',
126+
'botname',
127+
'secret',
128+
'webhook',
129+
'selfcrt',
130+
'logging',
131+
'admins',
132+
'mysql',
133+
'download_path',
134+
'upload_path',
135+
'commands_paths',
136+
'command_configs',
137+
'botan_token',
138+
'custom_input'
139+
];
140+
141+
142+
/**
143+
* BotManager constructor that assigns all necessary member variables.
144+
*
145+
* @param array $vars
146+
*
147+
* @throws \Exception
148+
*/
52149
public function __construct(array $vars)
53150
{
54151
if (!isset($vars['api_key'], $vars['botname'], $vars['secret'])) {
55152
throw new \Exception('Some vital info is missing (api_key, botname or secret)');
56153
}
57154

58-
// Set all important info.
155+
// Set all vital and extra parameters.
59156
foreach ($vars as $var => $value) {
60-
$this->$var = $value;
157+
in_array($var, self::$valid_params, true) && $this->$var = $value;
61158
}
62159
}
63160

@@ -94,6 +191,16 @@ public function run()
94191
return $this;
95192
}
96193

194+
/**
195+
* Check if this script is being called from CLI.
196+
*
197+
* @return bool
198+
*/
199+
public function isCli()
200+
{
201+
return PHP_SAPI === 'cli';
202+
}
203+
97204
/**
98205
* Allow this script to be called via CLI.
99206
*
@@ -102,7 +209,7 @@ public function run()
102209
public function makeCliFriendly()
103210
{
104211
// If we're running from CLI, properly set $_GET.
105-
if (PHP_SAPI === 'cli') {
212+
if ($this->isCli()) {
106213
// We don't need the first arg (the file name).
107214
$args = array_slice($_SERVER['argv'], 1);
108215

@@ -120,7 +227,7 @@ public function makeCliFriendly()
120227
*/
121228
public function initLogging()
122229
{
123-
if (isset($this->logging) && is_array($this->logging)) {
230+
if (is_array($this->logging)) {
124231
foreach ($this->logging as $logger => $logfile) {
125232
('debug' === $logger) && TelegramLog::initDebugLog($logfile);
126233
('error' === $logger) && TelegramLog::initErrorLog($logfile);
@@ -134,13 +241,19 @@ public function initLogging()
134241
/**
135242
* Make sure the passed secret is valid.
136243
*
244+
* @param bool $force Force validation, even on CLI.
245+
*
246+
* @return $this
137247
* @throws \Exception
138248
*/
139-
public function validateSecret()
249+
public function validateSecret($force = false)
140250
{
141-
$secretGet = isset($_GET['s']) ? (string)$_GET['s'] : '';
142-
if (empty($this->secret) || $secretGet !== $this->secret) {
143-
throw new \Exception('Invalid access');
251+
// If we're running from CLI, secret isn't necessary.
252+
if ($force || !$this->isCli()) {
253+
$secretGet = isset($_GET['s']) ? (string)$_GET['s'] : '';
254+
if (empty($this->secret) || $secretGet !== $this->secret) {
255+
throw new \Exception('Invalid access');
256+
}
144257
}
145258

146259
return $this;
@@ -153,9 +266,10 @@ public function validateSecret()
153266
*/
154267
public function validateAndSetAction()
155268
{
156-
$validActions = ['set', 'unset', 'reset', 'handle'];
157-
$this->action = isset($_GET['a']) ? (string)$_GET['a'] : '';
158-
if (!$this->isAction($validActions)) {
269+
// Only set the action if it has been passed, else use the default.
270+
isset($_GET['a']) && $this->action = (string)$_GET['a'];
271+
272+
if (!$this->isAction(self::$valid_actions)) {
159273
throw new \Exception('Invalid action');
160274
}
161275

@@ -177,7 +291,10 @@ public function validateAndSetWebhook()
177291
$this->test_output = $this->telegram->unsetWebHook()->getDescription();
178292
}
179293
if ($this->isAction(['set', 'reset'])) {
180-
$this->test_output = $this->telegram->setWebHook($this->webhook . '?a=handle&s=' . $this->secret, $this->selfcrt)->getDescription();
294+
$this->test_output = $this->telegram->setWebHook(
295+
$this->webhook . '?a=handle&s=' . $this->secret,
296+
$this->selfcrt
297+
)->getDescription();
181298
}
182299

183300
(@constant('PHPUNIT_TEST') !== true) && print($this->test_output . PHP_EOL);
@@ -188,7 +305,7 @@ public function validateAndSetWebhook()
188305
/**
189306
* Check if the current action is one of the passed ones.
190307
*
191-
* @param $actions
308+
* @param string|array $actions
192309
*
193310
* @return bool
194311
*/
@@ -242,7 +359,9 @@ public function handleRequest()
242359
/**
243360
* Loop the getUpdates method for the passed amount of seconds.
244361
*
245-
* @param $loop_time_in_seconds int
362+
* @param int $loop_time_in_seconds
363+
*
364+
* @return $this
246365
*/
247366
public function handleGetUpdatesLoop($loop_time_in_seconds)
248367
{
@@ -277,15 +396,15 @@ public function handleGetUpdates()
277396
/** @var Entities\Update $result */
278397
foreach ($results as $result) {
279398
$chat_id = 0;
280-
$text = 'Nothing';
399+
$text = 'Nothing';
281400

282401
$update_content = $result->getUpdateContent();
283402
if ($update_content instanceof Entities\Message) {
284403
$chat_id = $update_content->getFrom()->getId();
285-
$text = $update_content->getText();
404+
$text = $update_content->getText();
286405
} elseif ($update_content instanceof Entities\InlineQuery || $update_content instanceof Entities\ChosenInlineResult) {
287406
$chat_id = $update_content->getFrom()->getId();
288-
$text = $update_content->getQuery();
407+
$text = $update_content->getQuery();
289408
}
290409

291410
printf(
@@ -318,15 +437,15 @@ public function handleWebhook()
318437
*/
319438
public function setBotExtras()
320439
{
321-
isset($this->admins) && $this->telegram->enableAdmins((array)$this->admins);
322-
isset($this->mysql) && $this->telegram->enableMySql($this->mysql);
323-
isset($this->botan_token) && $this->telegram->enableBotan($this->botan_token);
324-
isset($this->commands_paths) && $this->telegram->addCommandsPaths((array)$this->commands_paths);
325-
isset($this->custom_input) && $this->telegram->setCustomInput($this->custom_input);
326-
isset($this->download_path) && $this->telegram->setDownloadPath($this->download_path);
327-
isset($this->upload_path) && $this->telegram->setUploadPath($this->upload_path);
328-
329-
if (isset($this->command_configs) && is_array($this->command_configs)) {
440+
$this->admins && $this->telegram->enableAdmins($this->admins);
441+
$this->mysql && $this->telegram->enableMySql($this->mysql);
442+
$this->botan_token && $this->telegram->enableBotan($this->botan_token);
443+
$this->commands_paths && $this->telegram->addCommandsPaths($this->commands_paths);
444+
$this->custom_input && $this->telegram->setCustomInput($this->custom_input);
445+
$this->download_path && $this->telegram->setDownloadPath($this->download_path);
446+
$this->upload_path && $this->telegram->setUploadPath($this->upload_path);
447+
448+
if (is_array($this->command_configs)) {
330449
foreach ($this->command_configs as $command => $config) {
331450
$this->telegram->setCommandConfig($command, $config);
332451
}

tests/BotManagerTest.php

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,13 @@ public function setUp()
6363
public function testSetParameters()
6464
{
6565
$botManager = new BotManager(array_merge($this->vitalParams, [
66-
'param1' => 'param1value',
67-
'param2' => 'param2value',
68-
'param3' => 'param3value',
66+
'admins' => [1], // valid
67+
'upload_path' => '/upload/path', // valid
68+
'paramX' => 'something' // invalid
6969
]));
70-
self::assertEquals('param1value', $botManager->param1);
71-
self::assertEquals('param2value', $botManager->param2);
72-
self::assertEquals('param3value', $botManager->param3);
73-
74-
self::assertObjectNotHasAttribute('param4', $botManager);
70+
self::assertEquals([1], $botManager->admins);
71+
self::assertEquals('/upload/path', $botManager->upload_path);
72+
self::assertObjectNotHasAttribute('paramX', $botManager);
7573
}
7674

7775
/**
@@ -161,24 +159,20 @@ public function testValidateSecretFail()
161159
$_GET = ['s' => 'NOT_my_secret_12345'];
162160
$botManager = new BotManager(array_merge($this->vitalParams, ['secret' => 'my_secret_12345']));
163161

164-
$botManager->validateSecret();
162+
$botManager->validateSecret(true);
165163
}
166164

167165
public function testValidateSecretSuccess()
168166
{
169-
$_GET = ['s' => 'my_secret_12345'];
170167
$botManager = new BotManager(array_merge($this->vitalParams, ['secret' => 'my_secret_12345']));
171168

172-
self::assertEquals($botManager, $botManager->validateSecret());
173-
}
169+
// Force validation to test non-CLI scenario.
170+
$_GET = ['s' => 'my_secret_12345'];
171+
$botManager->validateSecret(true);
174172

175-
/**
176-
* @expectedException \Exception
177-
* @expectedExceptionMessage Invalid action
178-
*/
179-
public function testValidateAndSetActionFailWithoutAction()
180-
{
181-
(new BotManager($this->vitalParams))->validateAndSetAction();
173+
// Calling from CLI doesn't require a secret.
174+
$_GET = ['s' => 'whatever_on_cli'];
175+
$botManager->validateSecret();
182176
}
183177

184178
/**
@@ -195,6 +189,9 @@ public function testValidateAndSetActionSuccess()
195189
{
196190
$botManager = new BotManager($this->vitalParams);
197191

192+
// Default value.
193+
self::assertEquals('handle', $botManager->validateAndSetAction()->action);
194+
198195
$validActions = ['set', 'unset', 'reset', 'handle'];
199196
foreach ($validActions as $action) {
200197
$_GET = ['a' => $action];
@@ -220,7 +217,7 @@ public function testValidateAndSetWebhookSuccess()
220217
$botManager->telegram->expects(static::any())
221218
->method('getDescription')
222219
->will(static::onConsecutiveCalls(
223-
// set
220+
// set
224221
'Webhook set',
225222
'Webhook already set',
226223
// unset

0 commit comments

Comments
 (0)