nhance/app/Controllers/ClientWebHooksController.php
2025-04-16 11:05:18 +05:30

320 lines
13 KiB
PHP

<?php
namespace App\Controllers;
use App\Controllers\BaseController;
use CodeIgniter\API\ResponseTrait;
use CodeIgniter\HTTP\ResponseInterface;
use App\Models\ClientApiModel;
use App\Models\ClientPolicyModel;
use App\Helpers\clientWebHookHelper;
use App\Helpers\ClientTokenHelper;
use Exception;
class ClientWebHooksController extends BaseController
{
use ResponseTrait;
protected $myLogger;
protected $clientAPI;
protected $clientPolicy;
protected $webHookHelper;
protected $clientTokenHelper;
public function __construct()
{
set_session_context('Client Webhook Controller');
$this->myLogger = \Config\Services::mylogger();
//models
$this->clientAPI = new ClientApiModel();
$this->clientPolicy = new ClientPolicyModel();
// Helpers
$this->webHookHelper = new clientWebHookHelper();
$this->clientTokenHelper = new ClientTokenHelper();
}
public function pushData($clientID, $type)
{
if ($type == 1) {
$webHookType = "emp";
} else if ($type == 2) {
$webHookType = "claim";
}
log_message('error', 'Client ID: ' . $clientID);
log_message('error', 'Webhook Type: ' . $webHookType);
// Validate client ID
if (empty($clientID)) {
return $this->respond(["status" => "Failure", "error" => ["message" => 'Client ID is required.', "code" => 400]], 400);
}
$webhookData = $this->clientAPI->where('client_id', $clientID)->where('is_active', 1)->first();
if (empty($webhookData)) {
log_message('error', 'Client Not Found or Unauthorized');
return $this->respond(["status" => "Failure", "error" => ["message" => 'Client Not Found or Client Does not have any Active Hooks.', "code" => 404]], 404);
}
$url = $webhookData[$webHookType . '_url'];
if (empty($url)) {
log_message('error', 'No active webhook found for the client.');
return $this->respond(["status" => "Failure", "error" => ["message" => 'No active webhook found for the client.', "code" => 404]], 404);
}
$method = $webhookData[$webHookType . '_method'];
$auth_method = $webhookData[$webHookType . '_tkn_type'];
$token = $webhookData[$webHookType . '_token'];
$objectType = json_decode($webhookData[$webHookType . '_obj']);
try {
$client = \Config\Services::curlrequest();
$data = [
"name" => "Kavitha",
"emp_code" => "EMP001-K4",
"emp_status" => "active",
"mobile" => "2233448965"
];
try {
$mapped_data = $this->webHookHelper->mapObjectType($data, $objectType);
} catch (Exception $e) {
$errorMessage = "Object Mapping Failed: " . $e->getMessage();
log_message('error', $errorMessage);
return $this->respond(['status' => 'Failure', 'error' => ['code' => 500, 'message' => "Object Mapping Failed"]], 500);
}
// Create payload
$payload = [
'event_type' => 'insert',
'timestamp' => date('c'),
'data' => $mapped_data
];
log_message("error", "Payload: " . json_encode($payload));
// Configure request headers
$headers = ['Content-Type' => 'application/json'];
if ($auth_method && $token) {
if (strtolower($auth_method) === 'bearer') {
$headers['Authorization'] = 'Bearer ' . $token;
} else {
$headers[$auth_method] = $token;
}
}
// Configure request based on method
$options = [
'headers' => $headers,
'timeout' => 10,
'http_errors' => false // Don't throw exceptions for 4xx/5xx responses
];
if ($method === 'GET') {
$options['query'] = $payload;
} else {
$options['json'] = $payload;
}
// Execute webhook request
$response = $client->request($method, $url, $options);
$statusCode = $response->getStatusCode();
$responseBody = $response->getBody();
// Log and format response
$logMessage = "Webhook to {$url} returned status: {$statusCode}";
log_message('error', $logMessage);
return $this->respond(['status' => 'Success', "response" => $responseBody], $statusCode);
} catch (\Throwable $e) {
$errorMessage = "Webhook failed: " . $e->getMessage();
log_message('error', $errorMessage);
return $this->respond(['status' => 'Failure', 'error' => ['code' => 500, 'message' => $errorMessage, 'exception' => get_class($e)]], 500);
}
}
public function validateToken($type)
{
$type = $type == 1 ? "pull_emp_token" : "pull_claim_token";
try {
$authHeader = $this->request->getHeaderLine('Authorization');
// Check if header exists
if (empty($authHeader)) {
log_message('error', 'Authorization header missing');
return $this->respond(['status' => "Failure", 'error' => ['message' => 'Authorization header missing', 'code' => 401]], 401);
}
// Check if Bearer is present
if (!str_contains($authHeader, 'Bearer ')) {
log_message('error', 'Authorization Bearer missing');
return $this->respond(['status' => "Failure", 'error' => ['message' => 'Invalid Authorization header', 'code' => 401]], 401);
}
// Extract the token
$token = str_replace('Bearer ', '', $authHeader);
if (empty($token)) {
log_message('error', 'Empty Token');
return $this->respond(['status' => "Failure", 'error' => ['message' => 'Invalid Token Format', 'code' => 401]], 401);
}
try {
// Extract client_id from the token
$client_id = ClientTokenHelper::extractClientId($token);
} catch (\Exception $e) {
log_message('error', 'Invalid Client Token Format');
return $this->respond(['status' => "Failure", 'error' => 'Invalid Token Format'], 401);
}
// Fetch client details from the database
$client = $this->clientAPI->where('client_id', $client_id)->where("is_active", 1)->where("api_access", 1)->first();
// Client validation
if (!$client) {
log_message('error', 'Client Not Found or Unauthorized');
return $this->respond(['status' => "Failure", 'error' => ['message' => 'Client not found or unauthorized', 'code' => '403']], 403);
}
// Validate the token
if (hash_equals($client[$type], $token)) {
log_message('error', 'Access Granted For Client : ' . $client_id);
return true;
} else {
log_message('error', 'Invalid Token given for client : ' . $client_id);
return $this->respond([
'status' => "Failure",
'error' => ['message' => 'Invalid token', 'code' => 401]
], 401);
}
} catch (\Exception $e) {
log_message('error', 'Error in ClientAPIController:validateToken - ' . $e->getMessage());
return $this->respond(['status' => "Failure", 'error' => ['message' => 'Internal Server Error', 'code' => 500]], 500);
}
}
public function getClientIdfromToken()
{
$authHeader = $this->request->getHeaderLine('Authorization');
$token = str_replace('Bearer ', '', $authHeader);
$client_id = ClientTokenHelper::extractClientId($token);
log_message('error', 'Client ID: ' . $client_id);
return [$client_id, $token];
}
public function pullData_emp()
{
$validationStatus = $this->validateToken(1);
$data = $this->getClientIdfromToken();
$client_id = $data[0];
log_message('error', "Pull data emp from Client ID: ". $client_id);
$client = $this->clientAPI->where('client_id', $client_id)->where("is_active", 1)->where("api_access", 1)->first();
if (empty($client)) {
log_message('error', 'Client Not Found or Unauthorized');
return $this->respond(['status' => 'Failure', 'error' => ['code' => 404, 'message' => 'Client Not Found or Unauthorized']], 404);
}
$objectType = $client['pull_emp_obj'];
if ($validationStatus) {
$responseBody = $this->request->getBody();
$data_to_map = json_decode($responseBody, true);
$objectType = json_decode($objectType, true);
if (!isset($data_to_map['data']) || !is_array($data_to_map['data'])) {
log_message('error', "Invalid Response from Endpoint 'data' Key Missing");
return $this->respond(['status' => 'Failure', 'error' => ['code' => 500, 'message' => "Invalid Response from Endpoint 'data' Key Missing"]], 500);
}
foreach ($data_to_map['data'] as $index => $item) {
try {
$mapped_data = $this->webHookHelper->mapObjectType($item, $objectType);
} catch (Exception $e) {
$errorMessage = "Object Mapping Failed: " . $e->getMessage();
log_message('error', $errorMessage);
return $this->respond(['status' => 'Failure', 'error' => ['code' => 500, 'message' => "Object Mapping Failed"]], 500);
}
try {
$mapped_data['client_id'] = $client_id;
$this->webHookHelper->insertData($mapped_data, 1);
} catch (Exception $e) {
$errorMessage = "Data Insertion Failed: " . $e->getMessage();
log_message('error', $errorMessage);
return $this->respond(['status' => 'Failure', 'error' => ['code' => 500, 'message' => "Data Insertion Failed"]], 500);
}
}
log_message('error', "Data Inserted Successfully for Client ID: " . $client_id);
// Return success response
return $this->respond(['status' => 'Success', 'message' => "Data Inserted Successfully"], 200);
}
}
public function pullData_claim()
{
$validationStatus = $this->validateToken(2);
$data = $this->getClientIdfromToken();
$client_id = $data[0];
log_message('error', "Pull data claim from Client ID: ". $client_id);
$client = $this->clientAPI->where('client_id', $client_id)->where("is_active", 1)->where("api_access", 1)->first();
if (empty($client)) {
log_message('error', 'Client Not Found or Unauthorized');
return $this->respond(['status' => 'Failure', 'error' => ['code' => 404, 'message' => 'Client Not Found or Unauthorized']], 404);
}
$objectType = $client['pull_claim_obj'];
if ($validationStatus) {
$responseBody = $this->request->getBody();
$data_to_map = json_decode($responseBody, true);
$objectType = json_decode($objectType, true);
if (!isset($data_to_map['data']) || !is_array($data_to_map['data'])) {
log_message('error', "Invalid Response from Endpoint 'data' Key Missing");
return $this->respond(['status' => 'Failure', 'error' => ['code' => 500, 'message' => "Invalid Response from Endpoint 'data' Key Missing"]], 500);
}
foreach ($data_to_map['data'] as $index => $item) {
try {
$mapped_data = $this->webHookHelper->mapObjectType($item, $objectType);
} catch (Exception $e) {
$errorMessage = "Object Mapping Failed: " . $e->getMessage();
log_message('error', $errorMessage);
return $this->respond(['status' => 'Failure', 'error' => ['code' => 500, 'message' => "Object Mapping Failed"]], 500);
}
try {
$mapped_data['client_id'] = $client_id;
$this->webHookHelper->insertData($mapped_data, 2);
} catch (Exception $e) {
$errorMessage = "Data Insertion Failed: " . $e->getMessage();
log_message('error', $errorMessage);
return $this->respond(['status' => 'Failure', 'error' => ['code' => 500, 'message' => "Data Insertion Failed"]], 500);
}
}
log_message('error', "Data Inserted Successfully for Client ID: " . $client_id);
// Return success response
return $this->respond(['status' => 'Success', 'message' => "Data Inserted Successfully"], 200);
}
}
}