update
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -223,4 +223,181 @@ class PermissionFlowTest extends TestCase
|
|||||||
$this->cleanupRouteGroup($user->role_id, $route, $auth_data);
|
$this->cleanupRouteGroup($user->role_id, $route, $auth_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== 边缘场景 ==========
|
||||||
|
|
||||||
|
public function test_accessor_with_invalid_store_id_denied(): void
|
||||||
|
{
|
||||||
|
$user = $this->createTestUser('accessor');
|
||||||
|
|
||||||
|
$route = Route::query()->where('method', 'GET')->where('path', '/api/v1/users')->first();
|
||||||
|
if (!$route) {
|
||||||
|
$this->markTestSkipped('routes 表中无 GET /api/v1/users 路由');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 授权路由访问
|
||||||
|
RoleRouteOverride::query()->create([
|
||||||
|
'role_id' => $user->role_id,
|
||||||
|
'route_id' => $route->id,
|
||||||
|
'allowed' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 添加 store scope(store_id=1),然后传不在 bitmap 中的 store_id
|
||||||
|
$store = Store::query()->first();
|
||||||
|
if (!$store) {
|
||||||
|
$this->markTestSkipped('stores 表中无数据');
|
||||||
|
}
|
||||||
|
|
||||||
|
UserDataScope::query()->create([
|
||||||
|
'user_id' => $user->id,
|
||||||
|
'scope_type' => 'store',
|
||||||
|
'scope_id' => $store->id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 传不属于自己的 store_id → 403
|
||||||
|
$response = $this->get('/api/v1/users', ['store_id' => 999999], $this->authHeaders($user));
|
||||||
|
$response->assertStatus(403);
|
||||||
|
} finally {
|
||||||
|
RoleRouteOverride::query()
|
||||||
|
->where('role_id', $user->role_id)
|
||||||
|
->where('route_id', $route->id)
|
||||||
|
->delete();
|
||||||
|
UserDataScope::query()->where('user_id', $user->id)->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_accessor_with_invalid_company_id_denied(): void
|
||||||
|
{
|
||||||
|
$user = $this->createTestUser('accessor');
|
||||||
|
|
||||||
|
$route = Route::query()->where('method', 'GET')->where('path', '/api/v1/users')->first();
|
||||||
|
if (!$route) {
|
||||||
|
$this->markTestSkipped('routes 表中无 GET /api/v1/users 路由');
|
||||||
|
}
|
||||||
|
|
||||||
|
RoleRouteOverride::query()->create([
|
||||||
|
'role_id' => $user->role_id,
|
||||||
|
'route_id' => $route->id,
|
||||||
|
'allowed' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$store = Store::query()->first();
|
||||||
|
if (!$store) {
|
||||||
|
$this->markTestSkipped('stores 表中无数据');
|
||||||
|
}
|
||||||
|
|
||||||
|
UserDataScope::query()->create([
|
||||||
|
'user_id' => $user->id,
|
||||||
|
'scope_type' => 'store',
|
||||||
|
'scope_id' => $store->id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 传不属于自己的 company_id → 403
|
||||||
|
$response = $this->get('/api/v1/users', ['company_id' => 999999], $this->authHeaders($user));
|
||||||
|
$response->assertStatus(403);
|
||||||
|
} finally {
|
||||||
|
RoleRouteOverride::query()
|
||||||
|
->where('role_id', $user->role_id)
|
||||||
|
->where('route_id', $route->id)
|
||||||
|
->delete();
|
||||||
|
UserDataScope::query()->where('user_id', $user->id)->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_accessor_with_no_scope_data_gets_empty_results(): void
|
||||||
|
{
|
||||||
|
$user = $this->createTestUser('accessor');
|
||||||
|
|
||||||
|
$route = Route::query()->where('method', 'GET')->where('path', '/api/v1/users')->first();
|
||||||
|
if (!$route) {
|
||||||
|
$this->markTestSkipped('routes 表中无 GET /api/v1/users 路由');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 授权路由访问但不设置任何 scope 数据
|
||||||
|
RoleRouteOverride::query()->create([
|
||||||
|
'role_id' => $user->role_id,
|
||||||
|
'route_id' => $route->id,
|
||||||
|
'allowed' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// accessor 无 scope 数据 → bitmap 为空 → scope_ids=[] → 200 但无数据
|
||||||
|
$response = $this->get('/api/v1/users', [], $this->authHeaders($user));
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertJsonPath('code', 0);
|
||||||
|
} finally {
|
||||||
|
RoleRouteOverride::query()
|
||||||
|
->where('role_id', $user->role_id)
|
||||||
|
->where('route_id', $route->id)
|
||||||
|
->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_developer_with_invalid_store_id_denied(): void
|
||||||
|
{
|
||||||
|
$user = $this->createTestUser('developer');
|
||||||
|
|
||||||
|
$route = Route::query()->where('method', 'GET')->where('path', '/api/v1/users')->first();
|
||||||
|
if (!$route) {
|
||||||
|
$this->markTestSkipped('routes 表中无 GET /api/v1/users 路由');
|
||||||
|
}
|
||||||
|
|
||||||
|
$auth_data = $this->authorizeRouteGroup($user->role_id, $route);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// developer 传不属于自己的 store_id → 403
|
||||||
|
$response = $this->get('/api/v1/users', ['store_id' => 999999], $this->authHeaders($user));
|
||||||
|
$response->assertStatus(403);
|
||||||
|
} finally {
|
||||||
|
$this->cleanupRouteGroup($user->role_id, $route, $auth_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_developer_with_no_platforms_gets_empty_scope(): void
|
||||||
|
{
|
||||||
|
// 创建 developer 用户但不关联任何 platform
|
||||||
|
$user = $this->createTestUser('developer');
|
||||||
|
|
||||||
|
$route = Route::query()->where('method', 'GET')->where('path', '/api/v1/users')->first();
|
||||||
|
if (!$route) {
|
||||||
|
$this->markTestSkipped('routes 表中无 GET /api/v1/users 路由');
|
||||||
|
}
|
||||||
|
|
||||||
|
$auth_data = $this->authorizeRouteGroup($user->role_id, $route);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// developer 无维护平台 → platform_ids=[] → scope_ids=[] → 200 但无数据
|
||||||
|
$response = $this->get('/api/v1/users', [], $this->authHeaders($user));
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertJsonPath('code', 0);
|
||||||
|
} finally {
|
||||||
|
$this->cleanupRouteGroup($user->role_id, $route, $auth_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_ungrouped_route_denied_for_non_admin(): void
|
||||||
|
{
|
||||||
|
$user = $this->createTestUser('developer');
|
||||||
|
|
||||||
|
$route = Route::query()->where('method', 'GET')->where('path', '/api/v1/users')->first();
|
||||||
|
if (!$route) {
|
||||||
|
$this->markTestSkipped('routes 表中无 GET /api/v1/users 路由');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保路由未分组且无 override
|
||||||
|
$old_group_id = $route->group_id;
|
||||||
|
$route->group_id = null;
|
||||||
|
$route->save();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 路由已注册但未分组、无 override → 403
|
||||||
|
$response = $this->get('/api/v1/users', [], $this->authHeaders($user));
|
||||||
|
$response->assertStatus(403);
|
||||||
|
} finally {
|
||||||
|
$route->group_id = $old_group_id;
|
||||||
|
$route->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user