Files
CodePress/cli/geoip-update.php
E.Noorlander d9ea2eee47 v2.6.5 (Lyra): Dynamische pad-resolutie, WordPress-stijl docblocks, security-fix wachtwoord, git-historie schoon
- Bug: dashboard toonde 0 content (AdminPluginAPI::getContentDir() gaf relatief pad terug zonder normalisatie)
- Dynamische pad-resolutie: PluginAPIInterface uitgebreid met getProjectRoot/getContentDir/getPluginsDir/getVersionInfo; CMSAPI en AdminPluginAPI implementeren deze universeel
- public/index.php media-serving gebruikt $config['content_dir'] i.p.v. hardcoded /content
- Navigation en Logs plugins halen paden via de API i.p.v. hardcoded dirname(__DIR__)
- WordPress-stijl docblocks toegevoegd voor alle classes, methods, properties en functies (~450 docblocks, @since 2.6.5)
- Security: hardcoded plaintext-wachtwoord 'admin' verwijderd uit AdminAuth.php; bij eerste installatie wordt een cryptografisch veilig wachtwoord gegenereerd (random_bytes, 16 tekens) en eenmalig op het inlogscherm getoond
- Security: git-geschiedenis schoongemaakt (admin.json, admin.json.example, admin-console/config/admin.json verwijderd uit alle commits; filter-branch over alle branches + tags, gc --prune --aggressive)
- README.md, README.en.md, AGENTS.md bijgewerkt
- Test-scripts bijgewerkt naar clean-URL structuur + actuele ARIA-waarden
- Versie verhoogd naar 2.6.5
- Tests: pentest 29/29, WCAG 25/25, functioneel 16/16, enhanced 25/25
2026-08-27 09:05:51 +00:00

156 lines
4.9 KiB
PHP

#!/usr/bin/env php
<?php
/**
* DB-IP Lite database downloader & binaire converter voor CodePress CMS.
*
* Downloadt de DB-IP Lite country-CSV (gzip) van download.db-ip.com, pakt
* deze uit en zet de IP-ranges om in compacte binaire bestanden voor IPv4
* en IPv6 (met 2-byte country codes), plus een meta.json met bron en
* statistieken. Kan via de CLI of vanuit een admin-handler worden aangeroepen.
*
* @since 2.6.5
* @package CodePress
*/
/**
* DB-IP Lite database downloader & binary converter for CodePress CMS
*/
if (php_sapi_name() !== 'cli' && (!isset($_SESSION['admin_user']))) {
// Can also be included from admin handler
}
/**
* GeoIP-database bijwerken: downloaden, uitpakken en converteren.
*
* Probeert maximaal drie recente maandelijkse DB-IP Lite releases. Bij
* succes worden ipv4.bin en ipv6.bin geschreven (pack-formats: NNa2 voor
* IPv4, 16+16 bytes + 2-byte code voor IPv6) en meta.json weggeschreven.
*
* @since 2.6.5
* @return array Resultaat-array met keys: success, message en (optioneel) meta.
*/
function updateGeoIPDatabase(): array
{
$baseDir = dirname(__DIR__) . '/admin/storage/geoip';
if (!is_dir($baseDir)) {
@mkdir($baseDir, 0755, true);
}
$currentDate = new DateTime('first day of this month');
$urls = [];
for ($i = 0; $i < 3; $i++) {
$ym = $currentDate->format('Y-m');
$urls[] = "https://download.db-ip.com/free/dbip-country-lite-{$ym}.csv.gz";
$currentDate->modify('-1 month');
}
$downloadUrl = null;
$gzContent = null;
foreach ($urls as $url) {
$ctx = stream_context_create(['http' => ['timeout' => 15, 'user_agent' => 'CodePressCMS/1.9.0']]);
$data = @file_get_contents($url, false, $ctx);
if ($data !== false && strlen($data) > 1000) {
$downloadUrl = $url;
$gzContent = $data;
break;
}
}
if (!$gzContent) {
return ['success' => false, 'message' => 'Kon DB-IP Lite database niet downloaden vanaf DB-IP.com.'];
}
$csvData = @gzdecode($gzContent);
if (!$csvData) {
return ['success' => false, 'message' => 'Kon gecomprimeerde DB-IP database niet uitpakken.'];
}
$ipv4BinPath = $baseDir . '/ipv4.bin';
$ipv6BinPath = $baseDir . '/ipv6.bin';
$v4Handle = fopen($ipv4BinPath, 'wb');
$v6Handle = fopen($ipv6BinPath, 'wb');
$lines = explode("\n", $csvData);
$v4Count = 0;
$v6Count = 0;
/**
* CSV-records omzetten naar binaire IPv4-/IPv6-records.
*
* Elke geldige regel met start-, end-IP en 2-letterige country code wordt
* weggeschreven naar het juiste binaire bestand met bijbehorend pack-formaat.
*
* @since 2.6.5
*/
foreach ($lines as $line) {
$line = trim($line);
if ($line === '' || $line[0] === '#') continue;
$parts = str_getcsv($line);
if (count($parts) < 3) continue;
$startIp = trim($parts[0]);
$endIp = trim($parts[1]);
$country = strtoupper(trim($parts[2]));
if (strlen($country) !== 2) continue;
if (filter_var($startIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
$startLong = ip2long($startIp);
$endLong = ip2long($endIp);
if ($startLong !== false && $endLong !== false) {
// Pack 4-byte uint32 start, 4-byte uint32 end, 2-byte country code
$record = pack('NNa2', $startLong, $endLong, $country);
fwrite($v4Handle, $record);
$v4Count++;
}
} elseif (filter_var($startIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
$startBin = inet_pton($startIp);
$endBin = inet_pton($endIp);
if ($startBin !== false && $endBin !== false) {
// Pack 16-byte start, 16-byte end, 2-byte country code
$record = $startBin . $endBin . $country;
fwrite($v6Handle, $record);
$v6Count++;
}
}
}
fclose($v4Handle);
fclose($v6Handle);
$meta = [
'source' => 'DB-IP Lite',
'attribution' => 'IP geolocation by DB-IP (https://dbip.com)',
'updated' => date('Y-m-d H:i:s'),
'url' => $downloadUrl,
'ipv4_records' => $v4Count,
'ipv6_records' => $v6Count,
'ipv4_size' => filesize($ipv4BinPath),
'ipv6_size' => filesize($ipv6BinPath),
];
file_put_contents($baseDir . '/meta.json', json_encode($meta, JSON_PRETTY_PRINT));
return [
'success' => true,
'message' => "GeoIP database succesvol bijgewerkt! ({$v4Count} IPv4, {$v6Count} IPv6 records)",
'meta' => $meta
];
}
/**
* CLI-entrypoint: DB-IP Lite database bijwerken.
*
* Roept updateGeoIPDatabase() aan en print het resultaatbericht.
*
* @since 2.6.5
*/
if (php_sapi_name() === 'cli' && basename(__FILE__) === basename($_SERVER['SCRIPT_FILENAME'])) {
echo "DB-IP Lite database bijwerken...\n";
$res = updateGeoIPDatabase();
echo $res['message'] . "\n";
}