68 lines
1.6 KiB
Rust
68 lines
1.6 KiB
Rust
|
use std::{
|
||
|
fs::File,
|
||
|
time::{SystemTime, UNIX_EPOCH},
|
||
|
};
|
||
|
|
||
|
use password_hash::{PasswordHash, PasswordHasher, SaltString};
|
||
|
use pbkdf2::{Params, Pbkdf2};
|
||
|
use serde::{de::DeserializeOwned, Serialize};
|
||
|
|
||
|
#[must_use]
|
||
|
pub fn load_or_create_config<T>(path: &str) -> T
|
||
|
where
|
||
|
T: Default + Serialize + DeserializeOwned,
|
||
|
{
|
||
|
std::fs::read_to_string(path).map_or_else(
|
||
|
|_| {
|
||
|
let defaults = T::default();
|
||
|
std::fs::write(path, toml::to_string(&defaults).unwrap()).unwrap();
|
||
|
defaults
|
||
|
},
|
||
|
|data| toml::from_str(&data).unwrap(),
|
||
|
)
|
||
|
}
|
||
|
|
||
|
#[must_use]
|
||
|
pub fn open_secret_key() -> Result<File, std::io::Error> {
|
||
|
File::open("assets/security/client_secret_key.ec2b")
|
||
|
}
|
||
|
|
||
|
#[must_use]
|
||
|
pub fn cur_timestamp_ms() -> u64 {
|
||
|
SystemTime::now()
|
||
|
.duration_since(UNIX_EPOCH)
|
||
|
.unwrap()
|
||
|
.as_millis() as u64
|
||
|
}
|
||
|
|
||
|
#[must_use]
|
||
|
pub fn cur_timestamp() -> u64 {
|
||
|
SystemTime::now()
|
||
|
.duration_since(UNIX_EPOCH)
|
||
|
.unwrap()
|
||
|
.as_secs() as u64
|
||
|
}
|
||
|
|
||
|
#[must_use]
|
||
|
pub fn hash_string(content: &str) -> Result<String, pbkdf2::password_hash::Error> {
|
||
|
let salt = SaltString::generate(rand::thread_rng());
|
||
|
let hash = Pbkdf2.hash_password_customized(
|
||
|
content.as_bytes(),
|
||
|
None,
|
||
|
None,
|
||
|
Params {
|
||
|
rounds: 10000,
|
||
|
output_length: 32,
|
||
|
},
|
||
|
&salt,
|
||
|
)?;
|
||
|
|
||
|
Ok(hash.serialize().to_string())
|
||
|
}
|
||
|
|
||
|
#[must_use]
|
||
|
pub fn verify_hash(content: &str, hash_str: &str) -> Option<()> {
|
||
|
let hash = PasswordHash::new(hash_str).ok()?;
|
||
|
hash.verify_password(&[&Pbkdf2], content).ok()
|
||
|
}
|