Pour tout problème contactez-nous par mail : support@froggit.fr | La FAQ :grey_question: | Rejoignez-nous sur le Chat :speech_balloon:

Skip to content
Snippets Groups Projects
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);
    }
}