From 1aea4bde206cbe0a848712b5c2ac957e5a04c357 Mon Sep 17 00:00:00 2001 From: Jukka Lampikoski Date: Thu, 12 Mar 2026 16:49:24 +0200 Subject: [PATCH] =?UTF-8?q?Tiukempi=20IP-rajoitus:=20est=C3=A4=20kirjautum?= =?UTF-8?q?inen=20ja=20suojaa=20asetukset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Login: jos kaikki käyttäjän yritykset IP-estetty → estä kirjautuminen kokonaan. Valitsee automaattisesti ei-estetyn yrityksen aktiiviseksi. - check_auth: jos aktiivinen yritys IP-estetty → vaihda sallittuun. Jos kaikki estetty → kirjaa ulos. - company_update: vain superadmin saa muuttaa allowed_ips-kenttää. Estää adminia poistamasta IP-rajoitusta itseltään. Co-Authored-By: Claude Opus 4.6 --- api.php | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/api.php b/api.php index 31802fa..61bfccd 100644 --- a/api.php +++ b/api.php @@ -1347,8 +1347,26 @@ switch ($action) { echo json_encode(['error' => 'Sinulla ei ole oikeutta kirjautua tälle sivustolle.']); break; } - // IP-rajoitus EI enää estä kirjautumista — tarkistetaan vasta requireCompany():ssa $allCompanies = dbLoadCompanies(); + + // IP-rajoitus: selvitä mihin yrityksiin on pääsy (superadmin ohittaa) + $allowedCompanyIds = $userCompanies; + if ($u['role'] !== 'superadmin') { + $allowedCompanyIds = []; + foreach ($allCompanies as $comp) { + if (in_array($comp['id'], $userCompanies) && isIpAllowed($ip, $comp['allowed_ips'] ?? '')) { + $allowedCompanyIds[] = $comp['id']; + } + } + // Jos kaikki yritykset IP-estetty → estä kirjautuminen + if (empty($allowedCompanyIds) && !empty($userCompanies)) { + dbRecordLoginAttempt($ip); + http_response_code(403); + echo json_encode(['error' => 'IP-osoitteesi (' . $ip . ') ei ole sallittu. Ota yhteyttä ylläpitoon.']); + break; + } + } + session_regenerate_id(true); $_SESSION['user_id'] = $u['id']; $_SESSION['username'] = $u['username']; @@ -1356,9 +1374,11 @@ switch ($action) { $_SESSION['role'] = $u['role']; $_SESSION['companies'] = $userCompanies; $_SESSION['company_roles'] = $u['company_roles'] ?? []; - // Jos domain matchaa ja käyttäjällä on oikeus -> käytä sitä - if ($domainCompanyId && in_array($domainCompanyId, $userCompanies)) { + // Valitse aktiivinen yritys: domain-match > ensimmäinen sallittu + if ($domainCompanyId && in_array($domainCompanyId, $allowedCompanyIds)) { $_SESSION['company_id'] = $domainCompanyId; + } elseif (!empty($allowedCompanyIds)) { + $_SESSION['company_id'] = $allowedCompanyIds[0]; } else { $_SESSION['company_id'] = !empty($userCompanies) ? $userCompanies[0] : ''; } @@ -1412,21 +1432,46 @@ switch ($action) { // Päivitä aktiivisen yrityksen rooli $_SESSION['company_role'] = $_SESSION['company_roles'][$_SESSION['company_id'] ?? ''] ?? 'user'; } - // Hae yritysten nimet — EI suodata IP:n perusteella pois, vaan merkitään ip_blocked + // Hae yritysten nimet ja IP-status $userCompanyIds = $_SESSION['companies'] ?? []; $allCompanies = dbLoadCompanies(); $ip = getClientIp(); + $isSuperAdmin = ($_SESSION['role'] ?? '') === 'superadmin'; $companyList = []; + $firstAllowedId = null; foreach ($allCompanies as $comp) { if (in_array($comp['id'], $userCompanyIds)) { $entry = ['id' => $comp['id'], 'nimi' => $comp['nimi']]; - // Merkitse IP-estetyt yritykset (superadmin ohittaa) - if (($_SESSION['role'] ?? '') !== 'superadmin' && !isIpAllowed($ip, $comp['allowed_ips'] ?? '')) { + if (!$isSuperAdmin && !isIpAllowed($ip, $comp['allowed_ips'] ?? '')) { $entry['ip_blocked'] = true; + } else { + if (!$firstAllowedId) $firstAllowedId = $comp['id']; } $companyList[] = $entry; } } + // Jos aktiivinen yritys on IP-estetty → vaihda sallittuun + if (!$isSuperAdmin) { + $activeBlocked = false; + $activeId = $_SESSION['company_id'] ?? ''; + foreach ($companyList as $c) { + if ($c['id'] === $activeId && !empty($c['ip_blocked'])) { + $activeBlocked = true; + break; + } + } + if ($activeBlocked) { + if ($firstAllowedId) { + $_SESSION['company_id'] = $firstAllowedId; + $_SESSION['company_role'] = $_SESSION['company_roles'][$firstAllowedId] ?? 'user'; + } else { + // Kaikki yritykset IP-estetty → kirjaa ulos + session_destroy(); + echo json_encode(['authenticated' => false, 'reason' => 'ip_blocked']); + break; + } + } + } // Hae allekirjoitukset (oletus generoituna jos omaa ei ole) $userSignatures = $u ? buildSignaturesWithDefaults($u, $u['companies'] ?? []) : []; // Brändäystiedot aktiivisen yrityksen mukaan (ei domain-pohjainen) @@ -3789,7 +3834,10 @@ switch ($action) { if (isset($input['enabled_modules']) && is_array($input['enabled_modules'])) { $c['enabled_modules'] = array_values($input['enabled_modules']); } - if (isset($input['allowed_ips'])) $c['allowed_ips'] = trim($input['allowed_ips']); + // Vain superadmin saa muuttaa IP-rajoituksia + if (isset($input['allowed_ips']) && isSuperAdmin()) { + $c['allowed_ips'] = trim($input['allowed_ips']); + } dbSaveCompany($c); $found = true; echo json_encode($c);