207 lines
7.3 KiB
PHP
207 lines
7.3 KiB
PHP
<?php
|
|
|
|
namespace App\Controllers;
|
|
|
|
use App\Models\Client;
|
|
use App\Utils\View;
|
|
|
|
class ClientController
|
|
{
|
|
public function index()
|
|
{
|
|
$clientModel = new Client();
|
|
$clients = $clientModel->findAll();
|
|
View::render('layouts.admin', [
|
|
'title' => 'Gerenciar Clientes',
|
|
'content' => __DIR__ . '/../../resources/views/admin/clients/index.php',
|
|
'clients' => $clients
|
|
]);
|
|
}
|
|
|
|
public function create()
|
|
{
|
|
View::render('layouts.admin', [
|
|
'title' => 'Novo Cliente',
|
|
'content' => __DIR__ . '/../../resources/views/admin/clients/form.php'
|
|
]);
|
|
}
|
|
|
|
public function store()
|
|
{
|
|
$data = [
|
|
'name' => $_POST['name'],
|
|
'asn' => $_POST['asn'],
|
|
'email' => $_POST['email'],
|
|
'financial_email' => $_POST['financial_email'],
|
|
'telegram_id' => $_POST['telegram_id'],
|
|
'status' => 'active'
|
|
];
|
|
|
|
// Basic validation could be added here
|
|
|
|
$conn = \App\Config\Database::getInstance()->getConnection();
|
|
|
|
$sql = "INSERT INTO clients (name, asn, email, financial_email, telegram_id, status) VALUES (:name, :asn, :email, :financial_email, :telegram_id, :status)";
|
|
$stmt = $conn->prepare($sql);
|
|
$stmt->execute($data);
|
|
|
|
$clientId = $conn->lastInsertId();
|
|
|
|
// Create User for Client
|
|
$password = $_POST['password'];
|
|
$validation = \App\Utils\PasswordValidator::validate($password);
|
|
if ($validation !== true) {
|
|
// Rollback or handle error. For simplicity, we redirect with error.
|
|
// Ideally we should use transactions.
|
|
// Deleting the client created above to keep consistency
|
|
$conn->exec("DELETE FROM clients WHERE id = $clientId");
|
|
|
|
$_SESSION['flash_error'] = "A senha deve ter no mínimo 8 caracteres, contendo pelo menos uma letra maiúscula e um caractere especial.";
|
|
$_SESSION['old_input'] = $_POST;
|
|
View::redirect('/admin/clients/create');
|
|
return;
|
|
}
|
|
|
|
$passwordHash = password_hash($password, PASSWORD_DEFAULT);
|
|
$sqlUser = "INSERT INTO users (name, email, password, role, client_id) VALUES (:name, :email, :password, 'client', :client_id)";
|
|
$stmtUser = $conn->prepare($sqlUser);
|
|
$stmtUser->execute([
|
|
'name' => $_POST['name'],
|
|
'email' => $_POST['email'],
|
|
'password' => $passwordHash,
|
|
'client_id' => $clientId
|
|
]);
|
|
|
|
// Pangolin Integration
|
|
try {
|
|
$pangolinService = new \App\Services\PangolinService();
|
|
if ($pangolinService->isEnabled()) {
|
|
$pangolinService->syncClient($clientId, 'add');
|
|
}
|
|
} catch (\Exception $e) {
|
|
// Log error silently, don't break the flow
|
|
error_log("Pangolin Sync Error (Create): " . $e->getMessage());
|
|
}
|
|
|
|
View::redirect('/admin/clients');
|
|
}
|
|
|
|
public function edit($id)
|
|
{
|
|
$clientModel = new Client();
|
|
$client = $clientModel->find($id);
|
|
|
|
if (!$client) {
|
|
View::redirect('/admin/clients');
|
|
}
|
|
|
|
View::render('layouts.admin', [
|
|
'title' => 'Editar Cliente',
|
|
'content' => __DIR__ . '/../../resources/views/admin/clients/form.php',
|
|
'client' => $client
|
|
]);
|
|
}
|
|
|
|
public function update($id)
|
|
{
|
|
$data = [
|
|
'id' => $id,
|
|
'name' => $_POST['name'],
|
|
'asn' => $_POST['asn'],
|
|
'email' => $_POST['email'],
|
|
'financial_email' => $_POST['financial_email'],
|
|
'telegram_id' => $_POST['telegram_id'] ?? null,
|
|
'status' => $_POST['status']
|
|
];
|
|
|
|
$conn = \App\Config\Database::getInstance()->getConnection();
|
|
|
|
$sql = "UPDATE clients SET name=:name, asn=:asn, email=:email, financial_email=:financial_email, telegram_id=:telegram_id, status=:status WHERE id=:id";
|
|
$stmt = $conn->prepare($sql);
|
|
$stmt->execute($data);
|
|
|
|
// Update User Email and Password (if provided)
|
|
$sqlUser = "UPDATE users SET email = :email";
|
|
$paramsUser = ['email' => $_POST['email'], 'client_id' => $id];
|
|
|
|
if (!empty($_POST['password'])) {
|
|
$password = $_POST['password'];
|
|
$validation = \App\Utils\PasswordValidator::validate($password);
|
|
if ($validation !== true) {
|
|
$_SESSION['flash_error'] = "A senha deve ter no mínimo 8 caracteres, contendo pelo menos uma letra maiúscula e um caractere especial.";
|
|
View::redirect('/admin/clients/edit/' . $id);
|
|
return;
|
|
}
|
|
|
|
$sqlUser .= ", password = :password";
|
|
$paramsUser['password'] = password_hash($password, PASSWORD_DEFAULT);
|
|
}
|
|
|
|
$sqlUser .= " WHERE client_id = :client_id";
|
|
|
|
$stmtUser = $conn->prepare($sqlUser);
|
|
$stmtUser->execute($paramsUser);
|
|
|
|
// Pangolin Integration - Buscar IPs dos servidores ATIVOS ANTES de desativá-los
|
|
$serverIpsToRemove = [];
|
|
if ($_POST['status'] === 'inactive') {
|
|
$stmtIps = $conn->prepare("SELECT ip_v4, ip_v6 FROM servers WHERE client_id = :client_id AND status = 'active'");
|
|
$stmtIps->execute(['client_id' => $id]);
|
|
$servers = $stmtIps->fetchAll(\PDO::FETCH_ASSOC);
|
|
foreach ($servers as $server) {
|
|
if (!empty($server['ip_v4'])) {
|
|
$serverIpsToRemove[] = $server['ip_v4'];
|
|
}
|
|
if (!empty($server['ip_v6'])) {
|
|
$serverIpsToRemove[] = $server['ip_v6'];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Cascade Deactivate Servers quando cliente é desativado
|
|
if ($_POST['status'] === 'inactive') {
|
|
$sqlServers = "UPDATE servers SET status = 'inactive' WHERE client_id = :client_id";
|
|
$stmtServers = $conn->prepare($sqlServers);
|
|
$stmtServers->execute(['client_id' => $id]);
|
|
}
|
|
|
|
// Pangolin Integration - Sincroniza com base no status
|
|
try {
|
|
$pangolinService = new \App\Services\PangolinService();
|
|
if ($pangolinService->isEnabled()) {
|
|
if ($_POST['status'] === 'active') {
|
|
$pangolinService->syncClient($id, 'add');
|
|
} else {
|
|
// Remove os IPs que foram coletados antes de desativar os servidores
|
|
if (!empty($serverIpsToRemove)) {
|
|
$pangolinService->removeServerIps($serverIpsToRemove);
|
|
}
|
|
}
|
|
}
|
|
} catch (\Exception $e) {
|
|
error_log("Pangolin Sync Error (Update): " . $e->getMessage());
|
|
}
|
|
|
|
View::redirect('/admin/clients');
|
|
}
|
|
|
|
public function delete($id)
|
|
{
|
|
$clientModel = new Client();
|
|
|
|
// Pangolin Integration (Remove before delete to get ASN)
|
|
try {
|
|
$client = $clientModel->find($id);
|
|
if ($client && $client['status'] === 'active') {
|
|
$pangolinService = new \App\Services\PangolinService();
|
|
$pangolinService->syncClient($id, 'remove');
|
|
}
|
|
} catch (\Exception $e) {
|
|
error_log("Pangolin Sync Error (Delete): " . $e->getMessage());
|
|
}
|
|
|
|
$clientModel->delete($id);
|
|
View::redirect('/admin/clients');
|
|
}
|
|
}
|