Skip to content

Commit 60a8f60

Browse files
Add agents controller
1 parent aead38b commit 60a8f60

File tree

10 files changed

+185
-12
lines changed

10 files changed

+185
-12
lines changed

composer.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

database/01-schema.sql

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,5 +561,24 @@ CREATE TABLE notification
561561
) ENGINE = InnoDB
562562
CHARSET = utf8mb4;
563563

564+
DROP TABLE IF EXISTS agent;
565+
566+
CREATE TABLE agent
567+
(
568+
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
569+
client_id VARCHAR(100) NOT NULL,
570+
last_boot_at TIMESTAMP NULL,
571+
last_ping_at TIMESTAMP NULL,
572+
active BOOLEAN NOT NULL DEFAULT FALSE,
573+
version VARCHAR(100) NULL,
574+
hostname VARCHAR(100) NULL,
575+
arch VARCHAR(100) NULL,
576+
cpu VARCHAR(100) NULL,
577+
memory VARCHAR(100) NULL,
578+
os VARCHAR(100) NULL,
579+
PRIMARY KEY (id)
580+
) ENGINE = InnoDB,
581+
CHARSET = utf8mb4;
582+
564583
SET
565584
FOREIGN_KEY_CHECKS = 1;

run-tests.sh

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
set -e
33

44
export XDEBUG_MODE=coverage
5-
export XDEBUG_MODE=off
6-
export PHPUNIT_ARGS="--coverage-clover=\"/var/www/webapp/tests/clover.xml\""
7-
export PHPUNIT_ARGS="--no-coverage --display-warnings"
5+
export PHPUNIT_ARGS=" --display-warnings --coverage-clover=\"/var/www/webapp/tests/clover.xml\""
86

97
pushd /var/www/webapp
108
./vendor/bin/phpunit $PHPUNIT_ARGS

