Przeglądaj źródła

new: implementation of the auth token from B3

EduLascala 1 tydzień temu
rodzic
commit
898fa1b989
6 zmienionych plików z 93 dodań i 10 usunięć
  1. 3 1
      .gitignore
  2. 1 1
      README.md
  3. 72 0
      controllers/B3TokenController.php
  4. 1 1
      migrations/migrations_v1.sql
  5. 2 0
      public/index.php
  6. 14 7
      routes.md

+ 3 - 1
.gitignore

@@ -4,4 +4,6 @@ vendor/
 test.db
 build/
 package-lock.json
-node_modules
+node_modules
+319245319-320109623_PROD.cer
+319245319-320109623_PROD.key

+ 1 - 1
README.md

@@ -3,7 +3,7 @@
 (deleta o banco existente, cria o banco de dados com as credenciais do ENV e aplica migrations)
 2. run ```composer install (instala dependencias)```
 
-3. run ```X_LISTEN=127.0.0.1:8000 php public/index.php (inicia servidor)```
+3. run ```X_LISTEN=127.0.0.1:8000 php public/index.php```
 
 ```
 fpm -s dir -t deb \

+ 72 - 0
controllers/B3TokenController.php

@@ -0,0 +1,72 @@
+<?php
+
+namespace Controllers;
+
+use Libs\ResponseLib;
+use Psr\Http\Message\ServerRequestInterface;
+use React\Http\Message\Response;
+
+class B3TokenController
+{
+    public function __invoke(ServerRequestInterface $request)
+    {
+        $b3Url = $_ENV['B3_URL'] ?? null;
+        $clientId = $_ENV['CLIENT_ID'] ?? null;
+        $clientSecret = $_ENV['CLIENT_SECRET'] ?? null;
+        $grantType = $_ENV['GRANT_TYPE'] ?? 'client_credentials';
+        $certPass = $_ENV['CERT_PASS'] ?? null;
+
+        if (!$b3Url || !$grantType || !$clientId || !$clientSecret) {
+            return ResponseLib::sendFail('Missing required env vars: B3_URL, GRANT_TYPE, CLIENT_ID, CLIENT_SECRET', [], 'E_VALIDATE')->withStatus(500);
+        }
+
+        $certPath = dirname(__DIR__) . DIRECTORY_SEPARATOR . '319245319-320109623_PROD.cer';
+        $keyPath  = dirname(__DIR__) . DIRECTORY_SEPARATOR . '319245319-320109623_PROD.key';
+        if (!file_exists($certPath) || !file_exists($keyPath)) {
+            return ResponseLib::sendFail('Client certificate or key not found', ['cert' => $certPath, 'key' => $keyPath], 'E_INTERNAL')->withStatus(500);
+        }
+
+        // Send grant_type + client credentials in body in the same order as the working curl
+        $postFields = 'grant_type=' . ($grantType);
+
+        $ch = curl_init($b3Url);
+        curl_setopt($ch, CURLOPT_POST, true);
+        $headers = [
+            'Content-Type: application/x-www-form-urlencoded',
+            'Accept: application/json',
+        ];
+        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+
+        // mTLS client certificate
+        curl_setopt($ch, CURLOPT_SSLCERT, $certPath);
+        curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
+        curl_setopt($ch, CURLOPT_SSLKEY, $keyPath);
+        curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
+        if ($certPass) {
+            curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $certPass);
+        }
+        // Keep verification enabled (recommended)
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
+
+        $responseBody = curl_exec($ch);
+        $curlErrNo = curl_errno($ch);
+        $curlErr = curl_error($ch);
+        $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
+        curl_close($ch);
+
+        if ($curlErrNo !== 0) {
+            return ResponseLib::sendFail('cURL error during B3 token request', ['error' => $curlErr, 'code' => $curlErrNo], 'E_EXTERNAL')->withStatus(502);
+        }
+
+        $decoded = json_decode($responseBody, true);
+        if ($decoded === null) {
+            // Not a JSON body; return raw text for troubleshooting
+            return Response::json(['raw' => $responseBody, 'status' => $httpCode])->withStatus($httpCode ?: 502);
+        }
+
+        return Response::json($decoded)->withStatus($httpCode ?: 200);
+    }
+}

+ 1 - 1
migrations/migrations_v1.sql

@@ -219,7 +219,7 @@ CREATE TABLE "token" (
     "token_id" SERIAL PRIMARY KEY,
     "token_external_id" TEXT NOT NULL,
     "token_commodities_amount" INTEGER NOT NULL,
-    "token_commodities_value" INTEGER NOT NULL,
+    "token_commodities_value" REAL NOT NULL,
     "token_uf" TEXT NOT NULL,
     "token_city" TEXT NOT NULL,
     "token_content" TEXT NOT NULL, -- financial instrument

+ 2 - 0
public/index.php

@@ -61,4 +61,6 @@ $app->post('/cpr/create', $authJwt, \Controllers\RegisterCprController::class);
 
 $app->post('/token/get', $authJwt, \Controllers\TokenGetController::class);
 
+$app->post('/b3/token', \Controllers\B3TokenController::class);
+
 $app->run();

+ 14 - 7
routes.md

@@ -408,16 +408,21 @@ curl --location 'http://localhost:8000/user/change-password' \
 
 ## 6. Commodities — List
 
-Returns a list of commodities filtered by `flag` or all if `flag=all`.
+Returns all commodities. No request body required. Requires JWT.
 
 ### **Endpoint**
 
-`GET /commodities`
+`POST /commodities/get`
+
+### **Headers**
+
+`Authorization: Bearer <JWT>`
 
 ### **cURL Example**
 
 ```bash
-curl --location 'http://localhost:8000/commodities?flag=all'
+curl --location -X POST 'http://localhost:8000/commodities/get' \
+  -H 'Authorization: Bearer <JWT>'
 ```
 
 ### **Responses**
@@ -664,7 +669,7 @@ curl --location 'http://localhost:8000/commodity/delete' \
 
 ## 10. Token Get
 
-Returns all tokens filtered by `token_uf`. Requires JWT.
+Returns all tokens filtered by `token_uf` and `commodities_name`. Requires JWT.
 
 ### **Endpoint**
 
@@ -680,7 +685,8 @@ Returns all tokens filtered by `token_uf`. Requires JWT.
 
 ```json
 {
-  "token_uf": "SP"
+  "token_uf": "SP",
+  "commodities_name": "soja"
 }
 ```
 
@@ -691,8 +697,9 @@ curl --location 'http://localhost:8000/token/get' \
   -H 'Content-Type: application/json' \
   -H 'Authorization: Bearer <JWT>' \
   --data '{
-    "token_uf": "SP"
-  }'
+  "token_uf": "SP",
+  "commodities_name": "soja"
+}'
 ```
 
 ### **Responses**