<?php
namespace App\Service;
use App\Model\User;
use App\Utils\JwtUtils;
use MiladRahimi\Jwt\Exceptions\InvalidKeyException;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
class Backend
{
// use SessionUtils;
use JwtUtils;
protected $backend_url;
protected $cert_dir;
protected $api_url;
protected $proxy_api_url;
protected $serializer;
protected $client;
// User Backend
// const LOGIN = 'user/login'; // Used
const LOGIN = 'api/login'; // Used
const TOKEN = 'user/token'; // Not used
const ACTIVATE = 'api/users/'; // 'user/activate'; //Use for POST and PUT
const REACTIVATE = 'api/emails/bubbles/' ; //Resend activation
const USER_UPDATE_ROLE = 'user/role';
const GET_USER = 'user/passwordReset'; //Use for POST and PUT
const USER_RESET_PASSWORD_BY_EMAIL = 'api/emails/reset-password';
const USER_RESET_PASSWORD = 'api/users/reset-password';
// Bubble Backend
const BUBBLE = 'api/bubbles'; // Used for POST new xx
const ACTIVATE_BUBBLE = 'bubble/activate'; // Used for PUT
const ADD_BUBBLE_USER = 'api/bubbles/'; // Used for POST xx
const DELETE_BUBBLE_USER = 'bubble/user/'; // Not used
const DELETE_BUBBLE_PROFILE = 'api/bubbles/'; //xx
const GET_BUBBLE_USER = 'bubble/users';
// const GET_BUBBLE_PROFILES = 'bubble/profiles/all'; //xx
const GET_BUBBLE_PROFILES = 'api/bubbles/'; // 'api/bubbles/:b_id/users/profiles'
const GET_BUBBLE_PROFILE_RIGTHS = 'api/bubbles/'; //Get one profile by profile id xx
const BUBBLE_PROFILES = 'profiles/bubble/';
const BUBBLE_UPDATE_PROFILES = 'api/bubbles/'; //xx
const GET_VALIDATORS = 'bubble/validators/print'; // get the user validator of a bubble
const GET_USER_BY_PROFILE = 'users/byProfile';
// const GET_ONE_PROFILE_RIGHTS = 'bubble/profiles/user/'; //To get the new profiles rights for one user
const GET_ONE_PROFILE_RIGHTS = 'api/bubbles/';
// const GET_ALL_PROFILE_RIGHTS = 'bubble/profiles/default'; //To get the new profiles rights for all users xx
const GET_ALL_PROFILE_RIGHTS = 'api/bubbles/';
// Site Backend
const ADD_SITE = 'api/sites'; // POST new site
// const SITE = 'site/'; // GET get sites by Bubble ID
const SITES = 'api/sites'; // GET get sites by Bubble ID
const SITE_ADD_USER = 'site/add/user'; // Add user to a site
// const UPDATE_SITE = 'sites/'; // PUT site OLD
const UPDATE_SITE = 'api/sites/';
const GET_SITE_BY_ID = 'api/sites/'; // GET site by ID
// Organization Backend
const ADD_ORGANIZATION = 'organization'; //POST new organization
const GET_ORGANIZATIONS = 'organizations/'; //GET organizations
const GET_ORGANIZATION_BY_ID = 'organization/'; //GET one organization by id
const UPDATE_ORGANIZATION = 'organization/'; //UPDATE organization
// Formation backend
const ADD_FORMATION = 'formation'; //POST new formation
const GET_FORMATIONS = 'formations/b_id'; //GET formation
const GET_FORMATION_BY_ID = 'formation/'; //GET one organization by id
//Structure backend
// const ADD_STRUCTURE = 'structure'; //POST new structure
const ADD_STRUCTURE = 'api/structures'; //POST new structure
const GET_STRUCTURE_ORG = 'api/bubbles/'; //'structures/organization/'; //GET structures org
const GET_STRUCTURE_FORM = 'api/bubbles/'; //GET structures form
const GET_STRUCTURE_CHILDREN = 'api/structures/'; //'structures/'; // GET structures children
const UPDATE_STRUCTURE = 'api/structures/'; //PUT structures
const GET_STRUCTURE_BY_ID = 'api/structures/'; //GET structure by ID
const GET_STRUCTURE_BY_B_ID = 'api/structures/';
const DELETE_STRUCTURE = 'api/structures';
// PrintJob Backend
const PRINT_REQUEST = 'printJob/request';
const GET_PRINT_REQUEST = 'printJob/requests';
// const GET_PRINT_LOGS = 'printJob/refreshPrintJob'; // get the print logs of BA and OP
const GET_PRINT_LOGS = 'api/dashboards/';
const START_PRINT_JOB = 'printJob/startPrint'; //Start Print Job
const CRM_UPDATE_JOB = 'api/job-orders/'; // 'sites/job_orders/status/'; //Update job for crm
// Production Order
const ADD_PRODUCTION_ORDER = 'api/production_orders'; // POST production order
const GET_PRODUCTION_ORDER = 'api/production_orders'; // GET production order
const GET_EXTRA_PRODUCTION_ORDER = 'productionOrder/children/'; // GET production order
const PRODUCTION_ORDER_RECEIVED = 'api/production_orders/received'; // GET production order received
const GET_PO_BY_ID = 'api/production_orders'; //GET PO by ID
// Plan Backend
const GET_PLANS = 'api/plans';
const POST_PLAN = 'api/plans';
const VALIDATE_PLAN = 'api/plans/'; // to validate a plan as VPLAN
const ECO_MODEL = 'api/plans/'; // 'plan/eco_model'; // Add (POST), GET (GET) and UPDATE (PUT) an ecoModel
const PLAN_EM_TRANCHES = 'plan/tranche';
const GET_PLAN = 'api/plans/';
const GET_PLAN_PIECES = 'api/plans/';
const PLAN_ADD_PIECE = 'api/plans/'; // 'plans/pieces';
const PLAN_DELETE_PIECE = 'api/plans/'; // Used for DELETE
const PLAN_ADD_INDUS = 'plans/indus';
const PLAN_ATTACH_INDUS = 'api/plans'; //PATCH
// const PLAN_DELETE_INDUS = 'plans/indus';
const PLAN_DELETE_INDUS = 'api/plans/'; // 'api/industrials'; // 'plans/indus';
const PLAN_DELETE = 'api/plans/'; // "plans/";
const PLAN_UPDATE = "plans/pieces";
const PLAN_PIECE_UPDATE = 'api/plans/';
const NON_CATALOG_FILE = 'api/prototype_orders';
const PLAN_MATERIALS = 'api/materials/';
// Categorie
const GET_CATEGORIES = 'api/categories/';
// Printer Backend
const ADD_PRINTER = 'printer/';
// const GET_PRINTERS = 'sites/printers/'; // get the printers of a bubble
// const GET_PRINTER_PER_SITE = 'site/printers/' ; // get printers per site
const GET_PRINTERS = 'api/printers';
const GET_PRINTER_PER_SITE = 'api/printers/';
const GET_PRINTERS_BY_BULLE = 'api/bubbles/';
const DELETE_SITE = 'api/sites/';
// PRODUCTION PLANNING Backend
const GET_PLANNING = 'api/planning';
const POST_PLANNING = 'api/planning';
const DELETE_PLANNING = 'api/planning/';
const UPDATE_PLANNING = 'api/planning/';
// Job Order Backend
const GET_JOB_ORDERS = 'api/job-orders'; //'sites/job_orders/'; // get job order
const GET_JOB_ORDER_BY_ID = 'api/job-orders/'; //get one job order by id
const ADD_JOB_ORDER = "api/job-orders"; //POST job order
const GET_JOB_ORDERS_BY_STATUS = "api/job-orders/controlled/job-order-status/"; //GET job order by :job_order_status= All Error Finished
// INDUSTRIAL Backend
//const GET_INDUSTRIALS = 'industrials/'; // GET INDUSTRIALS OLD
const GET_INDUSTRIALS = 'api/industrials/';
const POST_INDUSTRIAL = 'api/industrials/'; // POST INDUSTRIAL
// QUALITY CONTROL
const GET_QC = 'api/quality_controls';
const SEND_QC = 'api/quality_controls'; //'printJob/qualityControl';
// const GET_QC_CRM = 'api/quality_controls/'; //'sites/job_orders/qualityControl/'; // get job order crm case
const GET_QC_CRM = 'api/job-orders'; //'sites/job_orders/qualityControl/'; // get job order crm case
// BILLS
const GET_BILLS = 'bills/';
const GET_BILL_DETAILS = 'bills/'; // id en get
// API
// const GET_API_TOKENS = 'bubble/apikeys'; //xx
const GET_API_TOKENS = 'api/bubbles/';
const BUBBLE_API_TOKEN = "tokens/bubble";
// const SITE_API_TOKEN = "tokens/site";
// DASHBOARD
const GET_DASHBOARD_LOGS = 'api/dashboards/'; // 'dashboard/logs/'; // get the print logs of BA and OP
// STRIPE
const GET_STRIPE_PAYMENT_METHOD = 'api/stripe/payment-method/';
const POST_CREATE_PAYMENT_INTENT = 'api/stripe/create-payment-intent/';
const CONTACT_EMAIL = 'api/emails/';
// private RequestStack $requestStack;
/**
* @param UrlGeneratorInterface $urlGenerator
* @param SerializerInterface $serializer
* @param HttpClientInterface $client
* @param ParameterBagInterface $param
* @param SessionInterface $session
* @param RequestStack $requestStack
* @param LoggerInterface $logger
*/
public function __construct(
UrlGeneratorInterface $urlGenerator,
SerializerInterface $serializer,
HttpClientInterface $client,
ParameterBagInterface $param,
SessionInterface $session,
RequestStack $requestStack,
LoggerInterface $logger
) {
$this->urlGenerator = $urlGenerator;
$this->serializer = $serializer;
$this->client= $client;
$this->param = $param;
$this->session = $session;
$this->requestStack = $requestStack;
$this->logger = $logger;
$this->backend_url = $param->get('backend_url');
$this->api_url = $param->get('api_url');
$this->proxy_api_url = $param->get('proxy_api_url');
}
/**
* When we need to make a call to the backend api, we should always use this function.
* It will make the call and log what we did
* It's all about control !
*
* @param string $reqType
* @param string $actionPath
* @param array $unloggedArguments
* @param array $loggedArguments
* @return ResponseInterface
* @throws InvalidKeyException
* @throws TransportExceptionInterface
*/
public function apiRequestLogin(string $reqType, string $actionPath, array $unloggedArguments, array $loggedArguments) //: JsonResponse
{
$this->logger->info('Je rentre dans la fonction : apiRequestLogin de la classe : src/Service/Backend.php ');
$password = $loggedArguments['u_pwd'];
$email = $loggedArguments['u_email'];
// Credantials from login form
$credantials = [
'u_email' => $email,
'u_pwd' => $password
];
$loggedArguments['verify_peer'] = false;
$jwtKeysDir = $this->param->get('jwt.file.dir');
$token = $this->generateFrontendJwtToken($jwtKeysDir, $credantials);
if (!empty($unloggedArguments['x-token-keycloak']) && $unloggedArguments['x-token-keycloak'] != '') {
$headers = [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $token,
'x-token-keycloak' => $this->session->get('oidc_access_token'),
'verify_peer' => false
];
} else {
$headers = [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $token,
'verify_peer' => false
];
}
// Send request to backend API
$response = $this->client->request($reqType, $this->proxy_api_url . $actionPath, [
'headers' => $headers,
'body' => json_encode($credantials),
'verify_peer' => false
]);
$this->logger->debug(sprintf("[src/Service/Backend.php] Le status de la réponse du front api lors du logging : %s", $response->getStatusCode()));
return $response;
}
/**
* @param string $reqType
* @param string $actionPath
* @param array $unloggedArguments
* @param array $loggedArguments
* @return ResponseInterface
* @throws ClientExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
public function apiRequestNewUrls(string $reqType, string $actionPath, array $unloggedArguments, array $loggedArguments)
{
$this->logger->info('[src/Service/Backend.php] Je rentre dans la fonction apiRequestNewUrls');
$session = $this->requestStack->getMainRequest()->getSession();
$token = $session->get('apiJwtToken');
$accessToken = $session->get('oidc_access_token'); // $session->get('keycloak_access_token');
if (!empty($accessToken) && $accessToken != '') {
$headers = [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $token,
'x-token-keycloak' => $accessToken
];
} else {
$headers = [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $token
];
}
$startTime = microtime(true);
$response = $this->client->request($reqType, $this->proxy_api_url . $actionPath, [
'headers' => $headers,
'body' => json_encode($loggedArguments),
'verify_peer' => false
]);
$endTime = microtime(true);
$executionTime = $endTime - $startTime;
$this->logger->info('[src/Service/Backend.php, METHOD : ' . $reqType . ', URL : ' . $this->proxy_api_url . $actionPath . ', Response Time : ] ' . $executionTime);
$this->logger->info('[src/Service/Backend.php - fonction: apiRequestNewUrls] Le status de la réponse pour chaque requête entre front api et le front web : ' . $response->getStatusCode());
$this->logger->info('[src/Service/Backend.php - fonction: apiRequestNewUrls] La réponse pour chaque requête entre front api et le front web : ' . $response->getContent(false));
return $response;
}
/**
* Activate user bulle
*
* @param string $reqType
* @param string $actionPath
* @param array $unloggedArguments
* @param array $loggedArguments
* @return ResponseInterface
* @throws ClientExceptionInterface
* @throws InvalidKeyException
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
public function apiRequestAdmin(string $reqType, string $actionPath, array $unloggedArguments, array $loggedArguments): ResponseInterface
{
$token = $this->generateFrontendJwtToken(
$this->param->get('jwt.file.dir'), [
'u_email' => $loggedArguments['u_email'],
'u_pwd' => $loggedArguments['u_pwd']
]);
$loggedArguments['verify_peer'] = false;
$headers = [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $token,
'verify_peer' => false
];
$response = $this->client->request($reqType, $this->proxy_api_url . $actionPath, [
'headers' => $headers,
'body' => json_encode($loggedArguments),
'verify_peer' => false
]);
$this->logger->debug(sprintf("[src/Service/Backend.php - fonction: apiRequestAdmin()] Le status de la réponse lors du logging du super admin : %s", $response->getStatusCode()));
$this->logger->debug(sprintf("[src/Service/Backend.php - fonction: apiRequestAdmin()] La réponse lors du logging du super admin : %s", $response->getContent(false)));
return $response;
}
/**
* @param string $reqType
* @param string $actionPath
* @param array $unloggedArguments
* @param array $loggedArguments
* @return ResponseInterface
* @throws ClientExceptionInterface
* @throws InvalidKeyException
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
public function apiRequestPW(string $reqType, string $actionPath, array $unloggedArguments, array $loggedArguments): ResponseInterface
{
$token = $this->generateFrontendJwtToken(
$this->param->get('jwt.file.dir'), [
'u_email' => $loggedArguments['u_email'],
'u_pwd' => $loggedArguments['u_pwd']
]);
$response = $this->getRequest($token, $token, $reqType, $actionPath, $loggedArguments);
$this->logger->debug(sprintf("[src/Service/Backend.php - fonction: apiRequestPW()] Le status de la réponse lors du changement de mot de passe : %s", $response->getStatusCode()));
$this->logger->debug(sprintf("[src/Service/Backend.php - fonction: apiRequestPW()] La réponse lors du changement de mot de passe : %s", $response->getContent(false)));
return $response;
}
/**
* @param mixed $accessToken
* @param mixed $token
* @param string $reqType
* @param string $actionPath
* @param array $loggedArguments
* @return ResponseInterface
* @throws TransportExceptionInterface
*/
public function getRequest(mixed $accessToken, mixed $token, string $reqType, string $actionPath, array $loggedArguments): ResponseInterface
{
$headers = [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $token
];
return $this->client->request($reqType, $this->proxy_api_url . $actionPath, [
'headers' => $headers,
'body' => json_encode($loggedArguments),
'verify_peer' => false
]);
}
}