Admin and opertor features #3
@ -404,6 +404,12 @@ impl ActiveAppWithNode {
|
|||||||
None => Ok(vec![]),
|
None => Ok(vec![]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn list_all(db: &Surreal<Client>) -> Result<Vec<Self>, Error> {
|
||||||
|
let mut query_response = db.query(format!("SELECT * FROM {ACTIVE_APP} FETCH out;")).await?;
|
||||||
|
let active_apps: Vec<Self> = query_response.take(0)?;
|
||||||
|
Ok(active_apps)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
|
@ -212,19 +212,18 @@ impl BrainGeneralCli for GeneralCliServer {
|
|||||||
|
|
||||||
async fn list_all_app_contracts(
|
async fn list_all_app_contracts(
|
||||||
&self,
|
&self,
|
||||||
_req: tonic::Request<Empty>,
|
req: tonic::Request<Empty>,
|
||||||
) -> Result<tonic::Response<Self::ListAllAppContractsStream>, Status> {
|
) -> Result<tonic::Response<Self::ListAllAppContractsStream>, Status> {
|
||||||
todo!();
|
check_admin_key(&req)?;
|
||||||
// check_admin_key(&req)?;
|
check_sig_from_req(req)?;
|
||||||
// let _ = check_sig_from_req(req)?;
|
let contracts = db::ActiveAppWithNode::list_all(&self.db).await?;
|
||||||
// let contracts = self.data.list_all_app_contracts();
|
let (tx, rx) = mpsc::channel(6);
|
||||||
// let (tx, rx) = mpsc::channel(6);
|
tokio::spawn(async move {
|
||||||
// tokio::spawn(async move {
|
for contract in contracts {
|
||||||
// for contract in contracts {
|
let _ = tx.send(Ok(contract.into())).await;
|
||||||
// let _ = tx.send(Ok(contract.into())).await;
|
}
|
||||||
// }
|
});
|
||||||
// });
|
let output_stream = ReceiverStream::new(rx);
|
||||||
// let output_stream = ReceiverStream::new(rx);
|
Ok(Response::new(Box::pin(output_stream)))
|
||||||
// Ok(Response::new(Box::pin(output_stream)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use super::test_utils::{admin_keys, Key};
|
use super::test_utils::{admin_keys, Key};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
use detee_shared::app_proto;
|
||||||
use detee_shared::common_proto::Empty;
|
use detee_shared::common_proto::Empty;
|
||||||
use detee_shared::general_proto::brain_general_cli_client::BrainGeneralCliClient;
|
use detee_shared::general_proto::brain_general_cli_client::BrainGeneralCliClient;
|
||||||
use detee_shared::general_proto::{Account, AirdropReq, RegOperatorReq, ReportNodeReq};
|
use detee_shared::general_proto::{Account, AirdropReq, RegOperatorReq, ReportNodeReq};
|
||||||
@ -134,3 +135,29 @@ pub async fn list_all_vm_contracts(
|
|||||||
|
|
||||||
Ok(vm_contracts)
|
Ok(vm_contracts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn list_all_app_contracts(
|
||||||
|
brain_channel: &Channel,
|
||||||
|
admin_key: &Key,
|
||||||
|
) -> Result<Vec<app_proto::AppContract>> {
|
||||||
|
let mut cli_client = BrainGeneralCliClient::new(brain_channel.clone());
|
||||||
|
let mut stream = cli_client
|
||||||
|
.list_all_app_contracts(admin_key.sign_request(Empty {}).unwrap())
|
||||||
|
.await?
|
||||||
|
.into_inner();
|
||||||
|
|
||||||
|
let mut app_contracts = Vec::new();
|
||||||
|
|
||||||
|
while let Some(stream_data) = stream.next().await {
|
||||||
|
match stream_data {
|
||||||
|
Ok(app_contract) => {
|
||||||
|
app_contracts.push(app_contract);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
panic!("Error while listing app_contracts: {e:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(app_contracts)
|
||||||
|
}
|
||||||
|
@ -3,7 +3,8 @@ use common::prepare_test_env::{
|
|||||||
};
|
};
|
||||||
use common::test_utils::{admin_keys, Key};
|
use common::test_utils::{admin_keys, Key};
|
||||||
use common::vm_cli_utils::{
|
use common::vm_cli_utils::{
|
||||||
airdrop, create_new_vm, list_accounts, list_all_vm_contracts, register_operator, report_node,
|
airdrop, create_new_vm, list_accounts, list_all_app_contracts, list_all_vm_contracts,
|
||||||
|
register_operator, report_node,
|
||||||
};
|
};
|
||||||
use common::vm_daemon_utils::{mock_vm_daemon, register_vm_node};
|
use common::vm_daemon_utils::{mock_vm_daemon, register_vm_node};
|
||||||
use detee_shared::common_proto::{Empty, Pubkey};
|
use detee_shared::common_proto::{Empty, Pubkey};
|
||||||
@ -11,7 +12,7 @@ use detee_shared::general_proto::brain_general_cli_client::BrainGeneralCliClient
|
|||||||
use detee_shared::general_proto::{AirdropReq, BanUserReq, SlashReq};
|
use detee_shared::general_proto::{AirdropReq, BanUserReq, SlashReq};
|
||||||
use detee_shared::vm_proto::brain_vm_daemon_client::BrainVmDaemonClient;
|
use detee_shared::vm_proto::brain_vm_daemon_client::BrainVmDaemonClient;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use surreal_brain::constants::{ACCOUNT, ACTIVE_VM, BAN, TOKEN_DECIMAL, VM_NODE};
|
use surreal_brain::constants::{ACCOUNT, ACTIVE_APP, ACTIVE_VM, BAN, TOKEN_DECIMAL, VM_NODE};
|
||||||
use surreal_brain::db::prelude as db;
|
use surreal_brain::db::prelude as db;
|
||||||
use surreal_brain::db::vm::VmNodeWithReports;
|
use surreal_brain::db::vm::VmNodeWithReports;
|
||||||
|
|
||||||
@ -264,7 +265,7 @@ async fn test_kick_contract() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
let db_conn = prepare_test_db().await.unwrap();
|
let db_conn = prepare_test_db().await.unwrap();
|
||||||
let contract_uuid = "e3d01f252b2a410b80e312f44e474334";
|
let contract_uuid = "5af49a714c64a82ef50e574b023b2a0ef0405ed";
|
||||||
let operator_wallet = "7V3rEuh6j8VuwMVB5PyGqWKLmjJ4fYSv6WtrTL51NZTB";
|
let operator_wallet = "7V3rEuh6j8VuwMVB5PyGqWKLmjJ4fYSv6WtrTL51NZTB";
|
||||||
let reason = "'; THROW 'Injected error'; --"; // sql injection query
|
let reason = "'; THROW 'Injected error'; --"; // sql injection query
|
||||||
|
|
||||||
@ -341,6 +342,7 @@ async fn test_ban_user() {
|
|||||||
|
|
||||||
assert!(operator_banned_you.to_string().contains("This operator banned you"));
|
assert!(operator_banned_you.to_string().contains("This operator banned you"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_slash_operator() {
|
async fn test_slash_operator() {
|
||||||
let db_conn = prepare_test_db().await.unwrap();
|
let db_conn = prepare_test_db().await.unwrap();
|
||||||
@ -389,8 +391,11 @@ async fn test_admin_list_account() {
|
|||||||
let unauthenticated = list_accounts(&brain_channel, &Key::new()).await.err().unwrap();
|
let unauthenticated = list_accounts(&brain_channel, &Key::new()).await.err().unwrap();
|
||||||
assert!(unauthenticated.to_string().contains("reserved to admin accounts"));
|
assert!(unauthenticated.to_string().contains("reserved to admin accounts"));
|
||||||
|
|
||||||
|
tokio::time::sleep(tokio::time::Duration::from_millis(200)).await; // sync time for other db opeartion
|
||||||
|
|
||||||
|
let acc_in_db = db_conn.select::<Vec<db::Account>>(ACCOUNT).await.unwrap();
|
||||||
let accounts = list_accounts(&brain_channel, &admin_key).await.unwrap();
|
let accounts = list_accounts(&brain_channel, &admin_key).await.unwrap();
|
||||||
assert_eq!(accounts.len(), 19);
|
assert_eq!(accounts.len(), acc_in_db.len());
|
||||||
|
|
||||||
airdrop(&brain_channel, &Key::new().pubkey, 10).await.unwrap();
|
airdrop(&brain_channel, &Key::new().pubkey, 10).await.unwrap();
|
||||||
|
|
||||||
@ -417,3 +422,24 @@ async fn test_admin_list_all_vm_contracts() {
|
|||||||
|
|
||||||
// TODO: mock vm daemon and deploy a new vm, then list again
|
// TODO: mock vm daemon and deploy a new vm, then list again
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_admin_list_all_app_contracts() {
|
||||||
|
let db_conn = prepare_test_db().await.unwrap();
|
||||||
|
let brain_channel = run_service_for_stream().await.unwrap();
|
||||||
|
|
||||||
|
let admin_key = admin_keys()[0].clone();
|
||||||
|
|
||||||
|
let unauthenticated = list_all_app_contracts(&brain_channel, &Key::new()).await.err().unwrap();
|
||||||
|
assert!(unauthenticated.to_string().contains("reserved to admin accounts"));
|
||||||
|
|
||||||
|
let app_contracts = list_all_app_contracts(&brain_channel, &admin_key).await.unwrap();
|
||||||
|
assert_eq!(app_contracts.len(), 1);
|
||||||
|
|
||||||
|
let app_in_db = db_conn.select::<Vec<db::ActiveApp>>(ACTIVE_APP).await.unwrap();
|
||||||
|
|
||||||
|
let app_contracts = list_all_app_contracts(&brain_channel, &admin_key).await.unwrap();
|
||||||
|
assert_eq!(app_contracts.len(), app_in_db.len());
|
||||||
|
|
||||||
|
// TODO: mock app daemon and deploy a new app, then list again
|
||||||
|
}
|
||||||
|
@ -405,6 +405,25 @@ vm_contracts:
|
|||||||
price_per_unit: 20000
|
price_per_unit: 20000
|
||||||
locked_nano: 12730960000
|
locked_nano: 12730960000
|
||||||
collected_at: 2025-04-20T00:34:15.461240342Z
|
collected_at: 2025-04-20T00:34:15.461240342Z
|
||||||
|
|
||||||
|
- uuid: 5af49a71-4c64-a82e-f50e574-b023-b2a0ef0405ed
|
||||||
|
hostname: hallow-hobo
|
||||||
|
admin_pubkey: 4qFJJJdRrSB9hCn8rrvYTXHLJg371ab36PJmZ4uxHjGQ
|
||||||
|
node_pubkey: 7fujZQeTme52RdXTLmQST5jBgAbvzic5iERtH5EWoYjk
|
||||||
|
exposed_ports:
|
||||||
|
- 46393
|
||||||
|
public_ipv4: ""
|
||||||
|
public_ipv6: ""
|
||||||
|
disk_size_gb: 10
|
||||||
|
vcpus: 1
|
||||||
|
memory_mb: 1000
|
||||||
|
kernel_sha: e765e56166ef321b53399b9638584d1279821dbe3d46191c1f66bbaa075e7919
|
||||||
|
dtrfs_sha: d207644ee60d54009b6ecdfb720e2ec251cde31774dd249fcc7435aca0377990
|
||||||
|
created_at: 2025-04-16T20:37:57.176592933Z
|
||||||
|
updated_at: 2025-04-16T20:37:57.176594069Z
|
||||||
|
price_per_unit: 20000
|
||||||
|
locked_nano: 12730960000
|
||||||
|
collected_at: 2025-04-20T00:34:15.461240342Z
|
||||||
app_nodes:
|
app_nodes:
|
||||||
- node_pubkey: BiqoPUEoAxYxMRXUmyofoS9H1TBQgQqvLJ6MbWh88AQg
|
- node_pubkey: BiqoPUEoAxYxMRXUmyofoS9H1TBQgQqvLJ6MbWh88AQg
|
||||||
operator_wallet: 7V3rEuh6j8VuwMVB5PyGqWKLmjJ4fYSv6WtrTL51NZTB
|
operator_wallet: 7V3rEuh6j8VuwMVB5PyGqWKLmjJ4fYSv6WtrTL51NZTB
|
||||||
|
Loading…
Reference in New Issue
Block a user