diff --git a/agent/modals/network/network_import.php b/agent/modals/network/network_import.php new file mode 100644 index 00000000..e2f4afca --- /dev/null +++ b/agent/modals/network/network_import.php @@ -0,0 +1,37 @@ + + + +
+ + + + + +
+ +
- 0) { ?> - +
diff --git a/agent/post/network.php b/agent/post/network.php index 3b7e1b02..845ee440 100644 --- a/agent/post/network.php +++ b/agent/post/network.php @@ -188,7 +188,7 @@ if (isset($_POST['export_networks_csv'])) { $file_name_prepend = "$session_company_name-"; } - $sql = mysqli_query($mysqli,"SELECT * FROM networks LEFT JOIN client ON client_id = network_client_id WHERE network_archived_at IS NULL $client_query $access_permission_query ORDER BY network_name ASC"); + $sql = mysqli_query($mysqli,"SELECT * FROM networks LEFT JOIN clients ON client_id = network_client_id WHERE network_archived_at IS NULL $client_query $access_permission_query ORDER BY network_name ASC"); $num_rows = mysqli_num_rows($sql); @@ -227,3 +227,161 @@ if (isset($_POST['export_networks_csv'])) { exit; } + +// ============================================================ +// Add these two blocks to agent/post/network.php +// Place them alongside the existing export_networks_csv block. +// ============================================================ + +// ---------------------------------------------------------- +// CSV Template Download +// GET: post.php?download_networks_csv_template= +// ---------------------------------------------------------- +if (isset($_GET['download_networks_csv_template'])) { + + $delimiter = ","; + $enclosure = '"'; + $escape = '\\'; + $filename = "Networks-Template.csv"; + + $f = fopen('php://memory', 'w'); + + $fields = array('Name', 'Description', 'VLAN', 'Network (CIDR)', 'Gateway', 'IP Range', 'Primary DNS', 'Secondary DNS'); + fputcsv($f, $fields, $delimiter, $enclosure, $escape); + + // One example row so the user can see expected formatting + $example = array('Office LAN', 'Main office network', '10', '192.168.1.0/24', '192.168.1.1', '192.168.1.100-192.168.1.200', '8.8.8.8', '8.8.4.4'); + fputcsv($f, $example, $delimiter, $enclosure, $escape); + + fseek($f, 0); + + header('Content-Type: text/csv'); + header('Content-Disposition: attachment; filename="' . $filename . '";'); + + fpassthru($f); + exit; + +} + +// ---------------------------------------------------------- +// CSV Import +// POST: post.php (name="import_networks_csv") +// ---------------------------------------------------------- +if (isset($_POST['import_networks_csv'])) { + + validateCSRFToken($_POST['csrf_token']); + + enforceUserPermission('module_support', 2); + + $client_id = intval($_POST['client_id']); + + enforceClientAccess(); + + $error = false; + + // File provided? + if (!empty($_FILES['file']['tmp_name'])) { + $file_name = $_FILES['file']['tmp_name']; + } else { + flash_alert("Please select a file to upload.", 'error'); + redirect(); + } + + // Check extension + $file_extension = strtolower(end(explode('.', $_FILES['file']['name']))); + if ($file_extension !== 'csv') { + $error = true; + flash_alert("Bad file extension — only .csv files are accepted.", 'error'); + } + + // Check not empty + elseif ($_FILES['file']['size'] < 1) { + $error = true; + flash_alert("Bad file size (empty file?).", 'error'); + } + + // Check column count matches the 8-column export/template format + else { + $f = fopen($file_name, 'r'); + $f_columns = fgetcsv($f, 1000, ','); + fclose($f); + + if (count($f_columns) !== 8) { + $error = true; + flash_alert("Bad column count — expected 8 columns: Name, Description, VLAN, Network (CIDR), Gateway, IP Range, Primary DNS, Secondary DNS.", 'error'); + } + } + + // Parse and insert + if (!$error) { + $file = fopen($file_name, 'r'); + fgetcsv($file, 1000, ','); // Skip header row + + $row_count = 0; + $duplicate_count = 0; + + while (($column = fgetcsv($file, 1000, ',')) !== false) { + + $duplicate_detect = 0; + + $name = isset($column[0]) ? sanitizeInput($column[0]) : ''; + $description = isset($column[1]) ? sanitizeInput($column[1]) : ''; + $vlan = isset($column[2]) ? intval($column[2]) : 0; + $network = isset($column[3]) ? sanitizeInput($column[3]) : ''; + $gateway = isset($column[4]) ? sanitizeInput($column[4]) : ''; + $dhcp_range = isset($column[5]) ? sanitizeInput($column[5]) : ''; + $primary_dns = isset($column[6]) ? sanitizeInput($column[6]) : ''; + $secondary_dns = isset($column[7]) ? sanitizeInput($column[7]) : ''; + + // Skip rows with no name + if ($name === '') { + continue; + } + + // Duplicate check — same name + network address for this client + $dup_check = mysqli_query($mysqli, + "SELECT network_id FROM networks + WHERE network_name = '$name' + AND network = '$network' + AND network_client_id = $client_id + AND network_archived_at IS NULL + LIMIT 1" + ); + + if (mysqli_num_rows($dup_check) > 0) { + $duplicate_detect = 1; + } + + if ($duplicate_detect === 0) { + mysqli_query($mysqli, + "INSERT INTO networks SET + network_name = '$name', + network_description = '$description', + network_vlan = $vlan, + network = '$network', + network_gateway = '$gateway', + network_dhcp_range = '$dhcp_range', + network_primary_dns = '$primary_dns', + network_secondary_dns = '$secondary_dns', + network_client_id = $client_id" + ); + $row_count++; + } else { + $duplicate_count++; + } + } + + fclose($file); + + logAction("Network", "Import", "$session_name imported $row_count network(s). $duplicate_count duplicate(s) found and not imported", $client_id); + + flash_alert("$row_count Network(s) imported, $duplicate_count duplicate(s) detected and not imported"); + + redirect(); + } + + if ($error) { + redirect(); + } + +}