Skip to content

Commit

Permalink
Merge pull request #416 from chesslablab/issue/411-Parallelize-the-to…
Browse files Browse the repository at this point in the history
…tp_refresh-command

Issue/411 parallelize the totp refresh command
  • Loading branch information
programarivm authored Oct 5, 2024
2 parents 6e1cd12 + 75badb3 commit 10c9f84
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 81 deletions.
12 changes: 1 addition & 11 deletions cli/ratchet/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace ChessServer\Cli\Ratchet;

use ChessServer\Db;
use ChessServer\Command\Parser;
use ChessServer\Command\Auth\Cli;
use ChessServer\Socket\Ratchet\ClientStorage;
Expand All @@ -13,7 +12,6 @@
use Ratchet\Http\HttpServer;
use Ratchet\Server\IoServer;
use Ratchet\WebSocket\WsServer;
use React\EventLoop\Factory;
use React\Socket\LimitingServer;
use React\Socket\Server;
use React\Socket\SecureServer;
Expand All @@ -26,18 +24,10 @@

$pool = Pool::create();

$db = new Db([
'driver' => $_ENV['DB_DRIVER'],
'host' => $_ENV['DB_HOST'],
'database' => $_ENV['DB_DATABASE'],
'username' => $_ENV['DB_USERNAME'],
'password' => $_ENV['DB_PASSWORD'],
]);

$logger = new Logger('auth');
$logger->pushHandler(new StreamHandler(__DIR__.'/../../storage' . '/auth.log', Logger::INFO));

$parser = new Parser(new Cli($pool, $db));
$parser = new Parser(new Cli($pool));

$clientStorage = new ClientStorage($logger);

Expand Down
11 changes: 1 addition & 10 deletions cli/workerman/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace ChessServer\Cli\Workerman;

use ChessServer\Db;
use ChessServer\Command\Parser;
use ChessServer\Command\Auth\Cli;
use ChessServer\Socket\Workerman\ClientStorage;
Expand All @@ -19,18 +18,10 @@

$pool = Pool::create();

$db = new Db([
'driver' => $_ENV['DB_DRIVER'],
'host' => $_ENV['DB_HOST'],
'database' => $_ENV['DB_DATABASE'],
'username' => $_ENV['DB_USERNAME'],
'password' => $_ENV['DB_PASSWORD'],
]);

$logger = new Logger('auth');
$logger->pushHandler(new StreamHandler(AuthWebSocket::STORAGE_FOLDER . '/auth.log', Logger::INFO));

$parser = new Parser(new Cli($pool, $db));
$parser = new Parser(new Cli($pool));

$clientStorage = new ClientStorage($logger);

Expand Down
8 changes: 2 additions & 6 deletions src/Command/Auth/Cli.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,16 @@

namespace ChessServer\Command\Auth;

use ChessServer\Db;
use ChessServer\Command\AbstractCli;
use Spatie\Async\Pool;

