diff --git a/src/storage.rs b/src/storage.rs index 2a6f274..4acc30a 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -331,6 +331,7 @@ impl DiskStorage { where T: AsRef, { + use tokio::io::AsyncWriteExt; let json = { use std::ops::Deref; let mut lock = self.tokens.lock().unwrap(); @@ -338,7 +339,9 @@ impl DiskStorage { serde_json::to_string(lock.deref()) .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))? }; - tokio::fs::write(self.filename.clone(), json).await + let mut f = open_writeable_file(&self.filename).await?; + f.write_all(json.as_bytes()).await?; + Ok(()) } pub(crate) fn get(&self, scopes: ScopeSet) -> Option @@ -349,6 +352,30 @@ impl DiskStorage { } } +#[cfg(unix)] +async fn open_writeable_file( + filename: impl AsRef, +) -> Result { + // Ensure if the file is created it's only readable and writable by the + // current user. + use std::os::unix::fs::OpenOptionsExt; + let opts: tokio::fs::OpenOptions = { + let mut opts = std::fs::OpenOptions::new(); + opts.write(true).create(true).truncate(true).mode(0o600); + opts.into() + }; + opts.open(filename).await +} + +#[cfg(not(unix))] +async fn open_writeable_file( + filename: impl AsRef, +) -> Result { + // I don't have knowledge of windows or other platforms to know how to + // create a file that's only readable by the current user. + tokio::fs::File::create(filename).await +} + #[cfg(test)] mod tests { use super::*;