Skip to content

Commit 952e4ef

Browse files
Merge pull request #4 from matracine/login-legacy
Fix #3: Add test on responses count when login, try with legacy=true …
2 parents 40e82b7 + dac8fb6 commit 952e4ef

2 files changed

Lines changed: 48 additions & 2 deletions

File tree

src/Client.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,12 +358,13 @@ private function pregResponse(string $value, &$matches)
358358
/**
359359
* Authorization logic
360360
*
361+
* @param bool $legacyRetry Retry login if we detect legacy version of RouterOS
361362
* @return bool
362363
* @throws \RouterOS\Exceptions\ClientException
363364
* @throws \RouterOS\Exceptions\ConfigException
364365
* @throws \RouterOS\Exceptions\QueryException
365366
*/
366-
private function login(): bool
367+
private function login(bool $legacyRetry = false): bool
367368
{
368369
// If legacy login scheme is enabled
369370
if ($this->config('legacy')) {
@@ -380,13 +381,39 @@ private function login(): bool
380381
$query = (new Query('/login'))
381382
->add('=name=' . $this->config('user'))
382383
->add('=password=' . $this->config('pass'));
384+
385+
// If we set modern auth scheme but router with legacy firmware then need to retry query,
386+
// but need to prevent endless loop
387+
$legacyRetry = true;
383388
}
384389

385390
// Execute query and get response
386391
$response = $this->write($query)->read(false);
387392

393+
// if:
394+
// - we have more than one response
395+
// - response is '!done'
396+
// => problem with legacy version, swap it and retry
397+
// Only tested with ROS pre 6.43, will test with post 6.43 => this could make legacy parameter obsolete?
398+
if ($legacyRetry && $this->isLegacy($response)) {
399+
$this->_config->set('legacy', true);
400+
return $this->login();
401+
}
402+
388403
// Return true if we have only one line from server and this line is !done
389-
return isset($response[0]) && $response[0] === '!done';
404+
return (1 === count($response)) && isset($response[0]) && ($response[0] === '!done');
405+
}
406+
407+
/**
408+
* Detect by login request if firmware is legacy
409+
*
410+
* @param array $response
411+
* @return bool
412+
* @throws ConfigException
413+
*/
414+
private function isLegacy(array &$response): bool
415+
{
416+
return \count($response) > 1 && $response[0] === '!done' && !$this->config('legacy');
390417
}
391418

392419
/**

tests/ClientTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,25 @@ public function test__constructLegacy()
8282
}
8383
}
8484

85+
/**
86+
* Test non legacy connection on legacy router (pre 6.43)
87+
*
88+
* login() method recognise legacy router response and swap to legacy mode
89+
*/
90+
public function test__constructLegacy2()
91+
{
92+
try {
93+
$config = new Config();
94+
$config->set('user', 'admin')->set('pass', 'admin')
95+
->set('host', '127.0.0.1')->set('port', 18728)->set('legacy', false);
96+
$obj = new Client($config);
97+
$this->assertInternalType('object', $obj);
98+
} catch (\Exception $e) {
99+
$this->assertContains('Must be initialized ', $e->getMessage());
100+
}
101+
}
102+
103+
85104
public function test__constructWrongPass()
86105
{
87106
$this->expectException(ClientException::class);

0 commit comments

Comments
 (0)