Move filesystem-related stuff into the config module

This commit is contained in:
Andrey Golovizin 2023-04-15 13:55:25 +02:00
parent a792007abd
commit 10cdbce746
3 changed files with 48 additions and 30 deletions

View file

@ -1,8 +1,10 @@
use directories::ProjectDirs; use directories::ProjectDirs;
use gethostname::gethostname; use gethostname::gethostname;
use std::{io::Write, path::Path};
use crate::keys::Key;
use once_cell::sync::OnceCell; use once_cell::sync::OnceCell;
use std::path::{Path, PathBuf}; use std::path::PathBuf;
const QUALIFIER: &str = "com"; const QUALIFIER: &str = "com";
const ORGANIZATION: &str = "Ero-sennin"; const ORGANIZATION: &str = "Ero-sennin";
@ -41,19 +43,52 @@ impl MachineConfig {
Ok(()) Ok(())
} }
pub(crate) fn path(&self) -> &Path { pub(crate) fn username(&self) -> anyhow::Result<String> {
Ok(std::fs::read_to_string(self.username_path())?)
}
pub(crate) fn token(&self) -> anyhow::Result<String> {
Ok(std::fs::read_to_string(self.token_path())?)
}
pub(crate) fn has_key(&self) -> bool {
self.key_path().is_file()
}
pub(crate) fn key(&self) -> anyhow::Result<Key> {
let key_data = std::fs::read_to_string(self.key_path())?;
Key::try_from_base64(key_data.trim_end())
}
pub(crate) fn save_username(&self, username: &str) -> anyhow::Result<()> {
std::fs::write(self.username_path(), username)?;
Ok(())
}
pub(crate) fn save_token(&self, token: &str) -> anyhow::Result<()> {
std::fs::write(self.token_path(), token)?;
Ok(())
}
pub(crate) fn save_key(&self, key: &Key) -> anyhow::Result<()> {
let mut file = std::fs::File::create(self.key_path())?;
writeln!(file, "{}", key.to_base64())?;
Ok(())
}
fn path(&self) -> &Path {
&self.path &self.path
} }
pub(crate) fn username_path(&self) -> PathBuf { fn username_path(&self) -> PathBuf {
self.path().join("username") self.path().join("username")
} }
pub(crate) fn token_path(&self) -> PathBuf { fn token_path(&self) -> PathBuf {
self.path().join("token") self.path().join("token")
} }
pub(crate) fn key_path(&self) -> PathBuf { fn key_path(&self) -> PathBuf {
self.path().join("key") self.path().join("key")
} }
} }

View file

@ -1,9 +1,6 @@
use base64::prelude::{Engine as _, BASE64_STANDARD}; use base64::prelude::{Engine as _, BASE64_STANDARD};
use log::debug;
use x25519_dalek::{PublicKey, StaticSecret}; use x25519_dalek::{PublicKey, StaticSecret};
use std::{io::Write, path::Path};
use crate::config::MachineConfig; use crate::config::MachineConfig;
const KEY_SIZE: usize = 32; const KEY_SIZE: usize = 32;
@ -12,7 +9,7 @@ const KEY_SIZE: usize = 32;
pub(crate) struct Key([u8; KEY_SIZE]); pub(crate) struct Key([u8; KEY_SIZE]);
impl Key { impl Key {
fn try_from_base64(data: &str) -> anyhow::Result<Self> { pub(crate) fn try_from_base64(data: &str) -> anyhow::Result<Self> {
let mut key_data = [0u8; KEY_SIZE]; let mut key_data = [0u8; KEY_SIZE];
let key_bytes = BASE64_STANDARD.decode(data)?; let key_bytes = BASE64_STANDARD.decode(data)?;
assert_eq!(key_bytes.len(), KEY_SIZE); assert_eq!(key_bytes.len(), KEY_SIZE);
@ -23,17 +20,6 @@ impl Key {
pub(crate) fn to_base64(&self) -> String { pub(crate) fn to_base64(&self) -> String {
BASE64_STANDARD.encode(self.0) BASE64_STANDARD.encode(self.0)
} }
fn load(path: &Path) -> anyhow::Result<Self> {
let key_data = std::fs::read_to_string(path)?;
Self::try_from_base64(key_data.trim_end())
}
fn save(&self, path: &Path) -> anyhow::Result<()> {
let mut file = std::fs::File::create(path)?;
writeln!(file, "{}", self.to_base64())?;
Ok(())
}
} }
#[derive(Debug)] #[derive(Debug)]
@ -43,14 +29,11 @@ pub(crate) struct WireguardKeyPair {
} }
pub(crate) fn get_keys(machine_config: &MachineConfig) -> Result<WireguardKeyPair, anyhow::Error> { pub(crate) fn get_keys(machine_config: &MachineConfig) -> Result<WireguardKeyPair, anyhow::Error> {
let key_path = machine_config.key_path(); let private_key = if machine_config.has_key() {
debug!("key path = {:?}", &key_path); machine_config.key()?
let private_key = if key_path.is_file() {
Key::load(&key_path)?
} else { } else {
let key = generate_private_key(); let key = generate_private_key();
key.save(&key_path)?; machine_config.save_key(&key)?;
key key
}; };

View file

@ -76,8 +76,8 @@ fn main() -> Result<(), anyhow::Error> {
fn login(opts: &Opts, login_opts: &LoginOpts) -> Result<(), anyhow::Error> { fn login(opts: &Opts, login_opts: &LoginOpts) -> Result<(), anyhow::Error> {
let machine_config = config::MachineConfig::new(opts.machine.as_ref())?; let machine_config = config::MachineConfig::new(opts.machine.as_ref())?;
std::fs::write(machine_config.username_path(), &login_opts.username)?; machine_config.save_username(&login_opts.username)?;
std::fs::write(machine_config.token_path(), &login_opts.token)?; machine_config.save_token(&login_opts.token)?;
Ok(()) Ok(())
} }
@ -131,9 +131,9 @@ fn get_config(opts: &Opts, config_opts: &ConfigOpts) -> Result<(), anyhow::Error
.ok_or_else(|| anyhow::anyhow!("no such location: {}", config_opts.location))?; .ok_or_else(|| anyhow::anyhow!("no such location: {}", config_opts.location))?;
debug!("location = {:?}", &location); debug!("location = {:?}", &location);
let keys = get_keys(&machine_config)?; let keys = get_keys(&machine_config)?;
let username = std::fs::read_to_string(machine_config.username_path())?;
let token = std::fs::read_to_string(machine_config.token_path())?;
debug!("keys = {:?}", &keys); debug!("keys = {:?}", &keys);
let username = machine_config.username()?;
let token = machine_config.token()?;
let addresses = api::add_ip(&username, &token, &keys.public_key)?; let addresses = api::add_ip(&username, &token, &keys.public_key)?;
write_config( write_config(