加上登录和角色权限,并用 Vue 控制台区分用户与管理员。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-10 22:43:31 +08:00
parent 78601aae5e
commit 8b55b9cf55
36 changed files with 2947 additions and 1007 deletions
+77 -6
View File
@@ -13,6 +13,10 @@ from pathlib import Path
_db_path = Path(tempfile.gettempdir()) / "depin_core_flow.db"
os.environ["DATABASE_URL"] = "sqlite:///" + _db_path.as_posix()
os.environ["DISABLE_SCHEDULER"] = "1"
os.environ["JWT_SECRET"] = "test-secret-test-secret-test-secret"
os.environ["ADMIN_USERNAME"] = "admin"
os.environ["ADMIN_PASSWORD"] = "test-admin-pass"
os.environ["ADMIN_WALLET"] = "admin-root"
from fastapi.testclient import TestClient
from sqlalchemy import select
@@ -129,7 +133,11 @@ class CoreFlowTest(unittest.TestCase):
session.add(self._task(miss.id, TaskStatus.FAILED, day_start))
session.commit()
settled = self.client.post("/api/v1/yield/settle", params={"yield_date": yesterday.isoformat()})
settled = self.client.post(
"/api/v1/yield/settle",
headers=self._admin_headers(),
params={"yield_date": yesterday.isoformat()},
)
self.assertEqual(settled.status_code, 200, settled.text)
self.assertEqual(settled.json()["created"], 3)
@@ -153,11 +161,19 @@ class CoreFlowTest(unittest.TestCase):
self.assertEqual(miss_row.points_delta, Decimal("0.70000000"))
self.assertEqual(miss_row.compute_output, Decimal("255.50000000"))
again = self.client.post("/api/v1/yield/settle", params={"yield_date": yesterday.isoformat()})
again = self.client.post(
"/api/v1/yield/settle",
headers=self._admin_headers(),
params={"yield_date": yesterday.isoformat()},
)
self.assertEqual(again.json()["created"], 0)
self.assertEqual(again.json()["skipped"], 3)
future = self.client.post("/api/v1/yield/settle", params={"yield_date": "2999-01-01"})
future = self.client.post(
"/api/v1/yield/settle",
headers=self._admin_headers(),
params={"yield_date": "2999-01-01"},
)
self.assertEqual(future.status_code, 400, future.text)
def test_open_interval_stops_at_last_heartbeat(self) -> None:
@@ -173,7 +189,11 @@ class CoreFlowTest(unittest.TestCase):
session.add(UptimeInterval(node_id=node.id, started_at=day_start, ended_at=None))
session.commit()
settled = self.client.post("/api/v1/yield/settle", params={"yield_date": yesterday.isoformat()})
settled = self.client.post(
"/api/v1/yield/settle",
headers=self._admin_headers(),
params={"yield_date": yesterday.isoformat()},
)
self.assertEqual(settled.status_code, 200, settled.text)
row = self._yield_row("NODE-HALF")
self.assertEqual(row.online_seconds, 12 * 60 * 60)
@@ -205,17 +225,24 @@ class CoreFlowTest(unittest.TestCase):
day_start = utcnow().replace(hour=0, minute=0, second=0, microsecond=0) - timedelta(days=1)
self._register("0xpay", "NODE-PAY", "365")
self._cover_full_day("NODE-PAY", day_start, day_start + timedelta(days=1))
settled = self.client.post("/api/v1/yield/settle", params={"yield_date": yesterday.isoformat()})
payer = self._auth("0xpay")
settled = self.client.post(
"/api/v1/yield/settle",
headers=self._admin_headers(),
params={"yield_date": yesterday.isoformat()},
)
self.assertEqual(settled.status_code, 200, settled.text)
too_much = self.client.post(
"/api/v1/withdrawals",
headers=payer,
json={"wallet_address": "0xpay", "amount": "10"},
)
self.assertEqual(too_much.status_code, 400, too_much.text)
created = self.client.post(
"/api/v1/withdrawals",
headers=payer,
json={"wallet_address": "0xpay", "amount": "0.4", "asset_symbol": "POINT"},
)
self.assertEqual(created.status_code, 200, created.text)
@@ -224,26 +251,70 @@ class CoreFlowTest(unittest.TestCase):
blocked = self.client.post(
"/api/v1/withdrawals",
headers=payer,
json={"wallet_address": "0xpay", "amount": "0.7"},
)
self.assertEqual(blocked.status_code, 400, blocked.text)
confirmed = self.client.post(
f"/api/v1/withdrawals/{withdrawal_id}/confirm",
headers=self._admin_headers(),
json={"tx_hash": "0xabc123"},
)
self.assertEqual(confirmed.status_code, 200, confirmed.text)
self.assertEqual(confirmed.json()["status"], "completed")
self.assertEqual(confirmed.json()["tx_hash"], "0xabc123")
balance = self.client.get("/api/v1/users/0xpay/balance")
balance = self.client.get("/api/v1/users/0xpay/balance", headers=self._auth("0xpay"))
self.assertEqual(balance.json()["available_points"], "0.60000000")
def test_roles_split_user_and_admin(self) -> None:
registered = self.client.post(
"/api/v1/auth/register",
json={"wallet_address": "0xuser01", "username": "miner", "password": "secret1"},
)
self.assertEqual(registered.status_code, 200, registered.text)
self.assertEqual(registered.json()["role"], "user")
token = registered.json()["access_token"]
user_headers = {"Authorization": f"Bearer {token}"}
by_wallet = self.client.post("/api/v1/auth/login", json={"wallet_address": "0xuser01"})
self.assertEqual(by_wallet.status_code, 200, by_wallet.text)
by_password = self.client.post(
"/api/v1/auth/login",
json={"username": "miner", "password": "secret1"},
)
self.assertEqual(by_password.status_code, 200, by_password.text)
denied = self.client.get("/api/v1/admin/users", headers=user_headers)
self.assertEqual(denied.status_code, 403, denied.text)
opened = self.client.get("/api/v1/admin/summary", headers=self._admin_headers())
self.assertEqual(opened.status_code, 200, opened.text)
self.assertGreaterEqual(opened.json()["users"], 1)
wallet_admin = self.client.post("/api/v1/auth/login", json={"wallet_address": "admin-root"})
self.assertEqual(wallet_admin.status_code, 403, wallet_admin.text)
def _auth(self, wallet: str) -> dict[str, str]:
logged = self.client.post("/api/v1/auth/login", json={"wallet_address": wallet})
self.assertEqual(logged.status_code, 200, logged.text)
return {"Authorization": f"Bearer {logged.json()['access_token']}"}
def _admin_headers(self) -> dict[str, str]:
logged = self.client.post(
"/api/v1/auth/login",
json={"username": "admin", "password": "test-admin-pass"},
)
self.assertEqual(logged.status_code, 200, logged.text)
self.assertEqual(logged.json()["role"], "admin")
return {"Authorization": f"Bearer {logged.json()['access_token']}"}
def _register(self, wallet: str, sn: str, amount: str) -> None:
user = self.client.post("/api/v1/users", json={"wallet_address": wallet})
self.assertEqual(user.status_code, 200, user.text)
node = self.client.post(
"/api/v1/nodes",
headers=self._auth(wallet),
json={"wallet_address": wallet, "sn": sn, "purchase_amount": amount},
)
self.assertEqual(node.status_code, 200, node.text)