-
Pierre Jarriges authoredPierre Jarriges authored
crypto.rs 3.31 KiB
use magic_crypt::{MagicCrypt, MagicCryptTrait, SecureBit};
use rand::{distributions::Alphanumeric, Rng};
#[derive(Debug, Clone)]
/// A structure responsible of encrypting and decrypting data such as auth token, passwords and email addresses.
pub struct Encryption {
/// The encryption key must be keeped secret and is loaded from the $CRYPT_KEY environment variable
pub key: String,
}
impl Encryption {
pub fn new(key: String) -> Self {
Encryption { key }
}
/// Gets a string as an argument and returns a base64 hash of the string based on the secret key and magic_crypt::SecureBit::Bit256 algorithm
pub fn encrypt(&self, source: &String) -> String {
let mc = MagicCrypt::new(&self.key, SecureBit::Bit256, None::<String>);
mc.encrypt_str_to_base64(source)
}
/// Gets a string base64 hash as an argument and returns the decryted string.
/// Panics if the source base64 string cannot be decrypted (should happen if trying to decrypt a regular string)
#[cfg(test)]
pub fn decrypt(&self, source: &String) -> String {
let mc = MagicCrypt::new(&self.key, SecureBit::Bit256, None::<String>);
mc.decrypt_base64_to_string(source).unwrap()
}
/// Generates a random ascii lowercase string. Length being given as argument.
pub fn random_ascii_lc_string(&self, length: usize) -> String {
// Thanks to https://stackoverflow.com/questions/54275459/how-do-i-create-a-random-string-by-sampling-from-alphanumeric-characters#54277357
rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(length)
.map(char::from)
.collect::<String>()
.to_ascii_lowercase()
}
}
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@
*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@
* _______ ______ ______ _______ *@@
* |__ __@ | ____@ / ____@ |__ __@ *@@
* | @ | @__ \_ @_ | @ *@@
* | @ | __@ \ @_ | @ *@@
* | @ | @___ ____\ @ | @ *@@
* |__@ |______@ \______@ |__@ *@@
* *@@
*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@
*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@*/
#[cfg(test)]
mod test_encryption {
use super::*;
#[test]
fn test_random_ascii_lc_string() {
dotenv::dotenv().ok();
let key = std::env::var("CRYPT_KEY").unwrap();
let enc = Encryption::new(key);
let rdm_str = enc.random_ascii_lc_string(32);
assert_eq!(rdm_str.len(), 32);
assert!(rdm_str.chars().all(char::is_alphanumeric));
assert_eq!(rdm_str, rdm_str.to_lowercase());
}
#[test]
fn test_encrypt() {
dotenv::dotenv().ok();
let key = std::env::var("CRYPT_KEY").unwrap();
let enc = Encryption::new(key);
let an_email = String::from("kuadrado-email@test.com");
let email_hash = enc.encrypt(&an_email);
assert_ne!(an_email, email_hash);
}
#[test]
fn test_decrypt() {
dotenv::dotenv().ok();
let key = std::env::var("CRYPT_KEY").unwrap();
let enc = Encryption::new(key);
let an_email = String::from("kuadrado-email@test.com");
let email_hash = enc.encrypt(&an_email);
let decrypted = enc.decrypt(&email_hash);
assert_eq!(an_email, decrypted);
}
}