Files
XC_VM/tests/Unit/SessionManagerTest.php
T
Divarion_D 2c7ea749e7 refactor(admin): delete functions.php, consolidate the admin bootstrap
Views/admin/functions.php duplicated, almost line for line, the body of
AdminScopeBootstrap::bootFunctions() (the front-controller admin boot), and
was also include'd by the JSON DataTables endpoint — where its cookies /
redirects / setup-COUNT query are inappropriate and the relative include was
fragile (only resolved via the FC's @chdir).

- AdminScopeBootstrap: expose the boot body through a public
  hydrateAdminContext() entry point; guard the setcookie()/header() calls with
  headers_sent() so the view scripts can call it after output has begun;
  validate the session via the shared predicate.
- SessionManager::adminSessionValid() is now the single definition of the admin
  session-integrity check (user/is_admin + login-IP + verify hash), split into
  adminIdentityValid()/adminIpAllowed() and covered by SessionManagerTest.
- The six $noBootstrapPages view scripts (login, logout, setup, database,
  player, post) call AdminScopeBootstrap::hydrateAdminContext() in place of
  include "functions.php", re-importing the view-facing globals in their own
  scope (the load-bearing part of the old include).
- Admin TableController: the api_key / api_user_id / session branches share a
  hydrateApiUser() helper; the session branch validates via adminSessionValid()
  and returns JSON on failure (no cookies / redirect / setup query). index()'s
  global is widened so Authorization::check sees $rUserInfo/$rSettings.

793 unit tests pass; make gates and the CRAP gate stay green.
2026-09-18 11:32:15 +03:00

74 lines
2.6 KiB
PHP

<?php
use XcVm\Core\Auth\SessionManager;
use PHPUnit\Framework\TestCase;
/**
* SessionManager::adminSessionValid — the admin session-integrity guard shared
* by the HTML bootstrap (AdminScopeBootstrap) and the JSON table endpoint
* (Admin\TableController). Seeds $_SESSION / $_SERVER (login IP, verify hash,
* request IP) and asserts the accept/reject decision, including the ip_logout /
* ip_subnet_match IP rules.
*/
final class SessionManagerTest extends TestCase {
/** @var array<string, string> */
private array $user;
/** @var array<string, int> */
private array $perms;
protected function setUp(): void {
$this->user = ['username' => 'admin', 'password' => 'secret'];
$this->perms = ['is_admin' => 1];
$_SESSION['ip'] = '10.0.0.5';
$_SESSION['verify'] = md5('admin||secret');
$_SERVER['REMOTE_ADDR'] = '10.0.0.5';
}
protected function tearDown(): void {
unset($_SESSION['ip'], $_SESSION['verify'], $_SERVER['REMOTE_ADDR']);
}
/** @return array{ip_logout: int, ip_subnet_match: int} */
private function settings(int $ipLogout = 0, int $subnet = 0): array {
return ['ip_logout' => $ipLogout, 'ip_subnet_match' => $subnet];
}
public function testAcceptsAValidSession(): void {
$this->assertTrue(SessionManager::adminSessionValid($this->user, $this->perms, $this->settings()));
}
public function testRejectsWhenUserMissing(): void {
$this->assertFalse(SessionManager::adminSessionValid(null, $this->perms, $this->settings()));
}
public function testRejectsWhenPermissionsMissing(): void {
$this->assertFalse(SessionManager::adminSessionValid($this->user, null, $this->settings()));
}
public function testRejectsWhenNotAdmin(): void {
$this->assertFalse(SessionManager::adminSessionValid($this->user, ['is_admin' => 0], $this->settings()));
}
public function testRejectsWhenVerifyHashMismatches(): void {
$_SESSION['verify'] = md5('admin||wrong');
$this->assertFalse(SessionManager::adminSessionValid($this->user, $this->perms, $this->settings()));
}
public function testRejectsChangedIpWhenIpLogoutEnabled(): void {
$_SERVER['REMOTE_ADDR'] = '10.0.0.9';
$this->assertFalse(SessionManager::adminSessionValid($this->user, $this->perms, $this->settings(1, 0)));
}
public function testAcceptsChangedHostInSameSubnetWhenSubnetMatch(): void {
$_SERVER['REMOTE_ADDR'] = '10.0.0.9';
$this->assertTrue(SessionManager::adminSessionValid($this->user, $this->perms, $this->settings(1, 1)));
}
public function testIgnoresIpChangeWhenIpLogoutDisabled(): void {
$_SERVER['REMOTE_ADDR'] = '203.0.113.1';
$this->assertTrue(SessionManager::adminSessionValid($this->user, $this->perms, $this->settings(0, 0)));
}
}