9]) { throw new \RuntimeException('wrong identity lookup'); } return new self(self::$row); } public function field(string $fields): self { return $this; } public function findOrEmpty(): self { return $this; } public function isEmpty(): bool { return $this->count() === 0; } } class AdminRole { public static function where(string $field, int $id): self { if ($field !== 'admin_id' || $id !== 9) { throw new \RuntimeException('wrong role lookup'); } return new self(); } public function column(string $field): array { return ['3', '2', '3']; } } } namespace app\adminapi\logic\auth { class AuthLogic { public static array $permissions = ['tcm.diagnosis/lists']; public static function getBtnAuthByRoleId(array $admin): array { if ($admin['id'] !== 9 || $admin['role_id'] !== [2, 3]) { throw new \RuntimeException('wrong permission identity'); } return $admin['root'] ? ['*'] : self::$permissions; } } } namespace { require dirname(__DIR__) . '/vendor/autoload.php'; require dirname(__DIR__) . '/vendor/topthink/framework/src/helper.php'; use app\adminapi\controller\DesktopController; use app\adminapi\http\middleware\AuthMiddleware; use app\adminapi\logic\auth\AuthLogic; use app\common\model\auth\Admin; $app = new think\App(); final class DesktopSessionFixture extends DesktopController { public function __construct(think\Request $request) { $this->request = $request; } protected function data($data) { return ['code' => 1, 'data' => $data]; } protected function fail(string $msg = 'fail', array $data = [], int $code = 0, int $show = 1) { return ['code' => $code, 'msg' => $msg]; } } function desktopCheck(bool $ok, string $message): void { if (!$ok) { throw new RuntimeException($message); } } $valid = ['admin_id' => 9, 'terminal' => 7, 'expire_time' => time() + 3600, 'root' => 0, 'login_ip' => '198.51.100.10']; $invoke = function (array $identity, string $action = 'session') use ($app) { $request = (new think\Request())->withServer(['REMOTE_ADDR' => '203.0.113.20']); $request->setAction($action); $request->setController('Desktop'); $request->adminInfo = $identity; $controller = new DesktopSessionFixture($request); $request->controllerObject = $controller; $app->instance('request', $request); return (new AuthMiddleware())->handle($request, static fn() => $controller->session()); }; Admin::$row = ['id' => 9, 'account' => 'doctor9', 'name' => '医助', 'avatar' => '', 'disable' => 0, 'root' => 0]; $result = $invoke($valid); desktopCheck($result['code'] === 1, 'valid desktop session works across different IPs'); desktopCheck($result['data']['user_id'] === 'admin:9', 'account is namespaced'); desktopCheck($result['data']['role_ids'] === [2, 3], 'current roles are normalized'); desktopCheck($result['data']['permissions'] === ['tcm.diagnosis/lists'], 'current permissions returned'); desktopCheck($result['data']['root'] === false, 'ordinary account stays ordinary'); desktopCheck(!isset($result['data']['token']) && !isset($result['data']['login_ip']), 'minimal response'); AuthLogic::$permissions = []; desktopCheck($invoke($valid)['data']['permissions'] === [], 'empty permissions remain empty'); Admin::$row['root'] = 1; desktopCheck($invoke($valid)['data']['permissions'] === ['*'], 'current root privilege returned'); desktopCheck($invoke($valid)['data']['root'] === true, 'root comes from current account'); Admin::$row['root'] = 0; desktopCheck($invoke([])['code'] === 0, 'missing or expired cached identity rejected'); desktopCheck($invoke(array_replace($valid, ['terminal' => 1]))['code'] === 0, 'web token rejected'); Admin::$row['disable'] = 1; desktopCheck($invoke($valid)['code'] === 0, 'disabled account rejected'); Admin::$row = []; desktopCheck($invoke($valid)['code'] === 0, 'deleted account rejected'); $webResult = $invoke($valid, 'mySelf')->getData(); desktopCheck($webResult['code'] === -1 && str_contains($webResult['msg'], 'ip地址'), 'ordinary web requests retain IP validation'); echo "AdminDesktopSessionBehaviorTest passed\n"; }