Files
Lucas/provision.php
Debian 24dbc7cd6a Initial commit — Serveur Lucas SmartEye
API réception alertes chute (SmartEye/YOLO), analyse IA (Gemini 2.5 Flash),
gestion alertes avec escalade (watchdog), notifications Firebase,
dashboard web, documentation MkDocs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 21:26:06 +01:00

137 lines
4.5 KiB
PHP

<?php
/**
* provision.php — Provisioning d'un nouveau site client
*
* Crée un nouveau client dans database.json, assigne un site_number,
* génère un token, crée le dossier client, et retourne les infos
* de provisioning (dont un QR code encodé en base64).
*
* POST /provision.php
* Content-Type: application/json
* Authorization: Bearer <ADMIN_PASSWORD>
*
* {
* "client_id": "dupont_marie",
* "name": "Marie Dupont",
* "senior_name": "Mamie Marie",
* "address": "12 rue des Roses",
* "city": "20270 Aleria",
* "latitude": "42.1028",
* "longitude": "9.5147",
* "emergency_number": "15",
* "contacts": [{"name": "Jean", "role": "Fils", "phone": "+33698765432"}]
* }
*/
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(204); exit; }
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
die(json_encode(["success" => false, "message" => "POST uniquement"]));
}
// Authentification admin
$ADMIN_PASS = "smart123";
$auth_header = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
$provided_pass = str_replace('Bearer ', '', $auth_header);
if ($provided_pass !== $ADMIN_PASS) {
http_response_code(401);
die(json_encode(["success" => false, "message" => "Authentification admin requise"]));
}
$input = json_decode(file_get_contents("php://input"), true);
$client_id = preg_replace('/[^a-z0-9_]/', '', strtolower($input['client_id'] ?? ''));
if (empty($client_id)) {
http_response_code(400);
die(json_encode(["success" => false, "message" => "client_id requis"]));
}
$DB_FILE = "database.json";
$db = json_decode(file_get_contents($DB_FILE), true);
// Vérifier unicité
foreach ($db['clients'] as $c) {
if (strcasecmp($c['name'] ?? '', $client_id) === 0 || strcasecmp($c['name'] ?? '', $input['name'] ?? '') === 0) {
http_response_code(409);
die(json_encode(["success" => false, "message" => "Client déjà existant"]));
}
}
// Calculer le prochain site_number
$max_site = 0;
foreach ($db['clients'] as $c) {
$sn = $c['site_number'] ?? 0;
if ($sn > $max_site) $max_site = $sn;
}
$site_number = $max_site + 1;
// Générer le token
$token = bin2hex(random_bytes(4));
// Calculer les ports
$base_port = 8550 + ($site_number - 1) * 10;
// Créer l'entrée client
$db['clients'][$client_id] = [
"name" => $input['name'] ?? $client_id,
"token" => $token,
"created_at" => date("Y-m-d H:i:s"),
"site_number" => $site_number,
"site_status" => "provisioned",
"senior_name" => $input['senior_name'] ?? $input['name'] ?? '',
"senior_nickname" => $input['senior_nickname'] ?? '',
"senior_photo" => "",
"latitude" => $input['latitude'] ?? '',
"longitude" => $input['longitude'] ?? '',
"emergency_number" => $input['emergency_number'] ?? '15',
"fcm_tokens" => [],
"contacts" => $input['contacts'] ?? [],
"address" => $input['address'] ?? '',
"city" => $input['city'] ?? '',
"phone_mobile" => $input['phone_mobile'] ?? '',
"phone_fixed" => '',
"age" => $input['age'] ?? '',
"sex" => $input['sex'] ?? 'F',
"alerte" => false,
];
// Créer le dossier client
$client_dir = "clients/" . ($input['name'] ?? $client_id) . "/";
if (!is_dir($client_dir)) {
mkdir($client_dir, 0775, true);
}
// Sauvegarder la DB
file_put_contents($DB_FILE, json_encode($db, JSON_PRETTY_PRINT));
// Données de provisioning pour le QR code
$provision_data = [
"client_id" => $input['name'] ?? $client_id,
"token" => $token,
"site_number" => $site_number,
"server" => "57.128.74.87",
];
// Écrire la demande de firewall dans une file d'attente
$fw_queue = "/var/www/lucas/firewall_queue.txt";
$fw_cmd = "ufw allow " . $base_port . ":" . ($base_port + 9) . "/tcp comment 'Site $site_number - $client_id'";
file_put_contents($fw_queue, $fw_cmd . "\n", FILE_APPEND);
// Réponse
echo json_encode([
"success" => true,
"status" => "provisioned",
"client_id" => $input['name'] ?? $client_id,
"token" => $token,
"site_number" => $site_number,
"base_port" => $base_port,
"port_range" => $base_port . "-" . ($base_port + 9),
"provision_qr_data" => json_encode($provision_data),
"firewall_queued" => true,
"message" => "Client provisionné. Ports $base_port-" . ($base_port + 9) . " en attente d'ouverture firewall.",
], JSON_PRETTY_PRINT);
?>