1
+ #![ cfg( not( target_arch = "wasm32" ) ) ]
1
2
use std:: { path:: Path , sync:: Arc } ;
2
3
3
4
use crate :: {
@@ -8,6 +9,11 @@ use crate::{
8
9
use super :: { Error , Result } ;
9
10
#[ cfg( test) ]
10
11
use mockall:: automock;
12
+ use tokio:: {
13
+ fs:: File ,
14
+ io:: { AsyncReadExt , AsyncWriteExt } ,
15
+ sync:: watch,
16
+ } ;
11
17
12
18
/// Allows to backup and restore the database as an encrypted file.
13
19
#[ cfg_attr( test, automock) ]
@@ -25,18 +31,21 @@ pub struct BackupService {
25
31
store : Arc < dyn BackupStoreApi > ,
26
32
identity_store : Arc < dyn IdentityStoreApi > ,
27
33
surreal_db_config : SurrealDbConfig ,
34
+ reboot_sender : watch:: Sender < bool > ,
28
35
}
29
36
30
37
impl BackupService {
31
38
pub fn new (
32
39
store : Arc < dyn BackupStoreApi > ,
33
40
identity_store : Arc < dyn IdentityStoreApi > ,
34
41
surreal_db_config : SurrealDbConfig ,
42
+ reboot_sender : watch:: Sender < bool > ,
35
43
) -> Self {
36
44
Self {
37
45
store,
38
46
identity_store,
39
47
surreal_db_config,
48
+ reboot_sender,
40
49
}
41
50
}
42
51
@@ -66,21 +75,23 @@ impl BackupServiceApi for BackupService {
66
75
}
67
76
68
77
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
71
79
. identity_store
72
80
. get_key_pair ( )
73
81
. await ?
74
82
. 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) ?;
79
87
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 ?;
82
90
self . store . drop_db ( & self . surreal_db_config . database ) . await ?;
83
91
self . store . restore ( out_path. as_path ( ) ) . await ?;
92
+ self . reboot_sender
93
+ . send ( true )
94
+ . expect ( "Can initiate a reboot" ) ;
84
95
Ok ( ( ) )
85
96
}
86
97
}
@@ -117,8 +128,13 @@ mod tests {
117
128
. returning ( || Ok ( vec ! [ 0 , 1 , 0 , 1 , 0 , 0 , 1 , 0 ] ) )
118
129
. once ( ) ;
119
130
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
+ ) ;
122
138
123
139
let result = service. backup ( ) . await ;
124
140
assert ! ( result. is_ok( ) ) ;
@@ -136,9 +152,13 @@ mod tests {
136
152
137
153
identity_store. expect_get_key_pair ( ) . never ( ) ;
138
154
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
+ ) ;
142
162
143
163
let result = service. backup ( ) . await ;
144
164
assert ! ( result. is_err( ) ) ;
@@ -173,7 +193,7 @@ DEFINE TABLE bill_chain TYPE ANY SCHEMALESS PERMISSIONS NONE;";
173
193
174
194
let temp_dir = env:: temp_dir ( ) ;
175
195
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 ( ) ;
177
197
test_file. write_all ( & encrypted_bytes) . await . unwrap ( ) ;
178
198
179
199
identity_store
@@ -189,10 +209,18 @@ DEFINE TABLE bill_chain TYPE ANY SCHEMALESS PERMISSIONS NONE;";
189
209
190
210
store. expect_restore ( ) . returning ( |_| Ok ( ( ) ) ) . once ( ) ;
191
211
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
+ ) ;
194
219
195
220
let result = service. restore ( & temp_dir. join ( "test.surql" ) ) . await ;
196
221
assert ! ( result. is_ok( ) ) ;
222
+
223
+ let should_reboot = * rx. borrow_and_update ( ) ;
224
+ assert ! ( should_reboot) ;
197
225
}
198
226
}
0 commit comments