diff --git a/.gitignore b/.gitignore index 2a0038a..c391ef9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /target -.idea \ No newline at end of file +.idea +*.env +test \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 8fd358e..c04e35f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,6 +15,35 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6789e291be47ace86a60303502173d84af8327e3627ecf334356ee0f87a164c" +[[package]] +name = "aho-corasick" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.0.1" @@ -48,6 +77,12 @@ version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +[[package]] +name = "cc" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed67cbde08356238e75fc4656be4749481eeffb09e19f320a25237d5221c985d" + [[package]] name = "cfg-if" version = "0.1.10" @@ -83,6 +118,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "time", + "winapi", +] + [[package]] name = "cipher" version = "0.2.5" @@ -92,6 +140,21 @@ dependencies = [ "generic-array", ] +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + [[package]] name = "cloudabi" version = "0.1.0" @@ -101,6 +164,17 @@ dependencies = [ "bitflags", ] +[[package]] +name = "colored" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +dependencies = [ + "atty", + "lazy_static", + "winapi", +] + [[package]] name = "const_fn" version = "0.4.3" @@ -161,6 +235,25 @@ dependencies = [ "generic-array", ] +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "env_logger" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54532e3223c5af90a6a757c90b5c5521564b07e5e7a958681bcd2afad421cdcd" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + [[package]] name = "fallible-iterator" version = "0.2.0" @@ -191,7 +284,7 @@ checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" dependencies = [ "cfg-if 0.1.10", "libc", - "wasi", + "wasi 0.9.0+wasi-snapshot-preview1", ] [[package]] @@ -212,6 +305,41 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "heck" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" +dependencies = [ + "libc", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "humantime" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a" + [[package]] name = "instant" version = "0.1.8" @@ -261,12 +389,50 @@ dependencies = [ "cfg-if 0.1.10", ] +[[package]] +name = "mac_address" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d9bb26482176bddeea173ceaa2acec85146d20cdcc631eafaf9d605d3d4fc23" +dependencies = [ + "nix", + "winapi", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + [[package]] name = "memchr" version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +[[package]] +name = "nix" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85db2feff6bf70ebc3a4793191517d5f0331100a2f10f9bf93b5e5214f32b7b7" +dependencies = [ + "bitflags", + "cc", + "cfg-if 0.1.10", + "libc", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.14" @@ -329,6 +495,30 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.24" @@ -394,6 +584,24 @@ version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +[[package]] +name = "regex" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" + [[package]] name = "rmp" version = "0.8.9" @@ -499,11 +707,51 @@ name = "snekcloud-node" version = "0.1.0" dependencies = [ "base64", + "chrono", + "colored", + "dotenv", + "env_logger", + "hostname", + "log", + "mac_address", "rand", "rusqlite", + "serde", + "structopt", + "toml", "vented", ] +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "structopt" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126d630294ec449fae0b16f964e35bf3c74f940da9dca17ee9b905f7b3112eb8" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e51c492f9e23a220534971ff5afc14037289de430e3c83f9daf6a1b6ae91e8" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "subtle" version = "2.3.0" @@ -533,12 +781,71 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "termcolor" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "time" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "toml" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645" +dependencies = [ + "serde", +] + [[package]] name = "typenum" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" +[[package]] +name = "unicode-segmentation" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + [[package]] name = "unicode-xid" version = "0.2.1" @@ -561,6 +868,12 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "vented" version = "0.1.2" @@ -595,6 +908,12 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "winapi" version = "0.3.9" @@ -611,6 +930,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 6c3027e..7c41452 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,4 +10,14 @@ edition = "2018" vented = "0.1.2" rusqlite = "0.24.1" rand = "0.7.3" -base64 = "0.13.0" \ No newline at end of file +base64 = "0.13.0" +structopt = "0.3.20" +dotenv = "0.15.0" +mac_address = "1.1.1" +hostname = "0.3.1" +log = "0.4.11" +env_logger = "0.8.1" +colored = "2.0.0" +chrono = "0.4.19" +toml = "0.5.7" +serde = { version = "1.0.117", features = ["serde_derive"] } \ No newline at end of file diff --git a/src/data/mod.rs b/src/data/mod.rs new file mode 100644 index 0000000..6f8c3ca --- /dev/null +++ b/src/data/mod.rs @@ -0,0 +1 @@ +pub mod node_data; \ No newline at end of file diff --git a/src/data/node_data.rs b/src/data/node_data.rs new file mode 100644 index 0000000..4832417 --- /dev/null +++ b/src/data/node_data.rs @@ -0,0 +1,44 @@ +use serde::{Serialize, Deserialize}; +use vented::crypto::PublicKey; +use crate::utils::keys::{armor_public_key, extract_public_key}; +use std::path::PathBuf; +use crate::utils::result::SnekcloudResult; +use std::fs; + +#[derive(Serialize, Deserialize)] +pub struct NodeData { + pub id: String, + pub address: Option, + public_key: String, +} + +impl NodeData { + pub fn with_address(id: String, address: String, public_key: PublicKey) -> Self { + let public_key = armor_public_key(public_key); + Self { + id, + address: Some(address), + public_key + } + } + + /// Creates the data structure from a given file + pub fn from_file(path: PathBuf) -> SnekcloudResult { + let content = fs::read_to_string(path)?; + let result = toml::from_str(&content)?; + + Ok(result) + } + + /// Writes the data to the given file + pub fn write_to_file(&self, path: PathBuf) -> SnekcloudResult<()> { + let content = toml::to_string(self)?; + fs::write(path, content.as_bytes())?; + + Ok(()) + } + + pub fn public_key(&self) -> PublicKey { + extract_public_key(&self.public_key).unwrap() + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index ca17819..ad615d3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,81 @@ +use crate::server::SnekcloudServer; +use crate::utils::get_node_id; +use crate::utils::env::{get_private_key_path, get_key_file_storage, get_listen_address}; +use crate::utils::keys::{extract_private_key, read_node_keys, generate_private_key, armor_private_key}; +use std::path::PathBuf; +use crate::utils::result::SnekcloudResult; +use crate::utils::logging::init_logger; +use std::fs; +use structopt::StructOpt; +use vented::crypto::SecretKey; +use crate::data::node_data::NodeData; + pub(crate) mod utils; pub(crate) mod server; +pub(crate) mod data; + +#[derive(StructOpt, Debug)] +struct Opt { + #[structopt(subcommand)] + sub_command: Option +} + +#[derive(StructOpt, Debug)] +#[structopt()] +enum SubCommand { + /// Generates a new private key + GenerateKey(GenerateKeyOptions), + + WriteInfoFile(WriteInfoFileOptions) +} + +#[derive(StructOpt, Debug)] +struct GenerateKeyOptions { + /// The file the key is stored to + #[structopt(parse(from_os_str))] + output_file: PathBuf +} -fn main() { - unimplemented!() + +#[derive(StructOpt, Debug)] +struct WriteInfoFileOptions { + /// The file the info is stored to + #[structopt(parse(from_os_str))] + output_file: PathBuf +} + +fn main() -> SnekcloudResult<()>{ + init_logger(); + let opt: Opt = Opt::from_args(); + if let Some(command) = opt.sub_command { + match command { + SubCommand::GenerateKey(options) => { + let key = generate_private_key(); + let string_content = armor_private_key(key); + fs::write(options.output_file, string_content)?; + }, + SubCommand::WriteInfoFile(options) => { + let key = get_private_key()?; + let data = NodeData::with_address(get_node_id(), get_listen_address(), key.public_key()); + data.write_to_file(options.output_file)?; + } + } + } else { + start_server(opt)?; + } + + Ok(()) } + +fn start_server(_options: Opt) -> SnekcloudResult<()> { + let keys = read_node_keys(&PathBuf::from(get_key_file_storage()))?; + let mut server = SnekcloudServer::new(get_node_id(), get_private_key()?, keys, 8); + server.add_listen_address(get_listen_address()); + server.run()?; + + Ok(()) +} + +fn get_private_key() -> SnekcloudResult { + extract_private_key(&fs::read_to_string(get_private_key_path())?) +} \ No newline at end of file diff --git a/src/server/mod.rs b/src/server/mod.rs index 673c3ff..29c18cf 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -1,7 +1,6 @@ use vented::server::VentedServer; use crate::utils::result::SnekcloudResult; use vented::crypto::SecretKey; -use std::path::PathBuf; use vented::server::data::Node; use vented::WaitGroup; diff --git a/src/utils/env.rs b/src/utils/env.rs new file mode 100644 index 0000000..d098601 --- /dev/null +++ b/src/utils/env.rs @@ -0,0 +1,20 @@ +const VAR_KEY_FILE_STORAGE: &str = "SNEKCLOUD_NODES_DIR"; +const VAR_PRIVATE_KEY_PATH: &str = "SNEKCLOUD_PRIVATE_KEY"; +const VAR_LISTEN_ADDRESS: &str = "SNEKCLOUD_LISTEN_ADDRESS"; +const VAR_NODE_ID: &str = "SNEKCLOUD_NODE_ID"; + +pub fn get_key_file_storage() -> String { + dotenv::var(VAR_KEY_FILE_STORAGE).unwrap_or("keys".to_string()) +} + +pub fn get_private_key_path() -> String { + dotenv::var(VAR_PRIVATE_KEY_PATH).unwrap_or("node_key".to_string()) +} + +pub fn get_env_node_id() -> Option { + dotenv::var(VAR_NODE_ID).ok() +} + +pub fn get_listen_address() -> String { + dotenv::var(VAR_LISTEN_ADDRESS).unwrap_or("127.0.0.1:22222".to_string()) +} \ No newline at end of file diff --git a/src/utils/keys.rs b/src/utils/keys.rs index a86043a..e43f265 100644 --- a/src/utils/keys.rs +++ b/src/utils/keys.rs @@ -1,8 +1,8 @@ use std::path::PathBuf; use vented::crypto::{SecretKey, PublicKey}; -use std::fs; use crate::utils::result::{SnekcloudResult, SnekcloudError}; use vented::server::data::Node; +use crate::data::node_data::NodeData; const PRIVATE_KEY_HEADER_LINE: &str = "---BEGIN-SNEKCLOUD-PRIVATE-KEY---\n"; const PRIVATE_KEY_FOOTER_LINE: &str = "\n---END-SNEKCLOUD-PRIVATE-KEY---"; @@ -22,37 +22,30 @@ pub fn read_node_keys(path: &PathBuf) -> SnekcloudResult> { }) .filter(|(meta, _)|meta.is_file()) .filter_map(|(_, entry)|{ - let key = read_public_key(&entry.path()).ok()?; + let data = NodeData::from_file(entry.path()).ok()?; - let file_name = entry.file_name(); - let file_name = file_name.to_string_lossy(); - let node_id = file_name.trim_end_matches(".pub"); - - Some(Node {public_key: key, address: None, id: node_id.to_string()}) + Some(Node {public_key: data.public_key(), address: data.address, id: data.id}) }).collect(); Ok(content) } /// Reads the private key from a file -pub fn read_private_key(filename: &PathBuf) -> SnekcloudResult { - let content = fs::read_to_string(filename)?; - - let bytes = extract_key(content, PUBLIC_KEY_HEADER_LINE, PUBLIC_KEY_FOOTER_LINE)?; +pub fn extract_private_key(content: &str) -> SnekcloudResult { + let bytes = extract_key(content, PRIVATE_KEY_HEADER_LINE, PRIVATE_KEY_FOOTER_LINE)?; Ok(SecretKey::from(bytes)) } /// Reads the public key from a file -pub fn read_public_key(filename: &PathBuf) -> SnekcloudResult { - let content = fs::read_to_string(filename)?; +pub fn extract_public_key(content: &str) -> SnekcloudResult { let bytes = extract_key(content, PUBLIC_KEY_HEADER_LINE, PUBLIC_KEY_FOOTER_LINE)?; Ok(PublicKey::from(bytes)) } /// Extracts a base64 encoded key between the prefix and suffix -fn extract_key(content: String, prefix: &str, suffix: &str) -> SnekcloudResult<[u8; 32]> { +fn extract_key(content: &str, prefix: &str, suffix: &str) -> SnekcloudResult<[u8; 32]> { let mut content = content.strip_prefix(prefix).ok_or(SnekcloudError::InvalidKey)?; content = content.strip_suffix(suffix).ok_or(SnekcloudError::InvalidKey)?; @@ -64,4 +57,24 @@ fn extract_key(content: String, prefix: &str, suffix: &str) -> SnekcloudResult<[ key_bytes.copy_from_slice(&key[..]); Ok(key_bytes) +} + +/// Encodes and encases the public key for text representation +pub fn armor_public_key(key: PublicKey) -> String { + armor_key(key.to_bytes(), PUBLIC_KEY_HEADER_LINE, PUBLIC_KEY_FOOTER_LINE) +} + +/// Encodes and encases the secret key for text representation +pub fn armor_private_key(key: SecretKey) -> String { + armor_key(key.to_bytes(), PRIVATE_KEY_HEADER_LINE, PRIVATE_KEY_FOOTER_LINE) +} + +/// Returns an armored key +fn armor_key(key: [u8; 32], prefix: &str, suffix: &str) -> String { + format!("{}{}{}", prefix, base64::encode(key), suffix) +} + +/// Generates a new private key +pub fn generate_private_key() -> SecretKey { + SecretKey::generate(&mut rand::thread_rng()) } \ No newline at end of file diff --git a/src/utils/logging.rs b/src/utils/logging.rs new file mode 100644 index 0000000..4f1ebb7 --- /dev/null +++ b/src/utils/logging.rs @@ -0,0 +1,40 @@ +use log::Level; +use std::thread; +use env_logger::Env; +use chrono::Local; +use colored::*; + +/// Initializes the env_logger with a custom format +/// that also logs the thread names +pub fn init_logger() { + env_logger::Builder::from_env(Env::default().default_filter_or("info")) + .format(|buf, record| { + use std::io::Write; + let color = get_level_style(record.level()); + writeln!( + buf, + "{:<12} {:<45}| {} {}: {}", + format!("thread::{}", thread::current().name().unwrap_or("main")).dimmed(), + record.target().dimmed().italic(), + Local::now().format("%Y-%m-%dT%H:%M:%S"), + record + .level() + .to_string() + .to_lowercase() + .as_str() + .color(color), + record.args() + ) + }) + .init(); +} + +fn get_level_style(level: Level) -> colored::Color { + match level { + Level::Trace => colored::Color::Magenta, + Level::Debug => colored::Color::Blue, + Level::Info => colored::Color::Green, + Level::Warn => colored::Color::Yellow, + Level::Error => colored::Color::Red, + } +} \ No newline at end of file diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 566d7ad..e7659f2 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,2 +1,27 @@ +use crate::utils::env::get_env_node_id; +use rand::RngCore; + pub mod result; -pub mod keys; \ No newline at end of file +pub mod keys; +pub mod env; +pub mod logging; + +pub fn get_node_id() -> String { + if let Some(id) = get_env_node_id() { + log::trace!("Using env node_id"); + id + } else if let Ok(Some(address)) = mac_address::get_mac_address() { + log::trace!("Using mac address as node_id"); + base64::encode(address.bytes()) + } else if let Ok(hostname) = hostname::get() { + log::trace!("Using hostname as node_id"); + base64::encode(hostname.to_string_lossy().as_bytes()) + } else { + log::trace!("Randomly generating node_id"); + let mut rng = rand::thread_rng(); + let mut id_raw = [0u8; 16]; + rng.fill_bytes(&mut id_raw); + + base64::encode(id_raw) + } +} \ No newline at end of file diff --git a/src/utils/result.rs b/src/utils/result.rs index 5ea3632..3bcb80e 100644 --- a/src/utils/result.rs +++ b/src/utils/result.rs @@ -11,6 +11,8 @@ pub enum SnekcloudError { Vented(VentedError), IoError(io::Error), Base64DecodeError(base64::DecodeError), + TomlDeserializeError(toml::de::Error), + TomlSerializeError(toml::ser::Error), InvalidKey, } @@ -21,6 +23,8 @@ impl fmt::Display for SnekcloudError { Self::IoError(e) => write!(f, "IO Error: {}", e), Self::Base64DecodeError(e) => write!(f, "Base 64 Decode error: {}", e), Self::InvalidKey => write!(f, "Invalid Key!"), + Self::TomlDeserializeError(e) => write!(f, "Toml Deserialization Error: {}", e), + Self::TomlSerializeError(e) => write!(f, "Toml Serialization Error: {}", e), } } } @@ -43,4 +47,16 @@ impl From for SnekcloudError { fn from(error: base64::DecodeError) -> Self { Self::Base64DecodeError(error) } +} + +impl From for SnekcloudError { + fn from(other: toml::ser::Error) -> Self { + Self::TomlSerializeError(other) + } +} + +impl From for SnekcloudError { + fn from(other: toml::de::Error) -> Self { + Self::TomlDeserializeError(other) + } } \ No newline at end of file