mini_identity_management_test.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <?php
  2. /** IdentityManagement.authorize and grant flow. All fixture rows are rolled back at the end. */
  3. require dirname(__DIR__) . '/vendor/autoload.php';
  4. \Dotenv\Dotenv::createUnsafeMutable(dirname(__DIR__))->load();
  5. \support\App::loadAllConfig(['route']);
  6. use app\miniapi\exception\ApiException;
  7. use app\miniapi\model\MiniAudit;
  8. use app\miniapi\model\MiniGrant;
  9. use app\miniapi\model\MiniUser;
  10. use app\miniapi\service\IdentityManagement;
  11. use plugin\saiadmin\app\model\water\WaterAgent;
  12. use plugin\saiadmin\app\model\water\WaterDriver;
  13. use plugin\saiadmin\app\model\water\WaterEnterprise;
  14. $checks = 0;
  15. function check(bool $ok, string $label): void
  16. {
  17. global $checks;
  18. $checks++;
  19. if (!$ok) {
  20. throw new RuntimeException($label);
  21. }
  22. }
  23. function reject(callable $action, int $code): void
  24. {
  25. try {
  26. $action();
  27. } catch (ApiException $error) {
  28. check($error->getCode() === $code, 'Expected rejection ' . $code . ' got ' . $error->getCode());
  29. return;
  30. }
  31. throw new RuntimeException('Missing rejection');
  32. }
  33. $db = (new MiniUser())->getConnection();
  34. $db->beginTransaction();
  35. $now = date('Y-m-d H:i:s');
  36. $rand = bin2hex(random_bytes(4));
  37. $baseUserId = (int) MiniUser::query()->insertGetId([
  38. 'appid' => 'wechat-app-fixture-' . $rand,
  39. 'openid' => 'openid-fixture-' . $rand,
  40. 'nickname' => 'identity-test',
  41. 'status' => 1,
  42. 'created_at' => $now,
  43. 'updated_at' => $now,
  44. ]);
  45. $opId = (int) WaterEnterprise::query()->insertGetId([
  46. 'name' => 'identity-test-' . $rand,
  47. 'contact' => 'fixture',
  48. 'phone' => '139' . str_pad((string) random_int(0, 99999999), 8, '0', STR_PAD_LEFT),
  49. 'region' => '',
  50. 'address' => 'fixture',
  51. 'agent_id' => 0,
  52. 'status' => 1,
  53. 'created_at' => $now,
  54. 'updated_at' => $now,
  55. ]);
  56. $driverId = (int) WaterDriver::query()->insertGetId([
  57. 'name' => 'fixture-driver-' . $rand,
  58. 'phone' => '138' . str_pad((string) random_int(0, 99999999), 8, '0', STR_PAD_LEFT),
  59. 'region' => '',
  60. 'vehicle' => '',
  61. 'capacity' => 100,
  62. 'status' => 1,
  63. 'created_at' => $now,
  64. 'updated_at' => $now,
  65. ]);
  66. $agentId = (int) WaterAgent::query()->insertGetId([
  67. 'name' => 'fixture-agent-' . $rand,
  68. 'contact' => 'fixture',
  69. 'phone' => '137' . str_pad((string) random_int(0, 99999999), 8, '0', STR_PAD_LEFT),
  70. 'region' => '',
  71. 'address' => '',
  72. 'status' => 1,
  73. 'created_at' => $now,
  74. 'updated_at' => $now,
  75. ]);
  76. try {
  77. $service = new IdentityManagement();
  78. reject(fn () => $service->users(2, []), 40301);
  79. reject(fn () => $service->grant(0, []), 40301);
  80. reject(fn () => $service->grant(1, [
  81. 'user_id' => $baseUserId,
  82. 'role' => 'enterprise_admin',
  83. 'resource_id' => 999999,
  84. 'status' => 1,
  85. ]), 40401);
  86. reject(fn () => $service->grant(1, [
  87. 'user_id' => 999999,
  88. 'role' => 'enterprise_admin',
  89. 'resource_id' => $opId,
  90. 'status' => 1,
  91. ]), 40401);
  92. reject(fn () => $service->grant(1, [
  93. 'user_id' => $baseUserId,
  94. 'role' => 'warehouse_keeper',
  95. 'resource_id' => $opId,
  96. 'status' => 1,
  97. ]), 42201);
  98. $first = $service->grant(1, [
  99. 'user_id' => $baseUserId,
  100. 'role' => 'enterprise_admin',
  101. 'resource_id' => $opId,
  102. 'status' => 1,
  103. ]);
  104. check(isset($first['id']) && $first['status'] === 1, 'first grant stored');
  105. check(MiniGrant::query()->where('user_id', $baseUserId)->where('role', 'enterprise_admin')->count() === 1, 'one grant row');
  106. $service->grant(1, [
  107. 'user_id' => $baseUserId,
  108. 'role' => 'enterprise_admin',
  109. 'resource_id' => $opId,
  110. 'status' => 0,
  111. ]);
  112. check(MiniGrant::query()->where('user_id', $baseUserId)->where('role', 'enterprise_admin')->count() === 1, 'toggling status must not create a new row');
  113. $service->grant(1, [
  114. 'user_id' => $baseUserId,
  115. 'role' => 'driver',
  116. 'resource_id' => $driverId,
  117. 'status' => 1,
  118. ]);
  119. $service->grant(1, [
  120. 'user_id' => $baseUserId,
  121. 'role' => 'agent',
  122. 'resource_id' => $agentId,
  123. 'status' => 1,
  124. ]);
  125. check(MiniGrant::query()->where('user_id', $baseUserId)->count() === 3, 'multiple roles coexist');
  126. $list = $service->users(1, ['page' => 1, 'page_size' => 20]);
  127. check(is_int($list['total']) && $list['total'] >= 1, 'users list returns total');
  128. $found = false;
  129. foreach ($list['items'] as $row) {
  130. if ((int) $row['id'] === $baseUserId) {
  131. $found = true;
  132. break;
  133. }
  134. }
  135. check($found, 'newly inserted user appears in listing');
  136. $auditCount = (int) MiniAudit::query()->where('action', 'identity.grant')->count();
  137. check($auditCount >= 3, 'audit rows written for grant operations');
  138. $users = $service->users(1, ['user_id' => $baseUserId, 'page' => 1, 'page_size' => 5]);
  139. check($users['total'] === 1, 'user_id filter narrows list to one');
  140. check(count($users['items'][0]['grants']) === 3, 'grants included in user detail');
  141. } finally {
  142. MiniGrant::query()->where('user_id', $baseUserId)->delete();
  143. MiniAudit::query()->where('action', 'identity.grant')->where('created_at', '>=', date('Y-m-d H:i:s', time() - 600))->delete();
  144. if ($agentId) {
  145. WaterAgent::query()->where('id', $agentId)->delete();
  146. }
  147. if ($driverId) {
  148. WaterDriver::query()->where('id', $driverId)->delete();
  149. }
  150. if ($opId) {
  151. WaterEnterprise::query()->where('id', $opId)->delete();
  152. }
  153. if ($baseUserId) {
  154. MiniUser::query()->where('id', $baseUserId)->delete();
  155. }
  156. $db->rollBack();
  157. }
  158. echo 'PASS: ' . $checks . ' identity management checks, database changes rolled back.' . PHP_EOL;