class Cli extends AbstractCli
{
private Db $db;

public function __construct(Pool $pool, Db $db)
public function __construct(Pool $pool)
{
parent::__construct();

$this->db = $db;
$this->commands->attach(new TotpRefreshCommand($db));
$this->commands->attach((new TotpRefreshCommand())->setPool($pool));
$this->commands->attach((new TotpSignInCommand())->setPool($pool));
$this->commands->attach((new TotpSignUpCommand())->setPool($pool));
}
Expand Down
54 changes: 54 additions & 0 deletions src/Command/Auth/TotpRefreshAsyncTask.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace ChessServer\Command\Auth;

use ChessServer\Db;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Spatie\Async\Task;

class TotpRefreshAsyncTask extends Task
{
private array $params;

private array $env;

private Db $db;

public function __construct(array $params, array $env)
{
$this->params = $params;
$this->env = $env;
}

public function configure()
{
$this->db = new Db($this->env['db']);
}

public function run()
{
if (isset($this->params['access_token'])) {
$decoded = JWT::decode($this->params['access_token'], new Key($this->env['jwt']['secret'], 'HS256'));
$sql = "SELECT * FROM users WHERE username = :username";
$values[] = [
'param' => ":username",
'value' => $decoded->username,
'type' => \PDO::PARAM_STR,
];
$arr = $this->db->query($sql, $values)->fetch(\PDO::FETCH_ASSOC);
$payload = [
'iss' => $this->env['jwt']['iss'],
'iat' => time(),
'exp' => time() + 3600, // one hour by default
'username' => $arr['username'],
'elo' => $arr['elo'],
];
return [
'access_token' => JWT::encode($payload, $this->env['jwt']['secret'], 'HS256'),
];
}

return null;
}
}
51 changes: 20 additions & 31 deletions src/Command/Auth/TotpRefreshCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,13 @@

namespace ChessServer\Command\Auth;

use ChessServer\Db;
use ChessServer\Command\AbstractCommand;
use ChessServer\Socket\AbstractSocket;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

class TotpRefreshCommand extends AbstractCommand
{
public function __construct(Db $db)
public function __construct()
{
parent::__construct($db);

$this->name = '/totp_refresh';
$this->description = 'Refresh the TOTP access token.';
$this->params = [
Expand All @@ -30,31 +25,25 @@ public function run(AbstractSocket $socket, array $argv, int $id)
{
$params = json_decode(stripslashes($argv[1]), true);

if (isset($params['access_token'])) {
$decoded = JWT::decode($params['access_token'], new Key($_ENV['JWT_SECRET'], 'HS256'));
$sql = "SELECT * FROM users WHERE username = :username";
$values[] = [
'param' => ":username",
'value' => $decoded->username,
'type' => \PDO::PARAM_STR,
];
$arr = $this->db->query($sql, $values)->fetch(\PDO::FETCH_ASSOC);
$payload = [
'iss' => $_ENV['JWT_ISS'],
'iat' => time(),
'exp' => time() + 3600, // one hour by default
'username' => $arr['username'],
'elo' => $arr['elo'],
];
return $socket->getClientStorage()->send([$id], [
$this->name => [
'access_token' => JWT::encode($payload, $_ENV['JWT_SECRET'], 'HS256'),
],
]);
}
$env = [
'db' => [
'driver' => $_ENV['DB_DRIVER'],
'host' => $_ENV['DB_HOST'],
'database' => $_ENV['DB_DATABASE'],
'username' => $_ENV['DB_USERNAME'],
'password' => $_ENV['DB_PASSWORD'],
],
'jwt' => [
'iss' => $_ENV['JWT_ISS'],
'secret' => $_ENV['JWT_SECRET'],
],
];

return $socket->getClientStorage()->send([$id], [
$this->name => null,
]);
$this->pool->add(new TotpRefreshAsyncTask($params, $env))
->then(function ($result) use ($socket, $id) {
return $socket->getClientStorage()->send([$id], [
$this->name => $result,
]);
});
}
}
1 change: 0 additions & 1 deletion src/Command/Data/Cli.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace ChessServer\Command\Data;

use ChessServer\Db;
use ChessServer\Command\AbstractCli;
use Spatie\Async\Pool;

Expand Down
12 changes: 0 additions & 12 deletions src/Socket/Ratchet/AuthWebSocket.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,10 @@
namespace ChessServer\Socket\Ratchet;

use ChessServer\Command\Parser;
use ChessServer\Socket\DbReconnectTrait;
use Ratchet\ConnectionInterface;

class AuthWebSocket extends AbstractWebSocket
{
use DbReconnectTrait;

public function __construct(Parser $parser)
{
parent::__construct($parser);

$this->loop->addPeriodicTimer($this->timeInterval, function() {
$this->reconnect();
});
}

public function onClose(ConnectionInterface $conn)
{
$this->clientStorage->detachById($conn->resourceId);
Expand Down
10 changes: 0 additions & 10 deletions src/Socket/Workerman/AuthWebSocket.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,13 @@
namespace ChessServer\Socket\Workerman;

use ChessServer\Command\Parser;
use ChessServer\Socket\DbReconnectTrait;
use Workerman\Timer;

class AuthWebSocket extends AbstractWebSocket
{
use DbReconnectTrait;

public function __construct(string $socketName, array $context, Parser $parser)
{
parent::__construct($socketName, $context, $parser);

$this->worker->onWorkerStart = function() {
Timer::add($this->timeInterval, function() {
$this->reconnect();
});
};

$this->connect()->message()->error()->close();
}

Expand Down

0 comments on commit 10c9f84

Please sign in to comment.