Skip to content

Commit

Permalink
Add more examples
Browse files Browse the repository at this point in the history
  • Loading branch information
mchristou committed Oct 15, 2024
1 parent dd0a32e commit 1835673
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 44 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

85 changes: 85 additions & 0 deletions examples/file_handling.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use core::str::FromStr;

use anyhow::Result;
use rencfs::{
crypto::Cipher,
encryptedfs::{
write_all_string_to_fs, CreateFileAttr, EncryptedFs, FileType, PasswordProvider,
},
};
use shush_rs::SecretString;
use std::{
fs,
path::{Path, PathBuf},
};

const ROOT_INODE: u64 = 1;

struct PasswordProviderImpl;

impl PasswordProvider for PasswordProviderImpl {
fn get_password(&self) -> Option<SecretString> {
Some(SecretString::from_str("password").unwrap())
}
}

#[tokio::main]
async fn main() -> Result<()> {
tracing_subscriber::fmt().init();

let data_dir = Path::new("/tmp/data_test").to_path_buf();
clean_up_directory(&data_dir)?;

let cipher = Cipher::ChaCha20Poly1305;
let fs = EncryptedFs::new(
data_dir.clone(),
Box::new(PasswordProviderImpl),
cipher,
false,
)
.await?;

let file_name = SecretString::from_str("file1").unwrap();
let (file_handle, attr) = fs
.create(ROOT_INODE, &file_name, file_attributes(), false, true)
.await?;

let data = "Hello, world!";
write_all_string_to_fs(&fs, attr.ino, 0, data, file_handle).await?;

fs.flush(file_handle).await?;
fs.release(file_handle).await?;

let file_handle = fs.open(attr.ino, true, false).await?;
let mut buffer = vec![0; data.len()];
fs.read(attr.ino, 0, &mut buffer, file_handle).await?;
fs.release(file_handle).await?;

assert_eq!(data, String::from_utf8(buffer)?);

assert!(fs.exists_by_name(ROOT_INODE, &file_name)?);
fs.remove_file(ROOT_INODE, &file_name).await?;
assert!(!fs.exists_by_name(ROOT_INODE, &file_name)?);

Ok(())
}

const fn file_attributes() -> CreateFileAttr {
CreateFileAttr {
kind: FileType::RegularFile,
perm: 0o644, // Permissions
uid: 0, // User ID
gid: 0, // Group ID
rdev: 0, // Device ID
flags: 0, // File flags
}
}

fn clean_up_directory(dir: &PathBuf) -> Result<()> {
if dir.exists() {
fs::remove_dir_all(dir)?;
}

fs::create_dir_all(dir)?;
Ok(())
}
1 change: 0 additions & 1 deletion src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,6 @@ where
{
let parent = file.parent().ok_or(Error::Generic("file has no parent"))?;
let mut file = fs_util::open_atomic_write(file)?;
// println!("file: {:#?}", file.as_file_mut().metadata()?);
file = serialize_encrypt_into(file, value, cipher, key)?;
file.commit()?;
File::open(parent)?.sync_all()?;
Expand Down
38 changes: 2 additions & 36 deletions src/fs_util.rs
Original file line number Diff line number Diff line change
@@ -1,40 +1,6 @@
#[cfg(unix)]
use atomic_write_file::unix::OpenOptionsExt;
use atomic_write_file::AtomicWriteFile;
use futures_util::TryStreamExt;
use std::path::Path;
use std::{fs, io};
use tokio_stream::wrappers::ReadDirStream;

/// Recursively moves the content of a directory to another.
/// It will create destination directory if it doesn't exist. It will delete the source directory after the move.
pub async fn rename_dir_content(src: &Path, dst: &Path) -> io::Result<()> {
if !src.is_dir() {
return Err(io::Error::new(
io::ErrorKind::NotFound,
"source directory does not exist",
));
}
if !dst.exists() {
fs::create_dir_all(dst)?;
}
let read_dir = tokio::fs::read_dir(src).await?;
let read_dir_stream = ReadDirStream::new(read_dir);
let vec = read_dir_stream.try_collect::<Vec<_>>().await?;
let entries = vec.iter().collect::<Vec<_>>();
for entry in entries {
let dst = dst.join(entry.file_name());
if entry.path().is_dir() {
fs::create_dir_all(&dst)?;
Box::pin(rename_dir_content(&entry.path(), &dst)).await?;
fs::remove_dir(entry.path())?;
} else {
fs::rename(entry.path(), dst)?;
}
}
fs::remove_dir(src)?;
Ok(())
}
use atomic_write_file::{unix::OpenOptionsExt, AtomicWriteFile};
use std::{io, path::Path};

pub fn open_atomic_write(file: &Path) -> io::Result<AtomicWriteFile> {
let mut opt = AtomicWriteFile::options();
Expand Down
5 changes: 0 additions & 5 deletions src/keyring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,19 @@ use std::str::FromStr;
use keyring::Entry;
use shush_rs::{ExposeSecret, SecretString};

#[allow(dead_code)]
const KEYRING_SERVICE: &str = "rencfs";
#[allow(dead_code)]
const KEYRING_USER: &str = "encrypted_fs";

#[allow(dead_code)]
pub(crate) fn save(password: &SecretString, suffix: &str) -> Result<(), keyring::Error> {
let entry = Entry::new(KEYRING_SERVICE, &format!("{KEYRING_USER}.{suffix}"))?;
entry.set_password(&password.expose_secret())
}

#[allow(dead_code)]
pub(crate) fn remove(suffix: &str) -> Result<(), keyring::Error> {
let entry = Entry::new(KEYRING_SERVICE, &format!("{KEYRING_USER}.{suffix}"))?;
entry.delete_password()
}

#[allow(dead_code)]
pub(crate) fn get(suffix: &str) -> Result<SecretString, keyring::Error> {
let entry = Entry::new(KEYRING_SERVICE, &format!("{KEYRING_USER}.{suffix}"))?;
Ok(SecretString::from_str(&entry.get_password()?).unwrap())
Expand Down

0 comments on commit 1835673

Please sign in to comment.