Skip to content
This repository was archived by the owner on Jul 2, 2025. It is now read-only.

Commit bbbd582

Browse files
authored
feat: add project et environment to caller (#142)
1 parent cb4987d commit bbbd582

File tree

3 files changed

+85
-42
lines changed

3 files changed

+85
-42
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
namespace ForestAdmin\AgentPHP\Agent\Utils;
4+
5+
use Firebase\JWT\JWT;
6+
use Firebase\JWT\Key;
7+
use ForestAdmin\AgentPHP\Agent\Http\Request;
8+
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Caller;
9+
use ForestAdmin\AgentPHP\DatasourceToolkit\Exceptions\ForestException;
10+
11+
use function ForestAdmin\config;
12+
13+
use Symfony\Component\HttpFoundation\Response;
14+
use Symfony\Component\HttpKernel\Exception\HttpException;
15+
16+
class CallerParser
17+
{
18+
public function __construct(
19+
protected Request $request,
20+
) {
21+
}
22+
23+
public function parse(): Caller
24+
{
25+
$this->validateHeaders();
26+
$params = $this->decodeToken();
27+
$params['timezone'] = $this->extractTimezone();
28+
$params['request'] = [ 'ip' => $this->request->getClientIp()];
29+
[$project, $environment] = $this->extractForestContext();
30+
$params['project'] = $project;
31+
$params['environment'] = $environment;
32+
33+
return Caller::makeFromRequestData($params);
34+
}
35+
36+
private function validateHeaders(): void
37+
{
38+
if (! $this->request->bearerToken()) {
39+
throw new HttpException(Response::HTTP_UNAUTHORIZED, 'You must be logged in to access at this resource.');
40+
}
41+
}
42+
43+
private function decodeToken(): array
44+
{
45+
$decoded = (array) JWT::decode($this->request->bearerToken(), new Key(config('authSecret'), 'HS256'));
46+
unset($decoded['exp']);
47+
48+
if (isset($decoded['tags']) && $decoded['tags'] instanceof \stdClass) {
49+
$decoded['tags'] = (array) $decoded['tags'];
50+
}
51+
52+
return $decoded;
53+
}
54+
55+
private function extractTimezone(): string
56+
{
57+
$timezone = $this->request->get('timezone');
58+
59+
if (! $timezone) {
60+
throw new ForestException('Missing timezone');
61+
}
62+
63+
if (! in_array($timezone, \DateTimeZone::listIdentifiers(), true)) {
64+
throw new ForestException("Invalid timezone: $timezone");
65+
}
66+
67+
return $timezone;
68+
}
69+
70+
private function extractForestContext(): array
71+
{
72+
$forestContextUrl = $this->request->header('forest-context-url');
73+
74+
if (preg_match('/https:\/\/[^\/]*\/([^\/]*)\/([^\/]*)/', $forestContextUrl, $matches)) {
75+
return [$matches[1], $matches[2]];
76+
}
77+
78+
return [null, null];
79+
}
80+
}

packages/Agent/src/Utils/QueryStringParser.php

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
namespace ForestAdmin\AgentPHP\Agent\Utils;
44

5-
use Firebase\JWT\JWT;
6-
use Firebase\JWT\Key;
75
use ForestAdmin\AgentPHP\Agent\Http\Request;
86
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Caller;
97
use ForestAdmin\AgentPHP\DatasourceToolkit\Components\Contracts\CollectionContract;
@@ -18,11 +16,8 @@
1816
use ForestAdmin\AgentPHP\DatasourceToolkit\Validations\ProjectionValidator;
1917
use ForestAdmin\AgentPHP\DatasourceToolkit\Validations\SortValidator;
2018

21-
use function ForestAdmin\config;
2219

2320
use Illuminate\Support\Str;
24-
use Symfony\Component\HttpFoundation\Response;
25-
use Symfony\Component\HttpKernel\Exception\HttpException;
2621

2722
class QueryStringParser
2823
{
@@ -134,29 +129,7 @@ public static function parseSegment(CollectionContract $collection, Request $req
134129
*/
135130
public static function parseCaller(Request $request): Caller
136131
{
137-
if (! $request->bearerToken()) {
138-
throw new HttpException(Response::HTTP_UNAUTHORIZED, 'You must be logged in to access at this resource.');
139-
}
140-
141-
$timezone = $request->get('timezone');
142-
$params = [
143-
'timezone' => $timezone,
144-
'request' => [
145-
'ip' => $request->getClientIp(),
146-
],
147-
];
148-
149-
if (! $timezone) {
150-
throw new ForestException('Missing timezone');
151-
}
152-
153-
if (! in_array($timezone, \DateTimeZone::listIdentifiers(), true)) {
154-
throw new ForestException("Invalid timezone: $timezone");
155-
}
156-
157-
$tokenData = JWT::decode($request->bearerToken(), new Key(config('authSecret'), 'HS256'));
158-
159-
return Caller::makeFromRequestData($tokenData, $params);
132+
return (new CallerParser($request))->parse();
160133
}
161134

162135
/**

packages/DatasourceToolkit/src/Components/Caller.php

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,15 @@ public function __construct(
1818
protected string $permissionLevel,
1919
protected ?string $role = null,
2020
protected array $request = [],
21+
protected ?string $project = null,
22+
protected ?string $environment = null,
2123
) {
2224
}
2325

24-
public static function makeFromRequestData(object $requestObjectData, array $params): self
26+
public static function makeFromRequestData(array $params): self
2527
{
26-
// cast object to array recursively
27-
$toArray = function ($x) use (&$toArray) {
28-
return is_scalar($x)
29-
? $x
30-
: array_map($toArray, (array) $x);
31-
};
32-
$data = $toArray($requestObjectData);
33-
34-
$data['timezone'] = $params['timezone'];
35-
$data['request'] = $params['request'];
36-
unset($data['exp']);
37-
3828
$attributes = [];
39-
foreach ($data as $key => $value) {
29+
foreach ($params as $key => $value) {
4030
$attributes[Str::camel($key)] = $value;
4131
}
4232

0 commit comments

Comments
 (0)