Skip to content

Commit 0bf6443

Browse files
authored
add web impl, add surreal impl for wasm, add tests and test harness (#439)
1 parent 5f18d72 commit 0bf6443

File tree

17 files changed

+410
-170
lines changed

17 files changed

+410
-170
lines changed

crates/bcr-ebill-api/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ bcr-ebill-core = { path = "../bcr-ebill-core" }
2828
bcr-ebill-persistence = { path = "../bcr-ebill-persistence" }
2929
bcr-ebill-transport = { path = "../bcr-ebill-transport" }
3030

31+
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
32+
tokio.workspace = true
33+
3134
[dev-dependencies]
3235
mockall = "0.13.1"
3336
nostr-relay-builder = "0.39.0"

crates/bcr-ebill-api/src/persistence/mod.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use crate::Config;
22
use bcr_ebill_persistence::{
3-
BackupStoreApi, ContactStoreApi, FileUploadStore, NostrEventOffsetStoreApi,
4-
NotificationStoreApi, SurrealBackupStore, SurrealBillChainStore, SurrealBillStore,
5-
SurrealCompanyChainStore, SurrealCompanyStore, SurrealContactStore, SurrealDbConfig,
6-
SurrealIdentityChainStore, SurrealIdentityStore, SurrealNostrEventOffsetStore,
7-
SurrealNotificationStore,
3+
BackupStoreApi, ContactStoreApi, NostrEventOffsetStoreApi, NotificationStoreApi,
4+
SurrealBackupStore, SurrealBillChainStore, SurrealBillStore, SurrealCompanyChainStore,
5+
SurrealCompanyStore, SurrealContactStore, SurrealDbConfig, SurrealIdentityChainStore,
6+
SurrealIdentityStore, SurrealNostrEventOffsetStore, SurrealNotificationStore,
87
bill::{BillChainStoreApi, BillStoreApi},
98
company::{CompanyChainStoreApi, CompanyStoreApi},
109
file_upload::FileUploadStoreApi,
@@ -15,6 +14,7 @@ use log::error;
1514
use std::sync::Arc;
1615

1716
pub use bcr_ebill_persistence::Error;
17+
#[cfg(not(target_arch = "wasm32"))]
1818
pub use bcr_ebill_persistence::backup;
1919
pub use bcr_ebill_persistence::bill;
2020
pub use bcr_ebill_persistence::company;
@@ -47,11 +47,22 @@ pub async fn get_db_context(conf: &Config) -> bcr_ebill_persistence::Result<DbCo
4747
let db = get_surreal_db(&surreal_db_config).await?;
4848

4949
let company_store = Arc::new(SurrealCompanyStore::new(db.clone()));
50+
#[cfg(target_arch = "wasm32")]
5051
let file_upload_store =
51-
Arc::new(FileUploadStore::new(&conf.data_dir, "files", "temp_upload").await?);
52+
Arc::new(bcr_ebill_persistence::db::file_upload::FileUploadStore::new(db.clone()));
53+
54+
#[cfg(not(target_arch = "wasm32"))]
55+
let file_upload_store = Arc::new(
56+
bcr_ebill_persistence::file_upload::FileUploadStore::new(
57+
&conf.data_dir,
58+
"files",
59+
"temp_upload",
60+
)
61+
.await?,
62+
);
5263

5364
if let Err(e) = file_upload_store.cleanup_temp_uploads().await {
54-
error!("Error cleaning up temp upload folder for bill: {e}");
65+
error!("Error cleaning up temp uploads: {e}");
5566
}
5667

5768
let contact_store = Arc::new(SurrealContactStore::new(db.clone()));

crates/bcr-ebill-api/src/service/backup_service.rs

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![cfg(not(target_arch = "wasm32"))]
12
use std::{path::Path, sync::Arc};
23

34
use crate::{
@@ -8,6 +9,11 @@ use crate::{
89
use super::{Error, Result};
910
#[cfg(test)]
1011
use mockall::automock;
12+
use tokio::{
13+
fs::File,
14+
io::{AsyncReadExt, AsyncWriteExt},
15+
sync::watch,
16+
};
1117

1218
/// Allows to backup and restore the database as an encrypted file.
1319
#[cfg_attr(test, automock)]
@@ -25,18 +31,21 @@ pub struct BackupService {
2531
store: Arc<dyn BackupStoreApi>,
2632
identity_store: Arc<dyn IdentityStoreApi>,
2733
surreal_db_config: SurrealDbConfig,
34+
reboot_sender: watch::Sender<bool>,
2835
}
2936

3037
impl BackupService {
3138
pub fn new(
3239
store: Arc<dyn BackupStoreApi>,
3340
identity_store: Arc<dyn IdentityStoreApi>,
3441
surreal_db_config: SurrealDbConfig,
42+
reboot_sender: watch::Sender<bool>,
3543
) -> Self {
3644
Self {
3745
store,
3846
identity_store,
3947
surreal_db_config,
48+
reboot_sender,
4049
}
4150
}
4251

@@ -66,21 +75,23 @@ impl BackupServiceApi for BackupService {
6675
}
6776

6877
async fn restore(&self, file_path: &Path) -> Result<()> {
69-
// TODO WASM: implement without file system access
70-
let _private_key = self
78+
let private_key = self
7179
.identity_store
7280
.get_key_pair()
7381
.await?
7482
.get_private_key_string();
75-
let _buffer: Vec<u8> = vec![];
76-
// let mut file = File::open(file_path).await?;
77-
// file.read_to_end(&mut buffer).await?;
78-
// let decrypted_bytes = util::crypto::decrypt_ecies(&buffer, &private_key)?;
83+
let mut buffer = vec![];
84+
let mut file = File::open(file_path).await?;
85+
file.read_to_end(&mut buffer).await?;
86+
let decrypted_bytes = util::crypto::decrypt_ecies(&buffer, &private_key)?;
7987
let out_path = file_path.with_file_name("restore.surql");
80-
// let mut out = File::create(out_path.as_path()).await?;
81-
// out.write_all(&decrypted_bytes).await?;
88+
let mut out = File::create(out_path.as_path()).await?;
89+
out.write_all(&decrypted_bytes).await?;
8290
self.store.drop_db(&self.surreal_db_config.database).await?;
8391
self.store.restore(out_path.as_path()).await?;
92+
self.reboot_sender
93+
.send(true)
94+
.expect("Can initiate a reboot");
8495
Ok(())
8596
}
8697
}
@@ -117,8 +128,13 @@ mod tests {
117128
.returning(|| Ok(vec![0, 1, 0, 1, 0, 0, 1, 0]))
118129
.once();
119130

120-
let service =
121-
BackupService::new(Arc::new(store), Arc::new(identity_store), surreal_db_config);
131+
let (tx, _) = watch::channel(false);
132+
let service = BackupService::new(
133+
Arc::new(store),
134+
Arc::new(identity_store),
135+
surreal_db_config,
136+
tx,
137+
);
122138

123139
let result = service.backup().await;
124140
assert!(result.is_ok());
@@ -136,9 +152,13 @@ mod tests {
136152

137153
identity_store.expect_get_key_pair().never();
138154
store.expect_backup().never();
139-
140-
let service =
141-
BackupService::new(Arc::new(store), Arc::new(identity_store), surreal_db_config);
155+
let (tx, _) = watch::channel(false);
156+
let service = BackupService::new(
157+
Arc::new(store),
158+
Arc::new(identity_store),
159+
surreal_db_config,
160+
tx,
161+
);
142162

143163
let result = service.backup().await;
144164
assert!(result.is_err());
@@ -173,7 +193,7 @@ DEFINE TABLE bill_chain TYPE ANY SCHEMALESS PERMISSIONS NONE;";
173193

174194
let temp_dir = env::temp_dir();
175195
let file_path = temp_dir.join("test.surql");
176-
let mut test_file = tokio::fs::File::create(file_path.as_path()).await.unwrap();
196+
let mut test_file = File::create(file_path.as_path()).await.unwrap();
177197
test_file.write_all(&encrypted_bytes).await.unwrap();
178198

179199
identity_store
@@ -189,10 +209,18 @@ DEFINE TABLE bill_chain TYPE ANY SCHEMALESS PERMISSIONS NONE;";
189209

190210
store.expect_restore().returning(|_| Ok(())).once();
191211

192-
let service =
193-
BackupService::new(Arc::new(store), Arc::new(identity_store), surreal_db_config);
212+
let (tx, mut rx) = watch::channel(false);
213+
let service = BackupService::new(
214+
Arc::new(store),
215+
Arc::new(identity_store),
216+
surreal_db_config,
217+
tx,
218+
);
194219

195220
let result = service.restore(&temp_dir.join("test.surql")).await;
196221
assert!(result.is_ok());
222+
223+
let should_reboot = *rx.borrow_and_update();
224+
assert!(should_reboot);
197225
}
198226
}

crates/bcr-ebill-persistence/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ surrealdb = { version = "2.2", default-features = false, features = ["kv-indxdb"
2727
# Enable "protocol-ws" for all other targets
2828
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
2929
surrealdb = { version = "2.2", default-features = false, features = ["protocol-ws"] }
30+
tokio.workspace = true
3031

3132
[dev-dependencies]
3233
surrealdb = { version = "2.2.0", features = ["kv-mem"], default-features = false }

crates/bcr-ebill-persistence/src/constants.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@ pub const DB_OP_CODE: &str = "op_code";
1414
pub const DB_COMPANY_ID: &str = "company_id";
1515
pub const DB_BILL_ID: &str = "bill_id";
1616
pub const DB_SEARCH_TERM: &str = "search_term";
17+
18+
pub const DB_ENTITY_ID: &str = "entity_id";
19+
pub const DB_FILE_NAME: &str = "file_name";

0 commit comments

Comments
 (0)