src/ApiRouter.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
use OpenApi\Attributes\Server;
1212
use Psr\Container\ContainerInterface;
1313
use Psr\Log\LoggerInterface;
14-
use Reconmap\{Controllers\Attachments\ServeAttachmentController,
14+
use Reconmap\{Controllers\Agents\AgentsRouter,
15+
Controllers\Attachments\ServeAttachmentController,
1516
Controllers\AuditLog\AuditLogRouter,
1617
Controllers\Auth\AuthRouter,
1718
Controllers\Clients\ClientsRouter,
@@ -49,6 +50,7 @@ class ApiRouter extends Router
4950
{
5051
private const array ROUTER_CLASSES = [
5152
AuthRouter::class,
53+
AgentsRouter::class,
5254
AttachmentsRouter::class,
5355
AuditLogRouter::class,
5456
CommandsRouter::class,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Reconmap\Controllers\Agents;
4+
5+
use League\Route\RouteCollectionInterface;
6+
7+
class AgentsRouter
8+
{
9+
public function mapRoutes(RouteCollectionInterface $router): void
10+
{
11+
$router->map('GET', '/agents', GetAgentsController::class);
12+
$router->map('GET', '/agents/ping', PingAgentController::class);
13+
$router->map('POST', '/agents/boot', BootAgentController::class);
14+
}
15+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Reconmap\Controllers\Agents;
4+
5+
use OpenApi\Attributes as OpenApi;
6+
use Psr\Http\Message\ServerRequestInterface;
7+
use Reconmap\Controllers\Controller;
8+
use Reconmap\Http\Docs\Default200OkResponse;
9+
use Reconmap\Http\Docs\Default403UnauthorisedResponse;
10+
use Reconmap\Repositories\AgentRepository;
11+
12+
#[OpenApi\Get(path: "/agents/boot", description: "Returns information about all agents", security: ["bearerAuth"], tags: ["Agents"])]
13+
#[Default200OkResponse]
14+
#[Default403UnauthorisedResponse]
15+
class BootAgentController extends Controller
16+
{
17+
18+
public function __construct(private readonly AgentRepository $repository)
19+
{
20+
}
21+
22+
public function __invoke(ServerRequestInterface $request): array
23+
{
24+
$info = $this->getJsonBodyDecoded($request);
25+
26+
return $this->repository->updateLastBootAt($info);
27+
}
28+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Reconmap\Controllers\Agents;
4+
5+
use OpenApi\Attributes as OpenApi;
6+
use Psr\Http\Message\ServerRequestInterface;
7+
use Reconmap\Controllers\Controller;
8+
use Reconmap\Http\Docs\Default200OkResponse;
9+
use Reconmap\Http\Docs\Default403UnauthorisedResponse;
10+
use Reconmap\Repositories\AgentRepository;
11+
12+
#[OpenApi\Get(path: "/agents", description: "Returns information about all agents", security: ["bearerAuth"], tags: ["Agents"])]
13+
#[Default200OkResponse]
14+
#[Default403UnauthorisedResponse]
15+
class GetAgentsController extends Controller
16+
{
17+
18+
public function __construct(private readonly AgentRepository $repository)
19+
{
20+
}
21+
22+
public function __invoke(ServerRequestInterface $request): array
23+
{
24+
return $this->repository->findAll();
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Reconmap\Controllers\Agents;
4+
5+
use OpenApi\Attributes as OpenApi;
6+
use Psr\Http\Message\ServerRequestInterface;
7+
use Reconmap\Controllers\Controller;
8+
use Reconmap\Http\Docs\Default200OkResponse;
9+
use Reconmap\Http\Docs\Default403UnauthorisedResponse;
10+
use Reconmap\Repositories\AgentRepository;
11+
12+
#[OpenApi\Get(path: "/agents/ping", description: "Returns information about all agents", security: ["bearerAuth"], tags: ["Agents"])]
13+
#[Default200OkResponse]
14+
#[Default403UnauthorisedResponse]
15+
class PingAgentController extends Controller
16+
{
17+
18+
public function __construct(private readonly AgentRepository $repository)
19+
{
20+
}
21+
22+
public function __invoke(ServerRequestInterface $request): array
23+
{
24+
return $this->repository->updateLastPingAt();
25+
}
26+
}

src/Http/AuthMiddleware.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
6565

6666
$tokenRole = $this->extractRoleFromToken($token);
6767
$request = $request->withAttribute('userId', $dbUser['id'])
68-
->withAttribute('role', $tokenRole);
68+
->withAttribute('role', $tokenRole)
69+
->withAttribute('token', $jwt);
6970
}
7071
return $handler->handle($request);
7172
} catch (ForbiddenException|ExpiredException $e) {
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Reconmap\Repositories;
4+
5+
use Ponup\SqlBuilders\SelectQueryBuilder;
6+
7+
class AgentRepository extends MysqlRepository
8+
{
9+
public const array UPDATABLE_COLUMNS_TYPES = [
10+
'version' => 's',
11+
'hostname' => 's',
12+
'arch' => 's',
13+
'cpu' => 's',
14+
'memory' => 's',
15+
'os' => 's',
16+
'active' => 'i',
17+
'last_boot_at' => 's',
18+
'last_ping_at' => 's',
19+
];
20+
21+
public function findAll(): array
22+
{
23+
$queryBuilder = $this->getBaseSelectQueryBuilder();
24+
$result = $this->mysqlServer->query($queryBuilder->toSql());
25+
return $result->fetch_all(MYSQLI_ASSOC);
26+
}
27+
28+
public function updateLastPingAt(): bool
29+
{
30+
return $this->updateByTableId('agent', 1, ['last_ping_at' => date('Y-m-d H:i:s')]);
31+
}
32+
33+
public function updateLastBootAt(object $info): bool
34+
{
35+
$currentDateTime = date('Y-m-d H:i:s');
36+
37+
return $this->updateByTableId('agent', 1, [
38+
'version' => $info->version,
39+
'hostname' => $info->hostname,
40+
'arch' => $info->arch,
41+
'cpu' => $info->cpu,
42+
'memory' => $info->memory,
43+
'os' => $info->os,
44+
'last_boot_at' => $currentDateTime,
45+
'last_ping_at' => $currentDateTime
46+
]);
47+
}
48+
49+
protected function getBaseSelectQueryBuilder(): SelectQueryBuilder
50+
{
51+
$queryBuilder = new SelectQueryBuilder('agent a');
52+
$queryBuilder->setColumns('
53+
a.*
54+
');
55+
$queryBuilder->setOrderBy('a.client_id ASC, a.last_ping_at DESC');
56+
return $queryBuilder;
57+
}
58+
}

0 commit comments

Comments
 (0)