176 lines
6.0 KiB
Python
176 lines
6.0 KiB
Python
from __future__ import annotations
|
|
|
|
import time
|
|
|
|
import pytest
|
|
|
|
from .conftest import ReleaseDatasetSeed, TenantSeed
|
|
from .helpers import ReleaseApiClient
|
|
|
|
|
|
def _dataset_ids(items: list[dict]) -> set[int]:
|
|
return {int(item["id"]) for item in items if item.get("id") is not None}
|
|
|
|
|
|
def _app_ids(items: list[dict]) -> set[str]:
|
|
return {str(item["appId"]) for item in items if item.get("appId") is not None}
|
|
|
|
|
|
@pytest.mark.release
|
|
def test_g5_rag_dataset_admin_scope_is_limited_to_own_tenant(
|
|
admin_client: ReleaseApiClient,
|
|
tenant_admin_api: ReleaseApiClient,
|
|
tenant_admin_api_b: ReleaseApiClient,
|
|
tenant_a: TenantSeed,
|
|
tenant_b: TenantSeed,
|
|
make_release_dataset,
|
|
) -> None:
|
|
dataset_a = make_release_dataset(
|
|
tenant=tenant_a,
|
|
dataset_name=f"Pytest G5 A {int(time.time())}",
|
|
)
|
|
dataset_b = make_release_dataset(
|
|
tenant=tenant_b,
|
|
dataset_name=f"Pytest G5 B {int(time.time())}",
|
|
)
|
|
|
|
global_admin_list = ReleaseApiClient.json_data(admin_client.get("/api/v3/rag/datasets/admin?page=1&pageSize=100"))
|
|
ids_a = _dataset_ids(global_admin_list["data"])
|
|
assert dataset_a.dataset_id in ids_a
|
|
assert dataset_b.dataset_id in ids_a
|
|
|
|
tenant_admin_list = ReleaseApiClient.json_data(
|
|
tenant_admin_api.get("/api/v3/rag/datasets/admin?page=1&pageSize=100")
|
|
)
|
|
tenant_admin_ids = _dataset_ids(tenant_admin_list["data"])
|
|
assert dataset_a.dataset_id in tenant_admin_ids
|
|
assert dataset_b.dataset_id not in tenant_admin_ids
|
|
|
|
forbidden_query = tenant_admin_api.get(
|
|
f"/api/v3/rag/datasets/admin?page=1&pageSize=100&tenant_code={tenant_b.tenant_code}",
|
|
expected_status=403,
|
|
)
|
|
assert "本地区知识库配置" in forbidden_query.text or "本租户知识库" in forbidden_query.text
|
|
|
|
|
|
@pytest.mark.release
|
|
def test_g5_rag_dataset_detail_and_update_respect_tenant_boundary(
|
|
admin_client: ReleaseApiClient,
|
|
tenant_admin_api: ReleaseApiClient,
|
|
tenant_a: TenantSeed,
|
|
tenant_b: TenantSeed,
|
|
make_release_dataset,
|
|
) -> None:
|
|
dataset_a = make_release_dataset(
|
|
tenant=tenant_a,
|
|
dataset_name=f"Pytest G5 Detail A {int(time.time())}",
|
|
)
|
|
dataset_b = make_release_dataset(
|
|
tenant=tenant_b,
|
|
dataset_name=f"Pytest G5 Detail B {int(time.time())}",
|
|
)
|
|
|
|
own_detail = ReleaseApiClient.json_data(tenant_admin_api.get(f"/api/v3/rag/datasets/{dataset_a.dataset_id}"))
|
|
assert int(own_detail["id"]) == dataset_a.dataset_id
|
|
assert str(own_detail.get("tenantCode") or "") == tenant_a.tenant_code
|
|
|
|
hidden_detail = ReleaseApiClient.json_data(tenant_admin_api.get(f"/api/v3/rag/datasets/{dataset_b.dataset_id}"))
|
|
assert hidden_detail is None
|
|
|
|
own_update = ReleaseApiClient.json_data(
|
|
tenant_admin_api.patch(
|
|
f"/api/v3/rag/datasets/{dataset_a.dataset_id}",
|
|
json={"name": f"{dataset_a.dataset_name}-tenant-updated"},
|
|
expected_status=200,
|
|
)
|
|
)
|
|
assert str(own_update["name"]).endswith("-tenant-updated")
|
|
|
|
hidden_update = ReleaseApiClient.json_data(
|
|
tenant_admin_api.patch(
|
|
f"/api/v3/rag/datasets/{dataset_b.dataset_id}",
|
|
json={"name": "should-not-work"},
|
|
expected_status=200,
|
|
)
|
|
)
|
|
assert hidden_update is None
|
|
|
|
admin_update = ReleaseApiClient.json_data(
|
|
admin_client.patch(
|
|
f"/api/v3/rag/datasets/{dataset_a.dataset_id}",
|
|
json={"name": f"{dataset_a.dataset_name}-updated"},
|
|
expected_status=200,
|
|
)
|
|
)
|
|
assert str(admin_update["name"]).endswith("-updated")
|
|
|
|
|
|
@pytest.mark.release
|
|
def test_g5_rag_apps_and_public_dataset_visibility(
|
|
tenant_admin_api: ReleaseApiClient,
|
|
tenant_admin_api_b: ReleaseApiClient,
|
|
common_api_a: ReleaseApiClient,
|
|
common_api_b: ReleaseApiClient,
|
|
tenant_a: TenantSeed,
|
|
tenant_b: TenantSeed,
|
|
make_release_dataset,
|
|
) -> None:
|
|
dataset_a = make_release_dataset(
|
|
tenant=tenant_a,
|
|
dataset_name=f"Pytest G5 App A {int(time.time())}",
|
|
is_default=True,
|
|
)
|
|
dataset_b = make_release_dataset(
|
|
tenant=tenant_b,
|
|
dataset_name=f"Pytest G5 App B {int(time.time())}",
|
|
is_default=True,
|
|
)
|
|
public_dataset = make_release_dataset(
|
|
tenant=tenant_a,
|
|
dataset_name=f"Pytest G5 Public {int(time.time())}",
|
|
is_public=True,
|
|
is_default=False,
|
|
)
|
|
|
|
apps_a = ReleaseApiClient.json_data(common_api_a.get("/api/v3/rag/apps"))
|
|
app_ids_a = _app_ids(apps_a["data"])
|
|
assert dataset_a.app_id is not None
|
|
assert str(dataset_a.app_id) in app_ids_a
|
|
assert dataset_b.app_id is not None
|
|
assert str(dataset_b.app_id) not in app_ids_a
|
|
assert public_dataset.app_id is not None
|
|
assert str(public_dataset.app_id) in app_ids_a
|
|
|
|
apps_b = ReleaseApiClient.json_data(common_api_b.get("/api/v3/rag/apps"))
|
|
app_ids_b = _app_ids(apps_b["data"])
|
|
assert str(dataset_b.app_id) in app_ids_b
|
|
assert str(dataset_a.app_id) not in app_ids_b
|
|
assert str(public_dataset.app_id) in app_ids_b
|
|
|
|
default_app_a = ReleaseApiClient.json_data(common_api_a.get("/api/v3/rag/apps/default"))
|
|
assert default_app_a is not None
|
|
assert str(default_app_a.get("tenantCode") or "") in {tenant_a.tenant_code, public_dataset.tenant_code}
|
|
|
|
|
|
@pytest.mark.release
|
|
def test_g5_common_user_cannot_access_rag_admin_endpoints(
|
|
common_api_a: ReleaseApiClient,
|
|
tenant_a: TenantSeed,
|
|
) -> None:
|
|
forbidden_admin_list = common_api_a.get("/api/v3/rag/datasets/admin?page=1&pageSize=20", expected_status=403)
|
|
assert "管理知识库权限" in forbidden_admin_list.text
|
|
|
|
forbidden_create = common_api_a.post(
|
|
"/api/v3/rag/datasets/admin",
|
|
json={
|
|
"tenant_code": tenant_a.tenant_code,
|
|
"tenant_name": tenant_a.tenant_name,
|
|
"area": tenant_a.tenant_name,
|
|
"name": f"should-forbid-{int(time.time())}",
|
|
"description": "forbidden",
|
|
"status": 1,
|
|
},
|
|
expected_status=403,
|
|
)
|
|
assert "创建知识库权限" in forbidden_create.text
|