OperationsAdminAccessTest.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. <?php
  2. namespace Tests\Integration;
  3. use App\Http\Middleware\OperationsAdminMiddleware;
  4. use Illuminate\Config\Repository;
  5. use Illuminate\Database\Capsule\Manager;
  6. use Illuminate\Events\Dispatcher;
  7. use Illuminate\Foundation\Application;
  8. use Illuminate\Http\Request;
  9. use Illuminate\Routing\Route;
  10. use Illuminate\Support\Facades\DB;
  11. use Illuminate\Support\Facades\Facade;
  12. use PHPUnit\Framework\TestCase;
  13. /** 运营配置类接口只看超级管理员和数据库角色授权,不读环境变量白名单。 */
  14. class OperationsAdminAccessTest extends TestCase
  15. {
  16. protected function setUp(): void
  17. {
  18. Facade::clearResolvedInstances(); $app = new Application(dirname(__DIR__, 2));
  19. $app->instance('config', new Repository(['operations' => ['admin_ids' => [1, 9]]]));
  20. Facade::setFacadeApplication($app);
  21. $db = new Manager($app); $db->addConnection(['driver' => 'sqlite', 'database' => ':memory:', 'prefix' => 'bot_']);
  22. $db->setEventDispatcher(new Dispatcher($app)); $db->setAsGlobal(); $db->bootEloquent();
  23. $app->instance('db', $db->getDatabaseManager());
  24. $app->instance(\Illuminate\Contracts\Routing\ResponseFactory::class, new \Tests\Support\JsonResponseFactory());
  25. DB::statement('CREATE TABLE bot_menus (id INTEGER PRIMARY KEY, uri TEXT, type INTEGER, status INTEGER)');
  26. DB::statement('CREATE TABLE bot_role_menu (role_id INTEGER, menu_id INTEGER)');
  27. DB::statement('CREATE TABLE bot_role_user (role_id INTEGER, user_id INTEGER)');
  28. DB::table('menus')->insert([
  29. ['id' => 1, 'uri' => 'maintenance', 'type' => 1, 'status' => 1], ['id' => 2, 'uri' => 'admin/maintenance', 'type' => 2, 'status' => 1],
  30. ['id' => 3, 'uri' => 'admin/maintenance/submit', 'type' => 2, 'status' => 0],
  31. ]);
  32. // 角色 10:只有页面菜单;11:维护列表按钮;12:保存按钮(隐藏状态也算授权)
  33. DB::table('role_menu')->insert([['role_id' => 10, 'menu_id' => 1], ['role_id' => 11, 'menu_id' => 2], ['role_id' => 12, 'menu_id' => 3]]);
  34. DB::table('role_user')->insert([['role_id' => 10, 'user_id' => 2], ['role_id' => 11, 'user_id' => 3], ['role_id' => 12, 'user_id' => 4], ['role_id' => 11, 'user_id' => 4]]);
  35. }
  36. protected function tearDown(): void { DB::disconnect(); Facade::clearResolvedInstances(); parent::tearDown(); }
  37. private function call(int $adminId, string $uri, ?string $permissionUri = null)
  38. {
  39. $request = Request::create('/' . $uri); $request->user = (object) ['id' => $adminId];
  40. $route = new Route('GET', $uri, []);
  41. if ($permissionUri !== null) $route->defaults('permission_uri', $permissionUri);
  42. $request->setRouteResolver(fn () => $route);
  43. $result = (new OperationsAdminMiddleware())->handle($request, static fn () => 'passed');
  44. return $result === 'passed' ? $result : $result->getData(true)['msg'];
  45. }
  46. public function test_super_admin_or_role_with_the_route_button_passes(): void
  47. {
  48. $this->assertSame('passed', $this->call(1, 'admin/maintenance'));
  49. $this->assertSame('无运营配置管理权限', $this->call(9, 'admin/maintenance'), '不再读 OPERATIONS_ADMIN_IDS');
  50. $this->assertSame('无运营配置管理权限', $this->call(0, 'admin/maintenance'));
  51. $this->assertSame('无运营配置管理权限', $this->call(2, 'admin/maintenance'), '只勾页面菜单不够,要勾接口按钮');
  52. $this->assertSame('passed', $this->call(3, 'admin/maintenance'));
  53. $this->assertSame('passed', $this->call(3, 'admin/maintenance/detail', 'admin/maintenance'), 'permission_uri 复用列表按钮');
  54. $this->assertSame('无运营配置管理权限', $this->call(3, 'admin/maintenance/submit'));
  55. $this->assertSame('passed', $this->call(4, 'admin/maintenance/submit'));
  56. $this->assertSame('passed', $this->call(3, 'admin/maintenance/logs'), '按钮没建时跟随同模块授权');
  57. $this->assertSame('无运营配置管理权限', $this->call(2, 'admin/maintenance/logs'), '只有前端页面菜单不算模块授权');
  58. $this->assertSame('无运营配置管理权限', $this->call(3, 'admin/paymentConfig/direct/save'), '其他模块没有授权');
  59. $this->assertSame('无运营配置管理权限', $this->call(3, 'admin/maintenanceX/logs'), '前缀相似但不是同一模块');
  60. DB::table('role_menu')->where('role_id', 11)->delete();
  61. $this->assertSame('无运营配置管理权限', $this->call(3, 'admin/maintenance'), '取消勾选后立即失效');
  62. }
  63. }