2020-04-19 12:14:47 +00:00
|
|
|
use argon2::{Config, Variant};
|
2020-04-06 20:57:58 +00:00
|
|
|
use rand::prelude::*;
|
2020-03-30 11:46:18 +00:00
|
|
|
use std::{
|
|
|
|
convert::TryInto,
|
|
|
|
time::{SystemTime, UNIX_EPOCH},
|
|
|
|
};
|
2020-03-29 11:48:44 +00:00
|
|
|
|
2020-04-12 19:12:50 +00:00
|
|
|
pub fn millis_since_unix_epoch() -> u64 {
|
|
|
|
SystemTime::now()
|
2020-03-29 11:48:44 +00:00
|
|
|
.duration_since(UNIX_EPOCH)
|
2020-06-09 13:13:17 +00:00
|
|
|
.expect("time is valid")
|
2020-04-12 19:12:50 +00:00
|
|
|
.as_millis() as u64
|
2020-03-29 11:48:44 +00:00
|
|
|
}
|
2020-03-29 19:05:20 +00:00
|
|
|
|
2020-03-30 11:46:18 +00:00
|
|
|
pub fn increment(old: Option<&[u8]>) -> Option<Vec<u8>> {
|
2020-06-09 13:13:17 +00:00
|
|
|
let number = match old.map(|bytes| bytes.try_into()) {
|
|
|
|
Some(Ok(bytes)) => {
|
|
|
|
let number = u64::from_be_bytes(bytes);
|
2020-03-30 11:46:18 +00:00
|
|
|
number + 1
|
|
|
|
}
|
2020-06-09 13:13:17 +00:00
|
|
|
_ => 1, // Start at one. since 0 should return the first event in the db
|
2020-03-30 11:46:18 +00:00
|
|
|
};
|
2020-03-29 19:05:20 +00:00
|
|
|
|
2020-03-30 11:46:18 +00:00
|
|
|
Some(number.to_be_bytes().to_vec())
|
2020-03-29 19:05:20 +00:00
|
|
|
}
|
|
|
|
|
2020-04-19 12:14:47 +00:00
|
|
|
pub fn generate_keypair(old: Option<&[u8]>) -> Option<Vec<u8>> {
|
2020-06-09 13:13:17 +00:00
|
|
|
Some(old.map(|s| s.to_vec()).unwrap_or_else(|| {
|
|
|
|
ruma::signatures::Ed25519KeyPair::generate()
|
|
|
|
.expect("Ed25519KeyPair generation always works (?)")
|
|
|
|
}))
|
2020-04-19 12:14:47 +00:00
|
|
|
}
|
|
|
|
|
2020-05-03 15:25:31 +00:00
|
|
|
/// Parses the bytes into an u64.
|
2020-06-09 13:13:17 +00:00
|
|
|
pub fn u64_from_bytes(bytes: &[u8]) -> Result<u64, std::array::TryFromSliceError> {
|
|
|
|
let array: [u8; 8] = bytes.try_into()?;
|
|
|
|
Ok(u64::from_be_bytes(array))
|
2020-04-03 15:27:08 +00:00
|
|
|
}
|
|
|
|
|
2020-05-03 15:25:31 +00:00
|
|
|
/// Parses the bytes into a string.
|
2020-06-09 13:13:17 +00:00
|
|
|
pub fn string_from_bytes(bytes: &[u8]) -> Result<String, std::string::FromUtf8Error> {
|
|
|
|
String::from_utf8(bytes.to_vec())
|
2020-03-29 19:05:20 +00:00
|
|
|
}
|
2020-04-06 20:57:58 +00:00
|
|
|
|
|
|
|
pub fn random_string(length: usize) -> String {
|
|
|
|
thread_rng()
|
|
|
|
.sample_iter(&rand::distributions::Alphanumeric)
|
|
|
|
.take(length)
|
|
|
|
.collect()
|
|
|
|
}
|
2020-04-14 20:25:44 +00:00
|
|
|
|
|
|
|
/// Calculate a new hash for the given password
|
2020-06-09 13:13:17 +00:00
|
|
|
pub fn calculate_hash(password: &str) -> Result<String, argon2::Error> {
|
2020-04-14 20:25:44 +00:00
|
|
|
let hashing_config = Config {
|
|
|
|
variant: Variant::Argon2id,
|
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
|
|
|
|
let salt = random_string(32);
|
2020-04-19 12:14:47 +00:00
|
|
|
argon2::hash_encoded(password.as_bytes(), salt.as_bytes(), &hashing_config)
|
|
|
|
}
|