2024-06-28 10:34:57 +00:00
{. push raises : [ ] . }
2023-02-08 15:26:23 +00:00
2024-03-15 23:08:47 +00:00
import json , std / [ os , sequtils ]
2023-08-29 12:16:21 +00:00
2024-03-15 23:08:47 +00:00
import . / keyfile , . / protocol_types
2023-02-08 15:26:23 +00:00
# Checks if a JsonNode has all keys contained in "keys"
proc hasKeys * ( data : JsonNode , keys : openArray [ string ] ) : bool =
2024-03-15 23:08:47 +00:00
return all (
keys ,
proc ( key : string ) : bool =
2024-09-11 01:51:42 +00:00
return data . hasKey ( key ) ,
2024-03-15 23:08:47 +00:00
)
2023-02-08 15:26:23 +00:00
2023-04-04 13:34:53 +00:00
# Safely saves a Keystore's JsonNode to disk.
# If exists, the destination file is renamed with extension .bkp; the file is written at its destination and the .bkp file is removed if write is successful, otherwise is restored
2023-02-08 15:26:23 +00:00
proc save * ( json : JsonNode , path : string , separator : string ) : KeystoreResult [ void ] =
# We first backup the current keystore
if fileExists ( path ) :
try :
moveFile ( path , path & " .bkp " )
2024-03-15 23:08:47 +00:00
except : # TODO: Fix "BareExcept" warning
return err (
AppKeystoreError (
kind : KeystoreOsError ,
msg : " could not backup keystore: " & getCurrentExceptionMsg ( ) ,
)
)
2023-04-04 13:34:53 +00:00
2023-02-08 15:26:23 +00:00
# We save the updated json
var f : File
if not f . open ( path , fmAppend ) :
2024-10-02 22:05:49 +00:00
return err (
AppKeystoreError (
kind : KeystoreOsError ,
msg : " error in waku_keystore save: " & getCurrentExceptionMsg ( ) ,
)
)
2023-02-08 15:26:23 +00:00
try :
# To avoid other users/attackers to be able to read keyfiles, we make the file readable/writable only by the running user
setFilePermissions ( path , { fpUserWrite , fpUserRead } )
f . write ( $ json )
# We store a keyfile per line
f . write ( separator )
except CatchableError :
# We got some KeystoreOsError writing to disk. We attempt to restore the previous keystore backup
if fileExists ( path & " .bkp " ) :
try :
f . close ( )
removeFile ( path )
moveFile ( path & " .bkp " , path )
2024-03-15 23:08:47 +00:00
except : # TODO: Fix "BareExcept" warning
2023-02-08 15:26:23 +00:00
# Unlucky, we just fail
2024-03-15 23:08:47 +00:00
return err (
AppKeystoreError (
kind : KeystoreOsError ,
msg : " could not restore keystore backup: " & getCurrentExceptionMsg ( ) ,
)
)
return err (
AppKeystoreError (
kind : KeystoreOsError ,
msg : " could not write keystore: " & getCurrentExceptionMsg ( ) ,
)
)
2023-02-08 15:26:23 +00:00
finally :
f . close ( )
# The write went fine, so we can remove the backup keystore
if fileExists ( path & " .bkp " ) :
try :
removeFile ( path & " .bkp " )
2023-04-04 13:34:53 +00:00
except CatchableError :
2024-03-15 23:08:47 +00:00
return err (
AppKeystoreError (
kind : KeystoreOsError ,
msg : " could not remove keystore backup: " & getCurrentExceptionMsg ( ) ,
)
)
2023-02-08 15:26:23 +00:00
return ok ( )